ombrac_client/
client.rs

1use std::io;
2
3use ombrac::prelude::*;
4use ombrac_transport::{Reliable, Transport};
5
6#[cfg(feature = "datagram")]
7use ombrac_transport::Unreliable;
8
9pub struct Client<T> {
10    secret: Secret,
11    transport: T,
12}
13
14impl<T: Transport> Client<T> {
15    pub fn new(secret: Secret, transport: T) -> Self {
16        Self { secret, transport }
17    }
18
19    pub async fn tcp_connect<A>(&self, addr: A) -> io::Result<impl Reliable + '_>
20    where
21        A: Into<Address>,
22    {
23        use tokio::io::AsyncWriteExt;
24
25        let mut stream = self.reliable().await?;
26        let request = Connect::with(self.secret, addr).to_bytes()?;
27
28        stream.write_all(&request).await?;
29
30        Ok(stream)
31    }
32
33    #[cfg(feature = "datagram")]
34    pub async fn udp_associate(&self) -> io::Result<Datagram<impl Unreliable + '_>> {
35        let stream = self.unreliable().await?;
36
37        Ok(Datagram::with(self.secret, stream))
38    }
39
40    #[inline]
41    async fn reliable(&self) -> io::Result<impl Reliable + '_> {
42        match self.transport.reliable().await {
43            Ok(stream) => Ok(stream),
44            Err(error) => Err(io::Error::other(error.to_string())),
45        }
46    }
47
48    #[cfg(feature = "datagram")]
49    #[inline]
50    async fn unreliable(&self) -> io::Result<impl Unreliable + '_> {
51        match self.transport.unreliable().await {
52            Ok(stream) => Ok(stream),
53            Err(error) => Err(io::Error::other(error.to_string())),
54        }
55    }
56}
57
58#[cfg(feature = "datagram")]
59pub struct Datagram<U: Unreliable>(Secret, U);
60
61#[cfg(feature = "datagram")]
62impl<U: Unreliable> Datagram<U> {
63    fn with(secret: Secret, stream: U) -> Self {
64        Self(secret, stream)
65    }
66
67    pub async fn send<A, B>(&self, addr: A, data: B) -> io::Result<()>
68    where
69        A: Into<Address>,
70        B: Into<bytes::Bytes>,
71    {
72        let packet = Packet::with(self.0, addr, data).to_bytes()?;
73
74        if let Err(error) = self.1.send(packet).await {
75            return Err(io::Error::other(error.to_string()));
76        };
77
78        Ok(())
79    }
80
81    pub async fn recv(&self) -> io::Result<(Address, bytes::Bytes)> {
82        match self.1.recv().await {
83            Ok(mut data) => {
84                let packet = Packet::from_bytes(&mut data)?;
85                Ok((packet.address, packet.data))
86            }
87            Err(error) => Err(io::Error::other(error.to_string())),
88        }
89    }
90}