1use std::io::{Read, Write};
4
5use lace_sans_io::core::PeerInput;
6use mio::event::Source;
7
8mod stream;
9
10pub use lace_sans_io::core::CarrierRole;
11pub(crate) use stream::StreamTransport;
12
13pub(crate) const TRANSPORT: mio::Token = mio::Token(0);
14
15pub trait WriteShutdown {
24 fn shutdown_write(&mut self) -> std::io::Result<()>;
25}
26
27impl WriteShutdown for mio::net::TcpStream {
28 fn shutdown_write(&mut self) -> std::io::Result<()> {
29 self.shutdown(std::net::Shutdown::Write)
30 }
31}
32
33#[cfg(unix)]
34impl WriteShutdown for mio::net::UnixStream {
35 fn shutdown_write(&mut self) -> std::io::Result<()> {
36 self.shutdown(std::net::Shutdown::Write)
37 }
38}
39
40#[cfg(unix)]
43impl WriteShutdown for mio::unix::pipe::Sender {
44 fn shutdown_write(&mut self) -> std::io::Result<()> {
45 Ok(())
46 }
47}
48
49pub(crate) enum TransportActivity {
50 Progress,
51 Input(PeerInput),
52 Eof,
53 Idle,
54}
55
56impl crate::ConnectedPeer {
57 pub fn from_duplex<IO>(
61 role: CarrierRole,
62 io: IO,
63 options: crate::ConnectedPeerOptions,
64 ) -> crate::Result<Self>
65 where
66 IO: Read + Write + WriteShutdown + Source + 'static,
67 {
68 let inputs = crate::runtime::connected_inputs(options)?;
69 Ok(Self {
70 transport: Box::new(StreamTransport::raw_duplex(io)),
71 role,
72 inputs,
73 })
74 }
75
76 pub fn from_split<R, W>(
81 role: CarrierRole,
82 reader: R,
83 writer: W,
84 options: crate::ConnectedPeerOptions,
85 ) -> crate::Result<Self>
86 where
87 R: Read + Source + 'static,
88 W: Write + WriteShutdown + Source + 'static,
89 {
90 let inputs = crate::runtime::connected_inputs(options)?;
91 Ok(Self {
92 transport: Box::new(StreamTransport::raw_split(reader, writer)),
93 role,
94 inputs,
95 })
96 }
97}