From 4e22ce7923777518d13fbac90de0291ca106ff33 Mon Sep 17 00:00:00 2001 From: asonix Date: Sat, 16 May 2020 15:34:35 -0500 Subject: [PATCH] Test primitives --- src/primitives.rs | 350 ++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 350 insertions(+) diff --git a/src/primitives.rs b/src/primitives.rs index c13a157..41edefe 100644 --- a/src/primitives.rs +++ b/src/primitives.rs @@ -1,3 +1,17 @@ +//! Types creating the base for most ActivityStreams fields. +//! +//! These types are not themselves defined by ActivityStreams, but are referenced by the +//! specification. +//! +//! ```rust +//! use activitystreams_new::primitives::{AnyString, OneOrMany, Unit}; +//! +//! let any_string = AnyString::from_xsd_string("hey"); +//! +//! let one_or_many = OneOrMany::::from_one(1234); +//! +//! let cm = Unit::centimeters(); +//! ``` use crate::either::Either; pub use activitystreams::primitives::{ @@ -5,37 +19,133 @@ pub use activitystreams::primitives::{ XsdNonNegativeInteger, XsdString, }; +/// A type representing any kind of string +/// +/// In the ActivityStreams specification, string types are often defined as either an xsd:String or +/// and rdf:langString. The AnyString type represents this union. #[derive(Clone, Debug, serde::Deserialize, serde::Serialize)] #[serde(transparent)] pub struct AnyString(Either); +/// A type representing units of length +/// +/// It can be any of the following +/// - Centimeters +/// - Meters +/// - Kilometers +/// - Inches +/// - Feet +/// - A custom value #[derive( Clone, Debug, Eq, Hash, Ord, PartialEq, PartialOrd, serde::Deserialize, serde::Serialize, )] #[serde(transparent)] pub struct Unit(Either); +/// A type representing at least one value +/// +/// When translated to JSON, it can represent the following structures: +/// ```json +/// { +/// "key": value +/// } +/// ``` +/// ```json +/// { +/// "key": [], +/// } +/// ``` +/// ```json +/// { +/// "key": [value, ...] +/// } +/// ``` #[derive(Clone, Debug, serde::Deserialize, serde::Serialize)] #[serde(transparent)] pub struct OneOrMany(pub Either>); impl AnyString { + /// Borrow the AnyString as an XsdString + /// + /// ```rust + /// # fn main() -> Result<(), anyhow::Error> { + /// # use activitystreams_new::primitives::AnyString; + /// # let any_string = AnyString::from_xsd_string("hi"); + /// # + /// let s_borrow = any_string + /// .as_xsd_string() + /// .ok_or(anyhow::Error::msg("Wrong string type"))?; + /// # Ok(()) + /// # } + /// ``` pub fn as_xsd_string(&self) -> Option<&XsdString> { self.0.as_ref().left() } + /// Borrow the AnyString as an RdfLangString + /// + /// ```rust + /// # fn main() -> Result<(), anyhow::Error> { + /// # use activitystreams_new::primitives::{AnyString, RdfLangString}; + /// # let any_string = AnyString::from_rdf_lang_string(RdfLangString { + /// # value: "hi".into(), + /// # language: "en".into(), + /// # }); + /// # + /// let s_borrow = any_string + /// .as_rdf_lang_string() + /// .ok_or(anyhow::Error::msg("Wrong string type"))?; + /// # Ok(()) + /// # } + /// ``` pub fn as_rdf_lang_string(&self) -> Option<&RdfLangString> { self.0.as_ref().right() } + /// Take the AnyString as an XsdString + /// + /// ```rust + /// # fn main() -> Result<(), anyhow::Error> { + /// # use activitystreams_new::primitives::AnyString; + /// # let any_string = AnyString::from_xsd_string("hi"); + /// # + /// let xsd_string = any_string + /// .xsd_string() + /// .ok_or(anyhow::Error::msg("Wrong string type"))?; + /// # Ok(()) + /// # } + /// ``` pub fn xsd_string(self) -> Option { self.0.left() } + /// Take the AnyString as an RdfLangString + /// + /// ```rust + /// # fn main() -> Result<(), anyhow::Error> { + /// # use activitystreams_new::primitives::{AnyString, RdfLangString}; + /// # let any_string = AnyString::from_rdf_lang_string(RdfLangString { + /// # value: "hi".into(), + /// # language: "en".into(), + /// # }); + /// # + /// let rdf_lang_string = any_string + /// .rdf_lang_string() + /// .ok_or(anyhow::Error::msg("Wrong string type"))?; + /// # Ok(()) + /// # } + /// ``` pub fn rdf_lang_string(self) -> Option { self.0.right() } + /// Create a new AnyString from an `Into` + /// + /// ```rust + /// use activitystreams_new::primitives::AnyString; + /// + /// let any_string = AnyString::from_xsd_string("hi"); + /// ``` pub fn from_xsd_string(string: T) -> Self where T: Into, @@ -43,6 +153,16 @@ impl AnyString { AnyString(Either::Left(string.into())) } + /// Create a new AnyString from an RdfLangString + /// + /// ```rust + /// use activitystreams_new::primitives::{AnyString, RdfLangString}; + /// + /// let any_string = AnyString::from_rdf_lang_string(RdfLangString { + /// value: "hi".into(), + /// language: "en".into(), + /// }); + /// ``` pub fn from_rdf_lang_string(string: T) -> Self where T: Into, @@ -50,6 +170,20 @@ impl AnyString { AnyString(Either::Right(string.into())) } + /// Replace the contents of self with an XsdString + /// + /// ```rust + /// use activitystreams_new::primitives::{AnyString, RdfLangString}; + /// + /// let mut any_string = AnyString::from_rdf_lang_string(RdfLangString { + /// value: "hi".into(), + /// language: "en".into(), + /// }); + /// + /// any_string.set_xsd_string("hi"); + /// + /// assert!(any_string.as_xsd_string().is_some()); + /// ``` pub fn set_xsd_string(&mut self, string: T) where T: Into, @@ -57,6 +191,20 @@ impl AnyString { self.0 = Either::Left(string.into()); } + /// Replace the contents of self with an RdfLangString + /// + /// ```rust + /// use activitystreams_new::primitives::{AnyString, RdfLangString}; + /// + /// let mut any_string = AnyString::from_xsd_string("hi"); + /// + /// any_string.set_rdf_lang_string(RdfLangString { + /// value: "hi".into(), + /// language: "en".into(), + /// }); + /// + /// assert!(any_string.as_rdf_lang_string().is_some()); + /// ``` pub fn set_rdf_lang_string(&mut self, string: T) where T: Into, @@ -66,25 +214,86 @@ impl AnyString { } impl OneOrMany { + /// Try to borrow a single XsdString from the current object + /// + /// ```rust + /// # fn main() -> Result<(), anyhow::Error> { + /// # use activitystreams_new::primitives::{OneOrMany, AnyString}; + /// # let string = OneOrMany::::from_xsd_string("Hey"); + /// string + /// .as_single_xsd_string() + /// .ok_or(anyhow::Error::msg("Wrong string type"))?; + /// # Ok(()) + /// # } + /// ``` pub fn as_single_xsd_string(&self) -> Option<&XsdString> { self.as_one() .and_then(|any_string| any_string.as_xsd_string()) } + /// Try to borrow a single RdfLangString from the current object + /// + /// ```rust + /// # fn main() -> Result<(), anyhow::Error> { + /// # use activitystreams_new::primitives::{OneOrMany, RdfLangString}; + /// # let string = OneOrMany::from_rdf_lang_string(RdfLangString { + /// # value: "hi".into(), + /// # language: "en".into(), + /// # }); + /// string + /// .as_single_rdf_lang_string() + /// .ok_or(anyhow::Error::msg("Wrong string type"))?; + /// # Ok(()) + /// # } + /// ``` pub fn as_single_rdf_lang_string(&self) -> Option<&RdfLangString> { self.as_one() .and_then(|any_string| any_string.as_rdf_lang_string()) } + /// Try to take a single XsdString from the current object + /// + /// ```rust + /// # fn main() -> Result<(), anyhow::Error> { + /// # use activitystreams_new::primitives::{OneOrMany, AnyString}; + /// # let string = OneOrMany::::from_xsd_string("Hey"); + /// string + /// .single_xsd_string() + /// .ok_or(anyhow::Error::msg("Wrong string type"))?; + /// # Ok(()) + /// # } + /// ``` pub fn single_xsd_string(self) -> Option { self.one().and_then(|any_string| any_string.xsd_string()) } + /// Try to take a single RdfLangString from the current object + /// + /// ```rust + /// # fn main() -> Result<(), anyhow::Error> { + /// # use activitystreams_new::primitives::{OneOrMany, RdfLangString}; + /// # let string = OneOrMany::from_rdf_lang_string(RdfLangString { + /// # value: "hi".into(), + /// # language: "en".into(), + /// # }); + /// string + /// .single_rdf_lang_string() + /// .ok_or(anyhow::Error::msg("Wrong string type"))?; + /// # Ok(()) + /// # } + /// ``` pub fn single_rdf_lang_string(self) -> Option { self.one() .and_then(|any_string| any_string.rdf_lang_string()) } + /// Create the object from a single XsdString + /// + /// ```rust + /// use activitystreams_new::primitives::{OneOrMany, AnyString}; + /// + /// let string = OneOrMany::::from_xsd_string("hi"); + /// ``` pub fn from_xsd_string(string: T) -> Self where T: Into, @@ -92,6 +301,16 @@ impl OneOrMany { Self::from_one(AnyString::from_xsd_string(string)) } + /// Create the object from a single RdfLangString + /// + /// ```rust + /// use activitystreams_new::primitives::{OneOrMany, RdfLangString}; + /// + /// let string = OneOrMany::from_rdf_lang_string(RdfLangString { + /// value: "hi".into(), + /// language: "en".into(), + /// }); + /// ``` pub fn from_rdf_lang_string(string: T) -> Self where T: Into, @@ -99,6 +318,17 @@ impl OneOrMany { Self::from_one(AnyString::from_rdf_lang_string(string)) } + /// Add an XsdString to the object, appending to whatever is currently included + /// + /// ```rust + /// use activitystreams_new::primitives::{OneOrMany, AnyString}; + /// + /// let mut string = OneOrMany::::from_xsd_string("Hello"); + /// + /// string + /// .add_xsd_string("Hey") + /// .add_xsd_string("hi"); + /// ``` pub fn add_xsd_string(&mut self, string: T) -> &mut Self where T: Into, @@ -106,6 +336,23 @@ impl OneOrMany { self.add(string.into()) } + /// Add an RdfLangString to the object, appending to whatever is currently included + /// + /// ```rust + /// use activitystreams_new::primitives::{AnyString, OneOrMany, RdfLangString}; + /// + /// let mut string = OneOrMany::::from_xsd_string("Hello"); + /// + /// string + /// .add_rdf_lang_string(RdfLangString { + /// value: "Hey".into(), + /// language: "en".into(), + /// }) + /// .add_rdf_lang_string(RdfLangString { + /// value: "hi".into(), + /// language: "en".into(), + /// }); + /// ``` pub fn add_rdf_lang_string(&mut self, string: T) -> &mut Self where T: Into, @@ -115,22 +362,71 @@ impl OneOrMany { } impl OneOrMany { + /// Get a reference to a single value + /// + /// ```rust + /// # use activitystreams_new::primitives::OneOrMany; + /// # let value = OneOrMany::from_one(1); + /// if let Some(v) = value.as_one() { + /// println!("{:?}", v); + /// } + /// ``` pub fn as_one(&self) -> Option<&T> { self.0.as_ref().left() } + /// Take a single value + /// + /// ```rust + /// # use activitystreams_new::primitives::OneOrMany; + /// # let value = OneOrMany::from_one(1); + /// if let Some(v) = value.one() { + /// println!("{:?}", v); + /// } + /// ``` pub fn one(self) -> Option { self.0.left() } + /// Get a slice of values + /// + /// ```rust + /// # use activitystreams_new::primitives::OneOrMany; + /// # let value = OneOrMany::from_many(vec![1, 2, 3]); + /// if let Some(v) = value.as_many() { + /// for item in v.iter() { + /// println!("{:?}", item); + /// } + /// } + /// ``` pub fn as_many(&self) -> Option<&[T]> { self.0.as_ref().right().map(|v| v.as_ref()) } + /// Take a Vec of values + /// + /// ```rust + /// # use activitystreams_new::primitives::OneOrMany; + /// # let value = OneOrMany::from_many(vec![1, 2, 3]); + /// if let Some(v) = value.many() { + /// for item in v.into_iter() { + /// println!("{:?}", item); + /// } + /// } + /// ``` pub fn many(self) -> Option> { self.0.right() } + /// Consume the type, returning a vec + /// + /// ```rust + /// # use activitystreams_new::primitives::OneOrMany; + /// # let value = OneOrMany::from_many(vec![1, 2, 3]); + /// for item in value.unwrap_to_vec() { + /// println!("{:?}", item); + /// } + /// ``` pub fn unwrap_to_vec(self) -> Vec { match self.0 { Either::Left(t) => vec![t], @@ -138,14 +434,35 @@ impl OneOrMany { } } + /// Produce a new object from one value + /// + /// ``` + /// use activitystreams_new::primitives::OneOrMany; + /// let v = OneOrMany::from_one(1234); + /// ``` pub fn from_one(t: T) -> Self { OneOrMany(Either::Left(t)) } + /// Produce a new object from a vec of values + /// + /// ``` + /// use activitystreams_new::primitives::OneOrMany; + /// let v = OneOrMany::from_many(vec![1, 2, 3, 4]); + /// ``` pub fn from_many(items: Vec) -> Self { OneOrMany(Either::Right(items)) } + /// Overwrite the contents with a single value + /// + /// ``` + /// # use activitystreams_new::primitives::OneOrMany; + /// # let mut value = OneOrMany::from_many(vec![1, 2, 3]); + /// value.set_one(3); + /// + /// assert!(value.as_one().is_some()); + /// ``` pub fn set_one(&mut self, u: U) -> &mut Self where U: Into, @@ -154,6 +471,15 @@ impl OneOrMany { self } + /// Overwrite the contents with vec of values + /// + /// ``` + /// # use activitystreams_new::primitives::OneOrMany; + /// # let mut value = OneOrMany::from_one(1234); + /// value.set_many(vec![1, 2, 3, 4]); + /// + /// assert!(value.as_many().is_some()); + /// ``` pub fn set_many(&mut self, items: impl IntoIterator) -> &mut Self where U: Into, @@ -162,6 +488,18 @@ impl OneOrMany { self } + /// Add a value to the object + /// + /// This appends the value to the existing vec, or converts the single value into a vec, and + /// then appends the new value + /// + /// ``` + /// use activitystreams_new::primitives::OneOrMany; + /// let mut value = OneOrMany::from_one(1234); + /// value.add(4321); + /// + /// assert!(value.as_many().is_some()); + /// ``` pub fn add(&mut self, u: U) -> &mut Self where U: Into, @@ -175,6 +513,18 @@ impl OneOrMany { self } + /// Add many values to the object + /// + /// This appends the values to the existing vec, or converts the single value into a vec, and + /// then appends the new values + /// + /// ``` + /// use activitystreams_new::primitives::OneOrMany; + /// let mut value = OneOrMany::from_one(1234); + /// value.add_many(vec![4321, 2345]); + /// + /// assert!(value.as_many().is_some()); + /// ``` pub fn add_many(&mut self, items: impl IntoIterator) -> &mut Self where U: Into,