apub_core/
deliver.rs

1//! Traits describing the delivery of objects to remote servers
2
3use std::{rc::Rc, sync::Arc};
4use url::Url;
5
6use crate::session::Session;
7
8/// Describes sending an activity to a server
9///
10/// When implementing this trait, things like HTTP Signatures and HTTP Digests should be considered
11///
12/// ```rust
13/// use apub_core::{deliver::Deliver, session::Session};
14/// use url::Url;
15///
16/// pub struct MyClient {
17///     inner: reqwest::Client,
18/// }
19///
20/// #[async_trait::async_trait(?Send)]
21/// impl Deliver for MyClient {
22///     type Error = reqwest::Error;
23///
24///     async fn deliver<T: serde::ser::Serialize, S: Session>(&self, inbox: &Url, activity: &T, _: S) -> Result<(), Self::Error> {
25///         self.inner.post(inbox.as_str()).json(activity).send().await?;
26///         Ok(())
27///     }
28/// }
29/// ```
30#[async_trait::async_trait(?Send)]
31pub trait Deliver {
32    /// Errors produced by the client
33    type Error: std::fmt::Display + 'static;
34
35    /// Deliver the activity to the inbox
36    async fn deliver<T: serde::ser::Serialize, S: Session>(
37        &self,
38        inbox: &Url,
39        activity: &T,
40        session: S,
41    ) -> Result<(), Self::Error>;
42}
43
44/// The inverse of [`Deliver`], allows for `item.deliver(&client)` syntax
45///
46/// ```rust
47/// use apub_core::deliver::Deliverable;
48/// use url::Url;
49///
50/// #[derive(serde::Deserialize, serde::Serialize)]
51/// pub struct MyActivity {
52///     id: Url,
53///     // etc...
54/// }
55///
56/// impl Deliverable for MyActivity {}
57/// ```
58#[async_trait::async_trait(?Send)]
59pub trait Deliverable: serde::ser::Serialize {
60    /// Deliver the activity to the inbox
61    async fn deliver<D: Deliver, S: Session>(
62        &self,
63        inbox: &Url,
64        client: &D,
65        session: S,
66    ) -> Result<(), D::Error>
67    where
68        Self: Sized,
69    {
70        client.deliver(inbox, self, session).await
71    }
72}
73
74#[async_trait::async_trait(?Send)]
75impl<'a, D> Deliver for &'a D
76where
77    D: Deliver,
78{
79    type Error = D::Error;
80
81    async fn deliver<T: serde::ser::Serialize, S: Session>(
82        &self,
83        inbox: &Url,
84        activity: &T,
85        session: S,
86    ) -> Result<(), Self::Error> {
87        D::deliver(self, inbox, activity, session).await
88    }
89}
90
91#[async_trait::async_trait(?Send)]
92impl<'a, D> Deliver for &'a mut D
93where
94    D: Deliver,
95{
96    type Error = D::Error;
97
98    async fn deliver<T: serde::ser::Serialize, S: Session>(
99        &self,
100        inbox: &Url,
101        activity: &T,
102        session: S,
103    ) -> Result<(), Self::Error> {
104        D::deliver(self, inbox, activity, session).await
105    }
106}
107
108#[async_trait::async_trait(?Send)]
109impl<D> Deliver for Box<D>
110where
111    D: Deliver,
112{
113    type Error = D::Error;
114
115    async fn deliver<T: serde::ser::Serialize, S: Session>(
116        &self,
117        inbox: &Url,
118        activity: &T,
119        session: S,
120    ) -> Result<(), Self::Error> {
121        D::deliver(self, inbox, activity, session).await
122    }
123}
124
125#[async_trait::async_trait(?Send)]
126impl<D> Deliver for Rc<D>
127where
128    D: Deliver,
129{
130    type Error = D::Error;
131
132    async fn deliver<T: serde::ser::Serialize, S: Session>(
133        &self,
134        inbox: &Url,
135        activity: &T,
136        session: S,
137    ) -> Result<(), Self::Error> {
138        D::deliver(self, inbox, activity, session).await
139    }
140}
141
142#[async_trait::async_trait(?Send)]
143impl<D> Deliver for Arc<D>
144where
145    D: Deliver,
146{
147    type Error = D::Error;
148
149    async fn deliver<T: serde::ser::Serialize, S: Session>(
150        &self,
151        inbox: &Url,
152        activity: &T,
153        session: S,
154    ) -> Result<(), Self::Error> {
155        D::deliver(self, inbox, activity, session).await
156    }
157}