ssip_client_async/
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
10pub mod synchronous {
11    use std::io::{self, BufReader, BufWriter};
12    pub use std::net::TcpStream;
13    use std::net::{SocketAddr, ToSocketAddrs};
14    use std::time::Duration;
15    use std::vec;
16
17    use crate::client::Client;
18    use crate::net::StreamMode;
19
20    struct Addresses(Vec<SocketAddr>);
21
22    impl ToSocketAddrs for Addresses {
23        type Iter = vec::IntoIter<SocketAddr>;
24        fn to_socket_addrs(&self) -> io::Result<Self::Iter> {
25            Ok(self.0.clone().into_iter())
26        }
27    }
28
29    pub struct Builder {
30        addrs: Addresses,
31        mode: StreamMode,
32    }
33
34    impl Builder {
35        pub fn new<A: ToSocketAddrs>(addrs: A) -> io::Result<Self> {
36            Ok(Self {
37                addrs: Addresses(addrs.to_socket_addrs()?.collect::<Vec<SocketAddr>>()),
38                mode: StreamMode::Blocking,
39            })
40        }
41
42        pub fn timeout(&mut self, read_timeout: Duration) -> &mut Self {
43            self.mode = StreamMode::TimeOut(read_timeout);
44            self
45        }
46
47        pub fn nonblocking(&mut self) -> &mut Self {
48            self.mode = StreamMode::NonBlocking;
49            self
50        }
51
52        pub fn build(&self) -> io::Result<Client<TcpStream>> {
53            let input = TcpStream::connect(&self.addrs)?;
54            match self.mode {
55                StreamMode::Blocking => input.set_nonblocking(false)?,
56                StreamMode::NonBlocking => input.set_nonblocking(true)?,
57                StreamMode::TimeOut(timeout) => input.set_read_timeout(Some(timeout))?,
58            }
59            let output = input.try_clone()?;
60            Ok(Client::new(BufReader::new(input), BufWriter::new(output)))
61        }
62    }
63}
64
65#[cfg(feature = "async-mio")]
66pub mod asynchronous_mio {
67    pub use mio::net::TcpStream;
68    use std::io::{self, BufReader, BufWriter};
69    use std::net::SocketAddr;
70    use std::net::TcpStream as StdTcpStream;
71
72    use crate::client::MioClient;
73
74    pub struct Builder {
75        addr: SocketAddr,
76    }
77
78    impl Builder {
79        pub fn new(addr: SocketAddr) -> Self {
80            Self { addr }
81        }
82
83        pub fn build(&self) -> io::Result<MioClient<TcpStream>> {
84            let stream = StdTcpStream::connect(self.addr)?;
85            Ok(MioClient::new(
86                BufReader::new(TcpStream::from_std(stream.try_clone()?)),
87                BufWriter::new(TcpStream::from_std(stream)),
88            ))
89        }
90    }
91}
92
93#[cfg(test)]
94mod tests {}