1pub mod methods;
2
3#[cfg(feature = "defmt")]
4use defmt::*;
5
6#[cfg(feature = "tokio")]
7pub mod tokio;
8
9#[cfg(feature = "embassy")]
10pub mod embassy;
11
12use nimbi_protocol::{microdot::MicrodotError, types::response::Error as ResponseError};
13
14use core::{future::Future, marker::PhantomData};
15
16pub struct Client<T, E>
17where
18 T: ClientConnection<E>,
19{
20 pub connection: T,
21 error: PhantomData<E>,
22}
23
24impl<T, E> Client<T, E>
25where
26 T: ClientConnection<E>,
27{
28 pub fn new(connection: T) -> Self {
29 Self {
30 connection,
31 error: PhantomData,
32 }
33 }
34
35 pub async fn close(&mut self) {
36 self.connection.close().await;
37 }
38}
39
40#[derive(Debug)]
41pub enum ClientError<E> {
42 ConnectionError(E),
43 Microdot(MicrodotError),
44 Response(ResponseError),
45 IncompleteMessage,
46 Other(&'static str),
47}
48
49impl<E> ClientError<E> {
50 pub fn client_connection(err: E) -> Self {
51 ClientError::ConnectionError(err)
52 }
53
54 pub fn microdot(err: MicrodotError) -> Self {
55 ClientError::Microdot(err)
56 }
57
58 pub fn response(err: ResponseError) -> Self {
59 ClientError::Response(err)
60 }
61
62 pub fn other(err: &'static str) -> Self {
63 ClientError::Other(err)
64 }
65}
66
67impl<E> From<E> for ClientError<E> {
68 fn from(err: E) -> Self {
69 ClientError::ConnectionError(err)
70 }
71}
72
73#[cfg(feature = "defmt")]
74impl<E> defmt::Format for ClientError<E> {
75 fn format(&self, f: defmt::Formatter) {
76 let msg = match self {
77 ClientError::ConnectionError(_) => "connection error",
78 ClientError::Microdot(error) => {
79 "microdot"
82 }
83 ClientError::Response(error) => "response",
84 ClientError::IncompleteMessage => "incomplete message",
85 ClientError::Other(_) => "other",
86 };
87
88 defmt::write!(f, "ClientError: {}", msg,)
89 }
90}
91
92pub trait ClientConnection<E> {
93 fn send(&mut self, buf: &[u8]) -> impl Future<Output = Result<usize, ClientError<E>>>;
94 fn recv(&mut self, buf: &mut [u8]) -> impl Future<Output = Result<usize, ClientError<E>>>;
95 fn close(&mut self) -> impl Future<Output = ()>;
96}