Hmmm...
This commit is contained in:
commit
96e9ad61bf
12 changed files with 2472 additions and 0 deletions
2
.gitignore
vendored
Normal file
2
.gitignore
vendored
Normal file
|
@ -0,0 +1,2 @@
|
||||||
|
/target
|
||||||
|
Cargo.lock
|
15
Cargo.toml
Normal file
15
Cargo.toml
Normal file
|
@ -0,0 +1,15 @@
|
||||||
|
[package]
|
||||||
|
name = "activitystreams-new"
|
||||||
|
version = "0.1.0"
|
||||||
|
authors = ["asonix <asonix@asonix.dog>"]
|
||||||
|
edition = "2018"
|
||||||
|
|
||||||
|
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
||||||
|
|
||||||
|
[dependencies]
|
||||||
|
activitystreams = { version = "0.6.1", default-features = false, features = ["kinds","primitives"] }
|
||||||
|
serde = { version = "1.0", features = ["derive"] }
|
||||||
|
serde_json = "1.0"
|
||||||
|
|
||||||
|
[dev-dependencies]
|
||||||
|
anyhow = "1.0"
|
36
examples/basic.rs
Normal file
36
examples/basic.rs
Normal file
|
@ -0,0 +1,36 @@
|
||||||
|
use activitystreams_new::{
|
||||||
|
context,
|
||||||
|
object::{ApObject, Video},
|
||||||
|
primitives::{XsdAnyUri, XsdString},
|
||||||
|
};
|
||||||
|
|
||||||
|
fn main() -> Result<(), Box<dyn std::error::Error>> {
|
||||||
|
let mut v: ApObject<Video> = Default::default();
|
||||||
|
|
||||||
|
v.inner.context = Some(context().into());
|
||||||
|
v.inner.id = Some(
|
||||||
|
"https://example.com/@example/lions"
|
||||||
|
.parse::<XsdAnyUri>()?
|
||||||
|
.into(),
|
||||||
|
);
|
||||||
|
v.inner.url = Some(
|
||||||
|
"https://example.com/@example/lions/video.webm"
|
||||||
|
.parse::<XsdAnyUri>()?
|
||||||
|
.into(),
|
||||||
|
);
|
||||||
|
v.inner.summary = Some(XsdString::from("A cool video").into());
|
||||||
|
v.inner.media_type = Some("video/webm".parse()?);
|
||||||
|
v.inner.duration = Some("PT4M20S".parse()?);
|
||||||
|
|
||||||
|
println!("Video, {:#?}", v);
|
||||||
|
|
||||||
|
let s = serde_json::to_string(&v)?;
|
||||||
|
|
||||||
|
println!("json, {}", s);
|
||||||
|
|
||||||
|
let v: ApObject<Video> = serde_json::from_str(&s)?;
|
||||||
|
|
||||||
|
println!("Video again, {:#?}", v);
|
||||||
|
|
||||||
|
Ok(())
|
||||||
|
}
|
68
examples/de.rs
Normal file
68
examples/de.rs
Normal file
|
@ -0,0 +1,68 @@
|
||||||
|
use activitystreams_new::{
|
||||||
|
collection::OrderedCollection,
|
||||||
|
object::{ApObject, Page},
|
||||||
|
traits::Extends,
|
||||||
|
};
|
||||||
|
use anyhow::Error;
|
||||||
|
|
||||||
|
fn main() -> Result<(), Error> {
|
||||||
|
let collection_json = r#"{
|
||||||
|
"type": "OrderedCollection",
|
||||||
|
"id": "http://lemmy_alpha:8540/federation/c/main",
|
||||||
|
"context": "https://www.w3.org/ns/activitystreams",
|
||||||
|
"items": [
|
||||||
|
{
|
||||||
|
"type": "Page",
|
||||||
|
"id": "http://lemmy_alpha:8540/federation/post/2",
|
||||||
|
"attributedTo": "http://lemmy_alpha:8540/federation/u/2",
|
||||||
|
"content": "test",
|
||||||
|
"context": "https://www.w3.org/ns/activitystreams",
|
||||||
|
"name": "test",
|
||||||
|
"published": "2020-03-13T00:14:41.188634+00:00"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "Page",
|
||||||
|
"id": "http://lemmy_alpha:8540/federation/post/1",
|
||||||
|
"attributedTo": "http://lemmy_alpha:8540/federation/u/2",
|
||||||
|
"context": "https://www.w3.org/ns/activitystreams",
|
||||||
|
"name": "test",
|
||||||
|
"published": "2020-03-13T00:13:56.311479+00:00"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"totalItems": 2
|
||||||
|
}"#;
|
||||||
|
|
||||||
|
let page_json = r#"{
|
||||||
|
"type": "Page",
|
||||||
|
"id": "http://lemmy_alpha:8540/federation/post/2",
|
||||||
|
"attributedTo": "http://lemmy_alpha:8540/federation/u/2",
|
||||||
|
"content": "test",
|
||||||
|
"name": "test",
|
||||||
|
"published": "2020-03-13T00:14:41.188634+00:00"
|
||||||
|
}"#;
|
||||||
|
|
||||||
|
let page: ApObject<Page> = serde_json::from_str(page_json)?;
|
||||||
|
println!("{:#?}", page);
|
||||||
|
let mut collection: OrderedCollection = serde_json::from_str(collection_json)?;
|
||||||
|
println!("{:#?}", collection);
|
||||||
|
|
||||||
|
let v: Vec<ApObject<Page>> = collection
|
||||||
|
.items
|
||||||
|
.clone()
|
||||||
|
.many()
|
||||||
|
.into_iter()
|
||||||
|
.flatten()
|
||||||
|
.filter_map(|any_object| any_object.object())
|
||||||
|
.map(|object| object.solidify().and_then(|o| o.extend()))
|
||||||
|
.collect::<Result<Vec<_>, _>>()?;
|
||||||
|
|
||||||
|
println!("{:#?}", v);
|
||||||
|
let v = v
|
||||||
|
.into_iter()
|
||||||
|
.map(|o| o.retracts().and_then(|o| o.into_generic()))
|
||||||
|
.collect::<Result<Vec<_>, _>>()?;
|
||||||
|
|
||||||
|
collection.items.set_many(v);
|
||||||
|
|
||||||
|
Ok(())
|
||||||
|
}
|
793
src/activity.rs
Normal file
793
src/activity.rs
Normal file
|
@ -0,0 +1,793 @@
|
||||||
|
use crate::{
|
||||||
|
object::{AnyObject, Object},
|
||||||
|
primitives::{OneOrMany, Unparsed},
|
||||||
|
traits::{self, Extends, WithUnparsed, WithUnparsedExt},
|
||||||
|
};
|
||||||
|
use std::convert::TryFrom;
|
||||||
|
|
||||||
|
pub mod kind {
|
||||||
|
pub use activitystreams::activity::kind::*;
|
||||||
|
}
|
||||||
|
|
||||||
|
use self::kind::*;
|
||||||
|
|
||||||
|
pub type Accept = ActorAndObject<AcceptType>;
|
||||||
|
pub type Add = ActorAndObject<AddType>;
|
||||||
|
pub type Block = ActorAndObject<BlockType>;
|
||||||
|
pub type Create = ActorAndObject<CreateType>;
|
||||||
|
pub type Dislike = ActorAndObject<DislikeType>;
|
||||||
|
pub type Flag = ActorAndObject<FlagType>;
|
||||||
|
pub type Follow = ActorAndObject<FollowType>;
|
||||||
|
pub type Ignore = ActorAndObject<IgnoreType>;
|
||||||
|
pub type Join = ActorAndObject<JoinType>;
|
||||||
|
pub type Leave = ActorAndObject<LeaveType>;
|
||||||
|
pub type Like = ActorAndObject<LikeType>;
|
||||||
|
pub type Listen = ActorAndObject<ListenType>;
|
||||||
|
pub type Read = ActorAndObject<ReadType>;
|
||||||
|
pub type Reject = ActorAndObject<RejectType>;
|
||||||
|
pub type TentativeAccept = ActorAndObject<TentativeAcceptType>;
|
||||||
|
pub type TentativeReject = ActorAndObject<TentativeRejectType>;
|
||||||
|
pub type Undo = ActorAndObject<UndoType>;
|
||||||
|
pub type Update = ActorAndObject<UpdateType>;
|
||||||
|
pub type View = ActorAndObject<ViewType>;
|
||||||
|
|
||||||
|
pub type Announce = ActorAndObjectOptTarget<AnnounceType>;
|
||||||
|
pub type Offer = ActorAndObjectOptTarget<OfferType>;
|
||||||
|
|
||||||
|
pub type Move = ActorAndObjectOptOriginAndTarget<MoveType>;
|
||||||
|
pub type Remove = ActorAndObjectOptOriginAndTarget<RemoveType>;
|
||||||
|
|
||||||
|
pub trait NormalActivity {
|
||||||
|
fn actor(&self) -> &OneOrMany<AnyObject>;
|
||||||
|
fn object(&self) -> &OneOrMany<AnyObject>;
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Clone, serde::Deserialize, serde::Serialize)]
|
||||||
|
#[serde(rename_all = "camelCase")]
|
||||||
|
pub struct Activity<Kind> {
|
||||||
|
#[serde(skip_serializing_if = "Option::is_none")]
|
||||||
|
pub result: Option<OneOrMany<AnyObject>>,
|
||||||
|
|
||||||
|
#[serde(skip_serializing_if = "Option::is_none")]
|
||||||
|
pub instrument: Option<Option<AnyObject>>,
|
||||||
|
|
||||||
|
#[serde(flatten)]
|
||||||
|
pub inner: Object<Kind>,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Clone, serde::Deserialize, serde::Serialize)]
|
||||||
|
#[serde(rename_all = "camelCase")]
|
||||||
|
pub struct ActorAndObject<Kind> {
|
||||||
|
pub actor: OneOrMany<AnyObject>,
|
||||||
|
pub object: OneOrMany<AnyObject>,
|
||||||
|
|
||||||
|
#[serde(flatten)]
|
||||||
|
pub inner: Activity<Kind>,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Clone, serde::Deserialize, serde::Serialize)]
|
||||||
|
#[serde(rename_all = "camelCase")]
|
||||||
|
pub struct Arrive {
|
||||||
|
pub actor: OneOrMany<AnyObject>,
|
||||||
|
pub origin: OneOrMany<AnyObject>,
|
||||||
|
|
||||||
|
#[serde(flatten)]
|
||||||
|
pub inner: Activity<ArriveType>,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Clone, serde::Deserialize, serde::Serialize)]
|
||||||
|
#[serde(rename_all = "camelCase")]
|
||||||
|
pub struct Invite {
|
||||||
|
pub actor: OneOrMany<AnyObject>,
|
||||||
|
pub object: OneOrMany<AnyObject>,
|
||||||
|
pub target: OneOrMany<AnyObject>,
|
||||||
|
|
||||||
|
#[serde(flatten)]
|
||||||
|
pub inner: Activity<InviteType>,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Clone, serde::Deserialize, serde::Serialize)]
|
||||||
|
#[serde(rename_all = "camelCase")]
|
||||||
|
pub struct Delete {
|
||||||
|
pub actor: OneOrMany<AnyObject>,
|
||||||
|
pub object: OneOrMany<AnyObject>,
|
||||||
|
|
||||||
|
#[serde(skip_serializing_if = "Option::is_none")]
|
||||||
|
pub origin: Option<OneOrMany<AnyObject>>,
|
||||||
|
|
||||||
|
#[serde(flatten)]
|
||||||
|
pub inner: Activity<DeleteType>,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Clone, serde::Deserialize, serde::Serialize)]
|
||||||
|
#[serde(rename_all = "camelCase")]
|
||||||
|
pub struct ActorAndObjectOptOriginAndTarget<Kind> {
|
||||||
|
pub actor: OneOrMany<AnyObject>,
|
||||||
|
pub object: OneOrMany<AnyObject>,
|
||||||
|
|
||||||
|
#[serde(skip_serializing_if = "Option::is_none")]
|
||||||
|
pub origin: Option<OneOrMany<AnyObject>>,
|
||||||
|
|
||||||
|
#[serde(skip_serializing_if = "Option::is_none")]
|
||||||
|
pub target: Option<OneOrMany<AnyObject>>,
|
||||||
|
|
||||||
|
#[serde(flatten)]
|
||||||
|
pub inner: Activity<Kind>,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Clone, serde::Deserialize, serde::Serialize)]
|
||||||
|
#[serde(rename_all = "camelCase")]
|
||||||
|
pub struct ActorAndObjectOptTarget<Kind> {
|
||||||
|
pub actor: OneOrMany<AnyObject>,
|
||||||
|
pub object: OneOrMany<AnyObject>,
|
||||||
|
|
||||||
|
#[serde(skip_serializing_if = "Option::is_none")]
|
||||||
|
pub target: Option<OneOrMany<AnyObject>>,
|
||||||
|
|
||||||
|
#[serde(flatten)]
|
||||||
|
pub inner: Activity<Kind>,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Clone, serde::Deserialize, serde::Serialize)]
|
||||||
|
#[serde(rename_all = "camelCase")]
|
||||||
|
pub struct Travel {
|
||||||
|
pub actor: OneOrMany<AnyObject>,
|
||||||
|
|
||||||
|
#[serde(skip_serializing_if = "Option::is_none")]
|
||||||
|
pub origin: Option<OneOrMany<AnyObject>>,
|
||||||
|
|
||||||
|
#[serde(skip_serializing_if = "Option::is_none")]
|
||||||
|
pub target: Option<OneOrMany<AnyObject>>,
|
||||||
|
|
||||||
|
#[serde(flatten)]
|
||||||
|
pub inner: Activity<TravelType>,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Clone, serde::Deserialize, serde::Serialize)]
|
||||||
|
#[serde(rename_all = "camelCase")]
|
||||||
|
pub struct Question {
|
||||||
|
#[serde(skip_serializing_if = "Option::is_none")]
|
||||||
|
pub one_of: Option<OneOrMany<AnyObject>>,
|
||||||
|
|
||||||
|
#[serde(skip_serializing_if = "Option::is_none")]
|
||||||
|
pub any_of: Option<OneOrMany<AnyObject>>,
|
||||||
|
|
||||||
|
#[serde(flatten)]
|
||||||
|
pub inner: Activity<QuestionType>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<Kind> Activity<Kind> {
|
||||||
|
fn extending(mut inner: Object<Kind>) -> Result<Self, serde_json::Error> {
|
||||||
|
let result = inner.remove("result")?;
|
||||||
|
let instrument = inner.remove("instrument")?;
|
||||||
|
|
||||||
|
Ok(Activity {
|
||||||
|
result,
|
||||||
|
instrument,
|
||||||
|
inner,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
fn retracting(self) -> Result<Object<Kind>, serde_json::Error> {
|
||||||
|
let Activity {
|
||||||
|
result,
|
||||||
|
instrument,
|
||||||
|
mut inner,
|
||||||
|
} = self;
|
||||||
|
|
||||||
|
inner
|
||||||
|
.insert("result", result)?
|
||||||
|
.insert("instrument", instrument)?;
|
||||||
|
|
||||||
|
Ok(inner)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<Kind> ActorAndObject<Kind> {
|
||||||
|
fn extending(object: Object<Kind>) -> Result<Self, serde_json::Error> {
|
||||||
|
let mut inner = Activity::extending(object)?;
|
||||||
|
|
||||||
|
let actor = inner.remove("actor")?;
|
||||||
|
let object = inner.remove("object")?;
|
||||||
|
|
||||||
|
Ok(ActorAndObject {
|
||||||
|
actor,
|
||||||
|
object,
|
||||||
|
inner,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
fn retracting(self) -> Result<Object<Kind>, serde_json::Error> {
|
||||||
|
let ActorAndObject {
|
||||||
|
actor,
|
||||||
|
object,
|
||||||
|
mut inner,
|
||||||
|
} = self;
|
||||||
|
|
||||||
|
inner.insert("actor", actor)?.insert("object", object)?;
|
||||||
|
|
||||||
|
inner.retracting()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Arrive {
|
||||||
|
fn extending(object: Object<ArriveType>) -> Result<Self, serde_json::Error> {
|
||||||
|
let mut inner = Activity::extending(object)?;
|
||||||
|
|
||||||
|
let actor = inner.remove("actor")?;
|
||||||
|
let origin = inner.remove("origin")?;
|
||||||
|
|
||||||
|
Ok(Arrive {
|
||||||
|
actor,
|
||||||
|
origin,
|
||||||
|
inner,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
fn retracting(self) -> Result<Object<ArriveType>, serde_json::Error> {
|
||||||
|
let Arrive {
|
||||||
|
actor,
|
||||||
|
origin,
|
||||||
|
mut inner,
|
||||||
|
} = self;
|
||||||
|
|
||||||
|
inner.insert("actor", actor)?.insert("origin", origin)?;
|
||||||
|
|
||||||
|
inner.retracting()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Invite {
|
||||||
|
fn extending(object: Object<InviteType>) -> Result<Self, serde_json::Error> {
|
||||||
|
let mut inner = Activity::extending(object)?;
|
||||||
|
|
||||||
|
let actor = inner.remove("actor")?;
|
||||||
|
let object = inner.remove("object")?;
|
||||||
|
let target = inner.remove("target")?;
|
||||||
|
|
||||||
|
Ok(Invite {
|
||||||
|
actor,
|
||||||
|
object,
|
||||||
|
target,
|
||||||
|
inner,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
fn retracting(self) -> Result<Object<InviteType>, serde_json::Error> {
|
||||||
|
let Invite {
|
||||||
|
actor,
|
||||||
|
object,
|
||||||
|
target,
|
||||||
|
mut inner,
|
||||||
|
} = self;
|
||||||
|
|
||||||
|
inner
|
||||||
|
.insert("actor", actor)?
|
||||||
|
.insert("object", object)?
|
||||||
|
.insert("target", target)?;
|
||||||
|
|
||||||
|
inner.retracting()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Delete {
|
||||||
|
fn extending(object: Object<DeleteType>) -> Result<Self, serde_json::Error> {
|
||||||
|
let mut inner = Activity::extending(object)?;
|
||||||
|
|
||||||
|
let actor = inner.remove("actor")?;
|
||||||
|
let object = inner.remove("object")?;
|
||||||
|
let origin = inner.remove("origin")?;
|
||||||
|
|
||||||
|
Ok(Delete {
|
||||||
|
actor,
|
||||||
|
object,
|
||||||
|
origin,
|
||||||
|
inner,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
fn retracting(self) -> Result<Object<DeleteType>, serde_json::Error> {
|
||||||
|
let Delete {
|
||||||
|
actor,
|
||||||
|
object,
|
||||||
|
origin,
|
||||||
|
mut inner,
|
||||||
|
} = self;
|
||||||
|
|
||||||
|
inner
|
||||||
|
.insert("actor", actor)?
|
||||||
|
.insert("object", object)?
|
||||||
|
.insert("origin", origin)?;
|
||||||
|
|
||||||
|
inner.retracting()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<Kind> ActorAndObjectOptOriginAndTarget<Kind> {
|
||||||
|
fn extending(object: Object<Kind>) -> Result<Self, serde_json::Error> {
|
||||||
|
let mut inner = Activity::extending(object)?;
|
||||||
|
|
||||||
|
let actor = inner.remove("actor")?;
|
||||||
|
let object = inner.remove("object")?;
|
||||||
|
let origin = inner.remove("origin")?;
|
||||||
|
let target = inner.remove("target")?;
|
||||||
|
|
||||||
|
Ok(ActorAndObjectOptOriginAndTarget {
|
||||||
|
actor,
|
||||||
|
object,
|
||||||
|
origin,
|
||||||
|
target,
|
||||||
|
inner,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
fn retracting(self) -> Result<Object<Kind>, serde_json::Error> {
|
||||||
|
let ActorAndObjectOptOriginAndTarget {
|
||||||
|
actor,
|
||||||
|
object,
|
||||||
|
origin,
|
||||||
|
target,
|
||||||
|
mut inner,
|
||||||
|
} = self;
|
||||||
|
|
||||||
|
inner
|
||||||
|
.insert("actor", actor)?
|
||||||
|
.insert("object", object)?
|
||||||
|
.insert("origin", origin)?
|
||||||
|
.insert("target", target)?;
|
||||||
|
|
||||||
|
inner.retracting()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<Kind> ActorAndObjectOptTarget<Kind> {
|
||||||
|
fn extending(object: Object<Kind>) -> Result<Self, serde_json::Error> {
|
||||||
|
let mut inner = Activity::extending(object)?;
|
||||||
|
|
||||||
|
let actor = inner.remove("actor")?;
|
||||||
|
let object = inner.remove("object")?;
|
||||||
|
let target = inner.remove("target")?;
|
||||||
|
|
||||||
|
Ok(ActorAndObjectOptTarget {
|
||||||
|
actor,
|
||||||
|
object,
|
||||||
|
target,
|
||||||
|
inner,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
fn retracting(self) -> Result<Object<Kind>, serde_json::Error> {
|
||||||
|
let ActorAndObjectOptTarget {
|
||||||
|
actor,
|
||||||
|
object,
|
||||||
|
target,
|
||||||
|
mut inner,
|
||||||
|
} = self;
|
||||||
|
|
||||||
|
inner
|
||||||
|
.insert("actor", actor)?
|
||||||
|
.insert("object", object)?
|
||||||
|
.insert("target", target)?;
|
||||||
|
|
||||||
|
inner.retracting()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Travel {
|
||||||
|
fn extending(object: Object<TravelType>) -> Result<Self, serde_json::Error> {
|
||||||
|
let mut inner = Activity::extending(object)?;
|
||||||
|
|
||||||
|
let actor = inner.remove("actor")?;
|
||||||
|
let origin = inner.remove("origin")?;
|
||||||
|
let target = inner.remove("target")?;
|
||||||
|
|
||||||
|
Ok(Travel {
|
||||||
|
actor,
|
||||||
|
origin,
|
||||||
|
target,
|
||||||
|
inner,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
fn retracting(self) -> Result<Object<TravelType>, serde_json::Error> {
|
||||||
|
let Travel {
|
||||||
|
actor,
|
||||||
|
origin,
|
||||||
|
target,
|
||||||
|
mut inner,
|
||||||
|
} = self;
|
||||||
|
|
||||||
|
inner
|
||||||
|
.insert("actor", actor)?
|
||||||
|
.insert("origin", origin)?
|
||||||
|
.insert("target", target)?;
|
||||||
|
|
||||||
|
inner.retracting()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Question {
|
||||||
|
fn extending(object: Object<QuestionType>) -> Result<Self, serde_json::Error> {
|
||||||
|
let mut inner = Activity::extending(object)?;
|
||||||
|
|
||||||
|
let one_of = inner.remove("oneOf")?;
|
||||||
|
let any_of = inner.remove("anyOf")?;
|
||||||
|
|
||||||
|
Ok(Question {
|
||||||
|
one_of,
|
||||||
|
any_of,
|
||||||
|
inner,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
fn retracting(self) -> Result<Object<QuestionType>, serde_json::Error> {
|
||||||
|
let Question {
|
||||||
|
one_of,
|
||||||
|
any_of,
|
||||||
|
mut inner,
|
||||||
|
} = self;
|
||||||
|
|
||||||
|
inner.insert("oneOf", one_of)?.insert("anyOf", any_of)?;
|
||||||
|
|
||||||
|
inner.retracting()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<Kind> traits::Base for Activity<Kind> where Kind: std::fmt::Debug {}
|
||||||
|
impl<Kind> traits::Object for Activity<Kind> where Kind: std::fmt::Debug {}
|
||||||
|
impl<Kind> traits::Activity for Activity<Kind> where Kind: std::fmt::Debug {}
|
||||||
|
|
||||||
|
impl<Kind> traits::Base for ActorAndObject<Kind> where Kind: std::fmt::Debug {}
|
||||||
|
impl<Kind> traits::Object for ActorAndObject<Kind> where Kind: std::fmt::Debug {}
|
||||||
|
impl<Kind> traits::Activity for ActorAndObject<Kind> where Kind: std::fmt::Debug {}
|
||||||
|
|
||||||
|
impl<Kind> traits::Base for ActorAndObjectOptTarget<Kind> where Kind: std::fmt::Debug {}
|
||||||
|
impl<Kind> traits::Object for ActorAndObjectOptTarget<Kind> where Kind: std::fmt::Debug {}
|
||||||
|
impl<Kind> traits::Activity for ActorAndObjectOptTarget<Kind> where Kind: std::fmt::Debug {}
|
||||||
|
|
||||||
|
impl<Kind> traits::Base for ActorAndObjectOptOriginAndTarget<Kind> where Kind: std::fmt::Debug {}
|
||||||
|
impl<Kind> traits::Object for ActorAndObjectOptOriginAndTarget<Kind> where Kind: std::fmt::Debug {}
|
||||||
|
impl<Kind> traits::Activity for ActorAndObjectOptOriginAndTarget<Kind> where Kind: std::fmt::Debug {}
|
||||||
|
|
||||||
|
impl traits::Base for Arrive {}
|
||||||
|
impl traits::Object for Arrive {}
|
||||||
|
impl traits::Activity for Arrive {}
|
||||||
|
impl traits::IntransitiveActivity for Arrive {}
|
||||||
|
|
||||||
|
impl traits::Base for Invite {}
|
||||||
|
impl traits::Object for Invite {}
|
||||||
|
impl traits::Activity for Invite {}
|
||||||
|
|
||||||
|
impl traits::Base for Delete {}
|
||||||
|
impl traits::Object for Delete {}
|
||||||
|
impl traits::Activity for Delete {}
|
||||||
|
|
||||||
|
impl traits::Base for Travel {}
|
||||||
|
impl traits::Object for Travel {}
|
||||||
|
impl traits::Activity for Travel {}
|
||||||
|
impl traits::IntransitiveActivity for Travel {}
|
||||||
|
|
||||||
|
impl traits::Base for Question {}
|
||||||
|
impl traits::Object for Question {}
|
||||||
|
impl traits::Activity for Question {}
|
||||||
|
impl traits::IntransitiveActivity for Question {}
|
||||||
|
|
||||||
|
impl<Kind> Extends<Object<Kind>> for Activity<Kind> {
|
||||||
|
type Error = serde_json::Error;
|
||||||
|
|
||||||
|
fn extends(object: Object<Kind>) -> Result<Self, Self::Error> {
|
||||||
|
Self::extending(object)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn retracts(self) -> Result<Object<Kind>, Self::Error> {
|
||||||
|
self.retracting()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<Kind> TryFrom<Object<Kind>> for Activity<Kind> {
|
||||||
|
type Error = serde_json::Error;
|
||||||
|
|
||||||
|
fn try_from(object: Object<Kind>) -> Result<Self, Self::Error> {
|
||||||
|
Self::extending(object)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<Kind> Extends<Object<Kind>> for ActorAndObject<Kind> {
|
||||||
|
type Error = serde_json::Error;
|
||||||
|
|
||||||
|
fn extends(object: Object<Kind>) -> Result<Self, Self::Error> {
|
||||||
|
Self::extending(object)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn retracts(self) -> Result<Object<Kind>, Self::Error> {
|
||||||
|
self.retracting()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<Kind> TryFrom<Object<Kind>> for ActorAndObject<Kind> {
|
||||||
|
type Error = serde_json::Error;
|
||||||
|
|
||||||
|
fn try_from(object: Object<Kind>) -> Result<Self, Self::Error> {
|
||||||
|
Self::extending(object)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Extends<Object<ArriveType>> for Arrive {
|
||||||
|
type Error = serde_json::Error;
|
||||||
|
|
||||||
|
fn extends(object: Object<ArriveType>) -> Result<Self, Self::Error> {
|
||||||
|
Self::extending(object)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn retracts(self) -> Result<Object<ArriveType>, Self::Error> {
|
||||||
|
self.retracting()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl TryFrom<Object<ArriveType>> for Arrive {
|
||||||
|
type Error = serde_json::Error;
|
||||||
|
|
||||||
|
fn try_from(object: Object<ArriveType>) -> Result<Self, Self::Error> {
|
||||||
|
Self::extending(object)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Extends<Object<InviteType>> for Invite {
|
||||||
|
type Error = serde_json::Error;
|
||||||
|
|
||||||
|
fn extends(object: Object<InviteType>) -> Result<Self, Self::Error> {
|
||||||
|
Self::extending(object)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn retracts(self) -> Result<Object<InviteType>, Self::Error> {
|
||||||
|
self.retracting()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl TryFrom<Object<InviteType>> for Invite {
|
||||||
|
type Error = serde_json::Error;
|
||||||
|
|
||||||
|
fn try_from(object: Object<InviteType>) -> Result<Self, Self::Error> {
|
||||||
|
Self::extending(object)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Extends<Object<DeleteType>> for Delete {
|
||||||
|
type Error = serde_json::Error;
|
||||||
|
|
||||||
|
fn extends(object: Object<DeleteType>) -> Result<Self, Self::Error> {
|
||||||
|
Self::extending(object)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn retracts(self) -> Result<Object<DeleteType>, Self::Error> {
|
||||||
|
self.retracting()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl TryFrom<Object<DeleteType>> for Delete {
|
||||||
|
type Error = serde_json::Error;
|
||||||
|
|
||||||
|
fn try_from(object: Object<DeleteType>) -> Result<Self, Self::Error> {
|
||||||
|
Self::extending(object)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<Kind> Extends<Object<Kind>> for ActorAndObjectOptOriginAndTarget<Kind> {
|
||||||
|
type Error = serde_json::Error;
|
||||||
|
|
||||||
|
fn extends(object: Object<Kind>) -> Result<Self, Self::Error> {
|
||||||
|
Self::extending(object)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn retracts(self) -> Result<Object<Kind>, Self::Error> {
|
||||||
|
self.retracting()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<Kind> TryFrom<Object<Kind>> for ActorAndObjectOptOriginAndTarget<Kind> {
|
||||||
|
type Error = serde_json::Error;
|
||||||
|
|
||||||
|
fn try_from(object: Object<Kind>) -> Result<Self, Self::Error> {
|
||||||
|
Self::extending(object)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<Kind> Extends<Object<Kind>> for ActorAndObjectOptTarget<Kind> {
|
||||||
|
type Error = serde_json::Error;
|
||||||
|
|
||||||
|
fn extends(object: Object<Kind>) -> Result<Self, Self::Error> {
|
||||||
|
Self::extending(object)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn retracts(self) -> Result<Object<Kind>, Self::Error> {
|
||||||
|
self.retracting()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<Kind> TryFrom<Object<Kind>> for ActorAndObjectOptTarget<Kind> {
|
||||||
|
type Error = serde_json::Error;
|
||||||
|
|
||||||
|
fn try_from(object: Object<Kind>) -> Result<Self, Self::Error> {
|
||||||
|
Self::extending(object)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Extends<Object<TravelType>> for Travel {
|
||||||
|
type Error = serde_json::Error;
|
||||||
|
|
||||||
|
fn extends(object: Object<TravelType>) -> Result<Self, Self::Error> {
|
||||||
|
Self::extending(object)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn retracts(self) -> Result<Object<TravelType>, Self::Error> {
|
||||||
|
self.retracting()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl TryFrom<Object<TravelType>> for Travel {
|
||||||
|
type Error = serde_json::Error;
|
||||||
|
|
||||||
|
fn try_from(object: Object<TravelType>) -> Result<Self, Self::Error> {
|
||||||
|
Self::extending(object)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Extends<Object<QuestionType>> for Question {
|
||||||
|
type Error = serde_json::Error;
|
||||||
|
|
||||||
|
fn extends(object: Object<QuestionType>) -> Result<Self, Self::Error> {
|
||||||
|
Self::extending(object)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn retracts(self) -> Result<Object<QuestionType>, Self::Error> {
|
||||||
|
self.retracting()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl TryFrom<Object<QuestionType>> for Question {
|
||||||
|
type Error = serde_json::Error;
|
||||||
|
|
||||||
|
fn try_from(object: Object<QuestionType>) -> Result<Self, Self::Error> {
|
||||||
|
Self::extending(object)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<Kind> WithUnparsed for Activity<Kind> {
|
||||||
|
fn unparsed(&self) -> &Unparsed {
|
||||||
|
self.inner.unparsed()
|
||||||
|
}
|
||||||
|
|
||||||
|
fn unparsed_mut(&mut self) -> &mut Unparsed {
|
||||||
|
self.inner.unparsed_mut()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<Kind> WithUnparsed for ActorAndObject<Kind> {
|
||||||
|
fn unparsed(&self) -> &Unparsed {
|
||||||
|
self.inner.unparsed()
|
||||||
|
}
|
||||||
|
|
||||||
|
fn unparsed_mut(&mut self) -> &mut Unparsed {
|
||||||
|
self.inner.unparsed_mut()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl WithUnparsed for Arrive {
|
||||||
|
fn unparsed(&self) -> &Unparsed {
|
||||||
|
self.inner.unparsed()
|
||||||
|
}
|
||||||
|
|
||||||
|
fn unparsed_mut(&mut self) -> &mut Unparsed {
|
||||||
|
self.inner.unparsed_mut()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl WithUnparsed for Invite {
|
||||||
|
fn unparsed(&self) -> &Unparsed {
|
||||||
|
self.inner.unparsed()
|
||||||
|
}
|
||||||
|
|
||||||
|
fn unparsed_mut(&mut self) -> &mut Unparsed {
|
||||||
|
self.inner.unparsed_mut()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl WithUnparsed for Delete {
|
||||||
|
fn unparsed(&self) -> &Unparsed {
|
||||||
|
self.inner.unparsed()
|
||||||
|
}
|
||||||
|
|
||||||
|
fn unparsed_mut(&mut self) -> &mut Unparsed {
|
||||||
|
self.inner.unparsed_mut()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<Kind> WithUnparsed for ActorAndObjectOptOriginAndTarget<Kind> {
|
||||||
|
fn unparsed(&self) -> &Unparsed {
|
||||||
|
self.inner.unparsed()
|
||||||
|
}
|
||||||
|
|
||||||
|
fn unparsed_mut(&mut self) -> &mut Unparsed {
|
||||||
|
self.inner.unparsed_mut()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<Kind> WithUnparsed for ActorAndObjectOptTarget<Kind> {
|
||||||
|
fn unparsed(&self) -> &Unparsed {
|
||||||
|
self.inner.unparsed()
|
||||||
|
}
|
||||||
|
|
||||||
|
fn unparsed_mut(&mut self) -> &mut Unparsed {
|
||||||
|
self.inner.unparsed_mut()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl WithUnparsed for Travel {
|
||||||
|
fn unparsed(&self) -> &Unparsed {
|
||||||
|
self.inner.unparsed()
|
||||||
|
}
|
||||||
|
|
||||||
|
fn unparsed_mut(&mut self) -> &mut Unparsed {
|
||||||
|
self.inner.unparsed_mut()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl WithUnparsed for Question {
|
||||||
|
fn unparsed(&self) -> &Unparsed {
|
||||||
|
self.inner.unparsed()
|
||||||
|
}
|
||||||
|
|
||||||
|
fn unparsed_mut(&mut self) -> &mut Unparsed {
|
||||||
|
self.inner.unparsed_mut()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<Kind> NormalActivity for ActorAndObject<Kind> {
|
||||||
|
fn actor(&self) -> &OneOrMany<AnyObject> {
|
||||||
|
&self.actor
|
||||||
|
}
|
||||||
|
|
||||||
|
fn object(&self) -> &OneOrMany<AnyObject> {
|
||||||
|
&self.object
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<Kind> NormalActivity for ActorAndObjectOptTarget<Kind> {
|
||||||
|
fn actor(&self) -> &OneOrMany<AnyObject> {
|
||||||
|
&self.actor
|
||||||
|
}
|
||||||
|
|
||||||
|
fn object(&self) -> &OneOrMany<AnyObject> {
|
||||||
|
&self.object
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<Kind> NormalActivity for ActorAndObjectOptOriginAndTarget<Kind> {
|
||||||
|
fn actor(&self) -> &OneOrMany<AnyObject> {
|
||||||
|
&self.actor
|
||||||
|
}
|
||||||
|
|
||||||
|
fn object(&self) -> &OneOrMany<AnyObject> {
|
||||||
|
&self.object
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl NormalActivity for Invite {
|
||||||
|
fn actor(&self) -> &OneOrMany<AnyObject> {
|
||||||
|
&self.actor
|
||||||
|
}
|
||||||
|
|
||||||
|
fn object(&self) -> &OneOrMany<AnyObject> {
|
||||||
|
&self.object
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl NormalActivity for Delete {
|
||||||
|
fn actor(&self) -> &OneOrMany<AnyObject> {
|
||||||
|
&self.actor
|
||||||
|
}
|
||||||
|
|
||||||
|
fn object(&self) -> &OneOrMany<AnyObject> {
|
||||||
|
&self.object
|
||||||
|
}
|
||||||
|
}
|
162
src/actor.rs
Normal file
162
src/actor.rs
Normal file
|
@ -0,0 +1,162 @@
|
||||||
|
use crate::{
|
||||||
|
object::Object,
|
||||||
|
primitives::{OneOrMany, Unparsed, XsdAnyUri, XsdString},
|
||||||
|
traits::{self, Extends, WithUnparsed, WithUnparsedExt},
|
||||||
|
};
|
||||||
|
|
||||||
|
pub mod kind {
|
||||||
|
pub use activitystreams::actor::kind::*;
|
||||||
|
}
|
||||||
|
|
||||||
|
use self::kind::*;
|
||||||
|
|
||||||
|
pub type Application = Object<ApplicationType>;
|
||||||
|
pub type Group = Object<GroupType>;
|
||||||
|
pub type Organization = Object<OrganizationType>;
|
||||||
|
pub type Person = Object<PersonType>;
|
||||||
|
pub type Service = Object<ServiceType>;
|
||||||
|
|
||||||
|
#[derive(Clone, Debug, Default, serde::Deserialize, serde::Serialize)]
|
||||||
|
#[serde(rename_all = "camelCase")]
|
||||||
|
pub struct ApActor<Inner> {
|
||||||
|
pub inbox: XsdAnyUri,
|
||||||
|
pub outbox: XsdAnyUri,
|
||||||
|
|
||||||
|
#[serde(skip_serializing_if = "Option::is_none")]
|
||||||
|
pub following: Option<XsdAnyUri>,
|
||||||
|
|
||||||
|
#[serde(skip_serializing_if = "Option::is_none")]
|
||||||
|
pub followers: Option<XsdAnyUri>,
|
||||||
|
|
||||||
|
#[serde(skip_serializing_if = "Option::is_none")]
|
||||||
|
pub liked: Option<XsdAnyUri>,
|
||||||
|
|
||||||
|
#[serde(skip_serializing_if = "Option::is_none")]
|
||||||
|
pub streams: Option<OneOrMany<XsdAnyUri>>,
|
||||||
|
|
||||||
|
#[serde(skip_serializing_if = "Option::is_none")]
|
||||||
|
pub preferred_username: Option<XsdString>,
|
||||||
|
|
||||||
|
#[serde(skip_serializing_if = "Option::is_none")]
|
||||||
|
pub endpoints: Option<Endpoints>,
|
||||||
|
|
||||||
|
#[serde(flatten)]
|
||||||
|
pub inner: Inner,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Clone, Debug, Default, serde::Deserialize, serde::Serialize)]
|
||||||
|
#[serde(rename_all = "camelCase")]
|
||||||
|
pub struct Endpoints {
|
||||||
|
#[serde(skip_serializing_if = "Option::is_none")]
|
||||||
|
pub proxy_url: Option<XsdAnyUri>,
|
||||||
|
|
||||||
|
#[serde(skip_serializing_if = "Option::is_none")]
|
||||||
|
pub oauth_authorization_endpoint: Option<XsdAnyUri>,
|
||||||
|
|
||||||
|
#[serde(skip_serializing_if = "Option::is_none")]
|
||||||
|
pub oauth_token_endpoint: Option<XsdAnyUri>,
|
||||||
|
|
||||||
|
#[serde(skip_serializing_if = "Option::is_none")]
|
||||||
|
pub provide_client_key: Option<XsdAnyUri>,
|
||||||
|
|
||||||
|
#[serde(skip_serializing_if = "Option::is_none")]
|
||||||
|
pub sign_client_key: Option<XsdAnyUri>,
|
||||||
|
|
||||||
|
#[serde(skip_serializing_if = "Option::is_none")]
|
||||||
|
pub shared_inbox: Option<XsdAnyUri>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<Inner> ApActor<Inner> {
|
||||||
|
fn extending(mut inner: Inner) -> Result<Self, serde_json::Error>
|
||||||
|
where
|
||||||
|
Inner: WithUnparsed + traits::Actor,
|
||||||
|
{
|
||||||
|
let inbox = inner.remove("inbox")?;
|
||||||
|
let outbox = inner.remove("outbox")?;
|
||||||
|
let following = inner.remove("following")?;
|
||||||
|
let followers = inner.remove("followers")?;
|
||||||
|
let liked = inner.remove("liked")?;
|
||||||
|
let streams = inner.remove("streams")?;
|
||||||
|
let preferred_username = inner.remove("preferredUsername")?;
|
||||||
|
let endpoints = inner.remove("endpoints")?;
|
||||||
|
|
||||||
|
Ok(ApActor {
|
||||||
|
inbox,
|
||||||
|
outbox,
|
||||||
|
following,
|
||||||
|
followers,
|
||||||
|
liked,
|
||||||
|
streams,
|
||||||
|
preferred_username,
|
||||||
|
endpoints,
|
||||||
|
inner,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
fn retracting(self) -> Result<Inner, serde_json::Error>
|
||||||
|
where
|
||||||
|
Inner: WithUnparsed + traits::Actor,
|
||||||
|
{
|
||||||
|
let ApActor {
|
||||||
|
inbox,
|
||||||
|
outbox,
|
||||||
|
following,
|
||||||
|
followers,
|
||||||
|
liked,
|
||||||
|
streams,
|
||||||
|
preferred_username,
|
||||||
|
endpoints,
|
||||||
|
mut inner,
|
||||||
|
} = self;
|
||||||
|
|
||||||
|
inner
|
||||||
|
.insert("endpoints", endpoints)?
|
||||||
|
.insert("preferredUsername", preferred_username)?
|
||||||
|
.insert("streams", streams)?
|
||||||
|
.insert("liked", liked)?
|
||||||
|
.insert("followers", followers)?
|
||||||
|
.insert("following", following)?
|
||||||
|
.insert("outbox", outbox)?
|
||||||
|
.insert("inbox", inbox)?;
|
||||||
|
|
||||||
|
Ok(inner)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl traits::Actor for Application {}
|
||||||
|
impl traits::Actor for Group {}
|
||||||
|
impl traits::Actor for Organization {}
|
||||||
|
impl traits::Actor for Person {}
|
||||||
|
impl traits::Actor for Service {}
|
||||||
|
|
||||||
|
impl<Inner> traits::Base for ApActor<Inner> where Inner: traits::Base {}
|
||||||
|
impl<Inner> traits::Object for ApActor<Inner> where Inner: traits::Object {}
|
||||||
|
impl<Inner> traits::Actor for ApActor<Inner> where Inner: traits::Actor {}
|
||||||
|
|
||||||
|
impl<Inner> Extends<Inner> for ApActor<Inner>
|
||||||
|
where
|
||||||
|
Inner: WithUnparsed + traits::Actor,
|
||||||
|
{
|
||||||
|
type Error = serde_json::Error;
|
||||||
|
|
||||||
|
fn extends(inner: Inner) -> Result<Self, Self::Error> {
|
||||||
|
Self::extending(inner)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn retracts(self) -> Result<Inner, Self::Error> {
|
||||||
|
self.retracting()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<Inner> WithUnparsed for ApActor<Inner>
|
||||||
|
where
|
||||||
|
Inner: WithUnparsed,
|
||||||
|
{
|
||||||
|
fn unparsed(&self) -> &Unparsed {
|
||||||
|
self.inner.unparsed()
|
||||||
|
}
|
||||||
|
|
||||||
|
fn unparsed_mut(&mut self) -> &mut Unparsed {
|
||||||
|
self.inner.unparsed_mut()
|
||||||
|
}
|
||||||
|
}
|
295
src/collection.rs
Normal file
295
src/collection.rs
Normal file
|
@ -0,0 +1,295 @@
|
||||||
|
use crate::{
|
||||||
|
object::{AnyObject, Object},
|
||||||
|
primitives::{OneOrMany, Unparsed},
|
||||||
|
traits::{self, Extends, WithUnparsed, WithUnparsedExt},
|
||||||
|
};
|
||||||
|
use activitystreams::primitives::XsdNonNegativeInteger;
|
||||||
|
use std::convert::TryFrom;
|
||||||
|
|
||||||
|
#[derive(Debug, Clone, serde::Deserialize, serde::Serialize)]
|
||||||
|
pub enum OrderedCollectionType {
|
||||||
|
OrderedCollection,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Clone, serde::Deserialize, serde::Serialize)]
|
||||||
|
pub enum UnorderedCollectionType {
|
||||||
|
UnorderedCollection,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Clone, serde::Deserialize, serde::Serialize)]
|
||||||
|
pub enum OrderedCollectionPageType {
|
||||||
|
OrderedCollectionPage,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Clone, serde::Deserialize, serde::Serialize)]
|
||||||
|
pub enum UnorderedCollectionPageType {
|
||||||
|
UnorderedCollectionPage,
|
||||||
|
}
|
||||||
|
|
||||||
|
pub type OrderedCollection = Collection<OrderedCollectionType>;
|
||||||
|
pub type UnorderedCollection = Collection<UnorderedCollectionType>;
|
||||||
|
pub type UnorderedCollectionPage = CollectionPage<UnorderedCollectionPageType>;
|
||||||
|
|
||||||
|
#[derive(Debug, Clone, serde::Deserialize, serde::Serialize)]
|
||||||
|
#[serde(rename_all = "camelCase")]
|
||||||
|
pub struct Collection<Kind> {
|
||||||
|
pub items: OneOrMany<AnyObject>,
|
||||||
|
|
||||||
|
#[serde(skip_serializing_if = "Option::is_none")]
|
||||||
|
pub total_items: Option<i64>,
|
||||||
|
|
||||||
|
#[serde(skip_serializing_if = "Option::is_none")]
|
||||||
|
pub current: Option<Object<serde_json::Value>>,
|
||||||
|
|
||||||
|
#[serde(skip_serializing_if = "Option::is_none")]
|
||||||
|
pub first: Option<Object<serde_json::Value>>,
|
||||||
|
|
||||||
|
#[serde(skip_serializing_if = "Option::is_none")]
|
||||||
|
pub last: Option<Object<serde_json::Value>>,
|
||||||
|
|
||||||
|
#[serde(flatten)]
|
||||||
|
pub inner: Object<Kind>,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Clone, serde::Deserialize, serde::Serialize)]
|
||||||
|
#[serde(rename_all = "camelCase")]
|
||||||
|
pub struct CollectionPage<Kind> {
|
||||||
|
#[serde(skip_serializing_if = "Option::is_none")]
|
||||||
|
pub part_of: Option<AnyObject>,
|
||||||
|
|
||||||
|
#[serde(skip_serializing_if = "Option::is_none")]
|
||||||
|
pub next: Option<AnyObject>,
|
||||||
|
|
||||||
|
#[serde(skip_serializing_if = "Option::is_none")]
|
||||||
|
pub prev: Option<AnyObject>,
|
||||||
|
|
||||||
|
#[serde(flatten)]
|
||||||
|
pub inner: Collection<Kind>,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Clone, serde::Deserialize, serde::Serialize)]
|
||||||
|
#[serde(rename_all = "camelCase")]
|
||||||
|
pub struct OrderedCollectionPage {
|
||||||
|
#[serde(skip_serializing_if = "Option::is_none")]
|
||||||
|
pub start_index: Option<XsdNonNegativeInteger>,
|
||||||
|
|
||||||
|
#[serde(flatten)]
|
||||||
|
pub inner: CollectionPage<OrderedCollectionPageType>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<Kind> Collection<Kind> {
|
||||||
|
fn extending(mut inner: Object<Kind>) -> Result<Self, serde_json::Error> {
|
||||||
|
let items = inner.remove("items")?;
|
||||||
|
let total_items = inner.remove("totalItems")?;
|
||||||
|
let current = inner.remove("current")?;
|
||||||
|
let first = inner.remove("first")?;
|
||||||
|
let last = inner.remove("last")?;
|
||||||
|
|
||||||
|
Ok(Collection {
|
||||||
|
items,
|
||||||
|
total_items,
|
||||||
|
current,
|
||||||
|
first,
|
||||||
|
last,
|
||||||
|
inner,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
fn retracting(self) -> Result<Object<Kind>, serde_json::Error> {
|
||||||
|
let Collection {
|
||||||
|
items,
|
||||||
|
total_items,
|
||||||
|
current,
|
||||||
|
first,
|
||||||
|
last,
|
||||||
|
mut inner,
|
||||||
|
} = self;
|
||||||
|
|
||||||
|
inner
|
||||||
|
.insert("last", last)?
|
||||||
|
.insert("first", first)?
|
||||||
|
.insert("current", current)?
|
||||||
|
.insert("totalItems", total_items)?
|
||||||
|
.insert("items", items)?;
|
||||||
|
|
||||||
|
Ok(inner)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<Kind> CollectionPage<Kind> {
|
||||||
|
fn extending(object: Object<Kind>) -> Result<Self, serde_json::Error> {
|
||||||
|
let mut inner = Collection::extending(object)?;
|
||||||
|
|
||||||
|
let part_of = inner.remove("partOf")?;
|
||||||
|
let next = inner.remove("next")?;
|
||||||
|
let prev = inner.remove("prev")?;
|
||||||
|
|
||||||
|
Ok(CollectionPage {
|
||||||
|
part_of,
|
||||||
|
next,
|
||||||
|
prev,
|
||||||
|
inner,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
fn retracting(self) -> Result<Object<Kind>, serde_json::Error> {
|
||||||
|
let CollectionPage {
|
||||||
|
part_of,
|
||||||
|
next,
|
||||||
|
prev,
|
||||||
|
mut inner,
|
||||||
|
} = self;
|
||||||
|
|
||||||
|
inner
|
||||||
|
.insert("prev", prev)?
|
||||||
|
.insert("next", next)?
|
||||||
|
.insert("partOf", part_of)?;
|
||||||
|
|
||||||
|
inner.retracting()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl OrderedCollectionPage {
|
||||||
|
fn extending(object: Object<OrderedCollectionPageType>) -> Result<Self, serde_json::Error> {
|
||||||
|
let mut inner = CollectionPage::extending(object)?;
|
||||||
|
|
||||||
|
let start_index = inner.remove("startIndex")?;
|
||||||
|
|
||||||
|
Ok(OrderedCollectionPage { start_index, inner })
|
||||||
|
}
|
||||||
|
|
||||||
|
fn retracting(self) -> Result<Object<OrderedCollectionPageType>, serde_json::Error> {
|
||||||
|
let OrderedCollectionPage {
|
||||||
|
start_index,
|
||||||
|
mut inner,
|
||||||
|
} = self;
|
||||||
|
|
||||||
|
inner.insert("startIndex", start_index)?;
|
||||||
|
|
||||||
|
inner.retracting()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<Kind> traits::Base for Collection<Kind> where Kind: std::fmt::Debug {}
|
||||||
|
impl<Kind> traits::Object for Collection<Kind> where Kind: std::fmt::Debug {}
|
||||||
|
impl<Kind> traits::Collection for Collection<Kind> where Kind: std::fmt::Debug {}
|
||||||
|
|
||||||
|
impl<Kind> traits::Base for CollectionPage<Kind> where Kind: std::fmt::Debug {}
|
||||||
|
impl<Kind> traits::Object for CollectionPage<Kind> where Kind: std::fmt::Debug {}
|
||||||
|
impl<Kind> traits::Collection for CollectionPage<Kind> where Kind: std::fmt::Debug {}
|
||||||
|
impl<Kind> traits::CollectionPage for CollectionPage<Kind> where Kind: std::fmt::Debug {}
|
||||||
|
|
||||||
|
impl traits::Base for OrderedCollectionPage {}
|
||||||
|
impl traits::Object for OrderedCollectionPage {}
|
||||||
|
impl traits::Collection for OrderedCollectionPage {}
|
||||||
|
impl traits::CollectionPage for OrderedCollectionPage {}
|
||||||
|
|
||||||
|
impl Extends<Object<UnorderedCollectionType>> for UnorderedCollection {
|
||||||
|
type Error = serde_json::Error;
|
||||||
|
|
||||||
|
fn extends(object: Object<UnorderedCollectionType>) -> Result<Self, Self::Error> {
|
||||||
|
Self::extending(object)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn retracts(self) -> Result<Object<UnorderedCollectionType>, Self::Error> {
|
||||||
|
self.retracting()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl TryFrom<Object<UnorderedCollectionType>> for UnorderedCollection {
|
||||||
|
type Error = serde_json::Error;
|
||||||
|
|
||||||
|
fn try_from(object: Object<UnorderedCollectionType>) -> Result<Self, Self::Error> {
|
||||||
|
Self::extending(object)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Extends<Object<OrderedCollectionType>> for OrderedCollection {
|
||||||
|
type Error = serde_json::Error;
|
||||||
|
|
||||||
|
fn extends(object: Object<OrderedCollectionType>) -> Result<Self, Self::Error> {
|
||||||
|
Self::extending(object)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn retracts(self) -> Result<Object<OrderedCollectionType>, Self::Error> {
|
||||||
|
self.retracting()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl TryFrom<Object<OrderedCollectionType>> for OrderedCollection {
|
||||||
|
type Error = serde_json::Error;
|
||||||
|
|
||||||
|
fn try_from(object: Object<OrderedCollectionType>) -> Result<Self, Self::Error> {
|
||||||
|
Self::extending(object)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Extends<Object<UnorderedCollectionPageType>> for UnorderedCollectionPage {
|
||||||
|
type Error = serde_json::Error;
|
||||||
|
|
||||||
|
fn extends(object: Object<UnorderedCollectionPageType>) -> Result<Self, Self::Error> {
|
||||||
|
Self::extending(object)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn retracts(self) -> Result<Object<UnorderedCollectionPageType>, Self::Error> {
|
||||||
|
self.retracting()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl TryFrom<Object<UnorderedCollectionPageType>> for UnorderedCollectionPage {
|
||||||
|
type Error = serde_json::Error;
|
||||||
|
|
||||||
|
fn try_from(object: Object<UnorderedCollectionPageType>) -> Result<Self, Self::Error> {
|
||||||
|
Self::extending(object)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Extends<Object<OrderedCollectionPageType>> for OrderedCollectionPage {
|
||||||
|
type Error = serde_json::Error;
|
||||||
|
|
||||||
|
fn extends(object: Object<OrderedCollectionPageType>) -> Result<Self, Self::Error> {
|
||||||
|
Self::extending(object)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn retracts(self) -> Result<Object<OrderedCollectionPageType>, Self::Error> {
|
||||||
|
self.retracting()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl TryFrom<Object<OrderedCollectionPageType>> for OrderedCollectionPage {
|
||||||
|
type Error = serde_json::Error;
|
||||||
|
|
||||||
|
fn try_from(object: Object<OrderedCollectionPageType>) -> Result<Self, Self::Error> {
|
||||||
|
Self::extending(object)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<Kind> WithUnparsed for Collection<Kind> {
|
||||||
|
fn unparsed(&self) -> &Unparsed {
|
||||||
|
self.inner.unparsed()
|
||||||
|
}
|
||||||
|
|
||||||
|
fn unparsed_mut(&mut self) -> &mut Unparsed {
|
||||||
|
self.inner.unparsed_mut()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<Kind> WithUnparsed for CollectionPage<Kind> {
|
||||||
|
fn unparsed(&self) -> &Unparsed {
|
||||||
|
self.inner.unparsed()
|
||||||
|
}
|
||||||
|
|
||||||
|
fn unparsed_mut(&mut self) -> &mut Unparsed {
|
||||||
|
self.inner.unparsed_mut()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl WithUnparsed for OrderedCollectionPage {
|
||||||
|
fn unparsed(&self) -> &Unparsed {
|
||||||
|
self.inner.unparsed()
|
||||||
|
}
|
||||||
|
|
||||||
|
fn unparsed_mut(&mut self) -> &mut Unparsed {
|
||||||
|
self.inner.unparsed_mut()
|
||||||
|
}
|
||||||
|
}
|
38
src/either.rs
Normal file
38
src/either.rs
Normal file
|
@ -0,0 +1,38 @@
|
||||||
|
#[derive(Clone, Debug, serde::Deserialize, serde::Serialize)]
|
||||||
|
#[serde(untagged)]
|
||||||
|
pub enum Either<L, R> {
|
||||||
|
Left(L),
|
||||||
|
Right(R),
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<L, R> Either<L, R> {
|
||||||
|
pub fn left(self) -> Option<L> {
|
||||||
|
if let Either::Left(l) = self {
|
||||||
|
Some(l)
|
||||||
|
} else {
|
||||||
|
None
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn right(self) -> Option<R> {
|
||||||
|
if let Either::Right(r) = self {
|
||||||
|
Some(r)
|
||||||
|
} else {
|
||||||
|
None
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn as_ref(&self) -> Either<&L, &R> {
|
||||||
|
match self {
|
||||||
|
Either::Left(ref l) => Either::Left(l),
|
||||||
|
Either::Right(ref r) => Either::Right(r),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn as_mut(&mut self) -> Either<&mut L, &mut R> {
|
||||||
|
match self {
|
||||||
|
Either::Left(ref mut l) => Either::Left(l),
|
||||||
|
Either::Right(ref mut r) => Either::Right(r),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
9
src/lib.rs
Normal file
9
src/lib.rs
Normal file
|
@ -0,0 +1,9 @@
|
||||||
|
pub mod activity;
|
||||||
|
pub mod actor;
|
||||||
|
pub mod collection;
|
||||||
|
pub mod either;
|
||||||
|
pub mod object;
|
||||||
|
pub mod primitives;
|
||||||
|
pub mod traits;
|
||||||
|
|
||||||
|
pub use activitystreams::{context, public, security};
|
806
src/object.rs
Normal file
806
src/object.rs
Normal file
|
@ -0,0 +1,806 @@
|
||||||
|
use crate::{
|
||||||
|
either::Either,
|
||||||
|
primitives::{
|
||||||
|
AnyString, MimeMediaType, OneOrMany, Unit, Unparsed, XsdAnyUri, XsdDateTime, XsdDuration,
|
||||||
|
XsdString,
|
||||||
|
},
|
||||||
|
traits::{self, Extends, WithUnparsed, WithUnparsedExt},
|
||||||
|
};
|
||||||
|
use std::convert::TryFrom;
|
||||||
|
|
||||||
|
pub mod kind {
|
||||||
|
pub use activitystreams::object::kind::*;
|
||||||
|
}
|
||||||
|
|
||||||
|
use self::kind::*;
|
||||||
|
|
||||||
|
pub type Article = Object<ArticleType>;
|
||||||
|
pub type Audio = Object<AudioType>;
|
||||||
|
pub type Document = Object<DocumentType>;
|
||||||
|
pub type Event = Object<EventType>;
|
||||||
|
pub type Image = Object<ImageType>;
|
||||||
|
pub type Note = Object<NoteType>;
|
||||||
|
pub type Page = Object<PageType>;
|
||||||
|
pub type Video = Object<VideoType>;
|
||||||
|
|
||||||
|
#[derive(Clone, Debug, serde::Deserialize, serde::Serialize)]
|
||||||
|
#[serde(transparent)]
|
||||||
|
struct IdOrObject(Either<XsdAnyUri, Box<Object<serde_json::Value>>>);
|
||||||
|
|
||||||
|
#[derive(Clone, Debug, serde::Deserialize, serde::Serialize)]
|
||||||
|
#[serde(transparent)]
|
||||||
|
pub struct AnyObject(Either<IdOrObject, XsdString>);
|
||||||
|
|
||||||
|
#[derive(Clone, Debug, Default, serde::Deserialize, serde::Serialize)]
|
||||||
|
#[serde(rename_all = "camelCase")]
|
||||||
|
pub struct Object<Kind> {
|
||||||
|
#[serde(skip_serializing_if = "Option::is_none")]
|
||||||
|
pub context: Option<OneOrMany<AnyObject>>,
|
||||||
|
|
||||||
|
#[serde(skip_serializing_if = "Option::is_none")]
|
||||||
|
pub id: Option<AnyObject>,
|
||||||
|
|
||||||
|
#[serde(rename = "type")]
|
||||||
|
#[serde(skip_serializing_if = "Option::is_none")]
|
||||||
|
pub kind: Option<Kind>,
|
||||||
|
|
||||||
|
#[serde(skip_serializing_if = "Option::is_none")]
|
||||||
|
pub attachment: Option<OneOrMany<AnyObject>>,
|
||||||
|
|
||||||
|
#[serde(skip_serializing_if = "Option::is_none")]
|
||||||
|
pub attributed_to: Option<OneOrMany<AnyObject>>,
|
||||||
|
|
||||||
|
#[serde(skip_serializing_if = "Option::is_none")]
|
||||||
|
pub audience: Option<OneOrMany<AnyObject>>,
|
||||||
|
|
||||||
|
#[serde(skip_serializing_if = "Option::is_none")]
|
||||||
|
pub content: Option<OneOrMany<AnyString>>,
|
||||||
|
|
||||||
|
#[serde(skip_serializing_if = "Option::is_none")]
|
||||||
|
pub name: Option<OneOrMany<AnyString>>,
|
||||||
|
|
||||||
|
#[serde(skip_serializing_if = "Option::is_none")]
|
||||||
|
pub summary: Option<OneOrMany<AnyString>>,
|
||||||
|
|
||||||
|
#[serde(skip_serializing_if = "Option::is_none")]
|
||||||
|
pub url: Option<OneOrMany<AnyObject>>,
|
||||||
|
|
||||||
|
#[serde(skip_serializing_if = "Option::is_none")]
|
||||||
|
pub media_type: Option<MimeMediaType>,
|
||||||
|
|
||||||
|
#[serde(skip_serializing_if = "Option::is_none")]
|
||||||
|
pub generator: Option<OneOrMany<AnyObject>>,
|
||||||
|
|
||||||
|
#[serde(skip_serializing_if = "Option::is_none")]
|
||||||
|
pub image: Option<OneOrMany<AnyObject>>,
|
||||||
|
|
||||||
|
#[serde(skip_serializing_if = "Option::is_none")]
|
||||||
|
pub location: Option<OneOrMany<AnyObject>>,
|
||||||
|
|
||||||
|
#[serde(skip_serializing_if = "Option::is_none")]
|
||||||
|
pub preview: Option<OneOrMany<AnyObject>>,
|
||||||
|
|
||||||
|
#[serde(skip_serializing_if = "Option::is_none")]
|
||||||
|
pub start_time: Option<XsdDateTime>,
|
||||||
|
|
||||||
|
#[serde(skip_serializing_if = "Option::is_none")]
|
||||||
|
pub end_time: Option<XsdDateTime>,
|
||||||
|
|
||||||
|
#[serde(skip_serializing_if = "Option::is_none")]
|
||||||
|
pub duration: Option<XsdDuration>,
|
||||||
|
|
||||||
|
#[serde(skip_serializing_if = "Option::is_none")]
|
||||||
|
pub published: Option<XsdDateTime>,
|
||||||
|
|
||||||
|
#[serde(skip_serializing_if = "Option::is_none")]
|
||||||
|
pub updated: Option<XsdDateTime>,
|
||||||
|
|
||||||
|
#[serde(skip_serializing_if = "Option::is_none")]
|
||||||
|
pub in_reply_to: Option<OneOrMany<AnyObject>>,
|
||||||
|
|
||||||
|
#[serde(skip_serializing_if = "Option::is_none")]
|
||||||
|
pub replies: Option<OneOrMany<AnyObject>>,
|
||||||
|
|
||||||
|
#[serde(skip_serializing_if = "Option::is_none")]
|
||||||
|
pub to: Option<OneOrMany<AnyObject>>,
|
||||||
|
|
||||||
|
#[serde(skip_serializing_if = "Option::is_none")]
|
||||||
|
pub bto: Option<OneOrMany<AnyObject>>,
|
||||||
|
|
||||||
|
#[serde(skip_serializing_if = "Option::is_none")]
|
||||||
|
pub cc: Option<OneOrMany<AnyObject>>,
|
||||||
|
|
||||||
|
#[serde(skip_serializing_if = "Option::is_none")]
|
||||||
|
pub bcc: Option<OneOrMany<AnyObject>>,
|
||||||
|
|
||||||
|
#[serde(flatten)]
|
||||||
|
pub unparsed: Unparsed,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Clone, Debug, Default, serde::Deserialize, serde::Serialize)]
|
||||||
|
#[serde(rename_all = "camelCase")]
|
||||||
|
pub struct ApObject<Inner> {
|
||||||
|
#[serde(skip_serializing_if = "Option::is_none")]
|
||||||
|
pub shares: Option<XsdAnyUri>,
|
||||||
|
|
||||||
|
#[serde(skip_serializing_if = "Option::is_none")]
|
||||||
|
pub likes: Option<XsdAnyUri>,
|
||||||
|
|
||||||
|
#[serde(skip_serializing_if = "Option::is_none")]
|
||||||
|
pub source: Option<AnyObject>,
|
||||||
|
|
||||||
|
#[serde(skip_serializing_if = "Option::is_none")]
|
||||||
|
pub upload_media: Option<OneOrMany<XsdAnyUri>>,
|
||||||
|
|
||||||
|
#[serde(flatten)]
|
||||||
|
pub inner: Inner,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Clone, serde::Deserialize, serde::Serialize)]
|
||||||
|
pub struct Place {
|
||||||
|
#[serde(skip_serializing_if = "Option::is_none")]
|
||||||
|
pub accuracy: Option<f64>,
|
||||||
|
|
||||||
|
#[serde(skip_serializing_if = "Option::is_none")]
|
||||||
|
pub altitude: Option<f64>,
|
||||||
|
|
||||||
|
#[serde(skip_serializing_if = "Option::is_none")]
|
||||||
|
pub latitude: Option<f64>,
|
||||||
|
|
||||||
|
#[serde(skip_serializing_if = "Option::is_none")]
|
||||||
|
pub longitude: Option<f64>,
|
||||||
|
|
||||||
|
#[serde(skip_serializing_if = "Option::is_none")]
|
||||||
|
pub radius: Option<f64>,
|
||||||
|
|
||||||
|
#[serde(skip_serializing_if = "Option::is_none")]
|
||||||
|
pub units: Option<Unit>,
|
||||||
|
|
||||||
|
#[serde(flatten)]
|
||||||
|
pub inner: Object<PlaceType>,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Clone, serde::Deserialize, serde::Serialize)]
|
||||||
|
pub struct Profile {
|
||||||
|
#[serde(skip_serializing_if = "Option::is_none")]
|
||||||
|
pub describes: Option<AnyObject>,
|
||||||
|
|
||||||
|
#[serde(flatten)]
|
||||||
|
pub inner: Object<ProfileType>,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Clone, serde::Deserialize, serde::Serialize)]
|
||||||
|
pub struct Relationship {
|
||||||
|
#[serde(skip_serializing_if = "Option::is_none")]
|
||||||
|
pub subject: Option<AnyObject>,
|
||||||
|
|
||||||
|
#[serde(skip_serializing_if = "Option::is_none")]
|
||||||
|
pub object: Option<OneOrMany<AnyObject>>,
|
||||||
|
|
||||||
|
#[serde(skip_serializing_if = "Option::is_none")]
|
||||||
|
pub relationship: Option<OneOrMany<AnyObject>>,
|
||||||
|
|
||||||
|
#[serde(flatten)]
|
||||||
|
pub inner: Object<RelationshipType>,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Clone, serde::Deserialize, serde::Serialize)]
|
||||||
|
pub struct Tombstone {
|
||||||
|
#[serde(skip_serializing_if = "Option::is_none")]
|
||||||
|
pub former_type: Option<OneOrMany<AnyObject>>,
|
||||||
|
|
||||||
|
#[serde(skip_serializing_if = "Option::is_none")]
|
||||||
|
pub deleted: Option<XsdDateTime>,
|
||||||
|
|
||||||
|
#[serde(flatten)]
|
||||||
|
pub inner: Object<TombstoneType>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl AnyObject {
|
||||||
|
pub fn as_xsd_any_uri(&self) -> Option<&XsdAnyUri> {
|
||||||
|
self.0.as_ref().left().and_then(|l| l.as_xsd_any_uri())
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn as_xsd_string(&self) -> Option<&XsdString> {
|
||||||
|
self.0.as_ref().right()
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn as_object(&self) -> Option<&Object<serde_json::Value>> {
|
||||||
|
self.0.as_ref().left().and_then(|l| l.as_object())
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn id(self) -> Option<XsdAnyUri> {
|
||||||
|
self.0.left().and_then(|l| l.id())
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn xsd_string(self) -> Option<XsdString> {
|
||||||
|
self.0.right()
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn object(self) -> Option<Object<serde_json::Value>> {
|
||||||
|
self.0.left().and_then(|l| l.object())
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn set_xsd_any_uri(&mut self, id: XsdAnyUri) {
|
||||||
|
self.0 = Either::Left(IdOrObject::from_xsd_any_uri(id));
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn set_object(&mut self, object: Object<serde_json::Value>) {
|
||||||
|
self.0 = Either::Left(IdOrObject::from_object(object));
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn set_xsd_string(&mut self, xsd_string: XsdString) {
|
||||||
|
self.0 = Either::Right(xsd_string);
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn from_xsd_any_uri(id: XsdAnyUri) -> Self {
|
||||||
|
AnyObject(Either::Left(IdOrObject::from_xsd_any_uri(id)))
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn from_object(object: Object<serde_json::Value>) -> Self {
|
||||||
|
AnyObject(Either::Left(IdOrObject::from_object(object)))
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn from_xsd_string(xsd_string: XsdString) -> Self {
|
||||||
|
AnyObject(Either::Right(xsd_string))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl IdOrObject {
|
||||||
|
fn as_xsd_any_uri(&self) -> Option<&XsdAnyUri> {
|
||||||
|
self.0.as_ref().left()
|
||||||
|
}
|
||||||
|
|
||||||
|
fn as_object(&self) -> Option<&Object<serde_json::Value>> {
|
||||||
|
self.0.as_ref().right().map(|b| b.as_ref())
|
||||||
|
}
|
||||||
|
|
||||||
|
fn id(self) -> Option<XsdAnyUri> {
|
||||||
|
self.0.left()
|
||||||
|
}
|
||||||
|
|
||||||
|
fn object(self) -> Option<Object<serde_json::Value>> {
|
||||||
|
self.0.right().map(|b| *b)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn from_xsd_any_uri(id: XsdAnyUri) -> Self {
|
||||||
|
IdOrObject(Either::Left(id))
|
||||||
|
}
|
||||||
|
|
||||||
|
fn from_object(object: Object<serde_json::Value>) -> Self {
|
||||||
|
IdOrObject(Either::Right(Box::new(object)))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl OneOrMany<AnyObject> {
|
||||||
|
pub fn as_single_xsd_any_uri(&self) -> Option<&XsdAnyUri> {
|
||||||
|
self.as_one().and_then(|inner| inner.as_xsd_any_uri())
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn as_single_xsd_string(&self) -> Option<&XsdString> {
|
||||||
|
self.as_one().and_then(|inner| inner.as_xsd_string())
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn as_single_object(&self) -> Option<&Object<serde_json::Value>> {
|
||||||
|
self.as_one().and_then(|inner| inner.as_object())
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn single_xsd_any_uri(self) -> Option<XsdAnyUri> {
|
||||||
|
self.one().and_then(|inner| inner.id())
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn single_xsd_string(self) -> Option<XsdString> {
|
||||||
|
self.one().and_then(|inner| inner.xsd_string())
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn single_object(self) -> Option<Object<serde_json::Value>> {
|
||||||
|
self.one().and_then(|inner| inner.object())
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn from_xsd_any_uri(id: XsdAnyUri) -> Self {
|
||||||
|
OneOrMany(Either::Left(AnyObject::from_xsd_any_uri(id)))
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn from_xsd_string(xsd_string: XsdString) -> Self {
|
||||||
|
OneOrMany(Either::Left(AnyObject::from_xsd_string(xsd_string)))
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn from_object(object: Object<serde_json::Value>) -> Self {
|
||||||
|
OneOrMany(Either::Left(AnyObject::from_object(object)))
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn set_single_xsd_any_uri(&mut self, id: XsdAnyUri) -> &mut Self {
|
||||||
|
self.0 = Either::Left(AnyObject::from_xsd_any_uri(id));
|
||||||
|
self
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn set_single_xsd_string(&mut self, xsd_string: XsdString) -> &mut Self {
|
||||||
|
self.0 = Either::Left(AnyObject::from_xsd_string(xsd_string));
|
||||||
|
self
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn set_single_object(&mut self, object: Object<serde_json::Value>) -> &mut Self {
|
||||||
|
self.0 = Either::Left(AnyObject::from_object(object));
|
||||||
|
self
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn add_xsd_any_uri(&mut self, id: XsdAnyUri) -> &mut Self {
|
||||||
|
self.add(AnyObject::from_xsd_any_uri(id))
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn add_xsd_string(&mut self, xsd_string: XsdString) -> &mut Self {
|
||||||
|
self.add(AnyObject::from_xsd_string(xsd_string))
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn add_object(&mut self, object: Object<serde_json::Value>) -> &mut Self {
|
||||||
|
self.add(AnyObject::from_object(object))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Object<serde_json::Value> {
|
||||||
|
pub fn solidify<Kind>(self) -> Result<Object<Kind>, serde_json::Error>
|
||||||
|
where
|
||||||
|
Kind: serde::de::DeserializeOwned,
|
||||||
|
{
|
||||||
|
self.try_map_kind(serde_json::from_value)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<Kind> Object<Kind> {
|
||||||
|
pub fn into_generic(self) -> Result<Object<serde_json::Value>, serde_json::Error>
|
||||||
|
where
|
||||||
|
Kind: serde::ser::Serialize,
|
||||||
|
{
|
||||||
|
self.try_map_kind(serde_json::to_value)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn map_kind<NewKind>(self, f: impl Fn(Kind) -> NewKind) -> Object<NewKind> {
|
||||||
|
Object {
|
||||||
|
kind: self.kind.map(f),
|
||||||
|
context: self.context,
|
||||||
|
id: self.id,
|
||||||
|
attachment: self.attachment,
|
||||||
|
attributed_to: self.attributed_to,
|
||||||
|
audience: self.audience,
|
||||||
|
content: self.content,
|
||||||
|
name: self.name,
|
||||||
|
summary: self.summary,
|
||||||
|
url: self.url,
|
||||||
|
media_type: self.media_type,
|
||||||
|
generator: self.generator,
|
||||||
|
image: self.image,
|
||||||
|
location: self.location,
|
||||||
|
preview: self.preview,
|
||||||
|
start_time: self.start_time,
|
||||||
|
end_time: self.end_time,
|
||||||
|
duration: self.duration,
|
||||||
|
published: self.published,
|
||||||
|
updated: self.updated,
|
||||||
|
in_reply_to: self.in_reply_to,
|
||||||
|
replies: self.replies,
|
||||||
|
to: self.to,
|
||||||
|
bto: self.bto,
|
||||||
|
cc: self.cc,
|
||||||
|
bcc: self.bcc,
|
||||||
|
unparsed: self.unparsed,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn try_map_kind<NewKind, E>(
|
||||||
|
self,
|
||||||
|
f: impl Fn(Kind) -> Result<NewKind, E>,
|
||||||
|
) -> Result<Object<NewKind>, E> {
|
||||||
|
Ok(Object {
|
||||||
|
kind: if let Some(kind) = self.kind {
|
||||||
|
Some((f)(kind)?)
|
||||||
|
} else {
|
||||||
|
None
|
||||||
|
},
|
||||||
|
context: self.context,
|
||||||
|
id: self.id,
|
||||||
|
attachment: self.attachment,
|
||||||
|
attributed_to: self.attributed_to,
|
||||||
|
audience: self.audience,
|
||||||
|
content: self.content,
|
||||||
|
name: self.name,
|
||||||
|
summary: self.summary,
|
||||||
|
url: self.url,
|
||||||
|
media_type: self.media_type,
|
||||||
|
generator: self.generator,
|
||||||
|
image: self.image,
|
||||||
|
location: self.location,
|
||||||
|
preview: self.preview,
|
||||||
|
start_time: self.start_time,
|
||||||
|
end_time: self.end_time,
|
||||||
|
duration: self.duration,
|
||||||
|
published: self.published,
|
||||||
|
updated: self.updated,
|
||||||
|
in_reply_to: self.in_reply_to,
|
||||||
|
replies: self.replies,
|
||||||
|
to: self.to,
|
||||||
|
bto: self.bto,
|
||||||
|
cc: self.cc,
|
||||||
|
bcc: self.bcc,
|
||||||
|
unparsed: self.unparsed,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn extend<Extended>(self) -> Result<Extended, Extended::Error>
|
||||||
|
where
|
||||||
|
Extended: Extends<Self>,
|
||||||
|
{
|
||||||
|
Extended::extends(self)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<Inner> ApObject<Inner> {
|
||||||
|
fn extending(mut inner: Inner) -> Result<Self, serde_json::Error>
|
||||||
|
where
|
||||||
|
Inner: WithUnparsed + traits::Object,
|
||||||
|
{
|
||||||
|
let shares = inner.remove("shares")?;
|
||||||
|
let likes = inner.remove("likes")?;
|
||||||
|
let source = inner.remove("source")?;
|
||||||
|
let upload_media = inner.remove("uploadMedia")?;
|
||||||
|
|
||||||
|
Ok(ApObject {
|
||||||
|
shares,
|
||||||
|
likes,
|
||||||
|
source,
|
||||||
|
upload_media,
|
||||||
|
inner,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
fn retracting(self) -> Result<Inner, serde_json::Error>
|
||||||
|
where
|
||||||
|
Inner: WithUnparsed + traits::Object,
|
||||||
|
{
|
||||||
|
let ApObject {
|
||||||
|
shares,
|
||||||
|
likes,
|
||||||
|
source,
|
||||||
|
upload_media,
|
||||||
|
mut inner,
|
||||||
|
} = self;
|
||||||
|
|
||||||
|
inner
|
||||||
|
.insert("uploadMedia", upload_media)?
|
||||||
|
.insert("source", source)?
|
||||||
|
.insert("likes", likes)?
|
||||||
|
.insert("shares", shares)?;
|
||||||
|
|
||||||
|
Ok(inner)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Place {
|
||||||
|
fn extending(mut inner: Object<PlaceType>) -> Result<Self, serde_json::Error> {
|
||||||
|
let accuracy = inner.remove("accuracy")?;
|
||||||
|
let altitude = inner.remove("altitude")?;
|
||||||
|
let latitude = inner.remove("latitude")?;
|
||||||
|
let longitude = inner.remove("longitude")?;
|
||||||
|
let radius = inner.remove("radius")?;
|
||||||
|
let units = inner.remove("units")?;
|
||||||
|
|
||||||
|
Ok(Place {
|
||||||
|
accuracy,
|
||||||
|
altitude,
|
||||||
|
latitude,
|
||||||
|
longitude,
|
||||||
|
radius,
|
||||||
|
units,
|
||||||
|
inner,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
fn retracting(self) -> Result<Object<PlaceType>, serde_json::Error> {
|
||||||
|
let Place {
|
||||||
|
accuracy,
|
||||||
|
altitude,
|
||||||
|
latitude,
|
||||||
|
longitude,
|
||||||
|
radius,
|
||||||
|
units,
|
||||||
|
mut inner,
|
||||||
|
} = self;
|
||||||
|
|
||||||
|
inner
|
||||||
|
.insert("units", units)?
|
||||||
|
.insert("radius", radius)?
|
||||||
|
.insert("longitude", longitude)?
|
||||||
|
.insert("latitude", latitude)?
|
||||||
|
.insert("altitude", altitude)?
|
||||||
|
.insert("accuracy", accuracy)?;
|
||||||
|
|
||||||
|
Ok(inner)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Profile {
|
||||||
|
fn extending(mut inner: Object<ProfileType>) -> Result<Self, serde_json::Error> {
|
||||||
|
let describes = inner.remove("describes")?;
|
||||||
|
|
||||||
|
Ok(Profile { describes, inner })
|
||||||
|
}
|
||||||
|
|
||||||
|
fn retracting(self) -> Result<Object<ProfileType>, serde_json::Error> {
|
||||||
|
let Profile {
|
||||||
|
describes,
|
||||||
|
mut inner,
|
||||||
|
} = self;
|
||||||
|
|
||||||
|
inner.insert("describes", describes)?;
|
||||||
|
Ok(inner)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Relationship {
|
||||||
|
fn extending(mut inner: Object<RelationshipType>) -> Result<Self, serde_json::Error> {
|
||||||
|
let subject = inner.remove("subject")?;
|
||||||
|
let object = inner.remove("object")?;
|
||||||
|
let relationship = inner.remove("relationship")?;
|
||||||
|
|
||||||
|
Ok(Relationship {
|
||||||
|
subject,
|
||||||
|
object,
|
||||||
|
relationship,
|
||||||
|
inner,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
fn retracting(self) -> Result<Object<RelationshipType>, serde_json::Error> {
|
||||||
|
let Relationship {
|
||||||
|
subject,
|
||||||
|
object,
|
||||||
|
relationship,
|
||||||
|
mut inner,
|
||||||
|
} = self;
|
||||||
|
|
||||||
|
inner
|
||||||
|
.insert("subject", subject)?
|
||||||
|
.insert("object", object)?
|
||||||
|
.insert("relationship", relationship)?;
|
||||||
|
|
||||||
|
Ok(inner)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Tombstone {
|
||||||
|
fn extending(mut inner: Object<TombstoneType>) -> Result<Self, serde_json::Error> {
|
||||||
|
let former_type = inner.remove("formerType")?;
|
||||||
|
let deleted = inner.remove("deleted")?;
|
||||||
|
|
||||||
|
Ok(Tombstone {
|
||||||
|
former_type,
|
||||||
|
deleted,
|
||||||
|
inner,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
fn retracting(self) -> Result<Object<TombstoneType>, serde_json::Error> {
|
||||||
|
let Tombstone {
|
||||||
|
former_type,
|
||||||
|
deleted,
|
||||||
|
mut inner,
|
||||||
|
} = self;
|
||||||
|
|
||||||
|
inner
|
||||||
|
.insert("formerType", former_type)?
|
||||||
|
.insert("deleted", deleted)?;
|
||||||
|
|
||||||
|
Ok(inner)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<Kind> traits::Base for Object<Kind> where Kind: std::fmt::Debug {}
|
||||||
|
impl<Kind> traits::Object for Object<Kind> where Kind: std::fmt::Debug {}
|
||||||
|
|
||||||
|
impl<Inner> traits::Base for ApObject<Inner> where Inner: traits::Base {}
|
||||||
|
impl<Inner> traits::Object for ApObject<Inner> where Inner: traits::Object {}
|
||||||
|
|
||||||
|
impl traits::Base for Place {}
|
||||||
|
impl traits::Object for Place {}
|
||||||
|
|
||||||
|
impl traits::Base for Profile {}
|
||||||
|
impl traits::Object for Profile {}
|
||||||
|
|
||||||
|
impl traits::Base for Relationship {}
|
||||||
|
impl traits::Object for Relationship {}
|
||||||
|
|
||||||
|
impl traits::Base for Tombstone {}
|
||||||
|
impl traits::Object for Tombstone {}
|
||||||
|
|
||||||
|
impl<Inner> Extends<Inner> for ApObject<Inner>
|
||||||
|
where
|
||||||
|
Inner: WithUnparsed + traits::Object,
|
||||||
|
{
|
||||||
|
type Error = serde_json::Error;
|
||||||
|
|
||||||
|
fn extends(inner: Inner) -> Result<Self, Self::Error> {
|
||||||
|
Self::extending(inner)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn retracts(self) -> Result<Inner, Self::Error> {
|
||||||
|
self.retracting()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Extends<Object<PlaceType>> for Place {
|
||||||
|
type Error = serde_json::Error;
|
||||||
|
|
||||||
|
fn extends(object: Object<PlaceType>) -> Result<Self, Self::Error> {
|
||||||
|
Self::extending(object)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn retracts(self) -> Result<Object<PlaceType>, Self::Error> {
|
||||||
|
self.retracting()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl TryFrom<Object<PlaceType>> for Place {
|
||||||
|
type Error = serde_json::Error;
|
||||||
|
|
||||||
|
fn try_from(object: Object<PlaceType>) -> Result<Self, Self::Error> {
|
||||||
|
Self::extending(object)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Extends<Object<ProfileType>> for Profile {
|
||||||
|
type Error = serde_json::Error;
|
||||||
|
|
||||||
|
fn extends(object: Object<ProfileType>) -> Result<Self, Self::Error> {
|
||||||
|
Self::extending(object)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn retracts(self) -> Result<Object<ProfileType>, Self::Error> {
|
||||||
|
self.retracting()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl TryFrom<Object<ProfileType>> for Profile {
|
||||||
|
type Error = serde_json::Error;
|
||||||
|
|
||||||
|
fn try_from(object: Object<ProfileType>) -> Result<Self, Self::Error> {
|
||||||
|
Self::extending(object)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Extends<Object<RelationshipType>> for Relationship {
|
||||||
|
type Error = serde_json::Error;
|
||||||
|
|
||||||
|
fn extends(object: Object<RelationshipType>) -> Result<Self, Self::Error> {
|
||||||
|
Self::extending(object)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn retracts(self) -> Result<Object<RelationshipType>, Self::Error> {
|
||||||
|
self.retracting()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl TryFrom<Object<RelationshipType>> for Relationship {
|
||||||
|
type Error = serde_json::Error;
|
||||||
|
|
||||||
|
fn try_from(object: Object<RelationshipType>) -> Result<Self, Self::Error> {
|
||||||
|
Self::extending(object)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Extends<Object<TombstoneType>> for Tombstone {
|
||||||
|
type Error = serde_json::Error;
|
||||||
|
|
||||||
|
fn extends(object: Object<TombstoneType>) -> Result<Self, Self::Error> {
|
||||||
|
Self::extending(object)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn retracts(self) -> Result<Object<TombstoneType>, Self::Error> {
|
||||||
|
self.retracting()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl TryFrom<Object<TombstoneType>> for Tombstone {
|
||||||
|
type Error = serde_json::Error;
|
||||||
|
|
||||||
|
fn try_from(object: Object<TombstoneType>) -> Result<Self, Self::Error> {
|
||||||
|
Self::extending(object)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<Kind> WithUnparsed for Object<Kind> {
|
||||||
|
fn unparsed(&self) -> &Unparsed {
|
||||||
|
&self.unparsed
|
||||||
|
}
|
||||||
|
|
||||||
|
fn unparsed_mut(&mut self) -> &mut Unparsed {
|
||||||
|
&mut self.unparsed
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<Inner> WithUnparsed for ApObject<Inner>
|
||||||
|
where
|
||||||
|
Inner: WithUnparsed,
|
||||||
|
{
|
||||||
|
fn unparsed(&self) -> &Unparsed {
|
||||||
|
self.inner.unparsed()
|
||||||
|
}
|
||||||
|
|
||||||
|
fn unparsed_mut(&mut self) -> &mut Unparsed {
|
||||||
|
self.inner.unparsed_mut()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl WithUnparsed for Place {
|
||||||
|
fn unparsed(&self) -> &Unparsed {
|
||||||
|
self.inner.unparsed()
|
||||||
|
}
|
||||||
|
|
||||||
|
fn unparsed_mut(&mut self) -> &mut Unparsed {
|
||||||
|
self.inner.unparsed_mut()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl WithUnparsed for Profile {
|
||||||
|
fn unparsed(&self) -> &Unparsed {
|
||||||
|
self.inner.unparsed()
|
||||||
|
}
|
||||||
|
|
||||||
|
fn unparsed_mut(&mut self) -> &mut Unparsed {
|
||||||
|
self.inner.unparsed_mut()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl WithUnparsed for Relationship {
|
||||||
|
fn unparsed(&self) -> &Unparsed {
|
||||||
|
self.inner.unparsed()
|
||||||
|
}
|
||||||
|
|
||||||
|
fn unparsed_mut(&mut self) -> &mut Unparsed {
|
||||||
|
self.inner.unparsed_mut()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl WithUnparsed for Tombstone {
|
||||||
|
fn unparsed(&self) -> &Unparsed {
|
||||||
|
self.inner.unparsed()
|
||||||
|
}
|
||||||
|
|
||||||
|
fn unparsed_mut(&mut self) -> &mut Unparsed {
|
||||||
|
self.inner.unparsed_mut()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl From<Object<serde_json::Value>> for AnyObject {
|
||||||
|
fn from(o: Object<serde_json::Value>) -> Self {
|
||||||
|
Self::from_object(o)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl From<XsdAnyUri> for AnyObject {
|
||||||
|
fn from(id: XsdAnyUri) -> Self {
|
||||||
|
Self::from_xsd_any_uri(id)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl From<XsdString> for AnyObject {
|
||||||
|
fn from(xsd_string: XsdString) -> Self {
|
||||||
|
Self::from_xsd_string(xsd_string)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl From<Object<serde_json::Value>> for OneOrMany<AnyObject> {
|
||||||
|
fn from(object: Object<serde_json::Value>) -> Self {
|
||||||
|
Self::from_object(object)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl From<XsdAnyUri> for OneOrMany<AnyObject> {
|
||||||
|
fn from(xsd_any_uri: XsdAnyUri) -> Self {
|
||||||
|
Self::from_xsd_any_uri(xsd_any_uri)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl From<XsdString> for OneOrMany<AnyObject> {
|
||||||
|
fn from(xsd_string: XsdString) -> Self {
|
||||||
|
Self::from_xsd_string(xsd_string)
|
||||||
|
}
|
||||||
|
}
|
210
src/primitives.rs
Normal file
210
src/primitives.rs
Normal file
|
@ -0,0 +1,210 @@
|
||||||
|
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)
|
||||||
|
}
|
||||||
|
}
|
38
src/traits.rs
Normal file
38
src/traits.rs
Normal file
|
@ -0,0 +1,38 @@
|
||||||
|
use crate::primitives::Unparsed;
|
||||||
|
pub use activitystreams::{
|
||||||
|
Activity, Actor, Base, Collection, CollectionPage, IntransitiveActivity, Link, Object,
|
||||||
|
};
|
||||||
|
|
||||||
|
pub trait WithUnparsed {
|
||||||
|
fn unparsed(&self) -> &Unparsed;
|
||||||
|
|
||||||
|
fn unparsed_mut(&mut self) -> &mut Unparsed;
|
||||||
|
}
|
||||||
|
|
||||||
|
pub trait WithUnparsedExt: WithUnparsed {
|
||||||
|
fn remove<T>(&mut self, key: &str) -> Result<T, serde_json::Error>
|
||||||
|
where
|
||||||
|
T: serde::de::DeserializeOwned,
|
||||||
|
{
|
||||||
|
serde_json::from_value(self.unparsed_mut().remove(key))
|
||||||
|
}
|
||||||
|
|
||||||
|
fn insert<T>(&mut self, key: &str, value: T) -> Result<&mut Self, serde_json::Error>
|
||||||
|
where
|
||||||
|
T: serde::ser::Serialize,
|
||||||
|
{
|
||||||
|
self.unparsed_mut()
|
||||||
|
.insert(key.to_owned(), serde_json::to_value(value)?);
|
||||||
|
Ok(self)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub trait Extends<T>: Sized {
|
||||||
|
type Error: std::error::Error;
|
||||||
|
|
||||||
|
fn extends(t: T) -> Result<Self, Self::Error>;
|
||||||
|
|
||||||
|
fn retracts(self) -> Result<T, Self::Error>;
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<T> WithUnparsedExt for T where T: WithUnparsed {}
|
Loading…
Reference in a new issue