1use std::{future::Future, path::Path};
2
3#[cfg(feature = "smol-socket")]
4use futures_lite::{AsyncBufReadExt as SmolAsyncBufReadExt, AsyncWriteExt as SmolAsyncWriteExt, StreamExt};
5#[cfg(feature = "tokio-socket")]
6use tokio::io::{AsyncBufReadExt as TokioAsyncBufReadExt, AsyncWriteExt as TokioAsyncWriteExt};
7
8pub trait Socket: Send + Sync + Sized + Unpin {
12 fn connect(socket_path: &Path) -> impl Future<Output = Result<Self, std::io::Error>> + Send;
13
14 fn write_line(&mut self, line: String) -> impl Future<Output = Result<(), std::io::Error>> + Send;
15
16 fn read_line(&mut self) -> impl Future<Output = Result<Option<String>, std::io::Error>> + Send;
17}
18
19#[cfg(feature = "tokio-socket")]
21#[cfg_attr(docsrs, doc(cfg(feature = "tokio-socket")))]
22pub struct TokioSocket(tokio::net::UnixStream);
23
24#[cfg(feature = "tokio-socket")]
25#[cfg_attr(docsrs, doc(cfg(feature = "tokio-socket")))]
26impl Socket for TokioSocket {
27 async fn connect(socket_path: &Path) -> Result<Self, std::io::Error> {
28 tokio::net::UnixStream::connect(socket_path).await.map(Self)
29 }
30
31 async fn write_line(&mut self, line: String) -> Result<(), std::io::Error> {
32 self.0.write_all(format!("{line}\n").as_bytes()).await
33 }
34
35 async fn read_line(&mut self) -> Result<Option<String>, std::io::Error> {
36 let mut lines = tokio::io::BufReader::new(&mut self.0).lines();
37 lines.next_line().await
38 }
39}
40
41#[cfg(feature = "smol-socket")]
43#[cfg_attr(docsrs, doc(cfg(feature = "smol-socket")))]
44pub struct SmolSocket(async_net::unix::UnixStream);
45
46#[cfg(feature = "smol-socket")]
47#[cfg_attr(docsrs, doc(cfg(feature = "smol-socket")))]
48impl Socket for SmolSocket {
49 async fn connect(socket_path: &Path) -> Result<Self, std::io::Error> {
50 async_net::unix::UnixStream::connect(socket_path).await.map(Self)
51 }
52
53 async fn write_line(&mut self, line: String) -> Result<(), std::io::Error> {
54 self.0.write_all(format!("{line}\n").as_bytes()).await
55 }
56
57 async fn read_line(&mut self) -> Result<Option<String>, std::io::Error> {
58 let mut lines = futures_lite::io::BufReader::new(&mut self.0).lines();
59 lines.next().await.transpose()
60 }
61}