activitystreams-new/src/primitives.rs

209 lines
4.9 KiB
Rust
Raw Normal View History

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,
};
#[derive(Clone, Debug, serde::Deserialize, serde::Serialize)]
#[serde(transparent)]
pub struct AnyString(Either<XsdString, RdfLangString>);
pub type Unit = Either<Length, XsdString>;
#[derive(Clone, Debug, serde::Deserialize, serde::Serialize)]
#[serde(transparent)]
pub struct OneOrMany<T>(pub Either<T, Vec<T>>);
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<XsdString> {
self.0.left()
}
pub fn rdf_lang_string(self) -> Option<RdfLangString> {
self.0.right()
}
pub fn from_xsd_string<T>(string: T) -> Self
where
XsdString: From<T>,
{
AnyString(Either::Left(string.into()))
}
pub fn from_rdf_lang_string<T>(string: T) -> Self
where
RdfLangString: From<T>,
{
AnyString(Either::Right(string.into()))
}
pub fn set_xsd_string<T>(&mut self, string: T)
where
XsdString: From<T>,
{
self.0 = Either::Left(string.into());
}
pub fn set_rdf_lang_string<T>(&mut self, string: T)
where
RdfLangString: From<T>,
{
self.0 = Either::Right(string.into());
}
}
impl OneOrMany<AnyString> {
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<XsdString> {
self.one().and_then(|any_string| any_string.xsd_string())
}
pub fn single_rdf_lang_string(self) -> Option<RdfLangString> {
self.one()
.and_then(|any_string| any_string.rdf_lang_string())
}
pub fn from_xsd_string<T>(string: T) -> Self
where
XsdString: From<T>,
{
Self::from_one(AnyString::from_xsd_string(string))
}
pub fn from_rdf_lang_string<T>(string: T) -> Self
where
RdfLangString: From<T>,
{
Self::from_one(AnyString::from_rdf_lang_string(string))
}
}
impl<T> OneOrMany<T> {
pub fn as_one(&self) -> Option<&T> {
self.0.as_ref().left()
}
pub fn one(self) -> Option<T> {
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<Vec<T>> {
self.0.right()
}
pub fn unwrap_to_vec(self) -> Vec<T> {
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<T>) -> Self {
OneOrMany(Either::Right(items))
}
pub fn set_one<U>(&mut self, u: U) -> &mut Self
where
T: From<U>,
{
self.0 = Either::Left(u.into());
self
}
pub fn set_many<U>(&mut self, items: impl IntoIterator<Item = U>) -> &mut Self
where
T: From<U>,
{
self.0 = Either::Right(items.into_iter().map(T::from).collect());
self
}
pub fn add<U>(&mut self, u: U) -> &mut Self
where
T: From<U>,
{
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<U>(&mut self, items: impl IntoIterator<Item = U>) -> &mut Self
where
T: From<U>,
{
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
}
}
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)
}
}