wrpc_transport/frame/
unix.rs1use std::path::{Path, PathBuf};
4
5use bytes::Bytes;
6use tokio::net::UnixStream;
7use tokio::net::unix::{OwnedReadHalf, OwnedWriteHalf};
8use tracing::instrument;
9
10use crate::Invoke;
11use crate::frame::{Incoming, Outgoing, invoke};
12
13pub type Oneshot = super::Oneshot<OwnedReadHalf, OwnedWriteHalf>;
18
19impl Oneshot {
20 pub fn unix_pair() -> std::io::Result<(Oneshot, UnixStream)> {
22 let (clt, srv) = UnixStream::pair()?;
23 Ok((clt.into(), srv))
24 }
25}
26
27impl From<UnixStream> for Oneshot {
28 fn from(stream: UnixStream) -> Self {
29 stream.into_split().into()
30 }
31}
32
33#[derive(Clone, Debug)]
35pub struct Client<T>(T);
36
37impl From<PathBuf> for Client<PathBuf> {
38 fn from(path: PathBuf) -> Self {
39 Self(path)
40 }
41}
42
43impl<'a> From<&'a Path> for Client<&'a Path> {
44 fn from(path: &'a Path) -> Self {
45 Self(path)
46 }
47}
48
49impl<'a> From<&'a std::os::unix::net::SocketAddr> for Client<&'a std::os::unix::net::SocketAddr> {
50 fn from(addr: &'a std::os::unix::net::SocketAddr) -> Self {
51 Self(addr)
52 }
53}
54
55impl From<std::os::unix::net::SocketAddr> for Client<std::os::unix::net::SocketAddr> {
56 fn from(addr: std::os::unix::net::SocketAddr) -> Self {
57 Self(addr)
58 }
59}
60
61impl Invoke for Client<PathBuf> {
62 type Context = ();
63
64 #[instrument(level = "trace", skip(self, paths, params), fields(params = format!("{params:02x?}")))]
65 async fn invoke<P>(
66 &self,
67 (): Self::Context,
68 instance: &str,
69 func: &str,
70 params: Bytes,
71 paths: impl AsRef<[P]> + Send,
72 ) -> anyhow::Result<(Outgoing, Incoming)>
73 where
74 P: AsRef<[Option<usize>]> + Send + Sync,
75 {
76 let stream = UnixStream::connect(&self.0).await?;
77 let (rx, tx) = stream.into_split();
78 invoke(tx, rx, instance, func, params, paths).await
79 }
80}
81
82impl Invoke for Client<&Path> {
83 type Context = ();
84
85 #[instrument(level = "trace", skip(self, paths, params), fields(params = format!("{params:02x?}")))]
86 async fn invoke<P>(
87 &self,
88 (): Self::Context,
89 instance: &str,
90 func: &str,
91 params: Bytes,
92 paths: impl AsRef<[P]> + Send,
93 ) -> anyhow::Result<(Outgoing, Incoming)>
94 where
95 P: AsRef<[Option<usize>]> + Send + Sync,
96 {
97 let stream = UnixStream::connect(self.0).await?;
98 let (rx, tx) = stream.into_split();
99 invoke(tx, rx, instance, func, params, paths).await
100 }
101}
102
103impl Invoke for Client<&std::os::unix::net::SocketAddr> {
104 type Context = ();
105
106 #[instrument(level = "trace", skip(self, paths, params), fields(params = format!("{params:02x?}")))]
107 async fn invoke<P>(
108 &self,
109 (): Self::Context,
110 instance: &str,
111 func: &str,
112 params: Bytes,
113 paths: impl AsRef<[P]> + Send,
114 ) -> anyhow::Result<(Outgoing, Incoming)>
115 where
116 P: AsRef<[Option<usize>]> + Send + Sync,
117 {
118 let stream = std::os::unix::net::UnixStream::connect_addr(self.0)?;
119 let stream = UnixStream::from_std(stream)?;
120 let (rx, tx) = stream.into_split();
121 invoke(tx, rx, instance, func, params, paths).await
122 }
123}
124
125impl Invoke for Client<std::os::unix::net::SocketAddr> {
126 type Context = ();
127
128 #[instrument(level = "trace", skip(self, paths, params), fields(params = format!("{params:02x?}")))]
129 async fn invoke<P>(
130 &self,
131 (): Self::Context,
132 instance: &str,
133 func: &str,
134 params: Bytes,
135 paths: impl AsRef<[P]> + Send,
136 ) -> anyhow::Result<(Outgoing, Incoming)>
137 where
138 P: AsRef<[Option<usize>]> + Send + Sync,
139 {
140 let stream = std::os::unix::net::UnixStream::connect_addr(&self.0)?;
141 let stream = UnixStream::from_std(stream)?;
142 let (rx, tx) = stream.into_split();
143 invoke(tx, rx, instance, func, params, paths).await
144 }
145}