trillium_server_common/
client.rs

1use trillium_http::transport::BoxedTransport;
2
3use crate::{async_trait, Transport, Url};
4use std::{
5    fmt::{self, Debug},
6    future::Future,
7    io::Result,
8    pin::Pin,
9    sync::Arc,
10};
11/**
12Interface for runtime and tls adapters for the trillium client
13
14See
15[`trillium_client`](https://docs.trillium.rs/trillium_client) for more
16information on usage.
17*/
18#[async_trait]
19pub trait Connector: Send + Sync + 'static {
20    ///
21    type Transport: Transport;
22    /**
23    Initiate a connection to the provided url
24
25    Async trait signature:
26    ```rust,ignore
27    async fn connect(&self, url: &Url) -> std::io::Result<Self::Transport>;
28    ```
29     */
30    async fn connect(&self, url: &Url) -> Result<Self::Transport>;
31
32    ///
33    fn spawn<Fut: Future<Output = ()> + Send + 'static>(&self, fut: Fut);
34}
35
36///
37#[async_trait]
38pub trait ObjectSafeConnector: Send + Sync + 'static {
39    ///
40    async fn connect(&self, url: &Url) -> Result<BoxedTransport>;
41    ///
42    fn spawn(&self, fut: Pin<Box<dyn Future<Output = ()> + Send + 'static>>);
43    ///
44    fn boxed(self) -> Box<dyn ObjectSafeConnector>
45    where
46        Self: Sized,
47    {
48        Box::new(self) as Box<dyn ObjectSafeConnector>
49    }
50
51    ///
52    fn arced(self) -> Arc<dyn ObjectSafeConnector>
53    where
54        Self: Sized,
55    {
56        Arc::new(self) as Arc<dyn ObjectSafeConnector>
57    }
58}
59
60#[async_trait]
61impl<T: Connector> ObjectSafeConnector for T {
62    async fn connect(&self, url: &Url) -> Result<BoxedTransport> {
63        T::connect(self, url).await.map(BoxedTransport::new)
64    }
65
66    fn spawn(&self, fut: Pin<Box<dyn Future<Output = ()> + Send + 'static>>) {
67        T::spawn(self, fut)
68    }
69}
70
71#[async_trait]
72impl Connector for Box<dyn ObjectSafeConnector> {
73    type Transport = BoxedTransport;
74    async fn connect(&self, url: &Url) -> Result<BoxedTransport> {
75        ObjectSafeConnector::connect(self.as_ref(), url).await
76    }
77
78    fn spawn<Fut: Future<Output = ()> + Send + 'static>(&self, fut: Fut) {
79        ObjectSafeConnector::spawn(self.as_ref(), Box::pin(fut))
80    }
81}
82
83#[async_trait]
84impl Connector for Arc<dyn ObjectSafeConnector> {
85    type Transport = BoxedTransport;
86    async fn connect(&self, url: &Url) -> Result<BoxedTransport> {
87        ObjectSafeConnector::connect(self.as_ref(), url).await
88    }
89
90    fn spawn<Fut: Future<Output = ()> + Send + 'static>(&self, fut: Fut) {
91        ObjectSafeConnector::spawn(self.as_ref(), Box::pin(fut))
92    }
93}
94
95impl Debug for dyn ObjectSafeConnector {
96    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
97        f.debug_struct("Arc<dyn ObjectSafeConnector>").finish()
98    }
99}