1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
use trillium_http::transport::BoxedTransport;

use crate::{async_trait, Transport, Url};
use std::{
    fmt::{self, Debug},
    future::Future,
    io::Result,
    pin::Pin,
    sync::Arc,
};
/**
Interface for runtime and tls adapters for the trillium client

See
[`trillium_client`](https://docs.trillium.rs/trillium_client) for more
information on usage.
*/
#[async_trait]
pub trait Connector: Send + Sync + 'static {
    ///
    type Transport: Transport;
    /**
    Initiate a connection to the provided url

    Async trait signature:
    ```rust,ignore
    async fn connect(&self, url: &Url) -> std::io::Result<Self::Transport>;
    ```
     */
    async fn connect(&self, url: &Url) -> Result<Self::Transport>;

    ///
    fn spawn<Fut: Future<Output = ()> + Send + 'static>(&self, fut: Fut);
}

///
#[async_trait]
pub trait ObjectSafeConnector: Send + Sync + 'static {
    ///
    async fn connect(&self, url: &Url) -> Result<BoxedTransport>;
    ///
    fn spawn(&self, fut: Pin<Box<dyn Future<Output = ()> + Send + 'static>>);
    ///
    fn boxed(self) -> Box<dyn ObjectSafeConnector>
    where
        Self: Sized,
    {
        Box::new(self) as Box<dyn ObjectSafeConnector>
    }

    ///
    fn arced(self) -> Arc<dyn ObjectSafeConnector>
    where
        Self: Sized,
    {
        Arc::new(self) as Arc<dyn ObjectSafeConnector>
    }
}

#[async_trait]
impl<T: Connector> ObjectSafeConnector for T {
    async fn connect(&self, url: &Url) -> Result<BoxedTransport> {
        T::connect(self, url).await.map(BoxedTransport::new)
    }

    fn spawn(&self, fut: Pin<Box<dyn Future<Output = ()> + Send + 'static>>) {
        T::spawn(self, fut)
    }
}

#[async_trait]
impl Connector for Box<dyn ObjectSafeConnector> {
    type Transport = BoxedTransport;
    async fn connect(&self, url: &Url) -> Result<BoxedTransport> {
        ObjectSafeConnector::connect(self.as_ref(), url).await
    }

    fn spawn<Fut: Future<Output = ()> + Send + 'static>(&self, fut: Fut) {
        ObjectSafeConnector::spawn(self.as_ref(), Box::pin(fut))
    }
}

#[async_trait]
impl Connector for Arc<dyn ObjectSafeConnector> {
    type Transport = BoxedTransport;
    async fn connect(&self, url: &Url) -> Result<BoxedTransport> {
        ObjectSafeConnector::connect(self.as_ref(), url).await
    }

    fn spawn<Fut: Future<Output = ()> + Send + 'static>(&self, fut: Fut) {
        ObjectSafeConnector::spawn(self.as_ref(), Box::pin(fut))
    }
}

impl Debug for dyn ObjectSafeConnector {
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
        f.debug_struct("Arc<dyn ObjectSafeConnector>").finish()
    }
}