interprocess/
bound_util.rs

1//! Trait bound utilities.
2
3use std::io::prelude::*;
4#[cfg(feature = "tokio")]
5use tokio::io::{AsyncRead as TokioAsyncRead, AsyncWrite as TokioAsyncWrite};
6
7pub(crate) trait Is<T: ?Sized> {}
8impl<T: ?Sized> Is<T> for T {}
9
10macro_rules! bound_util {
11    (#[doc = $doc:literal] $trtname:ident of $otrt:ident with $aty:ident mtd $mtd:ident) => {
12        #[doc = $doc]
13        pub trait $trtname {
14            #[doc(hidden)]
15            #[allow(private_bounds)]
16            type $aty<'a>: $otrt + Is<&'a Self>
17            where
18                Self: 'a;
19            #[doc = concat!(
20                                "Returns `self` with the guarantee that `&Self` implements `",
21                                stringify!($otrt),
22                                "` encoded in a way which is visible to Rust's type system.",
23                            )]
24            fn $mtd(&self) -> Self::$aty<'_>;
25        }
26        impl<T: ?Sized> $trtname for T
27        where
28            for<'a> &'a T: $otrt,
29        {
30            type $aty<'a> = &'a Self
31                        where Self: 'a;
32            #[inline(always)]
33            fn $mtd(&self) -> Self::$aty<'_> {
34                self
35            }
36        }
37    };
38    ($(#[doc = $doc:literal] $trtname:ident of $otrt:ident with $aty:ident mtd $mtd:ident)+) => {$(
39        bound_util!(#[doc = $doc] $trtname of $otrt with $aty mtd $mtd);
40    )+};
41}
42
43bound_util! {
44    /// [`Read`] by reference.
45    RefRead  of Read  with Read  mtd as_read
46    /// [`Write`] by reference.
47    RefWrite of Write with Write mtd as_write
48}
49
50#[cfg(feature = "tokio")]
51bound_util! {
52    /// [Tokio's `AsyncRead`](TokioAsyncRead) by reference.
53    RefTokioAsyncRead  of TokioAsyncRead  with Read  mtd as_tokio_async_read
54    /// [Tokio's `AsyncWrite`](TokioAsyncWrite) by reference.
55    RefTokioAsyncWrite of TokioAsyncWrite with Write mtd as_tokio_async_write
56}