ombrac_client/
client.rs

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