uid_mux/
lib.rs

1//! Multiplexing with unique channel ids.
2
3#![deny(missing_docs, unreachable_pub, unused_must_use)]
4#![deny(clippy::all)]
5#![forbid(unsafe_code)]
6
7pub(crate) mod future;
8#[cfg(feature = "serio")]
9mod serio;
10#[cfg(any(test, feature = "test-utils"))]
11pub mod test_utils;
12pub mod yamux;
13
14#[cfg(feature = "serio")]
15pub use serio::{FramedMux, FramedUidMux};
16
17use core::fmt;
18
19use async_trait::async_trait;
20use futures::io::{AsyncRead, AsyncWrite};
21
22/// Internal stream identifier.
23///
24/// User provided ids are hashed to a fixed length.
25#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
26pub(crate) struct InternalId([u8; 32]);
27
28impl InternalId {
29    /// Creates a new `InternalId` from a byte slice.
30    pub(crate) fn new(bytes: &[u8]) -> Self {
31        Self(blake3::hash(bytes).into())
32    }
33}
34
35impl fmt::Display for InternalId {
36    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
37        for byte in &self.0[..4] {
38            write!(f, "{:02x}", byte)?;
39        }
40        Ok(())
41    }
42}
43
44impl AsRef<[u8]> for InternalId {
45    fn as_ref(&self) -> &[u8] {
46        &self.0
47    }
48}
49
50/// A multiplexer that opens streams with unique ids.
51#[async_trait]
52pub trait UidMux<Id> {
53    /// Stream type.
54    type Stream: AsyncWrite + AsyncRead + Send + Sync + Unpin + 'static;
55    /// Error type.
56    type Error;
57
58    /// Open a new stream with the given id.
59    async fn open(&self, id: &Id) -> Result<Self::Stream, Self::Error>;
60}
61
62pub(crate) mod log {
63    macro_rules! error {
64        ($( $tokens:tt )*) => {
65            {
66                #[cfg(feature = "tracing")]
67                tracing::error!($( $tokens )*);
68            }
69        };
70    }
71
72    macro_rules! warn_ {
73        ($( $tokens:tt )*) => {
74            {
75                #[cfg(feature = "tracing")]
76                tracing::warn!($( $tokens )*);
77            }
78        };
79    }
80
81    macro_rules! trace {
82        ($( $tokens:tt )*) => {
83            {
84                #[cfg(feature = "tracing")]
85                tracing::trace!($( $tokens )*);
86            }
87        };
88    }
89
90    macro_rules! debug {
91        ($( $tokens:tt )*) => {
92            {
93                #[cfg(feature = "tracing")]
94                tracing::debug!($( $tokens )*);
95            }
96        };
97    }
98
99    macro_rules! info {
100        ($( $tokens:tt )*) => {
101            {
102                #[cfg(feature = "tracing")]
103                tracing::info!($( $tokens )*);
104            }
105        };
106    }
107
108    pub(crate) use {debug, error, info, trace, warn_ as warn};
109}