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
113
114
115
mod binary;
#[cfg(any(
    feature = "deflate",
    feature = "deflate_ng",
    feature = "deflate_static"
))]
mod deflate;
mod frame;
mod text;

pub use binary::*;
#[cfg(any(
    feature = "deflate",
    feature = "deflate_ng",
    feature = "deflate_static"
))]
pub use deflate::*;
pub use frame::*;
pub use text::*;

/// split something into two parts
pub trait Split {
    /// read half type
    type R;
    /// write half type
    type W;
    /// consume and return parts
    fn split(self) -> (Self::R, Self::W);
}

#[cfg(feature = "sync")]
mod blocking {
    use super::Split;
    use std::{
        io::{Read, Write},
        net::TcpStream,
    };

    // impl<R: Read> Read for ReadHalf<R> {
    //     fn read(&mut self, buf: &mut [u8]) -> std::io::Result<usize> {
    //         self.inner.read(buf)
    //     }
    // }

    // impl<W: Write> Write for WriteHalf<W> {
    //     fn write(&mut self, buf: &[u8]) -> std::io::Result<usize> {
    //         self.inner.write(buf)
    //     }

    //     fn flush(&mut self) -> std::io::Result<()> {
    //         self.inner.flush()
    //     }
    // }

    pub struct TcpReadHalf(pub TcpStream);

    impl Read for TcpReadHalf {
        fn read(&mut self, buf: &mut [u8]) -> std::io::Result<usize> {
            self.0.read(buf)
        }
    }

    pub struct TcpWriteHalf(pub TcpStream);

    impl Write for TcpWriteHalf {
        fn write(&mut self, buf: &[u8]) -> std::io::Result<usize> {
            self.0.write(buf)
        }

        fn flush(&mut self) -> std::io::Result<()> {
            self.0.flush()
        }
    }

    impl Split for TcpStream {
        type R = TcpStream;
        type W = TcpStream;
        fn split(self) -> (Self::R, Self::W) {
            let cloned = self.try_clone().expect("failed to split tcp stream");
            (self, cloned)
        }
    }
}

#[cfg(feature = "async")]
mod non_blocking {
    use tokio::{
        io::{AsyncRead, AsyncWrite, BufStream},
        net::TcpStream,
    };

    impl crate::codec::Split for TcpStream {
        type R = tokio::io::ReadHalf<TcpStream>;
        type W = tokio::io::WriteHalf<TcpStream>;
        fn split(self) -> (Self::R, Self::W) {
            tokio::io::split(self)
        }
    }

    impl<S: AsyncRead + AsyncWrite> crate::codec::Split for BufStream<S> {
        type R = tokio::io::ReadHalf<BufStream<S>>;
        type W = tokio::io::WriteHalf<BufStream<S>>;
        fn split(self) -> (Self::R, Self::W) {
            tokio::io::split(self)
        }
    }

    // impl<S: AsyncRead + AsyncWrite> crate::codec::Split for BufStream<S> {
    //     type R = tokio::io::ReadHalf<BufStream<S>>;
    //     type W = tokio::io::WriteHalf<BufStream<S>>;
    //     fn split(self) -> (Self::R, Self::W) {
    //         tokio::io::split(self)
    //     }
    // }
}