From 106380d3b70da6c8dea78a6858ce1d98a8915207 Mon Sep 17 00:00:00 2001 From: alemi Date: Tue, 19 Mar 2024 06:49:02 +0100 Subject: [PATCH] feat: improved Node API --- src/activitystream/node.rs | 84 ++++++++++++++++++++++---------- src/activitystream/object/mod.rs | 1 + 2 files changed, 59 insertions(+), 26 deletions(-) diff --git a/src/activitystream/node.rs b/src/activitystream/node.rs index 243af8f5..1b11e121 100644 --- a/src/activitystream/node.rs +++ b/src/activitystream/node.rs @@ -1,14 +1,4 @@ -#[derive(Debug, thiserror::Error)] -pub enum NodeResolutionError { - #[error("error fetching object: {0}")] - FetchError(#[from] reqwest::Error), - - #[error("empty array")] - EmptyArray, - - #[error("field not present")] - Empty, -} +use super::Object; pub enum Node { Array(Vec>), @@ -31,7 +21,13 @@ impl Node { match self { Node::Empty | Node::Link(_) => None, Node::Object(x) => Some(x), - Node::Array(v) => v.first(), + Node::Array(v) => match v.iter().find_map(|x| match x { + Node::Object(x) => Some(x), + _ => None, + }) { + Some(x) => Some(x), + None => None, + }, } } @@ -40,7 +36,17 @@ impl Node { Node::Empty | Node::Link(_) => None, Node::Object(x) => Some(vec![x]), Node::Array(v) => - Some(v.iter().map(|x| &x).collect()), + Some(v.iter().filter_map(|x| match x { + Node::Object(x) => Some(x), + _ => None, + }).collect()), + } + } + + pub fn is_empty(&self) -> bool { + match self { + Node::Empty | Node::Link(_) => true, + Node::Object(_) | Node::Array(_) => false, } } @@ -54,6 +60,35 @@ impl Node { } } +impl Node +where + T : Object +{ + pub fn id(&self) -> Option<&str> { + match self { + Node::Empty => None, + Node::Link(uri) => Some(uri.href()), + Node::Object(obj) => obj.id(), + Node::Array(arr) => arr.first()?.id(), + } + } +} + +impl From> for Node { + fn from(value: Option<&str>) -> Self { + match value { + Some(x) => Node::Link(Box::new(x.to_string())), + None => Node::Empty, + } + } +} + +impl From<&str> for Node { + fn from(value: &str) -> Self { + Node::Link(Box::new(value.to_string())) + } +} + impl From for Node { fn from(value: serde_json::Value) -> Self { match value { @@ -65,7 +100,7 @@ impl From for Node { serde_json::Value::Array(arr) => Node::Array( arr .into_iter() - .filter_map(|x| Self::new(x).ok()) + .map(Self::from) .collect() ), _ => Node::Empty, @@ -86,7 +121,12 @@ impl Node{ } } -pub trait NodeExtractor { + + + + + +pub(crate) trait NodeExtractor { fn node(&self, id: &str) -> Node; fn node_vec(&self, id: &str) -> Node; } @@ -95,26 +135,18 @@ impl NodeExtractor for serde_json::Value { fn node(&self, id: &str) -> Node { match self.get(id) { None => Node::Empty, - Some(x) => match Node::new(x.clone()) { - Err(e) => Node::Empty, - Ok(x) => x, - } + Some(x) => Node::from(x.clone()), } } fn node_vec(&self, id: &str) -> Node { match self.get(id) { None => Node::Empty, - Some(x) => match Node::many(x.clone()) { - Err(e) => Node::Empty, - Ok(x) => x, - } + Some(x) => Node::from(x.clone()), } } } - - pub(crate) trait InsertStr { fn insert_str(&mut self, k: &str, v: Option<&str>); fn insert_timestr(&mut self, k: &str, t: Option>); @@ -133,7 +165,7 @@ impl InsertStr for serde_json::Map { fn insert_timestr(&mut self, k: &str, t: Option>) { if let Some(published) = t { self.insert( - "published".to_string(), + k.to_string(), serde_json::Value::String(published.to_rfc3339()), ); } diff --git a/src/activitystream/object/mod.rs b/src/activitystream/object/mod.rs index 2b81f774..02965a7c 100644 --- a/src/activitystream/object/mod.rs +++ b/src/activitystream/object/mod.rs @@ -70,6 +70,7 @@ pub trait Object : super::Base { impl Object for serde_json::Value { fn object_type(&self) -> Option { + use super::Base; match self.base_type() { Some(super::BaseType::Object(o)) => Some(o), _ => None,