2020-05-16 20:34:35 +00:00
|
|
|
//! 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::<i32>::from_one(1234);
|
|
|
|
//!
|
|
|
|
//! let cm = Unit::centimeters();
|
|
|
|
//! ```
|
2020-05-14 03:54:50 +00:00
|
|
|
use crate::either::Either;
|
|
|
|
|
|
|
|
pub use activitystreams::primitives::{
|
2020-05-14 16:23:38 +00:00
|
|
|
Length, MimeMediaType, RdfLangString, XsdAnyUri, XsdDateTime, XsdDuration, XsdFloat,
|
2020-05-14 03:54:50 +00:00
|
|
|
XsdNonNegativeInteger, XsdString,
|
|
|
|
};
|
|
|
|
|
2020-05-16 20:34:35 +00:00
|
|
|
/// 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.
|
2020-05-14 03:54:50 +00:00
|
|
|
#[derive(Clone, Debug, serde::Deserialize, serde::Serialize)]
|
|
|
|
#[serde(transparent)]
|
|
|
|
pub struct AnyString(Either<XsdString, RdfLangString>);
|
|
|
|
|
2020-05-16 20:34:35 +00:00
|
|
|
/// A type representing units of length
|
|
|
|
///
|
|
|
|
/// It can be any of the following
|
|
|
|
/// - Centimeters
|
|
|
|
/// - Meters
|
|
|
|
/// - Kilometers
|
|
|
|
/// - Inches
|
|
|
|
/// - Feet
|
|
|
|
/// - A custom value
|
2020-05-16 19:49:29 +00:00
|
|
|
#[derive(
|
|
|
|
Clone, Debug, Eq, Hash, Ord, PartialEq, PartialOrd, serde::Deserialize, serde::Serialize,
|
|
|
|
)]
|
|
|
|
#[serde(transparent)]
|
|
|
|
pub struct Unit(Either<Length, XsdString>);
|
2020-05-14 03:54:50 +00:00
|
|
|
|
2020-05-16 20:34:35 +00:00
|
|
|
/// 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, ...]
|
|
|
|
/// }
|
|
|
|
/// ```
|
2020-05-14 03:54:50 +00:00
|
|
|
#[derive(Clone, Debug, serde::Deserialize, serde::Serialize)]
|
|
|
|
#[serde(transparent)]
|
|
|
|
pub struct OneOrMany<T>(pub Either<T, Vec<T>>);
|
|
|
|
|
|
|
|
impl AnyString {
|
2020-05-16 20:34:35 +00:00
|
|
|
/// 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(())
|
|
|
|
/// # }
|
|
|
|
/// ```
|
2020-05-14 03:54:50 +00:00
|
|
|
pub fn as_xsd_string(&self) -> Option<&XsdString> {
|
|
|
|
self.0.as_ref().left()
|
|
|
|
}
|
|
|
|
|
2020-05-16 20:34:35 +00:00
|
|
|
/// 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(())
|
|
|
|
/// # }
|
|
|
|
/// ```
|
2020-05-14 03:54:50 +00:00
|
|
|
pub fn as_rdf_lang_string(&self) -> Option<&RdfLangString> {
|
|
|
|
self.0.as_ref().right()
|
|
|
|
}
|
|
|
|
|
2020-05-16 20:34:35 +00:00
|
|
|
/// 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(())
|
|
|
|
/// # }
|
|
|
|
/// ```
|
2020-05-14 03:54:50 +00:00
|
|
|
pub fn xsd_string(self) -> Option<XsdString> {
|
|
|
|
self.0.left()
|
|
|
|
}
|
|
|
|
|
2020-05-16 20:34:35 +00:00
|
|
|
/// 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(())
|
|
|
|
/// # }
|
|
|
|
/// ```
|
2020-05-14 03:54:50 +00:00
|
|
|
pub fn rdf_lang_string(self) -> Option<RdfLangString> {
|
|
|
|
self.0.right()
|
|
|
|
}
|
|
|
|
|
2020-05-16 20:34:35 +00:00
|
|
|
/// Create a new AnyString from an `Into<XsdString>`
|
|
|
|
///
|
|
|
|
/// ```rust
|
|
|
|
/// use activitystreams_new::primitives::AnyString;
|
|
|
|
///
|
|
|
|
/// let any_string = AnyString::from_xsd_string("hi");
|
|
|
|
/// ```
|
2020-05-14 03:54:50 +00:00
|
|
|
pub fn from_xsd_string<T>(string: T) -> Self
|
|
|
|
where
|
2020-05-16 01:08:43 +00:00
|
|
|
T: Into<XsdString>,
|
2020-05-14 03:54:50 +00:00
|
|
|
{
|
|
|
|
AnyString(Either::Left(string.into()))
|
|
|
|
}
|
|
|
|
|
2020-05-16 20:34:35 +00:00
|
|
|
/// 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(),
|
|
|
|
/// });
|
|
|
|
/// ```
|
2020-05-14 03:54:50 +00:00
|
|
|
pub fn from_rdf_lang_string<T>(string: T) -> Self
|
|
|
|
where
|
2020-05-16 01:08:43 +00:00
|
|
|
T: Into<RdfLangString>,
|
2020-05-14 03:54:50 +00:00
|
|
|
{
|
|
|
|
AnyString(Either::Right(string.into()))
|
|
|
|
}
|
|
|
|
|
2020-05-16 20:34:35 +00:00
|
|
|
/// 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());
|
|
|
|
/// ```
|
2020-05-14 03:54:50 +00:00
|
|
|
pub fn set_xsd_string<T>(&mut self, string: T)
|
|
|
|
where
|
2020-05-16 01:08:43 +00:00
|
|
|
T: Into<XsdString>,
|
2020-05-14 03:54:50 +00:00
|
|
|
{
|
|
|
|
self.0 = Either::Left(string.into());
|
|
|
|
}
|
|
|
|
|
2020-05-16 20:34:35 +00:00
|
|
|
/// 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());
|
|
|
|
/// ```
|
2020-05-14 03:54:50 +00:00
|
|
|
pub fn set_rdf_lang_string<T>(&mut self, string: T)
|
|
|
|
where
|
2020-05-16 01:08:43 +00:00
|
|
|
T: Into<RdfLangString>,
|
2020-05-14 03:54:50 +00:00
|
|
|
{
|
|
|
|
self.0 = Either::Right(string.into());
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
impl OneOrMany<AnyString> {
|
2020-05-16 20:34:35 +00:00
|
|
|
/// 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::<AnyString>::from_xsd_string("Hey");
|
|
|
|
/// string
|
|
|
|
/// .as_single_xsd_string()
|
|
|
|
/// .ok_or(anyhow::Error::msg("Wrong string type"))?;
|
|
|
|
/// # Ok(())
|
|
|
|
/// # }
|
|
|
|
/// ```
|
2020-05-14 03:54:50 +00:00
|
|
|
pub fn as_single_xsd_string(&self) -> Option<&XsdString> {
|
|
|
|
self.as_one()
|
|
|
|
.and_then(|any_string| any_string.as_xsd_string())
|
|
|
|
}
|
|
|
|
|
2020-05-16 20:34:35 +00:00
|
|
|
/// 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(())
|
|
|
|
/// # }
|
|
|
|
/// ```
|
2020-05-14 03:54:50 +00:00
|
|
|
pub fn as_single_rdf_lang_string(&self) -> Option<&RdfLangString> {
|
|
|
|
self.as_one()
|
|
|
|
.and_then(|any_string| any_string.as_rdf_lang_string())
|
|
|
|
}
|
|
|
|
|
2020-05-16 20:34:35 +00:00
|
|
|
/// 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::<AnyString>::from_xsd_string("Hey");
|
|
|
|
/// string
|
|
|
|
/// .single_xsd_string()
|
|
|
|
/// .ok_or(anyhow::Error::msg("Wrong string type"))?;
|
|
|
|
/// # Ok(())
|
|
|
|
/// # }
|
|
|
|
/// ```
|
2020-05-14 03:54:50 +00:00
|
|
|
pub fn single_xsd_string(self) -> Option<XsdString> {
|
|
|
|
self.one().and_then(|any_string| any_string.xsd_string())
|
|
|
|
}
|
|
|
|
|
2020-05-16 20:34:35 +00:00
|
|
|
/// 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(())
|
|
|
|
/// # }
|
|
|
|
/// ```
|
2020-05-14 03:54:50 +00:00
|
|
|
pub fn single_rdf_lang_string(self) -> Option<RdfLangString> {
|
|
|
|
self.one()
|
|
|
|
.and_then(|any_string| any_string.rdf_lang_string())
|
|
|
|
}
|
|
|
|
|
2020-05-16 20:34:35 +00:00
|
|
|
/// Create the object from a single XsdString
|
|
|
|
///
|
|
|
|
/// ```rust
|
|
|
|
/// use activitystreams_new::primitives::{OneOrMany, AnyString};
|
|
|
|
///
|
|
|
|
/// let string = OneOrMany::<AnyString>::from_xsd_string("hi");
|
|
|
|
/// ```
|
2020-05-14 03:54:50 +00:00
|
|
|
pub fn from_xsd_string<T>(string: T) -> Self
|
|
|
|
where
|
2020-05-16 01:08:43 +00:00
|
|
|
T: Into<XsdString>,
|
2020-05-14 03:54:50 +00:00
|
|
|
{
|
|
|
|
Self::from_one(AnyString::from_xsd_string(string))
|
|
|
|
}
|
|
|
|
|
2020-05-16 20:34:35 +00:00
|
|
|
/// 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(),
|
|
|
|
/// });
|
|
|
|
/// ```
|
2020-05-14 03:54:50 +00:00
|
|
|
pub fn from_rdf_lang_string<T>(string: T) -> Self
|
|
|
|
where
|
2020-05-16 01:08:43 +00:00
|
|
|
T: Into<RdfLangString>,
|
2020-05-14 03:54:50 +00:00
|
|
|
{
|
|
|
|
Self::from_one(AnyString::from_rdf_lang_string(string))
|
|
|
|
}
|
2020-05-16 01:08:43 +00:00
|
|
|
|
2020-05-16 20:34:35 +00:00
|
|
|
/// Add an XsdString to the object, appending to whatever is currently included
|
|
|
|
///
|
|
|
|
/// ```rust
|
|
|
|
/// use activitystreams_new::primitives::{OneOrMany, AnyString};
|
|
|
|
///
|
|
|
|
/// let mut string = OneOrMany::<AnyString>::from_xsd_string("Hello");
|
|
|
|
///
|
|
|
|
/// string
|
|
|
|
/// .add_xsd_string("Hey")
|
|
|
|
/// .add_xsd_string("hi");
|
|
|
|
/// ```
|
2020-05-16 01:08:43 +00:00
|
|
|
pub fn add_xsd_string<T>(&mut self, string: T) -> &mut Self
|
|
|
|
where
|
|
|
|
T: Into<XsdString>,
|
|
|
|
{
|
|
|
|
self.add(string.into())
|
|
|
|
}
|
|
|
|
|
2020-05-16 20:34:35 +00:00
|
|
|
/// Add an RdfLangString to the object, appending to whatever is currently included
|
|
|
|
///
|
|
|
|
/// ```rust
|
|
|
|
/// use activitystreams_new::primitives::{AnyString, OneOrMany, RdfLangString};
|
|
|
|
///
|
|
|
|
/// let mut string = OneOrMany::<AnyString>::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(),
|
|
|
|
/// });
|
|
|
|
/// ```
|
2020-05-16 01:08:43 +00:00
|
|
|
pub fn add_rdf_lang_string<T>(&mut self, string: T) -> &mut Self
|
|
|
|
where
|
|
|
|
T: Into<RdfLangString>,
|
|
|
|
{
|
|
|
|
self.add(string.into())
|
|
|
|
}
|
2020-05-14 03:54:50 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
impl<T> OneOrMany<T> {
|
2020-05-16 20:34:35 +00:00
|
|
|
/// 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);
|
|
|
|
/// }
|
|
|
|
/// ```
|
2020-05-14 03:54:50 +00:00
|
|
|
pub fn as_one(&self) -> Option<&T> {
|
|
|
|
self.0.as_ref().left()
|
|
|
|
}
|
|
|
|
|
2020-05-16 20:34:35 +00:00
|
|
|
/// Take a single value
|
|
|
|
///
|
|
|
|
/// ```rust
|
|
|
|
/// # use activitystreams_new::primitives::OneOrMany;
|
|
|
|
/// # let value = OneOrMany::from_one(1);
|
|
|
|
/// if let Some(v) = value.one() {
|
|
|
|
/// println!("{:?}", v);
|
|
|
|
/// }
|
|
|
|
/// ```
|
2020-05-14 03:54:50 +00:00
|
|
|
pub fn one(self) -> Option<T> {
|
|
|
|
self.0.left()
|
|
|
|
}
|
|
|
|
|
2020-05-16 20:34:35 +00:00
|
|
|
/// 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);
|
|
|
|
/// }
|
|
|
|
/// }
|
|
|
|
/// ```
|
2020-05-14 03:54:50 +00:00
|
|
|
pub fn as_many(&self) -> Option<&[T]> {
|
|
|
|
self.0.as_ref().right().map(|v| v.as_ref())
|
|
|
|
}
|
|
|
|
|
2020-05-16 20:34:35 +00:00
|
|
|
/// 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);
|
|
|
|
/// }
|
|
|
|
/// }
|
|
|
|
/// ```
|
2020-05-14 03:54:50 +00:00
|
|
|
pub fn many(self) -> Option<Vec<T>> {
|
|
|
|
self.0.right()
|
|
|
|
}
|
|
|
|
|
2020-05-16 20:34:35 +00:00
|
|
|
/// 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);
|
|
|
|
/// }
|
|
|
|
/// ```
|
2020-05-14 03:54:50 +00:00
|
|
|
pub fn unwrap_to_vec(self) -> Vec<T> {
|
|
|
|
match self.0 {
|
|
|
|
Either::Left(t) => vec![t],
|
|
|
|
Either::Right(v) => v,
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2020-05-16 20:34:35 +00:00
|
|
|
/// Produce a new object from one value
|
|
|
|
///
|
|
|
|
/// ```
|
|
|
|
/// use activitystreams_new::primitives::OneOrMany;
|
|
|
|
/// let v = OneOrMany::from_one(1234);
|
|
|
|
/// ```
|
2020-05-14 03:54:50 +00:00
|
|
|
pub fn from_one(t: T) -> Self {
|
|
|
|
OneOrMany(Either::Left(t))
|
|
|
|
}
|
|
|
|
|
2020-05-16 20:34:35 +00:00
|
|
|
/// Produce a new object from a vec of values
|
|
|
|
///
|
|
|
|
/// ```
|
|
|
|
/// use activitystreams_new::primitives::OneOrMany;
|
|
|
|
/// let v = OneOrMany::from_many(vec![1, 2, 3, 4]);
|
|
|
|
/// ```
|
2020-05-14 03:54:50 +00:00
|
|
|
pub fn from_many(items: Vec<T>) -> Self {
|
|
|
|
OneOrMany(Either::Right(items))
|
|
|
|
}
|
|
|
|
|
2020-05-16 20:34:35 +00:00
|
|
|
/// 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());
|
|
|
|
/// ```
|
2020-05-14 03:54:50 +00:00
|
|
|
pub fn set_one<U>(&mut self, u: U) -> &mut Self
|
|
|
|
where
|
2020-05-16 01:08:43 +00:00
|
|
|
U: Into<T>,
|
2020-05-14 03:54:50 +00:00
|
|
|
{
|
|
|
|
self.0 = Either::Left(u.into());
|
|
|
|
self
|
|
|
|
}
|
|
|
|
|
2020-05-16 20:34:35 +00:00
|
|
|
/// 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());
|
|
|
|
/// ```
|
2020-05-14 03:54:50 +00:00
|
|
|
pub fn set_many<U>(&mut self, items: impl IntoIterator<Item = U>) -> &mut Self
|
|
|
|
where
|
2020-05-16 01:08:43 +00:00
|
|
|
U: Into<T>,
|
2020-05-14 03:54:50 +00:00
|
|
|
{
|
2020-05-16 01:08:43 +00:00
|
|
|
self.0 = Either::Right(items.into_iter().map(Into::into).collect());
|
2020-05-14 03:54:50 +00:00
|
|
|
self
|
|
|
|
}
|
|
|
|
|
2020-05-16 20:34:35 +00:00
|
|
|
/// 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());
|
|
|
|
/// ```
|
2020-05-14 03:54:50 +00:00
|
|
|
pub fn add<U>(&mut self, u: U) -> &mut Self
|
|
|
|
where
|
2020-05-16 01:08:43 +00:00
|
|
|
U: Into<T>,
|
2020-05-14 03:54:50 +00:00
|
|
|
{
|
|
|
|
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
|
|
|
|
}
|
|
|
|
|
2020-05-16 20:34:35 +00:00
|
|
|
/// 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());
|
|
|
|
/// ```
|
2020-05-14 03:54:50 +00:00
|
|
|
pub fn add_many<U>(&mut self, items: impl IntoIterator<Item = U>) -> &mut Self
|
|
|
|
where
|
2020-05-16 01:08:43 +00:00
|
|
|
U: Into<T>,
|
2020-05-14 03:54:50 +00:00
|
|
|
{
|
|
|
|
let mut v = match std::mem::replace(&mut self.0, Either::Right(vec![])) {
|
|
|
|
Either::Left(one) => vec![one],
|
|
|
|
Either::Right(v) => v,
|
|
|
|
};
|
2020-05-16 01:08:43 +00:00
|
|
|
v.extend(items.into_iter().map(Into::into));
|
2020-05-14 03:54:50 +00:00
|
|
|
self.0 = Either::Right(v);
|
|
|
|
self
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2020-05-16 19:49:29 +00:00
|
|
|
impl Unit {
|
|
|
|
/// Create a new unit measuring Centimeters
|
|
|
|
///
|
|
|
|
/// ```rust
|
|
|
|
/// use activitystreams_new::primitives::Unit;
|
|
|
|
///
|
|
|
|
/// Unit::centimeters();
|
|
|
|
/// ```
|
|
|
|
pub fn centimeters() -> Self {
|
|
|
|
Unit(Either::Left(Length::Centimeters))
|
|
|
|
}
|
|
|
|
|
|
|
|
/// Check if the unit is Centimeters
|
|
|
|
///
|
|
|
|
/// ```rust
|
|
|
|
/// use activitystreams_new::primitives::Unit;
|
|
|
|
///
|
|
|
|
/// assert!(Unit::centimeters().is_centimeters());
|
|
|
|
/// ```
|
|
|
|
pub fn is_centimeters(&self) -> bool {
|
|
|
|
self.0
|
|
|
|
.as_ref()
|
|
|
|
.left()
|
|
|
|
.map(|l| l.is_centimeters())
|
|
|
|
.unwrap_or(false)
|
|
|
|
}
|
|
|
|
|
|
|
|
/// Create a new unit measuring Meters
|
|
|
|
///
|
|
|
|
/// ```rust
|
|
|
|
/// use activitystreams_new::primitives::Unit;
|
|
|
|
///
|
|
|
|
/// Unit::meters();
|
|
|
|
/// ```
|
|
|
|
pub fn meters() -> Self {
|
|
|
|
Unit(Either::Left(Length::Meters))
|
|
|
|
}
|
|
|
|
|
|
|
|
/// Check if the unit is Meters
|
|
|
|
///
|
|
|
|
/// ```rust
|
|
|
|
/// use activitystreams_new::primitives::Unit;
|
|
|
|
///
|
|
|
|
/// assert!(Unit::meters().is_meters());
|
|
|
|
/// ```
|
|
|
|
pub fn is_meters(&self) -> bool {
|
|
|
|
self.0
|
|
|
|
.as_ref()
|
|
|
|
.left()
|
|
|
|
.map(|l| l.is_meters())
|
|
|
|
.unwrap_or(false)
|
|
|
|
}
|
|
|
|
|
|
|
|
/// Create a new unit measuring Kilometers
|
|
|
|
///
|
|
|
|
/// ```rust
|
|
|
|
/// use activitystreams_new::primitives::Unit;
|
|
|
|
///
|
|
|
|
/// Unit::kilometers();
|
|
|
|
/// ```
|
|
|
|
pub fn kilometers() -> Self {
|
|
|
|
Unit(Either::Left(Length::Kilometers))
|
|
|
|
}
|
|
|
|
|
|
|
|
/// Check if the unit is Kilometers
|
|
|
|
///
|
|
|
|
/// ```rust
|
|
|
|
/// use activitystreams_new::primitives::Unit;
|
|
|
|
///
|
|
|
|
/// assert!(Unit::kilometers().is_kilometers());
|
|
|
|
/// ```
|
|
|
|
pub fn is_kilometers(&self) -> bool {
|
|
|
|
self.0
|
|
|
|
.as_ref()
|
|
|
|
.left()
|
|
|
|
.map(|l| l.is_kilometers())
|
|
|
|
.unwrap_or(false)
|
|
|
|
}
|
|
|
|
|
|
|
|
/// Create a new unit measuring Feet
|
|
|
|
///
|
|
|
|
/// ```rust
|
|
|
|
/// use activitystreams_new::primitives::Unit;
|
|
|
|
///
|
|
|
|
/// Unit::feet();
|
|
|
|
/// ```
|
|
|
|
pub fn feet() -> Self {
|
|
|
|
Unit(Either::Left(Length::Feet))
|
|
|
|
}
|
|
|
|
|
|
|
|
/// Check if the unit is Feet
|
|
|
|
///
|
|
|
|
/// ```rust
|
|
|
|
/// use activitystreams_new::primitives::Unit;
|
|
|
|
///
|
|
|
|
/// assert!(Unit::feet().is_feet());
|
|
|
|
/// ```
|
|
|
|
pub fn is_feet(&self) -> bool {
|
|
|
|
self.0.as_ref().left().map(|l| l.is_feet()).unwrap_or(false)
|
|
|
|
}
|
|
|
|
|
|
|
|
/// Create a new unit measuring Inches
|
|
|
|
///
|
|
|
|
/// ```rust
|
|
|
|
/// use activitystreams_new::primitives::Unit;
|
|
|
|
///
|
|
|
|
/// Unit::inches();
|
|
|
|
/// ```
|
|
|
|
pub fn inches() -> Self {
|
|
|
|
Unit(Either::Left(Length::Inches))
|
|
|
|
}
|
|
|
|
|
|
|
|
/// Check if the unit is Inches
|
|
|
|
///
|
|
|
|
/// ```rust
|
|
|
|
/// use activitystreams_new::primitives::Unit;
|
|
|
|
///
|
|
|
|
/// assert!(Unit::inches().is_inches());
|
|
|
|
/// ```
|
|
|
|
pub fn is_inches(&self) -> bool {
|
|
|
|
self.0
|
|
|
|
.as_ref()
|
|
|
|
.left()
|
|
|
|
.map(|l| l.is_inches())
|
|
|
|
.unwrap_or(false)
|
|
|
|
}
|
|
|
|
|
|
|
|
/// Create a new custom unit
|
|
|
|
///
|
|
|
|
/// ```rust
|
|
|
|
/// use activitystreams_new::primitives::Unit;
|
|
|
|
///
|
|
|
|
/// Unit::custom("Yards");
|
|
|
|
/// ```
|
|
|
|
pub fn custom<T>(string: T) -> Self
|
|
|
|
where
|
|
|
|
T: Into<XsdString>,
|
|
|
|
{
|
|
|
|
Unit(Either::Right(string.into()))
|
|
|
|
}
|
|
|
|
|
|
|
|
/// Check if a unit is custom
|
|
|
|
///
|
|
|
|
/// ```rust
|
|
|
|
/// use activitystreams_new::primitives::Unit;
|
|
|
|
///
|
|
|
|
/// assert!(Unit::custom("Yards").is_custom());
|
|
|
|
/// ```
|
|
|
|
pub fn is_custom(&self) -> bool {
|
|
|
|
self.as_custom().is_some()
|
|
|
|
}
|
|
|
|
|
|
|
|
/// Fetch a custom unit
|
|
|
|
///
|
|
|
|
/// ```rust
|
|
|
|
/// use activitystreams_new::primitives::{Unit, XsdString};
|
|
|
|
///
|
|
|
|
/// assert!(Unit::custom("Yards").as_custom() == Some(&XsdString::from("Yards")));
|
|
|
|
/// ```
|
|
|
|
pub fn as_custom(&self) -> Option<&XsdString> {
|
|
|
|
self.0.as_ref().right()
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
impl Default for Unit {
|
|
|
|
fn default() -> Self {
|
|
|
|
Self::meters()
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
impl std::str::FromStr for Unit {
|
|
|
|
type Err = std::convert::Infallible;
|
|
|
|
|
|
|
|
fn from_str(s: &str) -> Result<Self, Self::Err> {
|
|
|
|
let unit = match s {
|
|
|
|
"cm" => Self::centimeters(),
|
|
|
|
"m" => Self::meters(),
|
|
|
|
"km" => Self::kilometers(),
|
|
|
|
"inches" => Self::inches(),
|
|
|
|
"feet" => Self::feet(),
|
|
|
|
other => Self::custom(other),
|
|
|
|
};
|
|
|
|
|
|
|
|
Ok(unit)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
impl From<String> for Unit {
|
|
|
|
fn from(s: String) -> Self {
|
|
|
|
match s.parse() {
|
|
|
|
Ok(u) => u,
|
|
|
|
Err(e) => match e {},
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
impl From<&str> for Unit {
|
|
|
|
fn from(s: &str) -> Self {
|
|
|
|
match s.parse() {
|
|
|
|
Ok(u) => u,
|
|
|
|
Err(e) => match e {},
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2020-05-15 03:18:34 +00:00
|
|
|
impl<T> From<T> for OneOrMany<T> {
|
|
|
|
fn from(t: T) -> Self {
|
|
|
|
OneOrMany::from_one(t)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
impl<T> From<Vec<T>> for OneOrMany<T> {
|
|
|
|
fn from(t: Vec<T>) -> Self {
|
|
|
|
OneOrMany::from_many(t)
|
2020-05-14 16:23:38 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2020-05-14 03:54:50 +00:00
|
|
|
impl From<XsdString> for AnyString {
|
|
|
|
fn from(s: XsdString) -> Self {
|
|
|
|
AnyString::from_xsd_string(s)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
impl From<RdfLangString> for AnyString {
|
|
|
|
fn from(s: RdfLangString) -> Self {
|
|
|
|
AnyString::from_rdf_lang_string(s)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
impl From<XsdString> for OneOrMany<AnyString> {
|
|
|
|
fn from(s: XsdString) -> Self {
|
|
|
|
OneOrMany::<AnyString>::from_xsd_string(s)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
impl From<RdfLangString> for OneOrMany<AnyString> {
|
|
|
|
fn from(s: RdfLangString) -> Self {
|
|
|
|
OneOrMany::<AnyString>::from_rdf_lang_string(s)
|
|
|
|
}
|
|
|
|
}
|