diff --git a/src/activitystream/node.rs b/src/activitystream/node.rs index 8d70a3e8..243af8f5 100644 --- a/src/activitystream/node.rs +++ b/src/activitystream/node.rs @@ -11,7 +11,7 @@ pub enum NodeResolutionError { } pub enum Node { - Array(Vec), + Array(Vec>), Object(T), Link(Box), Empty, @@ -27,7 +27,7 @@ impl From> for Node { } impl Node { - pub fn first(&self) -> Option<&T> { + pub fn get(&self) -> Option<&T> { match self { Node::Empty | Node::Link(_) => None, Node::Object(x) => Some(x), @@ -35,7 +35,7 @@ impl Node { } } - pub fn items(&self) -> Option> { + pub fn all(&self) -> Option> { match self { Node::Empty | Node::Link(_) => None, Node::Object(x) => Some(vec![x]), @@ -43,46 +43,49 @@ impl Node { Some(v.iter().map(|x| &x).collect()), } } -} -impl Node -where - T : super::Base -{ - pub fn id(&self) -> Option<&str> { + pub fn len(&self) -> usize { match self { - Node::Array(v) => v.first()?.id(), - Node::Link(x) => Some(x.href()), - Node::Object(x) => x.id(), - Node::Empty => None, + Node::Empty => 0, + Node::Link(_) => 0, + Node::Object(_) => 1, + Node::Array(v) => v.len(), } } } -impl Node -where - T : Clone + for<'de> serde::Deserialize<'de>, -{ - pub async fn resolve(self) -> Result { - match self { - Node::Empty => Err(NodeResolutionError::Empty), - Node::Object(object) => Ok(object), - Node::Array(array) => Ok( - array - .first() - .ok_or(NodeResolutionError::EmptyArray)? - .clone() - ), - Node::Link(link) => Ok( - reqwest::get(link.href()) - .await? - .json::() - .await? +impl From for Node { + fn from(value: serde_json::Value) -> Self { + match value { + serde_json::Value::String(uri) => Node::Link(Box::new(uri)), + serde_json::Value::Object(_) => match value.get("href") { + Some(_) => Node::Object(value), + None => Node::Link(Box::new(value)), + }, + serde_json::Value::Array(arr) => Node::Array( + arr + .into_iter() + .filter_map(|x| Self::new(x).ok()) + .collect() ), + _ => Node::Empty, } } } +impl Node{ + pub async fn fetch(&mut self) -> reqwest::Result<()> { + if let Node::Link(link) = self { + *self = reqwest::get(link.href()) + .await? + .json::() + .await? + .into(); + } + Ok(()) + } +} + pub trait NodeExtractor { fn node(&self, id: &str) -> Node; fn node_vec(&self, id: &str) -> Node; @@ -110,41 +113,13 @@ impl NodeExtractor for serde_json::Value { } } -#[derive(Debug, thiserror::Error)] -#[error("json object is wrongly structured")] -pub struct JsonStructureError; - -impl Node { - pub fn new(value: serde_json::Value) -> Result { - if !(value.is_string() || value.is_object()) { - return Err(JsonStructureError); - } - if value.is_string() || value.get("href").is_some() { - Ok(Self::Link(Box::new(value))) - } else { - Ok(Self::Object(value)) - } - } - - pub fn many(value: serde_json::Value) -> Result, JsonStructureError> { - if let serde_json::Value::Array(arr) = value { - Ok( - arr - .into_iter() - .filter_map(|x| Self::new(x.clone()).ok()) - .collect() - ) - } else { - Ok(vec![Self::new(value)?]) - } - } -} pub(crate) trait InsertStr { fn insert_str(&mut self, k: &str, v: Option<&str>); fn insert_timestr(&mut self, k: &str, t: Option>); } + impl InsertStr for serde_json::Map { fn insert_str(&mut self, k: &str, v: Option<&str>) { if let Some(v) = v {