ssip_client/
tcp.rs

1// ssip-client -- Speech Dispatcher client in Rust
2// Copyright (c) 2022 Laurent Pelecq
3//
4// Licensed under the Apache License, Version 2.0
5// <LICENSE-APACHE or http://www.apache.org/licenses/LICENSE-2.0> or the MIT
6// license <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
7// option. All files in the project carrying such notice may not be copied,
8// modified, or distributed except according to those terms.
9
10#[cfg(not(feature = "async-mio"))]
11mod synchronous {
12    use std::io::{self, BufReader, BufWriter};
13    pub use std::net::TcpStream;
14    use std::net::{SocketAddr, ToSocketAddrs};
15    use std::time::Duration;
16    use std::vec;
17
18    use crate::client::Client;
19    use crate::net::StreamMode;
20
21    #[derive(Debug)]
22    struct Addresses(Vec<SocketAddr>);
23
24    impl ToSocketAddrs for Addresses {
25        type Iter = vec::IntoIter<SocketAddr>;
26        fn to_socket_addrs(&self) -> io::Result<Self::Iter> {
27            Ok(self.0.clone().into_iter())
28        }
29    }
30
31    #[derive(Debug)]
32    pub struct Builder {
33        addrs: Addresses,
34        mode: StreamMode,
35    }
36
37    impl Builder {
38        pub fn new<A: ToSocketAddrs>(addrs: A) -> io::Result<Self> {
39            Ok(Self {
40                addrs: Addresses(addrs.to_socket_addrs()?.collect::<Vec<SocketAddr>>()),
41                mode: StreamMode::Blocking,
42            })
43        }
44
45        pub fn timeout(&mut self, read_timeout: Duration) -> &mut Self {
46            self.mode = StreamMode::TimeOut(read_timeout);
47            self
48        }
49
50        pub fn nonblocking(&mut self) -> &mut Self {
51            self.mode = StreamMode::NonBlocking;
52            self
53        }
54
55        pub fn build(&self) -> io::Result<Client<TcpStream>> {
56            let input = TcpStream::connect(&self.addrs)?;
57            match self.mode {
58                StreamMode::Blocking => input.set_nonblocking(false)?,
59                StreamMode::NonBlocking => input.set_nonblocking(true)?,
60                StreamMode::TimeOut(timeout) => input.set_read_timeout(Some(timeout))?,
61            }
62            let output = input.try_clone()?;
63            Ok(Client::new(BufReader::new(input), BufWriter::new(output)))
64        }
65    }
66}
67
68#[cfg(not(feature = "async-mio"))]
69pub use synchronous::{Builder, TcpStream};
70
71#[cfg(feature = "async-mio")]
72mod asynchronous {
73    pub use mio::net::TcpStream;
74    use std::io::{self, BufReader, BufWriter};
75    use std::net::SocketAddr;
76    use std::net::TcpStream as StdTcpStream;
77
78    use crate::client::Client;
79
80    pub struct Builder {
81        addr: SocketAddr,
82    }
83
84    impl Builder {
85        pub fn new(addr: SocketAddr) -> Self {
86            Self { addr }
87        }
88
89        pub fn build(&self) -> io::Result<Client<TcpStream>> {
90            let stream = StdTcpStream::connect(self.addr)?;
91            Ok(Client::new(
92                BufReader::new(TcpStream::from_std(stream.try_clone()?)),
93                BufWriter::new(TcpStream::from_std(stream)),
94            ))
95        }
96    }
97}
98
99#[cfg(feature = "async-mio")]
100pub use asynchronous::{Builder, TcpStream};
101
102#[cfg(test)]
103mod tests {}