1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
use async_trait::async_trait;
use std::{io, marker::Unpin};
use tokio::io::{AsyncRead, AsyncWrite};

/// Interface to split something into writing and reading halves
pub trait IntoSplit {
    type Write;
    type Read;

    fn into_split(self) -> (Self::Write, Self::Read);
}

impl<W, R> IntoSplit for (W, R) {
    type Write = W;
    type Read = R;

    fn into_split(self) -> (Self::Write, Self::Read) {
        (self.0, self.1)
    }
}

/// Interface representing a transport of raw bytes into and out of the system
pub trait RawTransport: RawTransportRead + RawTransportWrite {}

/// Interface representing a transport of raw bytes into the system
pub trait RawTransportRead: AsyncRead + Send + Unpin {}

/// Interface representing a transport of raw bytes out of the system
pub trait RawTransportWrite: AsyncWrite + Send + Unpin {}

/// Interface representing a transport of typed data into and out of the system
pub trait TypedTransport<W, R>: TypedAsyncRead<R> + TypedAsyncWrite<W> {}

/// Interface to read some structured data asynchronously
#[async_trait]
pub trait TypedAsyncRead<T> {
    /// Reads some data, returning `Some(T)` if available or `None` if the reader
    /// has closed and no longer is providing data
    async fn read(&mut self) -> io::Result<Option<T>>;
}

#[async_trait]
impl<W, R, T> TypedAsyncRead<T> for (W, R)
where
    W: Send,
    R: TypedAsyncRead<T> + Send,
{
    async fn read(&mut self) -> io::Result<Option<T>> {
        self.1.read().await
    }
}

#[async_trait]
impl<T: Send> TypedAsyncRead<T> for Box<dyn TypedAsyncRead<T> + Send> {
    async fn read(&mut self) -> io::Result<Option<T>> {
        (**self).read().await
    }
}

/// Interface to write some structured data asynchronously
#[async_trait]
pub trait TypedAsyncWrite<T> {
    async fn write(&mut self, data: T) -> io::Result<()>;
}

#[async_trait]
impl<W, R, T> TypedAsyncWrite<T> for (W, R)
where
    W: TypedAsyncWrite<T> + Send,
    R: Send,
    T: Send + 'static,
{
    async fn write(&mut self, data: T) -> io::Result<()> {
        self.0.write(data).await
    }
}

#[async_trait]
impl<T: Send> TypedAsyncWrite<T> for Box<dyn TypedAsyncWrite<T> + Send> {
    async fn write(&mut self, data: T) -> io::Result<()> {
        (**self).write(data).await
    }
}

mod router;

mod framed;
pub use framed::*;

mod inmemory;
pub use inmemory::*;

mod mpsc;
pub use mpsc::*;

mod tcp;
pub use tcp::*;

#[cfg(unix)]
mod unix;

#[cfg(unix)]
pub use unix::*;

mod untyped;
pub use untyped::*;

#[cfg(windows)]
mod windows;

#[cfg(windows)]
pub use windows::*;