//! Types and traits for dealing with Actor attributes //! //! ```rust //! # fn main() -> Result<(), anyhow::Error> { //! use activitystreams_new::{ //! actor::{ApActor, Person}, //! prelude::*, //! primitives::XsdAnyUri, //! }; //! //! let mut person = ApActor::new( //! "https://example.com/actor/inbox".parse()?, //! "https://example.com/actor/outbox".parse()?, //! Person::new(), //! ); //! //! person //! .set_following("https://example.com/actor/following".parse()?) //! .set_followers("https://example.com/actor/followers".parse()?); //! # //! # Ok(()) //! # } //! ``` use crate::{ base::{AsBase, Base, Extends}, markers, object::{ApObject, AsApObject, AsObject, Object}, primitives::{OneOrMany, XsdAnyUri, XsdString}, unparsed::{Unparsed, UnparsedMut, UnparsedMutExt}, }; use typed_builder::TypedBuilder; pub mod kind { //! Kinds of actors defined by the spec //! //! These types exist only to be statically-typed versions of the associated string. e.g. //! `PersonType` -> `"Person"` pub use activitystreams::actor::kind::*; } use self::kind::*; /// Implementation trait for deriving ActivityPub Actor methods for a type /// /// Any type implementing AsObject will automatically gain methods provided by ApActorExt pub trait AsApActor: markers::Actor { /// Immutable borrow of `ApActor` fn ap_actor_ref(&self) -> &ApActor; /// Mutable borrow of `ApActor` fn ap_actor_mut(&mut self) -> &mut ApActor; } /// Helper methods for interacting with ActivityPub Actor types /// /// This trait represents methods valid for any ActivityPub Actor. /// /// Documentation for the fields related to these methods can be found on the `ApActor` struct pub trait ApActorExt: AsApActor { /// Fetch the inbox for the current actor /// /// ```rust /// # use activitystreams_new::{actor::{ApActor, Person}, context}; /// # let mut person = ApActor::new(context(), context(), Person::new()); /// use activitystreams_new::prelude::*; /// /// let inbox_ref = person.inbox(); /// ``` fn inbox<'a>(&'a self) -> &'a XsdAnyUri where Inner: 'a, { &self.ap_actor_ref().inbox } /// Set the inbox for the current actor /// /// ```rust /// # fn main() -> Result<(), anyhow::Error> { /// # use activitystreams_new::{actor::{ApActor, Person}, context}; /// # let mut person = ApActor::new(context(), context(), Person::new()); /// use activitystreams_new::prelude::*; /// /// person.set_inbox("https://example.com/inbox".parse()?); /// # Ok(()) /// # } /// ``` fn set_inbox(&mut self, inbox: XsdAnyUri) -> &mut Self { self.ap_actor_mut().inbox = inbox; self } /// Fetch the outbox for the current actor /// /// ```rust /// # use activitystreams_new::{actor::{ApActor, Person}, context}; /// # let mut person = ApActor::new(context(), context(), Person::new()); /// use activitystreams_new::prelude::*; /// /// let outbox_ref = person.outbox(); /// ``` fn outbox<'a>(&'a self) -> &'a XsdAnyUri where Inner: 'a, { &self.ap_actor_ref().outbox } /// Set the outbox for the current actor /// /// ```rust /// # fn main() -> Result<(), anyhow::Error> { /// # use activitystreams_new::{actor::{ApActor, Person}, context}; /// # let mut person = ApActor::new(context(), context(), Person::new()); /// use activitystreams_new::prelude::*; /// /// person.set_outbox("https://example.com/outbox".parse()?); /// # Ok(()) /// # } /// ``` fn set_outbox(&mut self, outbox: XsdAnyUri) -> &mut Self { self.ap_actor_mut().outbox = outbox; self } /// Fetch the following link for the current actor /// /// ```rust /// # use activitystreams_new::{actor::{ApActor, Person}, context}; /// # let mut person = ApActor::new(context(), context(), Person::new()); /// use activitystreams_new::prelude::*; /// /// if let Some(following) = person.following() { /// println!("{:?}", following); /// } /// ``` fn following<'a>(&'a self) -> Option<&'a XsdAnyUri> where Inner: 'a, { self.ap_actor_ref().following.as_ref() } /// Set the following link for the current actor /// /// ```rust /// # fn main() -> Result<(), anyhow::Error> { /// # use activitystreams_new::{actor::{ApActor, Person}, context}; /// # let mut person = ApActor::new(context(), context(), Person::new()); /// use activitystreams_new::prelude::*; /// /// person.set_following("https://example.com/following".parse()?); /// # Ok(()) /// # } /// ``` fn set_following(&mut self, following: XsdAnyUri) -> &mut Self { self.ap_actor_mut().following = Some(following); self } /// Take the following link for the current actor, leaving nothing /// /// ```rust /// # use activitystreams_new::{actor::{ApActor, Person}, context}; /// # let mut person = ApActor::new(context(), context(), Person::new()); /// use activitystreams_new::prelude::*; /// /// if let Some(following) = person.take_following() { /// println!("{:?}", following); /// } /// ``` fn take_following(&mut self) -> Option { self.ap_actor_mut().following.take() } /// Delete the following link from the current object /// /// ```rust /// # fn main() -> Result<(), anyhow::Error> { /// # use activitystreams_new::{actor::{ApActor, Person}, context}; /// # let mut person = ApActor::new(context(), context(), Person::new()); /// # person.set_following("https://example.com/following".parse()?); /// use activitystreams_new::prelude::*; /// /// assert!(person.following().is_some()); /// person.delete_following(); /// assert!(person.following().is_none()); /// # Ok(()) /// # } /// ``` fn delete_following(&mut self) -> &mut Self { self.ap_actor_mut().following = None; self } /// Fetch the followers link for the current actor /// /// ```rust /// # use activitystreams_new::{actor::{ApActor, Person}, context}; /// # let mut person = ApActor::new(context(), context(), Person::new()); /// use activitystreams_new::prelude::*; /// /// if let Some(followers) = person.take_followers() { /// println!("{:?}", followers); /// } /// ``` fn followers<'a>(&'a self) -> Option<&'a XsdAnyUri> where Inner: 'a, { self.ap_actor_ref().followers.as_ref() } /// Set the followers link for the current actor /// /// ```rust /// # fn main() -> Result<(), anyhow::Error> { /// # use activitystreams_new::{actor::{ApActor, Person}, context}; /// # let mut person = ApActor::new(context(), context(), Person::new()); /// use activitystreams_new::prelude::*; /// /// person.set_followers("https://example.com/followers".parse()?); /// # Ok(()) /// # } /// ``` fn set_followers(&mut self, followers: XsdAnyUri) -> &mut Self { self.ap_actor_mut().followers = Some(followers); self } /// Take the followers link for the current actor, leaving nothing /// /// ```rust /// # use activitystreams_new::{actor::{ApActor, Person}, context}; /// # let mut person = ApActor::new(context(), context(), Person::new()); /// use activitystreams_new::prelude::*; /// /// if let Some(followers) = person.take_followers() { /// println!("{:?}", followers); /// } /// ``` fn take_followers(&mut self) -> Option { self.ap_actor_mut().followers.take() } /// Delete the followers link from the current object /// /// ```rust /// # fn main() -> Result<(), anyhow::Error> { /// # use activitystreams_new::{actor::{ApActor, Person}, context}; /// # let mut person = ApActor::new(context(), context(), Person::new()); /// # person.set_followers("https://example.com/followers".parse()?); /// use activitystreams_new::prelude::*; /// /// assert!(person.followers().is_some()); /// person.delete_followers(); /// assert!(person.followers().is_none()); /// # Ok(()) /// # } /// ``` fn delete_followers(&mut self) -> &mut Self { self.ap_actor_mut().followers = None; self } /// Fetch the liked link for the current actor /// /// ```rust /// # use activitystreams_new::{actor::{ApActor, Person}, context}; /// # let mut person = ApActor::new(context(), context(), Person::new()); /// use activitystreams_new::prelude::*; /// /// if let Some(liked) = person.take_liked() { /// println!("{:?}", liked); /// } /// ``` fn liked<'a>(&'a self) -> Option<&'a XsdAnyUri> where Inner: 'a, { self.ap_actor_ref().liked.as_ref() } /// Set the liked link for the current actor /// /// ```rust /// # fn main() -> Result<(), anyhow::Error> { /// # use activitystreams_new::{actor::{ApActor, Person}, context}; /// # let mut person = ApActor::new(context(), context(), Person::new()); /// use activitystreams_new::prelude::*; /// /// person.set_streams("https://example.com/liked".parse()?); /// # Ok(()) /// # } /// ``` fn set_liked(&mut self, liked: XsdAnyUri) -> &mut Self { self.ap_actor_mut().liked = Some(liked); self } /// Take the liked link for the current actor, leaving nothing /// /// ```rust /// # use activitystreams_new::{actor::{ApActor, Person}, context}; /// # let mut person = ApActor::new(context(), context(), Person::new()); /// use activitystreams_new::prelude::*; /// /// if let Some(liked) = person.take_liked() { /// println!("{:?}", liked); /// } /// ``` fn take_liked(&mut self) -> Option { self.ap_actor_mut().liked.take() } /// Delete the liked link from the current object /// /// ```rust /// # fn main() -> Result<(), anyhow::Error> { /// # use activitystreams_new::{actor::{ApActor, Person}, context}; /// # let mut person = ApActor::new(context(), context(), Person::new()); /// # person.set_liked("https://example.com/liked".parse()?); /// use activitystreams_new::prelude::*; /// /// assert!(person.liked().is_some()); /// person.delete_liked(); /// assert!(person.liked().is_none()); /// # Ok(()) /// # } /// ``` fn delete_liked(&mut self) -> &mut Self { self.ap_actor_mut().liked = None; self } /// Fetch the streams links for the current actor /// /// ```rust /// # use activitystreams_new::{actor::{ApActor, Person}, context}; /// # let mut person = ApActor::new(context(), context(), Person::new()); /// use activitystreams_new::prelude::*; /// /// if let Some(streams) = person.take_streams() { /// println!("{:?}", streams); /// } /// ``` fn streams<'a>(&'a self) -> Option<&'a OneOrMany> where Inner: 'a, { self.ap_actor_ref().streams.as_ref() } /// Set the streams links for the current actor /// /// ```rust /// # fn main() -> Result<(), anyhow::Error> { /// # use activitystreams_new::{actor::{ApActor, Person}, context}; /// # let mut person = ApActor::new(context(), context(), Person::new()); /// use activitystreams_new::prelude::*; /// /// person.set_streams("https://example.com/streams".parse()?); /// # Ok(()) /// # } /// ``` fn set_streams(&mut self, streams: XsdAnyUri) -> &mut Self { self.ap_actor_mut().streams = Some(streams.into()); self } /// Set many streams links for the current actor /// /// ```rust /// # fn main() -> Result<(), anyhow::Error> { /// # use activitystreams_new::{actor::{ApActor, Person}, context}; /// # let mut person = ApActor::new(context(), context(), Person::new()); /// use activitystreams_new::prelude::*; /// /// person.set_many_streams(vec![ /// "https://example.com/streams1".parse()?, /// "https://example.com/streams2".parse()? /// ]); /// # Ok(()) /// # } /// ``` fn set_many_streams(&mut self, items: I) -> &mut Self where I: IntoIterator, { let v: Vec<_> = items.into_iter().collect(); self.ap_actor_mut().streams = Some(v.into()); self } /// Add a streams link for the current actor /// /// ```rust /// # fn main() -> Result<(), anyhow::Error> { /// # use activitystreams_new::{actor::{ApActor, Person}, context}; /// # let mut person = ApActor::new(context(), context(), Person::new()); /// use activitystreams_new::prelude::*; /// /// person /// .add_streams("https://example.com/streams1".parse()?) /// .add_streams("https://example.com/streams2".parse()?); /// # Ok(()) /// # } /// ``` fn add_streams(&mut self, stream: XsdAnyUri) -> &mut Self { let v = match self.ap_actor_mut().streams.take() { Some(mut v) => { v.add(stream); v } None => vec![stream].into(), }; self.ap_actor_mut().streams = Some(v); self } /// Take the streams links for the current actor, leaving nothing /// /// ```rust /// # use activitystreams_new::{actor::{ApActor, Person}, context}; /// # let mut person = ApActor::new(context(), context(), Person::new()); /// use activitystreams_new::prelude::*; /// /// if let Some(streams) = person.take_streams() { /// println!("{:?}", streams); /// } /// ``` fn take_streams(&mut self) -> Option> { self.ap_actor_mut().streams.take() } /// Delete the streams links from the current object /// /// ```rust /// # fn main() -> Result<(), anyhow::Error> { /// # use activitystreams_new::{actor::{ApActor, Person}, context}; /// # let mut person = ApActor::new(context(), context(), Person::new()); /// # person.set_streams("https://example.com/streams".parse()?); /// use activitystreams_new::prelude::*; /// /// assert!(person.streams().is_some()); /// person.delete_streams(); /// assert!(person.streams().is_none()); /// # Ok(()) /// # } /// ``` fn delete_streams(&mut self) -> &mut Self { self.ap_actor_mut().streams = None; self } /// Fetch the preferred_username for the current actor /// /// ```rust /// # use activitystreams_new::{actor::{ApActor, Person}, context}; /// # let mut person = ApActor::new(context(), context(), Person::new()); /// use activitystreams_new::prelude::*; /// /// if let Some(preferred_username) = person.preferred_username() { /// println!("{:?}", preferred_username); /// } /// ``` fn preferred_username<'a>(&'a self) -> Option<&'a XsdString> where Inner: 'a, { self.ap_actor_ref().preferred_username.as_ref() } /// Set the preferred_username for the current actor /// /// ```rust /// # fn main() -> Result<(), anyhow::Error> { /// # use activitystreams_new::{actor::{ApActor, Person}, context}; /// # let mut person = ApActor::new(context(), context(), Person::new()); /// use activitystreams_new::prelude::*; /// /// person.set_preferred_username("user123".into()); /// # Ok(()) /// # } /// ``` fn set_preferred_username(&mut self, string: XsdString) -> &mut Self { self.ap_actor_mut().preferred_username = Some(string); self } /// Take the preferred_username from the current actor, leaving nothing /// /// ```rust /// # use activitystreams_new::{actor::{ApActor, Person}, context}; /// # let mut person = ApActor::new(context(), context(), Person::new()); /// use activitystreams_new::prelude::*; /// /// if let Some(preferred_username) = person.take_preferred_username() { /// println!("{:?}", preferred_username); /// } /// ``` fn take_preferred_username(&mut self) -> Option { self.ap_actor_mut().preferred_username.take() } /// Delete the preferred_username from the current actor /// /// ```rust /// # use activitystreams_new::{actor::{ApActor, Person}, context}; /// # let mut person = ApActor::new(context(), context(), Person::new()); /// # person.set_preferred_username("hey".into()); /// use activitystreams_new::prelude::*; /// /// assert!(person.preferred_username().is_some()); /// person.delete_preferred_username(); /// assert!(person.preferred_username().is_none()); /// ``` fn delete_preferred_username(&mut self) -> &mut Self { self.ap_actor_mut().preferred_username = None; self } /// Fetch the endpoints for the current actor /// /// ```rust /// # use activitystreams_new::{actor::{ApActor, Person}, context}; /// # let mut person = ApActor::new(context(), context(), Person::new()); /// use activitystreams_new::prelude::*; /// /// if let Some(endpoints) = person.endpoints() { /// println!("{:?}", endpoints); /// } /// ``` fn endpoints<'a>(&'a self) -> Option<&'a Endpoints> where Inner: 'a, { self.ap_actor_ref().endpoints.as_ref() } /// Set the endpoints for the current actor /// /// ```rust /// # fn main() -> Result<(), anyhow::Error> { /// # use activitystreams_new::{actor::{ApActor, Endpoints, Person}, context}; /// # let mut person = ApActor::new(context(), context(), Person::new()); /// use activitystreams_new::prelude::*; /// /// person.set_endpoints(Endpoints { /// shared_inbox: Some("https://example.com/inbox".parse()?), /// ..Default::default() /// }); /// # Ok(()) /// # } /// ``` fn set_endpoints(&mut self, endpoints: Endpoints) -> &mut Self { self.ap_actor_mut().endpoints = Some(endpoints); self } /// Take the endpoints from the current actor, leaving nothing /// /// ```rust /// # use activitystreams_new::{actor::{ApActor, Person}, context}; /// # let mut person = ApActor::new(context(), context(), Person::new()); /// use activitystreams_new::prelude::*; /// /// if let Some(endpoints) = person.endpoints() { /// println!("{:?}", endpoints); /// } /// ``` fn take_endpoints(&mut self) -> Option { self.ap_actor_mut().endpoints.take() } /// Delete the endpoints from the current actor /// /// ```rust /// # use activitystreams_new::{actor::{ApActor, Person}, context}; /// # let mut person = ApActor::new(context(), context(), Person::new()); /// # person.set_endpoints(Default::default()); /// use activitystreams_new::prelude::*; /// /// assert!(person.endpoints().is_some()); /// person.delete_endpoints(); /// assert!(person.endpoints().is_none()); /// ``` fn delete_endpoints(&mut self) -> &mut Self { self.ap_actor_mut().endpoints = None; self } } /// Describes a software application. /// /// This is just an alias for `Object` because there's no fields inherent to /// Application that aren't already present on an Object. pub type Application = Object; /// Represents a formal or informal collective of Actors. /// /// This is just an alias for `Object` because there's no fields inherent to /// Group that aren't already present on an Object. pub type Group = Object; /// Represents an organization. /// /// This is just an alias for `Object` because there's no fields inherent to /// Organization that aren't already present on an Object. pub type Organization = Object; /// Represents an individual person. /// /// This is just an alias for `Object` because there's no fields inherent to /// Person that aren't already present on an Object. pub type Person = Object; /// Represents a service of any kind. /// /// This is just an alias for `Object` because there's no fields inherent to /// Service that aren't already present on an Object. pub type Service = Object; /// Actor types are Object types that are capable of performing activities. /// /// This specification intentionally defines Actors in only the most generalized way, stopping /// short of defining semantically specific properties for each. All Actor objects are /// specializations of Object and inherit all of the core properties common to all Objects. /// External vocabularies can be used to express additional detail not covered by the Activity /// Vocabulary. VCard [vcard-rdf SHOULD be used to provide additional metadata for Person, Group, /// and Organization instances. /// /// While implementations are free to introduce new types of Actors beyond those defined by the /// Activity Vocabulary, interoperability issues can arise when applications rely too much on /// extension types that are not recognized by other implementations. Care should be taken to not /// unduly overlap with or duplicate the existing Actor types. /// /// When an implementation uses an extension type that overlaps with a core vocabulary type, the /// implementation MUST also specify the core vocabulary type. For instance, some vocabularies /// (e.g. VCard) define their own types for describing people. An implementation that wishes, for /// example, to use a vcard:Individual as an Actor MUST also identify that Actor as a Person. #[derive(Clone, Debug, serde::Deserialize, serde::Serialize, TypedBuilder)] #[serde(rename_all = "camelCase")] pub struct ApActor { /// A reference to an [ActivityStreams] OrderedCollection comprised of all the messages received by the actor. /// /// - Range: xsd:anyUri /// - Functional: true pub inbox: XsdAnyUri, /// An ActivityStreams] OrderedCollection comprised of all the messages produced by the actor. /// /// - Range: xsd:anyUri /// - Functional: true pub outbox: XsdAnyUri, /// A link to an [ActivityStreams] collection of the actors that this actor is following. /// /// - Range: xsd:anyUri /// - Functional: true #[serde(skip_serializing_if = "Option::is_none")] #[builder(default, setter(strip_option))] pub following: Option, /// A link to an [ActivityStreams] collection of the actors that follow this actor. /// /// - Range: xsd:anyUri /// - Functional: true #[serde(skip_serializing_if = "Option::is_none")] #[builder(default, setter(strip_option))] pub followers: Option, /// A link to an [ActivityStreams] collection of objects this actor has liked. /// /// - Range: xsd:anyUri /// - Functional: true #[serde(skip_serializing_if = "Option::is_none")] #[builder(default, setter(strip_option))] pub liked: Option, /// A list of supplementary Collections which may be of interest. /// /// - Range: xsd:anyUri /// - Functional: false #[serde(skip_serializing_if = "Option::is_none")] #[builder(default, setter(strip_option, into))] pub streams: Option>, /// A short username which may be used to refer to the actor, with no uniqueness guarantees. /// /// - Range: xsd:string /// - Functional: true #[serde(skip_serializing_if = "Option::is_none")] #[builder(default, setter(strip_option))] pub preferred_username: Option, /// A json object which maps additional (typically server/domain-wide) endpoints which may be /// useful either for this actor or someone referencing this actor. /// /// This mapping may be nested inside the actor document as the value or may be a link to a /// JSON-LD document with these properties. /// /// - Range: Endpoint /// - Functional: true #[serde(skip_serializing_if = "Option::is_none")] #[builder(default, setter(strip_option))] pub endpoints: Option, /// base fields and unparsed json ends up here #[serde(flatten)] pub inner: Inner, } /// A json object which maps additional (typically server/domain-wide) endpoints which may be /// useful either for this actor or someone referencing this actor. /// /// This mapping may be nested inside the actor document as the value or may be a link to a /// JSON-LD document with these properties. #[derive(Clone, Debug, Default, serde::Deserialize, serde::Serialize, TypedBuilder)] #[serde(rename_all = "camelCase")] pub struct Endpoints { /// Endpoint URI so this actor's clients may access remote ActivityStreams objects which /// require authentication to access. /// /// To use this endpoint, the client posts an x-www-form-urlencoded id parameter with the /// value being the id of the requested ActivityStreams object. /// /// - Range: anyUri /// - Functional: true #[serde(skip_serializing_if = "Option::is_none")] #[builder(default, setter(strip_option))] pub proxy_url: Option, /// If OAuth 2.0 bearer tokens [RFC6749](https://tools.ietf.org/html/rfc6749) /// [RFC6750](https://tools.ietf.org/html/rfc6750) are being used for authenticating client to /// server interactions, this endpoint specifies a URI at which a browser-authenticated user /// may obtain a new authorization grant. /// /// - Range: anyUri /// - Functional: true #[serde(skip_serializing_if = "Option::is_none")] #[builder(default, setter(strip_option))] pub oauth_authorization_endpoint: Option, /// If OAuth 2.0 bearer tokens [RFC6749](https://tools.ietf.org/html/rfc6749) /// [RFC6750](https://tools.ietf.org/html/rfc6750) are being used for authenticating client to /// server interactions, this endpoint specifies a URI at which a client may acquire an access /// token. /// /// - Range: anyUri /// - Functional: true #[serde(skip_serializing_if = "Option::is_none")] #[builder(default, setter(strip_option))] pub oauth_token_endpoint: Option, /// If Linked Data Signatures and HTTP Signatures are being used for authentication and /// authorization, this endpoint specifies a URI at which browser-authenticated users may /// authorize a client's public key for client to server interactions. /// /// - Range: anyUri /// - Functional: true #[serde(skip_serializing_if = "Option::is_none")] #[builder(default, setter(strip_option))] pub provide_client_key: Option, /// If Linked Data Signatures and HTTP Signatures are being used for authentication and /// authorization, this endpoint specifies a URI at which a client key may be signed by the /// actor's key for a time window to act on behalf of the actor in interacting with foreign /// servers. /// /// - Range: anyUri /// - Functional: true #[serde(skip_serializing_if = "Option::is_none")] #[builder(default, setter(strip_option))] pub sign_client_key: Option, /// An optional endpoint used for wide delivery of publicly addressed activities and /// activities sent to followers. /// /// shared_inbox endpoints SHOULD also be publicly readable OrderedCollection objects /// containing objects addressed to the Public special collection. Reading from the /// shared_inbox endpoint MUST NOT present objects which are not addressed to the Public /// endpoint. /// /// - Range: anyUri /// - Functional: true #[serde(skip_serializing_if = "Option::is_none")] #[builder(default, setter(strip_option))] pub shared_inbox: Option, } impl ApActor { /// Create a new ActivityPub Actor /// /// ```rust /// # fn main() -> Result<(), anyhow::Error> { /// use activitystreams_new::actor::{ApActor, Person}; /// /// let actor = ApActor::new( /// "https://example.com/inbox".parse()?, /// "https://example.com/outbox".parse()?, /// Person::new(), /// ); /// # Ok(()) /// # } /// ``` pub fn new(inbox: XsdAnyUri, outbox: XsdAnyUri, inner: Inner) -> Self where Inner: markers::Actor, { Self::builder() .inbox(inbox) .outbox(outbox) .inner(inner) .build() } fn extending(mut inner: Inner) -> Result where Inner: UnparsedMut + markers::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 where Inner: UnparsedMut + markers::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 markers::Actor for Application {} impl markers::Actor for Group {} impl markers::Actor for Organization {} impl markers::Actor for Person {} impl markers::Actor for Service {} impl markers::Base for ApActor where Inner: markers::Base {} impl markers::Object for ApActor where Inner: markers::Object {} impl markers::Actor for ApActor where Inner: markers::Actor {} impl Extends for ApActor where Inner: Extends + UnparsedMut + markers::Actor, Kind: serde::de::DeserializeOwned + serde::ser::Serialize, { type Error = serde_json::Error; fn extends(base: Base) -> Result { let inner = Inner::extends(base)?; Self::extending(inner) } fn retracts(self) -> Result, Self::Error> { let inner = self.retracting()?; inner.retracts() } } impl UnparsedMut for ApActor where Inner: UnparsedMut, { fn unparsed_mut(&mut self) -> &mut Unparsed { self.inner.unparsed_mut() } } impl AsBase for ApActor where Inner: AsBase, { fn base_ref(&self) -> &Base { self.inner.base_ref() } fn base_mut(&mut self) -> &mut Base { self.inner.base_mut() } } impl AsObject for ApActor where Inner: AsObject, { fn object_ref(&self) -> &Object { self.inner.object_ref() } fn object_mut(&mut self) -> &mut Object { self.inner.object_mut() } } impl AsApActor for ApActor where Inner: markers::Actor, { fn ap_actor_ref(&self) -> &ApActor { self } fn ap_actor_mut(&mut self) -> &mut ApActor { self } } impl AsApObject for ApActor where Inner1: AsApObject, { fn ap_object_ref(&self) -> &ApObject { self.inner.ap_object_ref() } fn ap_object_mut(&mut self) -> &mut ApObject { self.inner.ap_object_mut() } } impl ApActorExt for T where T: AsApActor {}