Skip to main content

xmtp_proto/traits/
boxed_client.rs

1/// a boxed version of [`Client`]
2pub type BoxClient = Box<dyn BoxClientT>;
3
4/// a type-erased version of [`Client`] in an [`Arc`](std::sync::Arc)
5pub type ArcClient = Arc<dyn BoxClientT>;
6
7use bytes::Bytes;
8use http::{request, uri::PathAndQuery};
9use std::sync::Arc;
10
11use crate::api::{ApiClientError, BytesStream, IsConnectedCheck};
12
13use super::Client;
14
15struct BoxedClient<C: ?Sized> {
16    inner: C,
17}
18
19impl<C> BoxedClient<C> {
20    pub fn new(client: C) -> Self {
21        Self { inner: client }
22    }
23}
24
25pub trait BoxClientT: Client + IsConnectedCheck {}
26
27impl<T> BoxClientT for T where T: ?Sized + IsConnectedCheck + Client {}
28
29#[xmtp_common::async_trait]
30impl<C> Client for BoxedClient<C>
31where
32    C: Client,
33{
34    async fn request(
35        &self,
36        request: request::Builder,
37        path: PathAndQuery,
38        body: Bytes,
39    ) -> Result<http::Response<Bytes>, ApiClientError> {
40        self.inner.request(request, path, body).await
41    }
42
43    async fn stream(
44        &self,
45        request: request::Builder,
46        path: http::uri::PathAndQuery,
47        body: Bytes,
48    ) -> Result<http::Response<BytesStream>, ApiClientError> {
49        self.inner.stream(request, path, body).await
50    }
51
52    async fn bidi_stream(
53        &self,
54        request: request::Builder,
55        path: http::uri::PathAndQuery,
56        body: xmtp_common::BoxDynStream<'static, Bytes>,
57    ) -> Result<http::Response<BytesStream>, ApiClientError> {
58        self.inner.bidi_stream(request, path, body).await
59    }
60}
61
62pub trait ToBoxedClient {
63    fn boxed(self) -> BoxClient;
64    fn arced(self) -> ArcClient;
65}
66
67impl<C> ToBoxedClient for C
68where
69    C: Client + IsConnectedCheck + 'static,
70{
71    fn boxed(self) -> BoxClient {
72        Box::new(BoxedClient::new(self))
73    }
74    fn arced(self) -> ArcClient {
75        Arc::new(BoxedClient::new(self))
76    }
77}
78
79#[xmtp_common::async_trait]
80impl<T> IsConnectedCheck for BoxedClient<T>
81where
82    T: ?Sized + IsConnectedCheck,
83{
84    /// Check if a client is connected
85    async fn is_connected(&self) -> bool {
86        self.inner.is_connected().await
87    }
88}