Path: blob/main/crates/wasi/src/cli/stdout.rs
1693 views
use crate::cli::{IsTerminal, StdoutStream};1use crate::p2;2use bytes::Bytes;3use std::io::{self, Write};4use std::pin::Pin;5use std::task::{Context, Poll};6use tokio::io::AsyncWrite;7use wasmtime_wasi_io::streams::OutputStream;89// Implementation for tokio::io::Stdout10impl IsTerminal for tokio::io::Stdout {11fn is_terminal(&self) -> bool {12std::io::stdout().is_terminal()13}14}15impl StdoutStream for tokio::io::Stdout {16fn p2_stream(&self) -> Box<dyn OutputStream> {17Box::new(StdioOutputStream::Stdout)18}19fn async_stream(&self) -> Box<dyn AsyncWrite + Send + Sync> {20Box::new(StdioOutputStream::Stdout)21}22}2324// Implementation for std::io::Stdout25impl IsTerminal for std::io::Stdout {26fn is_terminal(&self) -> bool {27std::io::IsTerminal::is_terminal(self)28}29}30impl StdoutStream for std::io::Stdout {31fn p2_stream(&self) -> Box<dyn OutputStream> {32Box::new(StdioOutputStream::Stdout)33}34fn async_stream(&self) -> Box<dyn AsyncWrite + Send + Sync> {35Box::new(StdioOutputStream::Stdout)36}37}3839// Implementation for tokio::io::Stderr40impl IsTerminal for tokio::io::Stderr {41fn is_terminal(&self) -> bool {42std::io::stderr().is_terminal()43}44}45impl StdoutStream for tokio::io::Stderr {46fn p2_stream(&self) -> Box<dyn OutputStream> {47Box::new(StdioOutputStream::Stderr)48}49fn async_stream(&self) -> Box<dyn AsyncWrite + Send + Sync> {50Box::new(StdioOutputStream::Stderr)51}52}5354// Implementation for std::io::Stderr55impl IsTerminal for std::io::Stderr {56fn is_terminal(&self) -> bool {57std::io::IsTerminal::is_terminal(self)58}59}60impl StdoutStream for std::io::Stderr {61fn p2_stream(&self) -> Box<dyn OutputStream> {62Box::new(StdioOutputStream::Stderr)63}64fn async_stream(&self) -> Box<dyn AsyncWrite + Send + Sync> {65Box::new(StdioOutputStream::Stderr)66}67}6869enum StdioOutputStream {70Stdout,71Stderr,72}7374impl OutputStream for StdioOutputStream {75fn write(&mut self, bytes: Bytes) -> p2::StreamResult<()> {76match self {77StdioOutputStream::Stdout => std::io::stdout().write_all(&bytes),78StdioOutputStream::Stderr => std::io::stderr().write_all(&bytes),79}80.map_err(|e| p2::StreamError::LastOperationFailed(anyhow::anyhow!(e)))81}8283fn flush(&mut self) -> p2::StreamResult<()> {84match self {85StdioOutputStream::Stdout => std::io::stdout().flush(),86StdioOutputStream::Stderr => std::io::stderr().flush(),87}88.map_err(|e| p2::StreamError::LastOperationFailed(anyhow::anyhow!(e)))89}9091fn check_write(&mut self) -> p2::StreamResult<usize> {92Ok(1024 * 1024)93}94}9596impl AsyncWrite for StdioOutputStream {97fn poll_write(98self: Pin<&mut Self>,99_cx: &mut Context<'_>,100buf: &[u8],101) -> Poll<io::Result<usize>> {102Poll::Ready(match *self {103StdioOutputStream::Stdout => std::io::stdout().write(buf),104StdioOutputStream::Stderr => std::io::stderr().write(buf),105})106}107fn poll_flush(self: Pin<&mut Self>, _cx: &mut Context<'_>) -> Poll<io::Result<()>> {108Poll::Ready(match *self {109StdioOutputStream::Stdout => std::io::stdout().flush(),110StdioOutputStream::Stderr => std::io::stderr().flush(),111})112}113fn poll_shutdown(self: Pin<&mut Self>, _cx: &mut Context<'_>) -> Poll<io::Result<()>> {114Poll::Ready(Ok(()))115}116}117118#[async_trait::async_trait]119impl p2::Pollable for StdioOutputStream {120async fn ready(&mut self) {}121}122123124