1#[cfg(not(feature = "tokio"))]
2mod imports {
3 pub(super) use std::io::{self, BufRead, BufReader, Stdin, Stdout, Write};
4 pub(super) use std::net::{Shutdown, TcpStream};
5 pub(super) use std::process::{Child, ChildStdin, ChildStdout};
6}
7#[cfg(feature = "tokio")]
8mod imports {
9 pub(super) use tokio::io::{
10 self, AsyncBufRead as BufRead, AsyncWrite as Write, AsyncWriteExt, BufReader, Stdin, Stdout,
11 };
12 pub(super) use tokio::net::tcp::{ReadHalf, WriteHalf};
13 pub(super) use tokio::net::TcpStream;
14 pub(super) use tokio::process::{Child, ChildStdin, ChildStdout};
15}
16
17use imports::*;
18
19#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash, Default)]
31pub struct Connection<R: BufRead, W: Write> {
32 reader: R,
33 writer: W,
34}
35
36impl<R: BufRead, W: Write> Connection<R, W> {
37 pub fn new(reader: R, writer: W) -> Self {
38 Self { reader, writer }
39 }
40}
41
42impl<'a> Connection<BufReader<&'a mut ChildStdout>, &'a mut ChildStdin> {
43 pub fn new_from_child(child: &'a mut Child) -> Option<Self> {
47 let stdin = child.stdin.as_mut()?;
48 let stdout = child.stdout.as_mut()?;
49
50 Some(Self {
51 reader: BufReader::new(stdout),
52 writer: stdin,
53 })
54 }
55}
56
57impl Connection<BufReader<Stdin>, Stdout> {
58 pub fn new_from_stdio() -> Self {
61 Self {
62 reader: BufReader::new(io::stdin()),
63 writer: io::stdout(),
64 }
65 }
66}
67
68#[cfg(not(feature = "tokio"))]
69impl Connection<BufReader<TcpStream>, TcpStream> {
70 pub fn new_from_tcp_stream(tcp_stream: TcpStream) -> io::Result<Self> {
72 Ok(Self {
73 reader: BufReader::new(tcp_stream.try_clone()?),
74 writer: tcp_stream,
75 })
76 }
77
78 pub fn shutdown(self) -> io::Result<()> {
80 self.writer.shutdown(Shutdown::Both)
81 }
82}
83
84#[cfg(feature = "tokio")]
85impl<'a> Connection<BufReader<ReadHalf<'a>>, WriteHalf<'a>> {
86 pub fn new_from_tcp_stream(tcp_stream: &'a mut TcpStream) -> io::Result<Self> {
88 let (read_half, write_half) = tcp_stream.split();
89
90 Ok(Self {
91 reader: BufReader::new(read_half),
92 writer: write_half,
93 })
94 }
95
96 pub async fn shutdown(mut self) -> io::Result<()> {
98 self.writer.shutdown().await
99 }
100}
101
102#[cfg(not(feature = "tokio"))]
103impl<R: BufRead, W: Write> Connection<R, W> {
104 pub fn read<T: serde::de::DeserializeOwned>(&mut self) -> Result<T, crate::ReadError> {
106 crate::read(&mut self.reader)
107 }
108
109 pub fn write<T: serde::Serialize>(&mut self, t: &T) -> Result<(), crate::WriteError> {
111 crate::write(&mut self.writer, t)
112 }
113
114 pub fn flush(&mut self) -> io::Result<()> {
116 self.writer.flush()
117 }
118}
119
120#[cfg(feature = "tokio")]
121impl<R: BufRead + Unpin, W: Write + Unpin> Connection<R, W> {
122 pub async fn read<T: serde::de::DeserializeOwned>(&mut self) -> Result<T, crate::ReadError> {
124 crate::read(&mut self.reader).await
125 }
126
127 pub async fn write<T: serde::Serialize>(&mut self, t: &T) -> Result<(), crate::WriteError> {
129 crate::write(&mut self.writer, t).await
130 }
131
132 pub async fn flush(&mut self) -> io::Result<()> {
134 self.writer.flush().await
135 }
136}