Skip to main content

nimbi_rs/client/
mod.rs

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                // info!("microdot error: {:?}", error);
80
81                "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}