ombrac_client/
client.rs

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