ctf_pwn/io/pipe/
write.rs

1use crate::io::{AsyncCacheRead, PipeError, PipeRead, PipeReadExt};
2use crossterm::Command;
3use std::time::Duration;
4use tokio::io::{AsyncRead, AsyncWrite, AsyncWriteExt};
5
6pub trait PipeWrite: AsyncWrite {}
7
8impl<W: PipeWrite> PipeWriteExt for W {}
9
10pub trait PipeWriteExt: AsyncWrite {
11    async fn write_line<T: AsRef<[u8]>>(&mut self, text: T) -> Result<usize, PipeError>
12    where
13        Self: Unpin,
14    {
15        // to_vec is used so we dont accidentally trigger
16        // flush if user did not wrap writer into BufWriter
17        let mut res = text.as_ref().to_vec();
18        res.push(b'\n');
19        let size = self.write(&res).await?;
20        self.flush().await?;
21        Ok(size)
22    }
23
24    async fn write_line_crlf<T: AsRef<[u8]>>(&mut self, text: T) -> Result<usize, PipeError>
25    where
26        Self: Unpin,
27    {
28        let mut res = text.as_ref().to_vec();
29        res.push(b'\r');
30        res.push(b'\n');
31        let size = self.write(&res).await?;
32        self.flush().await?;
33        Ok(size)
34    }
35
36    async fn write_flush<T: AsRef<[u8]>>(&mut self, data: T) -> Result<usize, PipeError>
37    where
38        Self: Unpin,
39    {
40        let size = self.write(data.as_ref()).await?;
41        self.flush().await?;
42        Ok(size)
43    }
44
45    async fn write_all_flush<T: AsRef<[u8]>>(&mut self, data: T) -> Result<(), PipeError>
46    where
47        Self: Unpin,
48    {
49        self.write_all(data.as_ref()).await?;
50        self.flush().await?;
51        Ok(())
52    }
53
54    async fn write_ansi_command<T: Command>(&mut self, command: T) -> Result<usize, PipeError>
55    where
56        Self: Unpin,
57    {
58        let mut ansi_command = String::new();
59        command.write_ansi(&mut ansi_command)?;
60        let size = self.write(ansi_command.as_bytes()).await?;
61        self.flush().await?;
62        Ok(size)
63    }
64}