2023-03-06 01:17:34 +00:00
|
|
|
//! Wrapper for federated structs which handles `@context` field.
|
|
|
|
//!
|
|
|
|
//! This wrapper can be used when sending Activitypub data, to automatically add `@context`. It
|
|
|
|
//! avoids having to repeat the `@context` property on every struct, and getting multiple contexts
|
|
|
|
//! in nested structs.
|
|
|
|
//!
|
|
|
|
//! ```
|
|
|
|
//! # use activitypub_federation::protocol::context::WithContext;
|
|
|
|
//! #[derive(serde::Serialize)]
|
|
|
|
//! struct Note {
|
|
|
|
//! content: String
|
|
|
|
//! }
|
|
|
|
//! let note = Note {
|
|
|
|
//! content: "Hello world".to_string()
|
|
|
|
//! };
|
|
|
|
//! let note_with_context = WithContext::new_default(note);
|
|
|
|
//! let serialized = serde_json::to_string(¬e_with_context)?;
|
2023-03-07 22:01:36 +00:00
|
|
|
//! assert_eq!(serialized, r#"{"@context":["https://www.w3.org/ns/activitystreams"],"content":"Hello world"}"#);
|
2023-03-06 01:17:34 +00:00
|
|
|
//! Ok::<(), serde_json::error::Error>(())
|
|
|
|
//! ```
|
|
|
|
|
2023-03-16 01:11:48 +00:00
|
|
|
use crate::{config::Data, protocol::helpers::deserialize_one_or_many, traits::ActivityHandler};
|
2022-06-02 11:17:12 +00:00
|
|
|
use serde::{Deserialize, Serialize};
|
|
|
|
use serde_json::Value;
|
|
|
|
use url::Url;
|
|
|
|
|
2023-02-19 12:26:01 +00:00
|
|
|
/// Default context used in Activitypub
|
2023-03-07 22:01:36 +00:00
|
|
|
const DEFAULT_CONTEXT: &str = "https://www.w3.org/ns/activitystreams";
|
2022-06-02 11:17:12 +00:00
|
|
|
|
2023-02-19 12:26:01 +00:00
|
|
|
/// Wrapper for federated structs which handles `@context` field.
|
2022-06-02 11:17:12 +00:00
|
|
|
#[derive(Serialize, Deserialize, Debug)]
|
|
|
|
pub struct WithContext<T> {
|
|
|
|
#[serde(rename = "@context")]
|
|
|
|
#[serde(deserialize_with = "deserialize_one_or_many")]
|
|
|
|
context: Vec<Value>,
|
|
|
|
#[serde(flatten)]
|
|
|
|
inner: T,
|
|
|
|
}
|
|
|
|
|
|
|
|
impl<T> WithContext<T> {
|
2023-02-19 12:26:01 +00:00
|
|
|
/// Create a new wrapper with the default Activitypub context.
|
2022-06-02 11:17:12 +00:00
|
|
|
pub fn new_default(inner: T) -> WithContext<T> {
|
2023-03-07 22:01:36 +00:00
|
|
|
let context = vec![Value::String(DEFAULT_CONTEXT.to_string())];
|
2022-06-02 11:17:12 +00:00
|
|
|
WithContext::new(inner, context)
|
|
|
|
}
|
|
|
|
|
2023-02-19 12:26:01 +00:00
|
|
|
/// Create new wrapper with custom context. Use this in case you are implementing extensions.
|
2022-06-02 11:17:12 +00:00
|
|
|
pub fn new(inner: T, context: Vec<Value>) -> WithContext<T> {
|
|
|
|
WithContext { context, inner }
|
|
|
|
}
|
2023-01-25 00:51:41 +00:00
|
|
|
|
2023-03-02 14:18:06 +00:00
|
|
|
/// Returns the inner `T` object which this `WithContext` object is wrapping
|
2023-01-25 00:51:41 +00:00
|
|
|
pub fn inner(&self) -> &T {
|
|
|
|
&self.inner
|
|
|
|
}
|
2022-06-02 11:17:12 +00:00
|
|
|
}
|
|
|
|
|
2022-11-28 21:19:56 +00:00
|
|
|
#[async_trait::async_trait]
|
2022-06-02 11:17:12 +00:00
|
|
|
impl<T> ActivityHandler for WithContext<T>
|
|
|
|
where
|
2023-03-09 21:09:44 +00:00
|
|
|
T: ActivityHandler + Send + Sync,
|
2022-06-02 11:17:12 +00:00
|
|
|
{
|
|
|
|
type DataType = <T as ActivityHandler>::DataType;
|
|
|
|
type Error = <T as ActivityHandler>::Error;
|
|
|
|
|
|
|
|
fn id(&self) -> &Url {
|
|
|
|
self.inner.id()
|
|
|
|
}
|
|
|
|
|
|
|
|
fn actor(&self) -> &Url {
|
|
|
|
self.inner.actor()
|
|
|
|
}
|
|
|
|
|
2023-03-16 01:11:48 +00:00
|
|
|
async fn verify(&self, data: &Data<Self::DataType>) -> Result<(), Self::Error> {
|
2023-03-09 21:09:44 +00:00
|
|
|
self.inner.verify(data).await
|
|
|
|
}
|
|
|
|
|
2023-03-16 01:11:48 +00:00
|
|
|
async fn receive(self, data: &Data<Self::DataType>) -> Result<(), Self::Error> {
|
2023-02-11 12:32:35 +00:00
|
|
|
self.inner.receive(data).await
|
2022-06-02 11:17:12 +00:00
|
|
|
}
|
|
|
|
}
|
2023-03-16 01:11:48 +00:00
|
|
|
|
|
|
|
impl<T> Clone for WithContext<T>
|
|
|
|
where
|
|
|
|
T: Clone,
|
|
|
|
{
|
|
|
|
fn clone(&self) -> Self {
|
|
|
|
Self {
|
|
|
|
context: self.context.clone(),
|
|
|
|
inner: self.inner.clone(),
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|