Bring in new properties derive

This commit is contained in:
Aode 2020-03-09 12:56:59 -05:00
parent d738c5e8fa
commit 62c8d245ff
13 changed files with 1361 additions and 998 deletions

View file

@ -10,7 +10,7 @@ keywords = ["activitystreams", "activitypub"]
edition = "2018" edition = "2018"
[dependencies] [dependencies]
activitystreams-traits = { version = "0.2", path = "activitystreams-traits" } activitystreams-traits = { version = "0.3", path = "activitystreams-traits" }
activitystreams-types = { version = "0.3.0", path = "activitystreams-types" } activitystreams-types = { version = "0.3.0", path = "activitystreams-types" }
[dev-dependencies] [dev-dependencies]
@ -18,7 +18,7 @@ anyhow = "1.0"
serde = "1.0" serde = "1.0"
serde_derive = "1.0" serde_derive = "1.0"
serde_json = "1.0" serde_json = "1.0"
activitystreams-derive = { version = "0.2", path = "activitystreams-derive" } activitystreams-derive = { version = "0.3", path = "activitystreams-derive" }
[workspace] [workspace]
members = [ members = [

View file

@ -1,7 +1,7 @@
[package] [package]
name = "activitystreams-derive" name = "activitystreams-derive"
description = "Derive macros for activitystreams" description = "Derive macros for activitystreams"
version = "0.2.0" version = "0.3.0"
license = "GPL-3.0" license = "GPL-3.0"
authors = ["asonix <asonix.dev@gmail.com>"] authors = ["asonix <asonix.dev@gmail.com>"]
repository = "https://git.asonix.dog/Aardwolf/activitystreams" repository = "https://git.asonix.dog/Aardwolf/activitystreams"
@ -15,7 +15,7 @@ syn = "1.0"
proc-macro2 = "1.0" proc-macro2 = "1.0"
[dev-dependencies] [dev-dependencies]
activitystreams-traits = { version = "0.2", path = "../activitystreams-traits" } activitystreams-traits = { version = "0.3", path = "../activitystreams-traits" }
serde = "1.0" serde = "1.0"
serde_derive = "1.0" serde_derive = "1.0"
serde_json = "1.0" serde_json = "1.0"

File diff suppressed because it is too large Load diff

View file

@ -1,7 +1,7 @@
[package] [package]
name = "activitystreams-traits" name = "activitystreams-traits"
description = "Traits for ActivityStreams objects" description = "Traits for ActivityStreams 2.0 objects"
version = "0.2.0" version = "0.3.0"
license = "GPL-3.0" license = "GPL-3.0"
authors = ["asonix <asonix.dev@gmail.com>"] authors = ["asonix <asonix.dev@gmail.com>"]
repository = "https://git.asonix.dog/Aardwolf/activitystreams" repository = "https://git.asonix.dog/Aardwolf/activitystreams"
@ -10,9 +10,8 @@ keywords = ["activitystreams", "activitypub"]
edition = "2018" edition = "2018"
[dependencies] [dependencies]
serde = "1.0"
serde_json = "1.0"
thiserror = "1.0" thiserror = "1.0"
typetag = "0.1.4"
[dev-dependencies] [dev-dependencies]
serde_derive = "1.0" serde = { version = "1.0", features = ["derive"] }

View file

@ -1,40 +0,0 @@
/*
* This file is part of ActivityStreams Traits.
*
* Copyright © 2018 Riley Trautman
*
* ActivityStreams Traits is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* ActivityStreams Traits is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with ActivityStreams Traits. If not, see <http://www.gnu.org/licenses/>.
*/
use std::result;
/// The Error type
#[derive(Copy, Clone, Debug, Eq, PartialEq, thiserror::Error)]
pub enum Error {
/// This error occurs when an Activity Streams type does not contain a requested value
#[error("Key not present")]
NotFound,
/// This error occurs when a requested value could not be deserialized into the requested type
#[error("Failed to deserialize data as requested type")]
Deserialize,
/// This error occurs when a provided item could not be serialized into an Activity Streams
/// type
#[error("Failed to serialize data")]
Serialize,
}
/// An alias for Result<T, Error>
pub type Result<T> = result::Result<T, Error>;

View file

@ -26,7 +26,7 @@
//! //!
//! ```rust //! ```rust
//! use activitystreams_traits::{Object, Actor}; //! use activitystreams_traits::{Object, Actor};
//! use serde_derive::{Deserialize, Serialize}; //! use serde::{Deserialize, Serialize};
//! //!
//! #[derive(Clone, Debug, Default, Deserialize, Serialize)] //! #[derive(Clone, Debug, Default, Deserialize, Serialize)]
//! #[serde(rename_all = "camelCase")] //! #[serde(rename_all = "camelCase")]
@ -38,7 +38,9 @@
//! kind: String, //! kind: String,
//! } //! }
//! //!
//! #[typetag::serde]
//! impl Object for Persona {} //! impl Object for Persona {}
//! #[typetag::serde]
//! impl Actor for Persona {} //! impl Actor for Persona {}
//! //!
//! # fn main() {} //! # fn main() {}
@ -47,14 +49,13 @@
mod activity; mod activity;
mod actor; mod actor;
mod collection; mod collection;
mod error;
mod link; mod link;
mod object; mod object;
pub mod properties;
pub use self::activity::*; pub use self::{
pub use self::actor::*; activity::{Activity, IntransitiveActivity},
pub use self::collection::*; actor::Actor,
pub use self::error::*; collection::{Collection, CollectionPage},
pub use self::link::*; link::Link,
pub use self::object::*; object::Object,
};

View file

@ -17,7 +17,7 @@
* along with ActivityStreams Traits. If not, see <http://www.gnu.org/licenses/>. * along with ActivityStreams Traits. If not, see <http://www.gnu.org/licenses/>.
*/ */
use serde::{de::DeserializeOwned, ser::Serialize}; use std::any::Any;
/// A Link is an indirect, qualified reference to a resource identified by a URL. /// A Link is an indirect, qualified reference to a resource identified by a URL.
/// ///
@ -27,4 +27,9 @@ use serde::{de::DeserializeOwned, ser::Serialize};
/// used, it establishes a qualified relation connecting the subject (the containing object) to the /// used, it establishes a qualified relation connecting the subject (the containing object) to the
/// resource identified by the href. Properties of the Link are properties of the reference as /// resource identified by the href. Properties of the Link are properties of the reference as
/// opposed to properties of the resource. /// opposed to properties of the resource.
pub trait Link: DeserializeOwned + Serialize {} #[typetag::serde(tag = "type")]
pub trait Link: std::fmt::Debug {
fn as_any(&self) -> &dyn Any;
fn as_any_mut(&mut self) -> &mut dyn Any;
}

View file

@ -17,11 +17,16 @@
* along with ActivityStreams Traits. If not, see <http://www.gnu.org/licenses/>. * along with ActivityStreams Traits. If not, see <http://www.gnu.org/licenses/>.
*/ */
use serde::{de::DeserializeOwned, ser::Serialize}; use std::any::Any;
/// Describes an object of any kind. /// Describes an object of any kind.
/// ///
/// The Object type serves as the base type for most of the other kinds of objects defined in the /// The Object type serves as the base type for most of the other kinds of objects defined in the
/// Activity Vocabulary, including other Core types such as `Activity`, `IntransitiveActivity`, /// Activity Vocabulary, including other Core types such as `Activity`, `IntransitiveActivity`,
/// `Collection` and `OrderedCollection`. /// `Collection` and `OrderedCollection`.
pub trait Object: DeserializeOwned + Serialize {} #[typetag::serde(tag = "type")]
pub trait Object: std::fmt::Debug {
fn as_any(&self) -> &dyn Any;
fn as_any_mut(&mut self) -> &mut dyn Any;
}

View file

@ -1,89 +0,0 @@
/*
* This file is part of ActivityStreams Traits.
*
* Copyright © 2018 Riley Trautman
*
* ActivityStreams Traits is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* ActivityStreams Traits is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with ActivityStreams Traits. If not, see <http://www.gnu.org/licenses/>.
*/
//! A module containing helpers for tranlsating common JSON representations to and from concrete
//! types
use serde::{de::DeserializeOwned, ser::Serialize};
use crate::error::{Error, Result};
/// Deserialize a `Value` into concrete type I
pub fn from_value<I>(item: &serde_json::Value) -> Result<I>
where
I: DeserializeOwned,
{
serde_json::from_value(item.clone()).map_err(|_| Error::Deserialize)
}
/// Serialize concrete type I into a `Value`
pub fn to_value<I>(item: I) -> Result<serde_json::Value>
where
I: Serialize,
{
serde_json::to_value(item).map_err(|_| Error::Serialize)
}
/// Deserialize an `Option<Value>` into concrete type I
pub fn from_item<I>(item: &Option<serde_json::Value>) -> Result<I>
where
I: DeserializeOwned,
{
if let &Some(ref item) = item {
from_value(item)
} else {
Err(Error::NotFound)
}
}
/// Serialize concrete type I into an `Option<Value>`
pub fn to_item<I>(item: I) -> Result<Option<serde_json::Value>>
where
I: Serialize,
{
to_value(item).map(Some)
}
/// Deserialize a `Vec<Value>` into a `Vec<I>`
pub fn from_vec<I>(v: &Vec<serde_json::Value>) -> Result<Vec<I>>
where
I: DeserializeOwned,
{
v.iter().fold(Ok(Vec::new()), |acc, item| match acc {
Ok(mut acc) => from_value(item).map(|item| {
acc.push(item);
acc
}),
e => e,
})
}
/// Serialize a `Vec<I>` into a `Vec<Value>`
pub fn to_vec<I>(v: Vec<I>) -> Result<Vec<serde_json::Value>>
where
I: Serialize,
{
v.into_iter().fold(Ok(Vec::new()), |acc, item| match acc {
Ok(mut acc) => to_value(item).map(|item| {
acc.push(item);
acc
}),
e => e,
})
}

View file

@ -11,13 +11,13 @@ edition = "2018"
[dependencies] [dependencies]
thiserror = "1.0.11" thiserror = "1.0.11"
activitystreams-derive = { version = "0.2", path = "../activitystreams-derive" } activitystreams-derive = { version = "0.3", path = "../activitystreams-derive" }
activitystreams-traits = { version = "0.2", path = "../activitystreams-traits" } activitystreams-traits = { version = "0.3", path = "../activitystreams-traits" }
chrono = { version = "0.4", features = ["serde"] } chrono = { version = "0.4", features = ["serde"] }
mime = "0.3" mime = "0.3"
serde = "1.0" serde = { version = "1.0", features = ["derive"] }
serde_derive = "1.0"
serde_json = "1.0" serde_json = "1.0"
typetag = "0.1.4"
[dev-dependencies] [dev-dependencies]
anyhow = "1.0" anyhow = "1.0"

View file

@ -59,3 +59,47 @@ impl LinkExt for Mention {
&mut self.link_props &mut self.link_props
} }
} }
#[derive(Clone, Debug, Deserialize, Serialize)]
#[serde(transparent)]
pub struct LinkBox(pub Box<dyn Link>);
impl LinkBox {
pub fn is<T>(&self) -> bool
where
T: Link,
{
self.0.as_any().is::<T>()
}
pub fn downcast_ref<T>(&self) -> Option<&T>
where
T: Link,
{
self.0.as_any().downcast_ref()
}
pub fn downcast_mut<T>(&mut self) -> Option<&mut T>
where
T: Link,
{
self.0.as_any_mut().downcast_mut()
}
pub fn downcast<T>(self) -> Option<T>
where
T: Link,
{
let any: Box<dyn Any> = self;
any.downcast()
}
}
impl<T> From<T> for LinkBox
where
T: Link,
{
fn from(t: T) -> Self {
LinkBox(Box::new(t))
}
}

