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}