use std::pin::Pin; use std::task::{Context, Poll}; use tokio::io::{AsyncRead, AsyncWrite, ReadBuf}; use tracing::warn; #[derive(Debug)] pub struct PipeWriter { pub(crate) stream: S, } impl PipeWriter { pub async fn finish(mut self) -> Result<(), mtp_common::CommunicationError> { self.stream.finish().await.map_err(|e| { warn!("[PipeWriter] finish failed: {e}"); mtp_common::CommunicationError::StreamWriteError(e) }) } pub fn abort(&mut self) -> Result<(), wtransport::error::ClosedStream> { self.stream.reset(wtransport::VarInt::from_u32(0)) } } impl PipeWriter { pub fn into_inner(self) -> S { self.stream } pub async fn finish_async(mut self) -> Result<(), mtp_common::CommunicationError> { tokio::io::AsyncWriteExt::shutdown(&mut self) .await .map_err(|e| { warn!("[PipeWriter] finish_async failed: {e}"); mtp_common::CommunicationError::StreamError }) } } impl AsyncWrite for PipeWriter { fn poll_write( mut self: Pin<&mut Self>, cx: &mut Context<'_>, buf: &[u8], ) -> Poll> { Pin::new(&mut self.stream).poll_write(cx, buf) } fn poll_flush(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll> { Pin::new(&mut self.stream).poll_flush(cx) } fn poll_shutdown(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll> { Pin::new(&mut self.stream).poll_shutdown(cx) } } #[derive(Debug)] pub struct PipeReader { pub(crate) stream: R, pub(crate) description: String, pub(crate) pipe_id: u32, } impl PipeReader { pub fn into_inner(self) -> R { self.stream } pub fn description(&self) -> &str { &self.description } pub fn pipe_id(&self) -> u32 { self.pipe_id } } impl AsyncRead for PipeReader { fn poll_read( mut self: Pin<&mut Self>, cx: &mut Context<'_>, buf: &mut ReadBuf<'_>, ) -> Poll> { Pin::new(&mut self.stream).poll_read(cx, buf) } }