View file

@ -182,7 +182,7 @@ pub struct Place {
/// `Actor` Type objects. /// `Actor` Type objects.
/// ///
/// The `describes` property is used to reference the object being described by the profile. /// The `describes` property is used to reference the object being described by the profile.
#[derive(Clone, Debug, Default, Deserialize, Serialize, PropRefs, Properties)] #[derive(Clone, Debug, Default, Deserialize, PropRefs, Serialize)]
#[serde(rename_all = "camelCase")] #[serde(rename_all = "camelCase")]
pub struct Profile { pub struct Profile {
#[serde(rename = "type")] #[serde(rename = "type")]
@ -215,7 +215,7 @@ pub struct Profile {
/// individuals that are directly connected within a person's social graph. Suppose we have a user, /// individuals that are directly connected within a person's social graph. Suppose we have a user,
/// Sally, with direct relationships to users Joe and Jane. Sally follows Joe's updates while Sally /// Sally, with direct relationships to users Joe and Jane. Sally follows Joe's updates while Sally
/// and Jane have a mutual relationship. /// and Jane have a mutual relationship.
#[derive(Clone, Debug, Default, Deserialize, Serialize, Properties, PropRefs)] #[derive(Clone, Debug, Default, Deserialize, PropRefs, Serialize)]
#[serde(rename_all = "camelCase")] #[serde(rename_all = "camelCase")]
pub struct Relationship { pub struct Relationship {
#[serde(rename = "type")] #[serde(rename = "type")]
@ -271,3 +271,63 @@ pub struct Video {
#[activitystreams(Object)] #[activitystreams(Object)]
pub object_props: ObjectProperties, pub object_props: ObjectProperties,
} }
#[derive(Clone, Debug, Deserialize, Serialize)]
#[serde(transparent)]
pub struct ImageBox(pub Box<Image>);
#[derive(Clone, Debug, Deserialize, Serialize)]
#[serde(transparent)]
pub struct ObjectBox(pub Box<dyn Object>);
impl ObjectBox {
pub fn is<T>(&self) -> bool
where
T: Object,
{
self.0.as_any().is::<T>()
}
pub fn downcast_ref<T>(&self) -> Option<&T>
where
T: Object,
{
self.0.as_any().downcast_ref()
}
pub fn downcast_mut<T>(&mut self) -> Option<&mut T>
where
T: Object,
{
self.0.as_any_mut().downcast_mut()
}
pub fn downcast<T>(self) -> Option<T>
where
T: Object,
{
let any: Box<dyn Any> = self;
any.downcast()
}
}
impl From<Image> for ImageBox {
fn from(i: Image) -> Self {
ImageBox(Box::new(i))
}
}
impl From<ImageBox> for Image {
fn from(i: ImageBox) -> Self {
*i.0
}
}
impl<T> From<T> for ObjectBox
where
T: Object,
{
fn from(t: T) -> Self {
ObjectBox(Box::new(t))
}
}

View file

@ -32,7 +32,7 @@
//! #[serde(rename = "type")] //! #[serde(rename = "type")]
//! pub kind: String, //! pub kind: String,
//! //!
//! /// Define a require property for the MyObject type //! /// Define a required property for the MyObject type
//! pub my_property: String, //! pub my_property: String,
//! //!
//! #[serde(flatten)] //! #[serde(flatten)]
@ -44,15 +44,16 @@
//! # fn main() {} //! # fn main() {}
//! ``` //! ```
use activitystreams_derive::Properties; use activitystreams_derive::properties;
use activitystreams_traits::{Collection, Error, Link, Object, Result}; use activitystreams_traits::{Collection, Error, Link, Object, Result};
use chrono::{offset::Utc, DateTime}; use chrono::{offset::Utc, DateTime};
use serde_derive::{Deserialize, Serialize}; use serde_derive::{Deserialize, Serialize};
use crate::object::Image; use crate::{
link::LinkBox,
/// Alias chrono::DateTime<Utc> for use in derive macros object::{Image, ObjectBox},
pub type UtcTime = DateTime<Utc>; primitives::*,
};
/// Define all the properties of the Object base type as described by the Activity Streams /// Define all the properties of the Object base type as described by the Activity Streams
/// vocabulary. /// vocabulary.
@ -66,417 +67,546 @@ pub type UtcTime = DateTime<Utc>;
/// own `type` properties as Unit Structs with custom serde behaviour. /// own `type` properties as Unit Structs with custom serde behaviour.
/// ///
/// All properties are optional (including the id and type). /// All properties are optional (including the id and type).
#[derive(Clone, Debug, Default, Deserialize, Serialize, Properties)] properties! {
#[serde(rename_all = "camelCase")] Object {
pub struct ObjectProperties { id {
// TODO: IRI type /// Provides the globally unique identifier for an Object or Link.
/// Provides the globally unique identifier for an Object or Link. ///
/// /// The `id` property is expressed as an absolute IRI in the spec, but for now is represented
/// The `id` property is expressed as an absolute IRI in the spec, but for now is represented /// as a string.
/// as a string. ///
/// /// - Range: `xsd:anyUri`
/// - Range: `anyUri` /// - Functional: true
/// - Functional: true types [
#[serde(skip_serializing_if = "Option::is_none")] XsdAnyUri,
#[serde(alias = "@id")] ],
#[activitystreams(concrete(String), functional)] functional,
pub id: Option<serde_json::Value>, },
/// Identifies a resource attached or related to an object that potentially requires special attachment {
/// handling. /// Identifies a resource attached or related to an object that potentially requires special
/// /// handling.
/// The intent is to provide a model that is at least semantically similar to attachments in ///
/// email. /// The intent is to provide a model that is at least semantically similar to attachments in
/// /// email.
/// - Range: `Object` | `Link` ///
/// - Functional: false /// - Range: `Object` | `Link`
#[serde(skip_serializing_if = "Option::is_none")] /// - Functional: false
#[activitystreams(ab(Object, Link), concrete(String))] types [
pub attachment: Option<serde_json::Value>, XsdAnyUri,
ObjectBox,
LinkBox,
],
},
/// Identifies one or more entities to which this object is attributed. attributed_to {
/// /// Identifies one or more entities to which this object is attributed.
/// The attributed entities might not be Actors. For instance, an object might be attributed to ///
/// the completion of another activity. /// The attributed entities might not be Actors. For instance, an object might be attributed to
/// /// the completion of another activity.
/// - Range: `Object` | `Link` ///
/// - Functional: false /// - Range: `Object` | `Link`
#[serde(skip_serializing_if = "Option::is_none")] /// - Functional: false
#[activitystreams(ab(Object, Link), concrete(String))] types [
pub attributed_to: Option<serde_json::Value>, XsdAnyUri,
ObjectBox,
LinkBox,
],
},
/// Identifies one or more entities that represent the total population of entities for which audience {
/// the object can considered to be relevant. /// Identifies one or more entities that represent the total population of entities for which
/// /// the object can considered to be relevant.
/// - Range: `Object` | `Link` ///
/// - Functional: false /// - Range: `Object` | `Link`
#[serde(skip_serializing_if = "Option::is_none")] /// - Functional: false
#[activitystreams(ab(Object, Link), concrete(String))] types [
pub audience: Option<serde_json::Value>, XsdAnyUri,
ObjectBox,
LinkBox,
],
},
// TODO: rdf:langString content {
/// The content or textual representation of the Object encoded as a JSON string. /// 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 /// By default, the value of content is HTML. The mediaType property can be used in the object
/// to indicate a different content type. /// 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.
/// ///
/// - Range: `xsd:string` | `rdf:langString` /// - Range: `xsd:string` | `rdf:langString`
/// - Functional: false /// - Functional: false
#[serde(skip_serializing_if = "Option::is_none")] types [
#[activitystreams(concrete(String))] XsdString,
pub content: Option<serde_json::Value>, RdfLangString,
],
},
/// Identifies the context within which the object exists or an activity was performed. context {
/// /// Identifies the context within which the object exists or an activity was performed.
/// 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 notion of "context" used is intentionally vague. The intended function is to serve as a
/// An example could be all activities relating to a common project or event. /// 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.
/// - Range: `Object` | `Link` ///
/// - Functional: false /// - Range: `Object` | `Link`
#[serde(skip_serializing_if = "Option::is_none", rename = "@context")] /// - Functional: false
#[activitystreams(ab(Object, Link), concrete(String))] types [
pub context: Option<serde_json::Value>, XsdAnyUri,
ObjectBox,
LinkBox,
],
},
// TODO: rdf:langString name {
/// A simple, human-readable, plain-text name for the object. /// 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 /// HTML markup MUST NOT be included. The name MAY be expressed using multiple language-tagged
/// values. /// values.
/// ///
/// - Range: `xsd:string` | `rdf:langString` /// - Range: `xsd:string` | `rdf:langString`
/// - Functional: false /// - Functional: false
#[serde(skip_serializing_if = "Option::is_none")] types [
#[serde(alias = "displayName")] XsdString,
#[activitystreams(concrete(String))] RdfLangString,
pub name: Option<serde_json::Value>, ],
alias("displayName"),
},
/// The date and time describing the actual or expected ending time of the object. end_time {
/// /// 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.
/// - Range: `xsd:dateTime` ///
/// - Functional: true /// - Range: `xsd:dateTime`
#[serde(skip_serializing_if = "Option::is_none")] /// - Functional: true
#[activitystreams(concrete(String, UtcTime), functional)] types [
pub end_time: Option<serde_json::Value>, XsdDateTime,
],
functional,
},
/// Identifies the entity (e.g. an application) that generated the object. generator {
/// /// Identifies the entity (e.g. an application) that generated the object.
/// - Range: `Object` | `Link` ///
/// - Functional: false /// - Range: `Object` | `Link`
#[serde(skip_serializing_if = "Option::is_none")] /// - Functional: false
#[activitystreams(ab(Object, Link), concrete(String))] types [
pub generator: Option<serde_json::Value>, XsdAnyUri,
ObjectBox,
LinkBox,
],
},
/// Indicates an entity that describes an icon for this object. icon {
/// /// Indicates an entity that describes an icon for this object.
/// The image should have an aspect ratio of one (horizontal) to one (vertical) and should be ///
/// suitable for presentation at a small size. /// The image should have an aspect ratio of one (horizontal) to one (vertical) and should be
/// /// suitable for presentation at a small size.
/// - Range: `Image` | `Link` ///
/// - Functional: false /// - Range: `Image` | `Link`
#[serde(skip_serializing_if = "Option::is_none")] /// - Functional: false
#[activitystreams(ab(Object, Link), concrete(Image, String))] types [
pub icon: Option<serde_json::Value>, XsdAnyUri,
ImageBox,
LinkBox,
],
},
/// Indicates an entity that describes an image for this object. image {
/// /// Indicates an entity that describes an image for this object.
/// Unlike the icon property, there are no aspect ratio or display size limitations assumed. ///
/// /// Unlike the icon property, there are no aspect ratio or display size limitations assumed.
/// - Range: `Image` | `Link` ///
/// - Functional: false /// - Range: `Image` | `Link`
#[serde(skip_serializing_if = "Option::is_none")] /// - Functional: false
#[activitystreams(ab(Object, Link), concrete(Image, String))] types [
pub image: Option<serde_json::Value>, XsdAnyUri,
ImageBox,
LinkBox,
],
},
/// Indicates one or more entities for which this object is considered a response. in_reply_to {
/// /// Indicates one or more entities for which this object is considered a response.
/// - Range: `Object` | `Link` ///
/// - Functional: false /// - Range: `Object` | `Link`
#[serde(skip_serializing_if = "Option::is_none")] /// - Functional: false
#[activitystreams(ab(Object, Link), concrete(String))] types [
pub in_reply_to: Option<serde_json::Value>, XsdAnyUri,
ObjectBox,
LinkBox,
],
},
/// Indicates one or more physical or logical locations associated with the object. location {
/// /// Indicates one or more physical or logical locations associated with the object.
/// - Range: `Object` | `Link` ///
/// - Functional: false /// - Range: `Object` | `Link`
#[serde(skip_serializing_if = "Option::is_none")] /// - Functional: false
#[activitystreams(ab(Object, Link), concrete(String))] types [
pub location: Option<serde_json::Value>, XsdAnyUri,
ObjectBox,
LinkBox,
],
},
/// Identifies an entity that provides a preview of this object. preview {
/// /// Identifies an entity that provides a preview of this object.
/// - Range: `Object` | `Link` ///
/// - Functional: false /// - Range: `Object` | `Link`
#[serde(skip_serializing_if = "Option::is_none")] /// - Functional: false
#[activitystreams(ab(Object, Link), concrete(String))] types [
pub preview: Option<serde_json::Value>, XsdAnyUri,
ObjectBox,
LinkBox,
],
},
/// The date and time at which the object was published. published {
/// /// The date and time at which the object was published.
/// - Range: `xsd:dateTime` ///
/// - Functional: true /// - Range: `xsd:dateTime`
#[serde(skip_serializing_if = "Option::is_none")] /// - Functional: true
#[activitystreams(concrete(String, UtcTime), functional)] types [
pub published: Option<serde_json::Value>, XsdDateTime,
],
functional,
},
/// Identifies a `Collection` containing objects considered to be responses to this object. replies {
/// /// Identifies a `Collection` containing objects considered to be responses to this object.
/// - Range: `Object` | `Link` ///
/// - Functional: false /// - Range: `Object` | `Link`
#[serde(skip_serializing_if = "Option::is_none")] /// - Functional: false
#[activitystreams(ab(Collection), concrete(String), functional)] types [
pub replies: Option<serde_json::Value>, XsdAnyUri,
ObjectBox,
LinkBox,
],
},
/// The date and time describing the actual or expected starting time of the object. start_time {
/// /// The date and time describing the actual or expected starting time of the object.
/// When used with an `Activity` object, for instance, the `start_time` property specifies the ///
/// moment the activity began or is scheduled to begin. /// When used with an `Activity` object, for instance, the `start_time` property specifies the
/// /// moment the activity began or is scheduled to begin.
/// - Range: `Object` | `Link` ///
/// - Functional: true /// - Range: `xsd:DateTime`
#[serde(skip_serializing_if = "Option::is_none")] /// - Functional: true
#[activitystreams(concrete(String, UtcTime), functional)] types [
pub start_time: Option<serde_json::Value>, XsdDateTime,
],
functional,
},
// TODO: rdf:langString summary {
/// A natural language summarization of the object encoded as HTML. /// A natural language summarization of the object encoded as HTML.
/// ///
/// Multiple language tagged summaries MAY be provided. /// Multiple language tagged summaries MAY be provided.
/// ///
/// - Range: `xsd:string` | `rdf:langString` /// - Range: `xsd:string` | `rdf:langString`
/// - Functional: false /// - Functional: false
#[serde(skip_serializing_if = "Option::is_none")] types [
#[activitystreams(concrete(String))] XsdString,
pub summary: Option<serde_json::Value>, RdfLangString,
],
},
/// One or more "tags" that have been associated with an objects. A tag can be any kind of tag {
/// `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.
/// - Range: `Object` | `Link` ///
/// - Functional: false /// - Range: `Object` | `Link`
#[serde(skip_serializing_if = "Option::is_none")] /// - Functional: false
#[activitystreams(ab(Object, Link), concrete(String))] types [
pub tag: Option<serde_json::Value>, XsdAnyUri,
ObjectBox,
LinkBox,
],
},
/// The date and time at which the object was updated, updated {
/// /// The date and time at which the object was updated,
/// - Range: `xsd:dateTime` ///
/// - Functional: true /// - Range: `xsd:dateTime`
#[serde(skip_serializing_if = "Option::is_none")] /// - Functional: true
#[activitystreams(concrete(String, UtcTime), functional)] types [
pub updated: Option<serde_json::Value>, XsdDateTime,
],
functional,
},
/// Identifies one or more links to representations of the object. url {
/// /// Identifies one or more links to representations of the object.
/// - Range: `xsd:anyUri` | `Link` ///
/// - Functional: false /// - Range: `xsd:anyUri` | `Link`
#[serde(skip_serializing_if = "Option::is_none")] /// - Functional: false
#[activitystreams(concrete(String), ab(Link))] types [
pub url: Option<serde_json::Value>, XsdAnyUri,
LinkBox,
],
},
/// Identifies an entity considered to be part of the public primary audience of an `Object`. to {
/// /// Identifies an entity considered to be part of the public primary audience of an `Object`.
/// - Range: `Object` | `Link` ///
/// - Functional: false /// - Range: `Object` | `Link`
#[serde(skip_serializing_if = "Option::is_none")] /// - Functional: false
#[activitystreams(ab(Object, Link), concrete(String))] types [
pub to: Option<serde_json::Value>, XsdAnyUri,
ObjectBox,
LinkBox,
],
},
/// Identifies an `Object` that is part of the private primary audience of this `Object`. bto {
/// /// Identifies an `Object` that is part of the private primary audience of this `Object`.
/// - Range: `Object` | `Link` ///
/// - Functional: false /// - Range: `Object` | `Link`
#[serde(skip_serializing_if = "Option::is_none")] /// - Functional: false
#[activitystreams(ab(Object, Link), concrete(String))] types [
pub bto: Option<serde_json::Value>, XsdAnyUri,
ObjectBox,
LinkBox,
],
},
/// Identifies an `Object` that is part of the public secondary audience of this `Object`. cc {
/// /// Identifies an `Object` that is part of the public secondary audience of this `Object`.
/// - Range: `Object` | `Link` ///
/// - Functional: false /// - Range: `Object` | `Link`
#[serde(skip_serializing_if = "Option::is_none")] /// - Functional: false
#[activitystreams(ab(Object, Link), concrete(String))] types [
pub cc: Option<serde_json::Value>, XsdAnyUri,
ObjectBox,
LinkBox,
],
},
/// Identifies one or more `Objects` that are part of the private secondary audience of this bcc {
/// `Object`. /// Identifies one or more `Objects` that are part of the private secondary audience of this
/// /// `Object`.
/// - Range: `Object` | `Link` ///
/// - Functional: false /// - Range: `Object` | `Link`
#[serde(skip_serializing_if = "Option::is_none")] /// - Functional: false
#[activitystreams(ab(Object, Link), concrete(String))] types [
pub bcc: Option<serde_json::Value>, XsdAnyUri,
ObjectBox,
LinkBox,
],
},
/// When used on an `Object`, identifies the MIME media type of the value of the content media_type {
/// 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.
/// - Range: `Mime Media Type` ///
/// - Functional: true /// - Range: `Mime Media Type`
#[serde(skip_serializing_if = "Option::is_none")] /// - Functional: true
#[activitystreams(concrete(String), functional)] types [
pub media_type: Option<serde_json::Value>, MimeMediaType,
],
functional,
},
// TODO: xsd:duration duration {
/// When the object describes a time-bound resource, such as an audio or video, a meeting, etc, /// 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 duration property indicates the object's approximate duration.
/// ///
/// The value MUST be expressed as an xsd:duration as defined by /// The value MUST be expressed as an xsd:duration as defined by
/// [[xmlschema11-2](https://www.w3.org/TR/xmlschema11-2/)], section /// [[xmlschema11-2](https://www.w3.org/TR/xmlschema11-2/)], section
/// 3.3.6 (e.g. a period of 5 seconds is represented as "PT5S"). /// 3.3.6 (e.g. a period of 5 seconds is represented as "PT5S").
/// ///
/// - Range: `xsd:duration` /// - Range: `xsd:duration`
/// - Functional: true /// - Functional: true
#[serde(skip_serializing_if = "Option::is_none")] types [
#[activitystreams(concrete(String), functional)] XsdDuration,
pub duration: Option<serde_json::Value>, ],
} functional,
},
impl ObjectProperties {
/// Fetch a typed `Mime` struct from the `media_type` field.
pub fn media_type(&self) -> Result<mime::Mime> {
self.media_type_string()
.and_then(|s| s.parse().map_err(|_| Error::Deserialize))
} }
} }
/// Define all the properties of the Location type as described by the Activity Streams vocabulary. /// Define all the properties of the Location type as described by the Activity Streams vocabulary.
#[derive(Clone, Debug, Default, Deserialize, Serialize, Properties)] properties! {
#[serde(rename_all = "camelCase")] Place {
pub struct PlaceProperties { accuracy {
/// Indicates the accuracy of position coordinates on a `Place` objects. /// Indicates the accuracy of position coordinates on a `Place` objects.
/// ///
/// Expressed in properties of percentage. e.g. "94.0" means "94.0% accurate". /// Expressed in properties of percentage. e.g. "94.0" means "94.0% accurate".
/// ///
/// - Range: `xsd:float` [>= 0.0f, <= 100.0f] /// - Range: `xsd:float` [>= 0.0f, <= 100.0f]
/// - Functional: true /// - Functional: true
#[serde(skip_serializing_if = "Option::is_none")] types [
#[activitystreams(concrete(f64), functional)] XsdFloat,
pub accuracy: Option<serde_json::Value>, ],
functional,
},
/// Indicates the altitude of a place. The measurement units is indicated using the units altitude {
/// property. /// Indicates the altitude of a place. The measurement units is indicated using the units
/// /// property.
/// If units is not specified, the default is assumed to be "m" indicating meters. ///
/// /// If units is not specified, the default is assumed to be "m" indicating meters.
/// - Range: `xsd:float` ///
/// - Functional: true /// - Range: `xsd:float`
#[serde(skip_serializing_if = "Option::is_none")] /// - Functional: true
#[activitystreams(concrete(f64), functional)] types [
pub altitude: Option<serde_json::Value>, XsdFloat,
],
functional,
},
/// The latitude of a place. latitude {
/// /// The latitude of a place.
/// - Range: `xsd:float` ///
/// - Functional: true /// - Range: `xsd:float`
#[serde(skip_serializing_if = "Option::is_none")] /// - Functional: true
#[activitystreams(concrete(f64), functional)] types [
pub latitude: Option<serde_json::Value>, XsdFloat,
],
functional,
}
/// The longitude of a place. logitude {
/// /// The longitude of a place.
/// - Range: `xsd:float` ///
/// - Functional: true /// - Range: `xsd:float`
#[serde(skip_serializing_if = "Option::is_none")] /// - Functional: true
#[activitystreams(concrete(f64), functional)] types [
pub longitude: Option<serde_json::Value>, XsdFloat,
],
functional,
},
/// The radius from the given latitude and longitude for a Place. radius {
/// /// The radius from the given latitude and longitude for a Place.
/// The units is expressed by the units property. If units is not specified, the default is ///
/// assumed to be "m" indicating "meters". /// The units is expressed by the units property. If units is not specified, the default is
/// /// assumed to be "m" indicating "meters".
/// - Range: `xsd:float` ///
/// - Functional: true /// - Range: `xsd:float`
#[serde(skip_serializing_if = "Option::is_none")] /// - Functional: true
#[activitystreams(concrete(f64), functional)] types [
pub radius: Option<serde_json::Value>, XsdFloat,
],
functional,
},
/// Specifies the measurement units for the radius and altitude properties on a `Place` object. units {
/// /// Specifies the measurement units for the radius and altitude properties on a `Place` object.
/// If not specified, the default is assumed to be "m" for "meters". ///
/// /// If not specified, the default is assumed to be "m" for "meters".
/// - Range: `xsd:float` ///
/// - Functional: true /// TODO: encode rage as any of `"cm"` | `"feet"` | `"inches"` | `"km"` | `"m"` | `xsd:anyUri`
#[serde(skip_serializing_if = "Option::is_none")] /// - Range: `xsd:anyUri` | `xsd:string`
#[activitystreams(concrete(String), functional)] /// - Functional: true
pub units: Option<serde_json::Value>, types [
XsdAnyUri,
XsdString,
],
functional,
},
}
} }
/// Define all the properties of the Profile type as described by the Activity Streams vocabulary. /// Define all the properties of the Profile type as described by the Activity Streams vocabulary.
#[derive(Clone, Debug, Default, Deserialize, Serialize, Properties)] properties! {
#[serde(rename_all = "camelCase")] Profile {
pub struct ProfileProperties { describes {
/// On a `Profile` object, the describes property identifies the object described by the /// On a `Profile` object, the describes property identifies the object described by the
/// `Profile`. /// `Profile`.
/// ///
/// - Range: `Object` /// - Range: `Object`
/// - Functional: true /// - Functional: true
#[activitystreams(ab(Object), concrete(String), functional)] types [
pub describes: serde_json::Value, XsdAnyUri,
ObjectBox,
],
functional,
},
}
} }
/// Define all the properties of the Relationship type as described by the Activity Streams /// Define all the properties of the Relationship type as described by the Activity Streams
/// vocabulary. /// vocabulary.
#[derive(Clone, Debug, Default, Deserialize, Serialize, Properties)] properties! {
#[serde(rename_all = "camelCase")] Relationship {
pub struct RelationshipProperties { subject {
/// On a `Relationship` object, the subject property identifies one of the connected /// On a `Relationship` object, the subject property identifies one of the connected
/// individuals. /// individuals.
/// ///
/// For instance, for a `Relationship` object describing "John is related to Sally", subject /// For instance, for a `Relationship` object describing "John is related to Sally", subject
/// would refer to John. /// would refer to John.
/// ///
/// - Range: `Object` | `Link` /// - Range: `Object` | `Link`
/// - Functional: true /// - Functional: true
#[activitystreams(ab(Object, Link), concrete(String), functional)] types [
subject: serde_json::Value, XsdAnyUri,
ObjectBox,
LinkBox,
],
functional,
},
/// When used within a `Relationship` describes the entity to which the subject is related. object {
/// /// When used within a `Relationship` describes the entity to which the subject is related.
/// - Range: `Object` | `Link` ///
/// - Functional: false /// - Range: `Object` | `Link`
#[activitystreams(ab(Object, Link), concrete(String))] /// - Functional: false
object: serde_json::Value, types [
XsdAnyUri,
ObjectBox,
LinkBox,
],
},
/// On a `Relationship` object, the relationship property identifies the kind of relationship relationship {
/// that exists between subject and object. /// On a `Relationship` object, the relationship property identifies the kind of relationship
/// /// that exists between subject and object.
/// - Range: `Object` ///
/// - Functional: false /// - Range: `Object`
#[activitystreams(ab(Object), concrete(String))] /// - Functional: false
relationship: serde_json::Value, types [
XsdAnyUri,
ObjectBox,
],
},
}
} }
/// Define all the properties of the Tombstone type as described by the Activity Streams vocabulary. /// Define all the properties of the Tombstone type as described by the Activity Streams vocabulary.
#[derive(Clone, Debug, Default, Deserialize, Serialize, Properties)] properties! {
#[serde(rename_all = "camelCase")] Tombstone {
pub struct TombstoneProperties { former_type {
/// On a `Tombstone` object, the formerType property identifies the type of the object that was /// On a `Tombstone` object, the formerType property identifies the type of the object that was
/// deleted. /// deleted.
/// ///
/// - Range: `Object` /// - Range: `Object`
/// - Functional: false /// - Functional: false
#[serde(skip_serializing_if = "Option::is_none")] types [
#[activitystreams(ab(Object), concrete(String))] XsdAnyUri,
pub former_type: Option<serde_json::Value>, ObjectBox,
],
},
/// On a `Tombstone` object, the deleted property is a timestamp for when the object was deleted {
/// deleted. /// On a `Tombstone` object, the deleted property is a timestamp for when the object was
/// /// deleted.
/// - Range: `xsd:dateTime` ///
/// - Functional: true /// - Range: `xsd:dateTime`
#[serde(skip_serializing_if = "Option::is_none")] /// - Functional: true
#[activitystreams(concrete(String, UtcTime), functional)] types [
pub deleted: Option<serde_json::Value>, XsdDateTime,
],
functional,
},
}
} }