alloy_transport_ipc/
connect.rs

1use interprocess::local_socket as ls;
2use std::io;
3
4pub(crate) fn to_name(path: &std::ffi::OsStr) -> io::Result<ls::Name<'_>> {
5    if cfg!(windows) && !path.as_encoded_bytes().starts_with(br"\\.\pipe\") {
6        ls::ToNsName::to_ns_name::<ls::GenericNamespaced>(path)
7    } else {
8        ls::ToFsName::to_fs_name::<ls::GenericFilePath>(path)
9    }
10}
11
12/// An IPC Connection object.
13#[derive(Clone, Debug)]
14pub struct IpcConnect<T> {
15    inner: T,
16}
17
18impl<T> IpcConnect<T> {
19    /// Create a new IPC connection object for any type T that can be converted into
20    /// `IpcConnect<T>`.
21    pub const fn new(inner: T) -> Self
22    where
23        Self: alloy_pubsub::PubSubConnect,
24    {
25        Self { inner }
26    }
27}
28
29macro_rules! impl_connect {
30    ($target:ty => | $inner:ident | $map:expr) => {
31        impl From<$target> for IpcConnect<$target> {
32            fn from(inner: $target) -> Self {
33                Self { inner }
34            }
35        }
36
37        impl From<IpcConnect<$target>> for $target {
38            fn from(this: IpcConnect<$target>) -> $target {
39                this.inner
40            }
41        }
42
43        impl alloy_pubsub::PubSubConnect for IpcConnect<$target> {
44            fn is_local(&self) -> bool {
45                true
46            }
47
48            async fn connect(
49                &self,
50            ) -> Result<alloy_pubsub::ConnectionHandle, alloy_transport::TransportError> {
51                let $inner = &self.inner;
52                let inner = $map;
53                let name = to_name(inner).map_err(alloy_transport::TransportErrorKind::custom)?;
54                crate::IpcBackend::connect(name)
55                    .await
56                    .map_err(alloy_transport::TransportErrorKind::custom)
57            }
58        }
59    };
60}
61
62impl_connect!(std::ffi::OsString => |s| s.as_os_str());
63impl_connect!(std::path::PathBuf => |s| s.as_os_str());
64impl_connect!(String => |s| s.as_ref());
65
66#[cfg(unix)]
67impl_connect!(std::ffi::CString => |s| {
68    use std::os::unix::ffi::OsStrExt;
69    std::ffi::OsStr::from_bytes(s.to_bytes())
70});