Browse Source

* [ap] added partial serialization/deserialization support to activity types

main
Riley Apeldoorn 9 months ago
parent
commit
f59e67c193
  1. 1
      Cargo.lock
  2. 1
      Cargo.toml
  3. 142
      src/ap/act.rs
  4. 9
      src/ap/mod.rs
  5. 19
      src/ap/obj.rs
  6. 7
      src/id.rs

1
Cargo.lock

@ -588,6 +588,7 @@ dependencies = [
"rand",
"reqwest",
"serde",
"serde_json",
"sled",
"url",
]

1
Cargo.toml

@ -12,6 +12,7 @@ async-trait = "*"
reqwest = { version = "^0.11", features = [ "json" ] }
bytes = "1"
serde = "1"
serde_json = "*"
sled = "^0.34"
rand = "*"
base64 = "^0.13"

142
src/ap/act.rs

@ -6,49 +6,73 @@ use super::{
Actor,
obj,
db,
id,
};
use serde::{ Serialize, Deserialize, };
impl Actor {
/// Boost/share/reblog a [`Note`].
///
/// [`Note`]: obj::Note
pub fn boost (self, obj: impl Into<obj::Boost>) -> Boost {
Boost { actor: self, object: obj.into(), }
Boost {
actor: self.id,
object: obj.into(),
}
}
/// Create a new [`Note`].
///
/// [`Note`]: obj::Note
pub fn create (self, obj: impl Into<obj::Create>) -> Create {
Create { actor: self, object: obj.into(), }
Create {
actor: self.id,
object: obj.into(),
}
}
/// Like a [`Note`].
///
/// [`Note`]: obj::Note
pub fn like (self, obj: impl Into<obj::Like>) -> Like {
Like { actor: self, object: obj.into(), }
Like {
actor: self.id,
object: obj.into(),
}
}
/// Accept a [`Follow`].
pub fn accept (self, obj: impl Into<obj::Accept>) -> Accept {
Accept { actor: self, object: obj.into(), }
Accept {
actor: self.id,
object: obj.into(),
}
}
/// Reject a [`Follow`].
pub fn reject (self, obj: impl Into<obj::Reject>) -> Reject {
Reject { actor: self, object: obj.into(), }
Reject {
actor: self.id,
object: obj.into(),
}
}
/// Undo a [`Follow`], [`Create`], [`Like`] or [`Boost`].
pub fn undo (self, obj: impl Into<obj::Undo>) -> Undo {
Undo { actor: self, object: obj.into(), }
Undo {
actor: self.id,
object: obj.into(),
}
}
/// Delete something.
pub fn delete (self, obj: impl Into<obj::Delete>) -> Delete {
Delete { actor: self, object: obj.into(), }
Delete {
actor: self.id,
object: obj.into(),
}
}
}
@ -65,8 +89,9 @@ impl Actor {
/// [Note]: https://www.w3.org/TR/activitystreams-vocabulary/#dfn-note
/// [`Note`]: obj::Note
#[derive(Clone, Debug, Serialize, Deserialize)]
pub struct Boost {
actor: Actor,
actor: id::Id<Actor>,
object: obj::Boost,
}
@ -76,10 +101,7 @@ impl IntoActivity for Boost {
fn into_activity (self, _: &db::Client) -> Activity<obj::Boost> {
let Boost { actor, object, .. } = self;
Activity {
actor: actor.id,
object,
}
Activity { actor, object, }
}
}
@ -91,8 +113,9 @@ impl IntoActivity for Boost {
/// This adds the `actor` of the `Follow` to its' `object`s'
/// `followers` collection.
#[derive(Clone, Debug, Serialize, Deserialize)]
pub struct Accept {
actor: Actor,
actor: id::Id<Actor>,
object: obj::Accept,
}
@ -102,18 +125,16 @@ impl IntoActivity for Accept {
fn into_activity (self, _: &db::Client) -> Activity<obj::Accept> {
let Accept { actor, object, .. } = self;
Activity {
actor: actor.id,
object,
}
Activity { actor, object, }
}
}
/// Reject a [`Follow`] activity.
#[derive(Clone, Debug, Serialize, Deserialize)]
pub struct Reject {
actor: Actor,
actor: id::Id<Actor>,
object: obj::Reject,
}
@ -123,16 +144,14 @@ impl IntoActivity for Reject {
fn into_activity (self, _: &db::Client) -> Activity<obj::Reject> {
let Reject { actor, object, .. } = self;
Activity {
actor: actor.id,
object,
}
Activity { actor, object, }
}
}
#[derive(Clone, Debug, Serialize, Deserialize)]
pub struct Follow {
actor: Actor,
actor: id::Id<Actor>,
object: obj::Follow,
}
@ -142,16 +161,14 @@ impl IntoActivity for Follow {
fn into_activity (self, _: &db::Client) -> Activity<obj::Follow> {
let Follow { actor, object, .. } = self;
Activity {
actor: actor.id,
object,
}
Activity { actor, object, }
}
}
#[derive(Clone, Debug, Serialize, Deserialize)]
pub struct Create {
actor: Actor,
actor: id::Id<Actor>,
object: obj::Create,
}
@ -161,16 +178,13 @@ impl IntoActivity for Create {
fn into_activity (self, _: &db::Client) -> Activity<obj::Create> {
let Create { actor, object, .. } = self;
Activity {
actor: actor.id,
object,
}
Activity { actor, object, }
}
}
#[derive(Clone, Debug, Serialize, Deserialize)]
pub struct Like {
actor: Actor,
actor: id::Id<Actor>,
object: obj::Like,
}
@ -180,16 +194,14 @@ impl IntoActivity for Like {
fn into_activity (self, _: &db::Client) -> Activity<obj::Like> {
let Like { actor, object, .. } = self;
Activity {
actor: actor.id,
object,
}
Activity { actor, object, }
}
}
#[derive(Clone, Debug, Serialize, Deserialize)]
pub struct Undo {
actor: Actor,
actor: id::Id<Actor>,
object: obj::Undo,
}
@ -199,16 +211,53 @@ impl IntoActivity for Undo {
fn into_activity (self, _: &db::Client) -> Activity<obj::Undo> {
let Undo { actor, object, .. } = self;
Activity {
actor: actor.id,
object,
}
Activity { actor, object, }
}
}
/// Request that the `object` is deleted.
///
/// ```
/// # use serde_json::json;
/// # use pod_be::ap::act::Delete;
/// # fn main () -> serde_json::Result<()> {
/// let raw = json!({
/// "actor": "https://pd.rly.cx/riley",
/// "object": {
/// "id": "https://pd.rly.cx/riley/a/kfsgjflgk",
/// "actor": "https://pd.rly.cx/riley",
/// "object": {
/// "id": "https://pd.rly.cx/riley/o/kfsgjflgk",
/// "type": "Note"
/// },
/// "type": "Create"
/// },
/// "type": "Delete"
/// });
///
/// let deserialized: Delete = serde_json::from_value(raw)?;
/// # Ok (())
/// # }
/// ```
///
/// ```
/// # use serde_json::json;
/// # use pod_be::ap::act::Delete;
/// # fn main () -> serde_json::Result<()> {
/// let raw = json!({
/// "actor": "https://pd.rly.cx/riley",
/// "object": "https://pd.rly.cx/riley/a/kfsgjflgk",
/// "type": "Delete"
/// });
///
/// let as_delete: Delete = serde_json::from_value(raw)?;
/// # Ok (())
/// # }
/// ```
#[derive(Clone, Debug, Serialize, Deserialize)]
pub struct Delete {
actor: Actor,
actor: id::Id<Actor>,
object: obj::Delete,
}
@ -218,9 +267,6 @@ impl IntoActivity for Delete {
fn into_activity (self, _: &db::Client) -> Activity<obj::Delete> {
let Delete { actor, object, .. } = self;
Activity {
actor: actor.id,
object,
}
Activity { actor, object, }
}
}

9
src/ap/mod.rs

@ -37,6 +37,8 @@
use super::{ id, db, };
use serde::{ Serialize, Deserialize, };
pub mod obj;
pub mod act;
@ -44,7 +46,7 @@ pub mod act;
///
/// [`Note`]: obj::Note
#[derive(Clone, Copy, Debug)]
#[derive(Clone, Copy, Debug, Serialize, Deserialize)]
pub enum Notelike {
Article,
Note,
@ -84,18 +86,19 @@ pub trait IntoActivity {
}
#[derive(Clone, Debug, Serialize, Deserialize)]
pub struct Activity<O> {
actor: id::Id<Actor>,
object: O,
}
impl<O> Activity<O> {
impl<O: id::HasId> Activity<O> {
pub async fn deliver (self) -> Result<(), db::Error> { todo!() }
}
/// The abstract representation of a source of [`Activity`] objects.
#[derive(Clone, Debug)]
#[derive(Clone, Debug, Serialize, Deserialize)]
pub struct Actor {
id: id::Id<Actor>,
}

19
src/ap/obj.rs

@ -8,6 +8,8 @@ use super::{
id,
};
use serde::{ Serialize, Deserialize, };
macro_rules! wrap_from {
{ for $o:ty {
$($i:ty => $to:path,)*
@ -27,6 +29,7 @@ macro_rules! wrap_from {
/// Pod understands any [`Notelike`] to be a [`Note`], but does keep track of
/// its former type. When relayed, its type is unchanged.
#[derive(Clone, Debug, Serialize, Deserialize)]
pub struct Note {
id: id::Id<Note>,
@ -34,6 +37,7 @@ pub struct Note {
content: Option<String>,
summary: Option<String>,
#[serde(rename = "type")]
kind: Notelike,
}
@ -91,6 +95,9 @@ impl id::HasId for Note {
///
/// [`Accept`]: act::Accept
#[derive(Clone, Debug, Serialize, Deserialize)]
#[serde(untagged)]
pub enum Accept {
/// Accept the follow request.
@ -106,6 +113,9 @@ wrap_from! { for Accept {
///
/// [`Reject`]: act::Reject.
#[derive(Clone, Debug, Serialize, Deserialize)]
#[serde(untagged)]
pub enum Reject {
/// Reject the follow request.
@ -120,6 +130,9 @@ wrap_from! { for Reject {
/// Objects on which the [`Follow`] activity is understood by
/// Pod.
#[derive(Clone, Debug, Serialize, Deserialize)]
#[serde(untagged)]
pub enum Follow {
/// A follow request addressed to an [`Actor`].
@ -158,6 +171,9 @@ pub type Like = Create;
///
/// [`Undo`]: act::Undo
#[derive(Clone, Debug, Serialize, Deserialize)]
#[serde(untagged)]
pub enum Undo {
/// Unfollow an actor.
@ -190,6 +206,9 @@ wrap_from! { for Undo {
///
/// [`Delete`]: act::Delete
#[derive(Clone, Debug, Serialize, Deserialize)]
#[serde(untagged)]
pub enum Delete {
/// Anything that counts as a [`Note`].

7
src/id.rs

@ -32,12 +32,13 @@ use serde::{ Serialize, Deserialize, };
/// ```
#[derive(Debug, Serialize, Deserialize)]
pub struct Id <T: HasId> {
#[serde(transparent)]
pub struct Id <T> {
pub (super) value: url::Url,
pub (super) _type: PhantomData<T>,
}
impl<T: HasId> Clone for Id<T> {
impl<T> Clone for Id<T> {
fn clone(&self) -> Id<T> {
Id {
value: self.value.clone(),
@ -59,7 +60,7 @@ impl<T: HasId> AsRef<[u8]> for Id<T> {
pub trait HasId: Sized {
type Type: From<Self> + HasId;
type Type: From<Self>;
fn get_id (&self) -> &Id<Self::Type>;

Loading…
Cancel
Save