ombrac_client/
client.rs

1use std::io;
2
3use ombrac::request::{Address, Request};
4use ombrac::Provider;
5use tokio::io::{AsyncRead, AsyncWrite};
6
7pub struct Client<T> {
8    secret: [u8; 32],
9    transport: T,
10}
11
12impl<Transport, Stream> Client<Transport>
13where
14    Transport: Provider<Item = Stream>,
15    Stream: AsyncRead + AsyncWrite + Unpin,
16{
17    pub fn new(secret: [u8; 32], transport: Transport) -> Self {
18        Self { secret, transport }
19    }
20
21    async fn outbound(&self) -> io::Result<Stream> {
22        match self.transport.fetch().await {
23            Some(value) => Ok(value),
24            None => Err(io::Error::new(
25                io::ErrorKind::ConnectionAborted,
26                "Connection has been lost",
27            )),
28        }
29    }
30
31    pub async fn tcp_connect<A>(&self, addr: A) -> io::Result<Stream>
32    where
33        A: Into<Address>,
34    {
35        use tokio::io::AsyncWriteExt;
36
37        let request: Vec<u8> = Request::TcpConnect(self.secret, addr.into()).into();
38        let mut stream = self.outbound().await?;
39
40        stream.write_all(&request).await?;
41
42        Ok(stream)
43    }
44}