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)
|
|
|
|
}
|
|
|
|
}
|