feat(apb): all owned by default

references are cool but it was mostly cloned anyway so may aswell be
consistent. it would be awesome to make a Node which works by references
eventually, so it can be Copy, but probably quite annoying to make
This commit is contained in:
əlemi 2024-11-20 19:19:20 +01:00
parent f7e1a1bbc0
commit 0dedb4d243
Signed by: alemi
GPG key ID: A4895B84D311642C
8 changed files with 110 additions and 118 deletions

View file

@ -3,16 +3,3 @@
pub struct FieldErr(pub &'static str); pub struct FieldErr(pub &'static str);
pub type Field<T> = Result<T, FieldErr>; pub type Field<T> = Result<T, FieldErr>;
// TODO this trait is really ad-hoc and has awful naming...
pub trait OptionalString {
fn str(self) -> Option<String>;
}
impl OptionalString for Field<&str> {
fn str(self) -> Option<String> {
self.ok().map(|x| x.to_string())
}
}

View file

@ -1,32 +1,32 @@
// TODO technically this is not part of ActivityStreams // TODO technically this is not part of ActivityStreams
pub trait PublicKey : super::Base { pub trait PublicKey : super::Base {
fn owner(&self) -> crate::Field<&str> { Err(crate::FieldErr("owner")) } fn owner(&self) -> crate::Field<String> { Err(crate::FieldErr("owner")) }
fn public_key_pem(&self) -> &str; fn public_key_pem(&self) -> String;
} }
pub trait PublicKeyMut : super::BaseMut { pub trait PublicKeyMut : super::BaseMut {
fn set_owner(self, val: Option<&str>) -> Self; fn set_owner(self, val: Option<String>) -> Self;
fn set_public_key_pem(self, val: &str) -> Self; fn set_public_key_pem(self, val: String) -> Self;
} }
#[cfg(feature = "unstructured")] #[cfg(feature = "unstructured")]
impl PublicKey for serde_json::Value { impl PublicKey for serde_json::Value {
crate::getter! { owner -> &str } crate::getter! { owner -> String }
fn public_key_pem(&self) -> &str { fn public_key_pem(&self) -> String {
self.get("publicKeyPem").map(|x| x.as_str().unwrap_or_default()).unwrap_or_default() self.get("publicKeyPem").and_then(|x| x.as_str()).unwrap_or_default().to_string()
} }
} }
#[cfg(feature = "unstructured")] #[cfg(feature = "unstructured")]
impl PublicKeyMut for serde_json::Value { impl PublicKeyMut for serde_json::Value {
crate::setter! { owner -> &str } crate::setter! { owner -> String }
fn set_public_key_pem(mut self, val: &str) -> Self { fn set_public_key_pem(mut self, val: String) -> Self {
self.as_object_mut().unwrap().insert( self.as_object_mut().unwrap().insert(
"publicKeyPem".to_string(), "publicKeyPem".to_string(),
serde_json::Value::String(val.to_string()), serde_json::Value::String(val),
); );
self self
} }

View file

@ -137,11 +137,12 @@ macro_rules! getter {
} }
}; };
($name:ident -> &str) => { ($name:ident -> String) => {
paste::paste! { paste::paste! {
fn [< $name:snake >](&self) -> $crate::Field<&str> { fn [< $name:snake >](&self) -> $crate::Field<String> {
self.get(stringify!($name)) self.get(stringify!($name))
.and_then(|x| x.as_str()) .and_then(|x| x.as_str())
.map(|x| x.to_string())
.ok_or($crate::FieldErr(stringify!($name))) .ok_or($crate::FieldErr(stringify!($name)))
} }
} }
@ -225,11 +226,11 @@ macro_rules! setter {
} }
}; };
($name:ident -> &str) => { ($name:ident -> String) => {
paste::item! { paste::item! {
fn [< set_$name:snake >](mut self, val: Option<&str>) -> Self { fn [< set_$name:snake >](mut self, val: Option<String>) -> Self {
$crate::macros::set_maybe_value( $crate::macros::set_maybe_value(
&mut self, stringify!($name), val.map(|x| serde_json::Value::String(x.to_string())) &mut self, stringify!($name), val.map(|x| serde_json::Value::String(x))
); );
self self
} }

View file

@ -113,7 +113,7 @@ impl<T : super::Base> Node<T> {
} }
/// returns id of object: url for link, id for object, None if empty or array /// returns id of object: url for link, id for object, None if empty or array
pub fn id(&self) -> crate::Field<&str> { pub fn id(&self) -> crate::Field<String> {
match self { match self {
Node::Empty => Err(crate::FieldErr("id")), Node::Empty => Err(crate::FieldErr("id")),
Node::Link(uri) => uri.href(), Node::Link(uri) => uri.href(),

View file

@ -9,20 +9,20 @@ crate::strenum! {
} }
pub trait Base : crate::macros::MaybeSend { pub trait Base : crate::macros::MaybeSend {
fn id(&self) -> crate::Field<&str> { Err(crate::FieldErr("id")) } fn id(&self) -> crate::Field<String> { Err(crate::FieldErr("id")) }
fn base_type(&self) -> crate::Field<BaseType> { Err(crate::FieldErr("type")) } fn base_type(&self) -> crate::Field<BaseType> { Err(crate::FieldErr("type")) }
} }
pub trait BaseMut : crate::macros::MaybeSend { pub trait BaseMut : crate::macros::MaybeSend {
fn set_id(self, val: Option<&str>) -> Self; fn set_id(self, val: Option<String>) -> Self;
fn set_base_type(self, val: Option<BaseType>) -> Self; fn set_base_type(self, val: Option<BaseType>) -> Self;
} }
impl Base for String { impl Base for String {
fn id(&self) -> crate::Field<&str> { fn id(&self) -> crate::Field<String> {
Ok(self) Ok(self.clone())
} }
fn base_type(&self) -> crate::Field<BaseType> { fn base_type(&self) -> crate::Field<BaseType> {
@ -43,12 +43,13 @@ impl Base for serde_json::Value {
} }
} }
fn id(&self) -> crate::Field<&str> { fn id(&self) -> crate::Field<String> {
if self.is_string() { if self.is_string() {
Ok(self.as_str().ok_or(crate::FieldErr("id"))?) Ok(self.as_str().ok_or(crate::FieldErr("id"))?.to_string())
} else { } else {
self.get("id") self.get("id")
.and_then(|x| x.as_str()) .and_then(|x| x.as_str())
.map(|x| x.to_string())
.ok_or(crate::FieldErr("id")) .ok_or(crate::FieldErr("id"))
} }
} }
@ -56,6 +57,6 @@ impl Base for serde_json::Value {
#[cfg(feature = "unstructured")] #[cfg(feature = "unstructured")]
impl BaseMut for serde_json::Value { impl BaseMut for serde_json::Value {
crate::setter! { id -> &str } crate::setter! { id -> String }
crate::setter! { base_type -> type BaseType } crate::setter! { base_type -> type BaseType }
} }

View file

@ -19,79 +19,82 @@ crate::strenum! {
pub trait Link : crate::Base { pub trait Link : crate::Base {
fn link_type(&self) -> Field<LinkType> { Err(FieldErr("type")) } fn link_type(&self) -> Field<LinkType> { Err(FieldErr("type")) }
fn href(&self) -> Field<&str>; fn href(&self) -> Field<String>;
fn rel(&self) -> Field<&str> { Err(FieldErr("rel")) } fn rel(&self) -> Field<String> { Err(FieldErr("rel")) }
fn media_type(&self) -> Field<&str> { Err(FieldErr("mediaType")) } // also in obj fn media_type(&self) -> Field<String> { Err(FieldErr("mediaType")) } // also in obj
fn name(&self) -> Field<&str> { Err(FieldErr("name")) } // also in obj fn name(&self) -> Field<String> { Err(FieldErr("name")) } // also in obj
fn hreflang(&self) -> Field<&str> { Err(FieldErr("hreflang")) } fn hreflang(&self) -> Field<String> { Err(FieldErr("hreflang")) }
fn height(&self) -> Field<u64> { Err(FieldErr("height")) } fn height(&self) -> Field<u64> { Err(FieldErr("height")) }
fn width(&self) -> Field<u64> { Err(FieldErr("width")) } fn width(&self) -> Field<u64> { Err(FieldErr("width")) }
fn preview(&self) -> Field<&str> { Err(FieldErr("linkPreview")) } // also in obj fn preview(&self) -> Field<String> { Err(FieldErr("linkPreview")) } // also in obj
} }
pub trait LinkMut : crate::BaseMut { pub trait LinkMut : crate::BaseMut {
fn set_link_type(self, val: Option<LinkType>) -> Self; fn set_link_type(self, val: Option<LinkType>) -> Self;
fn set_href(self, href: Option<&str>) -> Self; fn set_href(self, href: Option<String>) -> Self;
fn set_rel(self, val: Option<&str>) -> Self; fn set_rel(self, val: Option<String>) -> Self;
fn set_media_type(self, val: Option<&str>) -> Self; // also in obj fn set_media_type(self, val: Option<String>) -> Self; // also in obj
fn set_name(self, val: Option<&str>) -> Self; // also in obj fn set_name(self, val: Option<String>) -> Self; // also in obj
fn set_hreflang(self, val: Option<&str>) -> Self; fn set_hreflang(self, val: Option<String>) -> Self;
fn set_height(self, val: Option<u64>) -> Self; fn set_height(self, val: Option<u64>) -> Self;
fn set_width(self, val: Option<u64>) -> Self; fn set_width(self, val: Option<u64>) -> Self;
fn set_preview(self, val: Option<&str>) -> Self; // also in obj fn set_preview(self, val: Option<String>) -> Self; // also in obj
} }
impl Link for String { impl Link for String {
fn href(&self) -> Field<&str> { fn href(&self) -> Field<String> {
Ok(self) Ok(self.to_string())
} }
} }
#[cfg(feature = "unstructured")] #[cfg(feature = "unstructured")]
impl Link for serde_json::Value { impl Link for serde_json::Value {
// TODO this can fail, but it should never do! // TODO this can fail, but it should never do!
fn href(&self) -> Field<&str> { fn href(&self) -> Field<String> {
if self.is_string() { if self.is_string() {
self.as_str().ok_or(FieldErr("href")) self.as_str().map(|x| x.to_string()).ok_or(FieldErr("href"))
} else { } else {
self.get("href").and_then(|x| x.as_str()).ok_or(FieldErr("href")) self.get("href")
.and_then(|x| x.as_str())
.map(|x| x.to_string())
.ok_or(FieldErr("href"))
} }
} }
crate::getter! { link_type -> type LinkType } crate::getter! { link_type -> type LinkType }
crate::getter! { rel -> &str } crate::getter! { rel -> String }
crate::getter! { mediaType -> &str } crate::getter! { mediaType -> String }
crate::getter! { name -> &str } crate::getter! { name -> String }
crate::getter! { hreflang -> &str } crate::getter! { hreflang -> String }
crate::getter! { height -> u64 } crate::getter! { height -> u64 }
crate::getter! { width -> u64 } crate::getter! { width -> u64 }
crate::getter! { preview -> &str } crate::getter! { preview -> String }
} }
#[cfg(feature = "unstructured")] #[cfg(feature = "unstructured")]
impl LinkMut for serde_json::Value { impl LinkMut for serde_json::Value {
fn set_href(mut self, href: Option<&str>) -> Self { fn set_href(mut self, href: Option<String>) -> Self {
match &mut self { match &mut self {
serde_json::Value::Object(map) => { serde_json::Value::Object(map) => {
match href { match href {
Some(href) => map.insert( Some(href) => map.insert(
"href".to_string(), "href".to_string(),
serde_json::Value::String(href.to_string()) serde_json::Value::String(href)
), ),
None => map.remove("href"), None => map.remove("href"),
}; };
}, },
x => *x = serde_json::Value::String(href.unwrap_or_default().to_string()), x => *x = serde_json::Value::String(href.unwrap_or_default()),
} }
self self
} }
crate::setter! { link_type -> type LinkType } crate::setter! { link_type -> type LinkType }
crate::setter! { rel -> &str } crate::setter! { rel -> String }
crate::setter! { mediaType -> &str } crate::setter! { mediaType -> String }
crate::setter! { name -> &str } crate::setter! { name -> String }
crate::setter! { hreflang -> &str } crate::setter! { hreflang -> String }
crate::setter! { height -> u64 } crate::setter! { height -> u64 }
crate::setter! { width -> u64 } crate::setter! { width -> u64 }
crate::setter! { preview -> &str } crate::setter! { preview -> String }
} }

View file

@ -16,7 +16,7 @@ pub trait Actor : Object {
fn actor_type(&self) -> Field<ActorType> { Err(FieldErr("type")) } fn actor_type(&self) -> Field<ActorType> { Err(FieldErr("type")) }
/// A short username which may be used to refer to the actor, with no uniqueness guarantees. /// A short username which may be used to refer to the actor, with no uniqueness guarantees.
fn preferred_username(&self) -> Field<&str> { Err(FieldErr("preferredUsername")) } fn preferred_username(&self) -> Field<String> { Err(FieldErr("preferredUsername")) }
/// A reference to an [ActivityStreams] OrderedCollection comprised of all the messages received by the actor; see 5.2 Inbox. /// A reference to an [ActivityStreams] OrderedCollection comprised of all the messages received by the actor; see 5.2 Inbox.
fn inbox(&self) -> Node<Self::Collection>; fn inbox(&self) -> Node<Self::Collection>;
/// An [ActivityStreams] OrderedCollection comprised of all the messages produced by the actor; see 5.1 Outbox. /// An [ActivityStreams] OrderedCollection comprised of all the messages produced by the actor; see 5.1 Outbox.
@ -64,17 +64,17 @@ pub trait Actor : Object {
pub trait Endpoints : Object { pub trait Endpoints : Object {
/// 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. /// 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.
fn proxy_url(&self) -> Field<&str> { Err(FieldErr("proxyUrl")) } fn proxy_url(&self) -> Field<String> { Err(FieldErr("proxyUrl")) }
/// If OAuth 2.0 bearer tokens [RFC6749] [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. /// If OAuth 2.0 bearer tokens [RFC6749] [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.
fn oauth_authorization_endpoint(&self) -> Field<&str> { Err(FieldErr("oauthAuthorizationEndpoint")) } fn oauth_authorization_endpoint(&self) -> Field<String> { Err(FieldErr("oauthAuthorizationEndpoint")) }
/// If OAuth 2.0 bearer tokens [RFC6749] [RFC6750] are being used for authenticating client to server interactions, this endpoint specifies a URI at which a client may acquire an access token. /// If OAuth 2.0 bearer tokens [RFC6749] [RFC6750] are being used for authenticating client to server interactions, this endpoint specifies a URI at which a client may acquire an access token.
fn oauth_token_endpoint(&self) -> Field<&str> { Err(FieldErr("oauthTokenEndpoint")) } fn oauth_token_endpoint(&self) -> Field<String> { Err(FieldErr("oauthTokenEndpoint")) }
/// 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. /// 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.
fn provide_client_key(&self) -> Field<&str> { Err(FieldErr("provideClientKey")) } fn provide_client_key(&self) -> Field<String> { Err(FieldErr("provideClientKey")) }
/// 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. /// 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.
fn sign_client_key(&self) -> Field<&str> { Err(FieldErr("signClientKey")) } fn sign_client_key(&self) -> Field<String> { Err(FieldErr("signClientKey")) }
/// An optional endpoint used for wide delivery of publicly addressed activities and activities sent to followers. sharedInbox endpoints SHOULD also be publicly readable OrderedCollection objects containing objects addressed to the Public special collection. Reading from the sharedInbox endpoint MUST NOT present objects which are not addressed to the Public endpoint. /// An optional endpoint used for wide delivery of publicly addressed activities and activities sent to followers. sharedInbox endpoints SHOULD also be publicly readable OrderedCollection objects containing objects addressed to the Public special collection. Reading from the sharedInbox endpoint MUST NOT present objects which are not addressed to the Public endpoint.
fn shared_inbox(&self) -> Field<&str> { Err(FieldErr("sharedInbox")) } fn shared_inbox(&self) -> Field<String> { Err(FieldErr("sharedInbox")) }
} }
pub trait ActorMut : ObjectMut { pub trait ActorMut : ObjectMut {
@ -82,7 +82,7 @@ pub trait ActorMut : ObjectMut {
type Endpoints : Endpoints; type Endpoints : Endpoints;
fn set_actor_type(self, val: Option<ActorType>) -> Self; fn set_actor_type(self, val: Option<ActorType>) -> Self;
fn set_preferred_username(self, val: Option<&str>) -> Self; fn set_preferred_username(self, val: Option<String>) -> Self;
fn set_inbox(self, val: Node<Self::Collection>) -> Self; fn set_inbox(self, val: Node<Self::Collection>) -> Self;
fn set_outbox(self, val: Node<Self::Collection>) -> Self; fn set_outbox(self, val: Node<Self::Collection>) -> Self;
fn set_following(self, val: Node<Self::Collection>) -> Self; fn set_following(self, val: Node<Self::Collection>) -> Self;
@ -122,17 +122,17 @@ pub trait ActorMut : ObjectMut {
pub trait EndpointsMut : ObjectMut { pub trait EndpointsMut : ObjectMut {
/// 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. /// 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.
fn set_proxy_url(self, val: Option<&str>) -> Self; fn set_proxy_url(self, val: Option<String>) -> Self;
/// If OAuth 2.0 bearer tokens [RFC6749] [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. /// If OAuth 2.0 bearer tokens [RFC6749] [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.
fn set_oauth_authorization_endpoint(self, val: Option<&str>) -> Self; fn set_oauth_authorization_endpoint(self, val: Option<String>) -> Self;
/// If OAuth 2.0 bearer tokens [RFC6749] [RFC6750] are being used for authenticating client to server interactions, this endpoint specifies a URI at which a client may acquire an access token. /// If OAuth 2.0 bearer tokens [RFC6749] [RFC6750] are being used for authenticating client to server interactions, this endpoint specifies a URI at which a client may acquire an access token.
fn set_oauth_token_endpoint(self, val: Option<&str>) -> Self; fn set_oauth_token_endpoint(self, val: Option<String>) -> Self;
/// 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. /// 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.
fn set_provide_client_key(self, val: Option<&str>) -> Self; fn set_provide_client_key(self, val: Option<String>) -> Self;
/// 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. /// 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.
fn set_sign_client_key(self, val: Option<&str>) -> Self; fn set_sign_client_key(self, val: Option<String>) -> Self;
/// An optional endpoint used for wide delivery of publicly addressed activities and activities sent to followers. sharedInbox endpoints SHOULD also be publicly readable OrderedCollection objects containing objects addressed to the Public special collection. Reading from the sharedInbox endpoint MUST NOT present objects which are not addressed to the Public endpoint. /// An optional endpoint used for wide delivery of publicly addressed activities and activities sent to followers. sharedInbox endpoints SHOULD also be publicly readable OrderedCollection objects containing objects addressed to the Public special collection. Reading from the sharedInbox endpoint MUST NOT present objects which are not addressed to the Public endpoint.
fn set_shared_inbox(self, val: Option<&str>) -> Self; fn set_shared_inbox(self, val: Option<String>) -> Self;
} }
#[cfg(feature = "unstructured")] #[cfg(feature = "unstructured")]
@ -141,7 +141,7 @@ impl Actor for serde_json::Value {
type Endpoints = serde_json::Value; type Endpoints = serde_json::Value;
crate::getter! { actorType -> type ActorType } crate::getter! { actorType -> type ActorType }
crate::getter! { preferredUsername -> &str } crate::getter! { preferredUsername -> String }
crate::getter! { inbox -> node Self::Collection } crate::getter! { inbox -> node Self::Collection }
crate::getter! { outbox -> node Self::Collection } crate::getter! { outbox -> node Self::Collection }
crate::getter! { following -> node Self::Collection } crate::getter! { following -> node Self::Collection }
@ -181,12 +181,12 @@ impl Actor for serde_json::Value {
#[cfg(feature = "unstructured")] #[cfg(feature = "unstructured")]
impl Endpoints for serde_json::Value { impl Endpoints for serde_json::Value {
crate::getter! { proxyUrl -> &str } crate::getter! { proxyUrl -> String }
crate::getter! { oauthAuthorizationEndpoint -> &str } crate::getter! { oauthAuthorizationEndpoint -> String }
crate::getter! { oauthTokenEndpoint -> &str } crate::getter! { oauthTokenEndpoint -> String }
crate::getter! { provideClientKey -> &str } crate::getter! { provideClientKey -> String }
crate::getter! { signClientKey -> &str } crate::getter! { signClientKey -> String }
crate::getter! { sharedInbox -> &str } crate::getter! { sharedInbox -> String }
} }
#[cfg(feature = "unstructured")] #[cfg(feature = "unstructured")]
@ -195,7 +195,7 @@ impl ActorMut for serde_json::Value {
type Endpoints = serde_json::Value; type Endpoints = serde_json::Value;
crate::setter! { actor_type -> type ActorType } crate::setter! { actor_type -> type ActorType }
crate::setter! { preferredUsername -> &str } crate::setter! { preferredUsername -> String }
crate::setter! { inbox -> node Self::Collection } crate::setter! { inbox -> node Self::Collection }
crate::setter! { outbox -> node Self::Collection } crate::setter! { outbox -> node Self::Collection }
crate::setter! { following -> node Self::Collection } crate::setter! { following -> node Self::Collection }
@ -236,10 +236,10 @@ impl ActorMut for serde_json::Value {
#[cfg(feature = "unstructured")] #[cfg(feature = "unstructured")]
impl EndpointsMut for serde_json::Value { impl EndpointsMut for serde_json::Value {
crate::setter! { proxyUrl -> &str } crate::setter! { proxyUrl -> String }
crate::setter! { oauthAuthorizationEndpoint -> &str } crate::setter! { oauthAuthorizationEndpoint -> String }
crate::setter! { oauthTokenEndpoint -> &str } crate::setter! { oauthTokenEndpoint -> String }
crate::setter! { provideClientKey -> &str } crate::setter! { provideClientKey -> String }
crate::setter! { signClientKey -> &str } crate::setter! { signClientKey -> String }
crate::setter! { sharedInbox -> &str } crate::setter! { sharedInbox -> String }
} }

View file

@ -52,14 +52,14 @@ pub trait Object : Base {
/// The content or textual representation of the Object encoded as a JSON string. By default, the value of content is HTML /// The content or textual representation of the Object encoded as a JSON string. By default, the value of content is HTML
/// The mediaType property can be used in the object to indicate a different content type /// The mediaType property can be used in the object to indicate a different content type
/// The content MAY be expressed using multiple language-tagged values /// The content MAY be expressed using multiple language-tagged values
fn content(&self) -> Field<&str> { Err(FieldErr("content")) } // TODO handle language maps fn content(&self) -> Field<String> { Err(FieldErr("content")) } // TODO handle language maps
/// Identifies the context within which the object exists or an activity was performed /// Identifies the context within which the object exists or an activity was performed
/// The notion of "context" used is intentionally vague /// The notion of "context" used is intentionally vague
/// The intended function is to serve as a means of grouping objects and activities that share a common originating context or purpose /// The intended function is to serve as a means of grouping objects and activities that share a common originating context or purpose
/// An example could be all activities relating to a common project or event /// An example could be all activities relating to a common project or event
fn context(&self) -> Node<Self::Object> { Node::Empty } fn context(&self) -> Node<Self::Object> { Node::Empty }
/// A simple, human-readable, plain-text name for the object. HTML markup MUST NOT be included. The name MAY be expressed using multiple language-tagged values /// A simple, human-readable, plain-text name for the object. HTML markup MUST NOT be included. The name MAY be expressed using multiple language-tagged values
fn name(&self) -> Field<&str> { Err(FieldErr("name")) } // also in link // TODO handle language maps fn name(&self) -> Field<String> { Err(FieldErr("name")) } // also in link // TODO handle language maps
/// The date and time describing the actual or expected ending time of the object /// The date and time describing the actual or expected ending time of the object
/// When used with an Activity object, for instance, the endTime property specifies the moment the activity concluded or is expected to conclude. /// When used with an Activity object, for instance, the endTime property specifies the moment the activity concluded or is expected to conclude.
fn end_time(&self) -> Field<chrono::DateTime<chrono::Utc>> { Err(FieldErr("endTime")) } fn end_time(&self) -> Field<chrono::DateTime<chrono::Utc>> { Err(FieldErr("endTime")) }
@ -89,7 +89,7 @@ pub trait Object : Base {
/// When used with an Activity object, for instance, the startTime property specifies the moment the activity began or is scheduled to begin. /// When used with an Activity object, for instance, the startTime property specifies the moment the activity began or is scheduled to begin.
fn start_time(&self) -> Field<chrono::DateTime<chrono::Utc>> { Err(FieldErr("startTime")) } fn start_time(&self) -> Field<chrono::DateTime<chrono::Utc>> { Err(FieldErr("startTime")) }
/// A natural language summarization of the object encoded as HTML. Multiple language tagged summaries MAY be provided /// A natural language summarization of the object encoded as HTML. Multiple language tagged summaries MAY be provided
fn summary(&self) -> Field<&str> { Err(FieldErr("summary")) } fn summary(&self) -> Field<String> { Err(FieldErr("summary")) }
/// One or more "tags" that have been associated with an objects. A tag can be any kind of Object /// One or more "tags" that have been associated with an objects. A tag can be any kind of Object
/// The key difference between attachment and tag is that the former implies association by inclusion, while the latter implies associated by reference /// The key difference between attachment and tag is that the former implies association by inclusion, while the latter implies associated by reference
// TODO technically this is an object? but spec says that it works my reference, idk // TODO technically this is an object? but spec says that it works my reference, idk
@ -107,10 +107,10 @@ pub trait Object : Base {
/// When used on a Link, identifies the MIME media type of the referenced resource. /// When used on a Link, identifies the MIME media type of the referenced resource.
/// When used on an Object, identifies the MIME media type of the value of the content property. /// When used on an Object, identifies the MIME media type of the value of the content property.
/// If not specified, the content property is assumed to contain text/html content. /// If not specified, the content property is assumed to contain text/html content.
fn media_type(&self) -> Field<&str> { Err(FieldErr("mediaType")) } // also in link fn media_type(&self) -> Field<String> { Err(FieldErr("mediaType")) } // also in link
/// When the object describes a time-bound resource, such as an audio or video, a meeting, etc, the duration property indicates the object's approximate duration. /// When the object describes a time-bound resource, such as an audio or video, a meeting, etc, the duration property indicates the object's approximate duration.
/// The value MUST be expressed as an xsd:duration as defined by [ xmlschema11-2], section 3.3.6 (e.g. a period of 5 seconds is represented as "PT5S"). /// The value MUST be expressed as an xsd:duration as defined by [ xmlschema11-2], section 3.3.6 (e.g. a period of 5 seconds is represented as "PT5S").
fn duration(&self) -> Field<&str> { Err(FieldErr("duration")) } // TODO how to parse xsd:duration ? fn duration(&self) -> Field<String> { Err(FieldErr("duration")) } // TODO how to parse xsd:duration ?
#[cfg(feature = "activitypub-miscellaneous-terms")] #[cfg(feature = "activitypub-miscellaneous-terms")]
fn sensitive(&self) -> Field<bool> { Err(FieldErr("sensitive")) } fn sensitive(&self) -> Field<bool> { Err(FieldErr("sensitive")) }
@ -129,7 +129,7 @@ pub trait Object : Base {
fn as_document(&self) -> Result<&Self::Document, FieldErr> { Err(FieldErr("type")) } fn as_document(&self) -> Result<&Self::Document, FieldErr> { Err(FieldErr("type")) }
#[cfg(feature = "did-core")] // TODO this isn't from did-core actually!?!?!?!?! #[cfg(feature = "did-core")] // TODO this isn't from did-core actually!?!?!?!?!
fn value(&self) -> Field<&str> { Err(FieldErr("value")) } fn value(&self) -> Field<String> { Err(FieldErr("value")) }
} }
pub trait ObjectMut : BaseMut { pub trait ObjectMut : BaseMut {
@ -143,9 +143,9 @@ pub trait ObjectMut : BaseMut {
fn set_attachment(self, val: Node<Self::Object>) -> Self; fn set_attachment(self, val: Node<Self::Object>) -> Self;
fn set_attributed_to(self, val: Node<Self::Actor>) -> Self; fn set_attributed_to(self, val: Node<Self::Actor>) -> Self;
fn set_audience(self, val: Node<Self::Actor>) -> Self; fn set_audience(self, val: Node<Self::Actor>) -> Self;
fn set_content(self, val: Option<&str>) -> Self; // TODO handle language maps fn set_content(self, val: Option<String>) -> Self; // TODO handle language maps
fn set_context(self, val: Node<Self::Object>) -> Self; fn set_context(self, val: Node<Self::Object>) -> Self;
fn set_name(self, val: Option<&str>) -> Self; // also in link // TODO handle language maps fn set_name(self, val: Option<String>) -> Self; // also in link // TODO handle language maps
fn set_end_time(self, val: Option<chrono::DateTime<chrono::Utc>>) -> Self; fn set_end_time(self, val: Option<chrono::DateTime<chrono::Utc>>) -> Self;
fn set_generator(self, val: Node<Self::Actor>) -> Self; fn set_generator(self, val: Node<Self::Actor>) -> Self;
fn set_icon(self, val: Node<Self::Document>) -> Self; fn set_icon(self, val: Node<Self::Document>) -> Self;
@ -159,15 +159,15 @@ pub trait ObjectMut : BaseMut {
fn set_likes(self, val: Node<Self::Collection>) -> Self; fn set_likes(self, val: Node<Self::Collection>) -> Self;
fn set_shares(self, val: Node<Self::Collection>) -> Self; fn set_shares(self, val: Node<Self::Collection>) -> Self;
fn set_start_time(self, val: Option<chrono::DateTime<chrono::Utc>>) -> Self; fn set_start_time(self, val: Option<chrono::DateTime<chrono::Utc>>) -> Self;
fn set_summary(self, val: Option<&str>) -> Self; fn set_summary(self, val: Option<String>) -> Self;
fn set_tag(self, val: Node<Self::Object>) -> Self; fn set_tag(self, val: Node<Self::Object>) -> Self;
fn set_url(self, val: Node<Self::Link>) -> Self; fn set_url(self, val: Node<Self::Link>) -> Self;
fn set_to(self, val: Node<Self::Link>) -> Self; fn set_to(self, val: Node<Self::Link>) -> Self;
fn set_bto(self, val: Node<Self::Link>) -> Self; fn set_bto(self, val: Node<Self::Link>) -> Self;
fn set_cc(self, val: Node<Self::Link>) -> Self; fn set_cc(self, val: Node<Self::Link>) -> Self;
fn set_bcc(self, val: Node<Self::Link>) -> Self; fn set_bcc(self, val: Node<Self::Link>) -> Self;
fn set_media_type(self, val: Option<&str>) -> Self; // also in link fn set_media_type(self, val: Option<String>) -> Self; // also in link
fn set_duration(self, val: Option<&str>) -> Self; // TODO how to parse xsd:duration ? fn set_duration(self, val: Option<String>) -> Self; // TODO how to parse xsd:duration ?
#[cfg(feature = "activitypub-miscellaneous-terms")] #[cfg(feature = "activitypub-miscellaneous-terms")]
fn set_sensitive(self, val: Option<bool>) -> Self; fn set_sensitive(self, val: Option<bool>) -> Self;
@ -181,7 +181,7 @@ pub trait ObjectMut : BaseMut {
fn set_conversation(self, val: Node<Self::Object>) -> Self; fn set_conversation(self, val: Node<Self::Object>) -> Self;
#[cfg(feature = "did-core")] // TODO this isn't from did-core actually!?!?!?!?! #[cfg(feature = "did-core")] // TODO this isn't from did-core actually!?!?!?!?!
fn set_value(self, val: Option<&str>) -> Self; fn set_value(self, val: Option<String>) -> Self;
} }
#[cfg(feature = "unstructured")] #[cfg(feature = "unstructured")]
@ -197,9 +197,9 @@ impl Object for serde_json::Value {
crate::getter! { attachment -> node <Self as Object>::Object } crate::getter! { attachment -> node <Self as Object>::Object }
crate::getter! { attributedTo -> node Self::Actor } crate::getter! { attributedTo -> node Self::Actor }
crate::getter! { audience -> node Self::Actor } crate::getter! { audience -> node Self::Actor }
crate::getter! { content -> &str } crate::getter! { content -> String }
crate::getter! { context -> node <Self as Object>::Object } crate::getter! { context -> node <Self as Object>::Object }
crate::getter! { name -> &str } crate::getter! { name -> String }
crate::getter! { endTime -> chrono::DateTime<chrono::Utc> } crate::getter! { endTime -> chrono::DateTime<chrono::Utc> }
crate::getter! { generator -> node Self::Actor } crate::getter! { generator -> node Self::Actor }
crate::getter! { icon -> node Self::Document } crate::getter! { icon -> node Self::Document }
@ -213,14 +213,14 @@ impl Object for serde_json::Value {
crate::getter! { likes -> node Self::Collection } crate::getter! { likes -> node Self::Collection }
crate::getter! { shares -> node Self::Collection } crate::getter! { shares -> node Self::Collection }
crate::getter! { startTime -> chrono::DateTime<chrono::Utc> } crate::getter! { startTime -> chrono::DateTime<chrono::Utc> }
crate::getter! { summary -> &str } crate::getter! { summary -> String }
crate::getter! { tag -> node <Self as Object>::Object } crate::getter! { tag -> node <Self as Object>::Object }
crate::getter! { to -> node Self::Link } crate::getter! { to -> node Self::Link }
crate::getter! { bto -> node Self::Link } crate::getter! { bto -> node Self::Link }
crate::getter! { cc -> node Self::Link } crate::getter! { cc -> node Self::Link }
crate::getter! { bcc -> node Self::Link } crate::getter! { bcc -> node Self::Link }
crate::getter! { mediaType -> &str } crate::getter! { mediaType -> String }
crate::getter! { duration -> &str } crate::getter! { duration -> String }
crate::getter! { url -> node Self::Link } crate::getter! { url -> node Self::Link }
#[cfg(feature = "activitypub-miscellaneous-terms")] #[cfg(feature = "activitypub-miscellaneous-terms")]
@ -235,7 +235,7 @@ impl Object for serde_json::Value {
crate::getter! { conversation -> node <Self as Object>::Object } crate::getter! { conversation -> node <Self as Object>::Object }
#[cfg(feature = "did-core")] // TODO this isn't from did-core actually!?!?!?!?! #[cfg(feature = "did-core")] // TODO this isn't from did-core actually!?!?!?!?!
crate::getter! { value -> &str } crate::getter! { value -> String }
fn as_activity(&self) -> Result<&Self::Activity, FieldErr> { fn as_activity(&self) -> Result<&Self::Activity, FieldErr> {
match self.object_type()? { match self.object_type()? {
@ -278,9 +278,9 @@ impl ObjectMut for serde_json::Value {
crate::setter! { attachment -> node <Self as Object>::Object } crate::setter! { attachment -> node <Self as Object>::Object }
crate::setter! { attributedTo -> node Self::Actor } crate::setter! { attributedTo -> node Self::Actor }
crate::setter! { audience -> node Self::Actor } crate::setter! { audience -> node Self::Actor }
crate::setter! { content -> &str } crate::setter! { content -> String }
crate::setter! { context -> node <Self as Object>::Object } crate::setter! { context -> node <Self as Object>::Object }
crate::setter! { name -> &str } crate::setter! { name -> String }
crate::setter! { endTime -> chrono::DateTime<chrono::Utc> } crate::setter! { endTime -> chrono::DateTime<chrono::Utc> }
crate::setter! { generator -> node Self::Actor } crate::setter! { generator -> node Self::Actor }
crate::setter! { icon -> node Self::Document } crate::setter! { icon -> node Self::Document }
@ -294,14 +294,14 @@ impl ObjectMut for serde_json::Value {
crate::setter! { likes -> node Self::Collection } crate::setter! { likes -> node Self::Collection }
crate::setter! { shares -> node Self::Collection } crate::setter! { shares -> node Self::Collection }
crate::setter! { startTime -> chrono::DateTime<chrono::Utc> } crate::setter! { startTime -> chrono::DateTime<chrono::Utc> }
crate::setter! { summary -> &str } crate::setter! { summary -> String }
crate::setter! { tag -> node <Self as Object>::Object } crate::setter! { tag -> node <Self as Object>::Object }
crate::setter! { to -> node Self::Link } crate::setter! { to -> node Self::Link }
crate::setter! { bto -> node Self::Link} crate::setter! { bto -> node Self::Link}
crate::setter! { cc -> node Self::Link } crate::setter! { cc -> node Self::Link }
crate::setter! { bcc -> node Self::Link } crate::setter! { bcc -> node Self::Link }
crate::setter! { mediaType -> &str } crate::setter! { mediaType -> String }
crate::setter! { duration -> &str } crate::setter! { duration -> String }
crate::setter! { url -> node Self::Link } crate::setter! { url -> node Self::Link }
#[cfg(feature = "activitypub-miscellaneous-terms")] #[cfg(feature = "activitypub-miscellaneous-terms")]
@ -316,5 +316,5 @@ impl ObjectMut for serde_json::Value {
crate::setter! { conversation -> node <Self as Object>::Object } crate::setter! { conversation -> node <Self as Object>::Object }
#[cfg(feature = "did-core")] // TODO this isn't from did-core actually!?!?!?!?! #[cfg(feature = "did-core")] // TODO this isn't from did-core actually!?!?!?!?!
crate::setter! { value -> &str } crate::setter! { value -> String }
} }