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}