From ac3f07f804d2a2780de3ac0c5cf7ac48b5cf3f76 Mon Sep 17 00:00:00 2001 From: alemi Date: Thu, 14 Mar 2024 05:27:08 +0100 Subject: [PATCH] feat: work on activitystream types --- src/activitystream/activity.rs | 4 ++ src/activitystream/mod.rs | 7 +++ src/activitystream/object.rs | 82 ++++++++++++++++++++++++++++++++++ src/main.rs | 1 + 4 files changed, 94 insertions(+) create mode 100644 src/activitystream/activity.rs create mode 100644 src/activitystream/mod.rs create mode 100644 src/activitystream/object.rs diff --git a/src/activitystream/activity.rs b/src/activitystream/activity.rs new file mode 100644 index 00000000..10586e60 --- /dev/null +++ b/src/activitystream/activity.rs @@ -0,0 +1,4 @@ +pub trait Activity : super::Object { + fn actor(&self) -> Option<&super::ObjectOrLink> { None } + fn object(&self) -> Option<&super::ObjectOrLink> { None } +} diff --git a/src/activitystream/mod.rs b/src/activitystream/mod.rs new file mode 100644 index 00000000..3837ac9e --- /dev/null +++ b/src/activitystream/mod.rs @@ -0,0 +1,7 @@ + +pub mod object; +pub use object::{Object, Link, ObjectOrLink}; + + +pub mod activity; +pub use activity::Activity; diff --git a/src/activitystream/object.rs b/src/activitystream/object.rs new file mode 100644 index 00000000..72c7fad8 --- /dev/null +++ b/src/activitystream/object.rs @@ -0,0 +1,82 @@ +pub enum ObjectOrLink { + Object(Box), + Link(Box), +} + +impl From for ObjectOrLink { + fn from(value: serde_json::Value) -> Self { + if value.get("href").is_some() { + Self::Link(Box::new(value)) + } else { + Self::Object(Box::new(value)) + } + } +} + +pub trait Link { + fn href(&self) -> Option<&str> { None } + fn rel(&self) -> Option<&str> { None } + fn media_type(&self) -> Option<&str> { None } // also in obj + fn name(&self) -> Option<&str> { None } // also in obj + fn hreflang(&self) -> Option<&str> { None } + fn height(&self) -> Option<&str> { None } + fn width(&self) -> Option<&str> { None } + fn preview(&self) -> Option<&str> { None } // also in obj +} + + +pub trait Object { + fn id(&self) -> Option<&str> { None } + fn object_type(&self) -> Option<&str> { None } + fn attachment (&self) -> Option<&str> { None } + fn attributed_to (&self) -> Option<&str> { None } + fn audience (&self) -> Option<&str> { None } + fn content (&self) -> Option<&str> { None } + fn context (&self) -> Option<&str> { None } + fn name (&self) -> Option<&str> { None } + fn end_time (&self) -> Option<&str> { None } + fn generator (&self) -> Option<&str> { None } + fn icon (&self) -> Option<&str> { None } + fn image (&self) -> Option<&str> { None } + fn in_reply_to (&self) -> Option<&str> { None } + fn location (&self) -> Option<&str> { None } + fn preview (&self) -> Option<&str> { None } + fn published (&self) -> Option<&str> { None } + fn replies (&self) -> Option<&str> { None } + fn start_time (&self) -> Option<&str> { None } + fn summary (&self) -> Option<&str> { None } + fn tag (&self) -> Option<&str> { None } + fn updated (&self) -> Option<&str> { None } + fn url (&self) -> Option<&str> { None } + fn to (&self) -> Option<&str> { None } + fn bto (&self) -> Option<&str> { None } + fn cc (&self) -> Option<&str> { None } + fn bcc (&self) -> Option<&str> { None } + fn media_type (&self) -> Option<&str> { None } + fn duration (&self) -> Option<&str> { None } +} + +/// impl for empty object +impl Object for () {} + +// TODO only Value::Object is a valid Object, but rn "asd" behaves like {} (both are valid...) +/// impl for any json value +impl Object for serde_json::Value { + fn id(&self) -> Option<&str> { + self.get("id")?.as_str() + } + + fn object_type(&self) -> Option<&str> { + self.get("type")?.as_str() + } + + // ... +} + +impl Link for serde_json::Value { + fn href(&self) -> Option<&str> { + self.get("href")?.as_str() + } + + // ... +} diff --git a/src/main.rs b/src/main.rs index ad40dbec..7dbb9b40 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,4 +1,5 @@ pub mod model; +pub mod activitystream; use axum::{ routing::get,