use crate::either::Either; pub use activitystreams::primitives::{ Length, MimeMediaType, RdfLangString, XsdAnyUri, XsdDateTime, XsdDuration, XsdNonNegativeInteger, XsdString, }; #[derive(Clone, Debug, Default, serde::Deserialize, serde::Serialize)] #[serde(transparent)] pub struct Unparsed(std::collections::HashMap); #[derive(Clone, Debug, serde::Deserialize, serde::Serialize)] #[serde(transparent)] pub struct AnyString(Either); pub type Unit = Either; #[derive(Clone, Debug, serde::Deserialize, serde::Serialize)] #[serde(transparent)] pub struct OneOrMany(pub Either>); impl Unparsed { pub(crate) fn remove(&mut self, key: &str) -> serde_json::Value { self.0.remove(key).unwrap_or(serde_json::Value::Null) } pub(crate) fn insert(&mut self, key: String, value: serde_json::Value) { self.0.insert(key, value); } } impl AnyString { pub fn as_xsd_string(&self) -> Option<&XsdString> { self.0.as_ref().left() } pub fn as_rdf_lang_string(&self) -> Option<&RdfLangString> { self.0.as_ref().right() } pub fn xsd_string(self) -> Option { self.0.left() } pub fn rdf_lang_string(self) -> Option { self.0.right() } pub fn from_xsd_string(string: T) -> Self where XsdString: From, { AnyString(Either::Left(string.into())) } pub fn from_rdf_lang_string(string: T) -> Self where RdfLangString: From, { AnyString(Either::Right(string.into())) } pub fn set_xsd_string(&mut self, string: T) where XsdString: From, { self.0 = Either::Left(string.into()); } pub fn set_rdf_lang_string(&mut self, string: T) where RdfLangString: From, { self.0 = Either::Right(string.into()); } } impl OneOrMany { pub fn as_single_xsd_string(&self) -> Option<&XsdString> { self.as_one() .and_then(|any_string| any_string.as_xsd_string()) } pub fn as_single_rdf_lang_string(&self) -> Option<&RdfLangString> { self.as_one() .and_then(|any_string| any_string.as_rdf_lang_string()) } pub fn single_xsd_string(self) -> Option { self.one().and_then(|any_string| any_string.xsd_string()) } pub fn single_rdf_lang_string(self) -> Option { self.one() .and_then(|any_string| any_string.rdf_lang_string()) } pub fn from_xsd_string(string: T) -> Self where XsdString: From, { Self::from_one(AnyString::from_xsd_string(string)) } pub fn from_rdf_lang_string(string: T) -> Self where RdfLangString: From, { Self::from_one(AnyString::from_rdf_lang_string(string)) } } impl OneOrMany { pub fn as_one(&self) -> Option<&T> { self.0.as_ref().left() } pub fn one(self) -> Option { self.0.left() } pub fn as_many(&self) -> Option<&[T]> { self.0.as_ref().right().map(|v| v.as_ref()) } pub fn many(self) -> Option> { self.0.right() } pub fn unwrap_to_vec(self) -> Vec { match self.0 { Either::Left(t) => vec![t], Either::Right(v) => v, } } pub fn from_one(t: T) -> Self { OneOrMany(Either::Left(t)) } pub fn from_many(items: Vec) -> Self { OneOrMany(Either::Right(items)) } pub fn set_one(&mut self, u: U) -> &mut Self where T: From, { self.0 = Either::Left(u.into()); self } pub fn set_many(&mut self, items: impl IntoIterator) -> &mut Self where T: From, { self.0 = Either::Right(items.into_iter().map(T::from).collect()); self } pub fn add(&mut self, u: U) -> &mut Self where T: From, { let mut v = match std::mem::replace(&mut self.0, Either::Right(vec![])) { Either::Left(one) => vec![one], Either::Right(v) => v, }; v.push(u.into()); self.0 = Either::Right(v); self } pub fn add_many(&mut self, items: impl IntoIterator) -> &mut Self where T: From, { let mut v = match std::mem::replace(&mut self.0, Either::Right(vec![])) { Either::Left(one) => vec![one], Either::Right(v) => v, }; v.extend(items.into_iter().map(T::from)); self.0 = Either::Right(v); self } } impl From for AnyString { fn from(s: XsdString) -> Self { AnyString::from_xsd_string(s) } } impl From for AnyString { fn from(s: RdfLangString) -> Self { AnyString::from_rdf_lang_string(s) } } impl From for OneOrMany { fn from(s: XsdString) -> Self { OneOrMany::::from_xsd_string(s) } } impl From for OneOrMany { fn from(s: RdfLangString) -> Self { OneOrMany::::from_rdf_lang_string(s) } }