211 lines
5.1 KiB
Rust
211 lines
5.1 KiB
Rust
|
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<String, serde_json::Value>);
|
||
|
|
||
|
#[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 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<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
|
||
|
}
|
||
|
}
|
||
|
|
||
|
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)
|
||
|
}
|
||
|
}
|