Document Link, most of Collection

This commit is contained in:
asonix 2018-05-13 19:53:01 -05:00
parent b9a92f0066
commit bf4df5f760
8 changed files with 303 additions and 59 deletions

View file

@ -17,81 +17,103 @@
* along with ActivityStreams. If not, see <http://www.gnu.org/licenses/>.
*/
use serde_json;
use object::{properties::ObjectProperties, Object};
use link::Link;
use object::Object;
pub mod kind;
pub mod properties;
use self::kind::*;
use self::properties::*;
mod kind;
mod properties;
pub use self::kind::*;
pub use self::properties::*;
/// A Collection is a subtype of `Object` that represents ordered or unordered sets of `Object` or
/// `Link` instances.
pub trait Collection: Object {}
pub trait CollectionPage: Object {}
#[derive(Clone, Debug, Default, Deserialize, Serialize, Properties)]
#[serde(rename_all = "camelCase")]
pub struct Collection {
pub struct UnorderedCollection {
#[serde(rename = "type")]
kind: CollectionType,
#[activitystreams(ab(Object, Link))]
items: Vec<serde_json::Value>,
/// Adds all valid object properties to this struct
#[serde(flatten)]
pub object_props: ObjectProperties,
/// Adds all valid collection properties to this struct
#[serde(flatten)]
pub collection_props: CollectionProperties,
}
impl Object for Collection {}
impl Object for UnorderedCollection {}
impl Collection for UnorderedCollection {}
/// A subtype of `Collection` in which members of the logical collection are assumed to always be
/// strictly ordered.
#[derive(Clone, Debug, Default, Deserialize, Serialize, Properties)]
#[serde(rename_all = "camelCase")]
pub struct OrderedCollection {
#[serde(rename = "type")]
kind: OrderedCollectionType,
#[activitystreams(ab(Object, Link))]
items: Vec<serde_json::Value>,
/// Adds all valid object properties to this struct
#[serde(flatten)]
pub object_props: ObjectProperties,
/// Adds all valid collection properties to this struct
#[serde(flatten)]
pub collection_props: CollectionProperties,
}
impl Object for OrderedCollection {}
impl Collection for OrderedCollection {}
/// Used to represent distinct subsets of items from a `Collection`.
#[derive(Clone, Debug, Default, Deserialize, Serialize, Properties)]
#[serde(rename_all = "camelCase")]
pub struct CollectionPage {
pub struct UnorderedCollectionPage {
#[serde(rename = "type")]
kind: CollectionPageType,
#[activitystreams(ab(Object, Link))]
items: Vec<serde_json::Value>,
/// Adds all valid object properties to this struct
#[serde(flatten)]
pub object_props: ObjectProperties,
/// Adds all valid collection properties to this struct
#[serde(flatten)]
pub collection_props: CollectionProperties,
/// Adds all valid collection page properties to this struct
#[serde(flatten)]
pub collection_page_props: CollectionPageProperties,
}
impl Object for CollectionPage {}
impl Object for UnorderedCollectionPage {}
impl Collection for UnorderedCollectionPage {}
/// Used to represent ordered subsets of items from an `OrderedCollection`.
#[derive(Clone, Debug, Default, Deserialize, Serialize, Properties)]
#[serde(rename_all = "camelCase")]
pub struct OrderedCollectionPage {
#[serde(rename = "type")]
kind: OrderedCollectionPageType,
#[activitystreams(ab(Object, Link))]
items: Vec<serde_json::Value>,
/// Adds all valid object properties to this struct
#[serde(flatten)]
pub object_props: ObjectProperties,
/// Adds all valid collection properties to this struct
#[serde(flatten)]
pub collection_props: CollectionProperties,
/// Adds all valid collection page properties to this struct
#[serde(flatten)]
pub collection_page_props: CollectionPageProperties,
/// Adds all valid ordered collection page properties to this struct
#[serde(flatten)]
pub ordered_collection_page_props: OrderedCollectionPageProperties,
}
impl Object for OrderedCollectionPage {}
impl Collection for OrderedCollectionPage {}

View file

@ -17,51 +17,154 @@
* along with ActivityStreams. If not, see <http://www.gnu.org/licenses/>.
*/
//! Namespace for properties of standard object types
//!
//! To use these properties in your own types, you can flatten them into your struct with serde:
//!
//! ```rust
//! # extern crate activitystreams;
//! # extern crate serde;
//! # #[macro_use]
//! # extern crate serde_derive;
//! #
//! # use activitystreams::{
//! # collection::properties::CollectionProperties,
//! # object::properties::ObjectProperties,
//! # Collection,
//! # Object
//! # };
//! #
//! #[derive(Clone, Debug, Serialize, Deserialize)]
//! #[serde(rename_all = "camelCase")]
//! pub struct MyCollection {
//! #[serde(rename = "type")]
//! pub kind: String,
//!
//! /// Define a require property for the MyCollection type
//! pub my_property: String,
//!
//! #[serde(flatten)]
//! pub object_properties: ObjectProperties,
//!
//! #[serde(flatten)]
//! pub collection_properties: CollectionProperties,
//! }
//!
//! impl Object for MyCollection {}
//! impl Collection for MyCollection {}
//! #
//! # fn main() {}
//! ```
use serde_json;
use super::{Collection, CollectionPage};
use super::{
OrderedCollection, OrderedCollectionPage, UnorderedCollection, UnorderedCollectionPage,
};
use link::Link;
use object::Object;
/// `Collection` objects are a specialization of the base `Object` that serve as a container for
/// other `Objects` or `Links`.
///
/// The items within a `Collection` can be ordered or unordered. The `OrderedCollection` type MAY be
/// used to identify a `Collection` whose items are always ordered. In the JSON serialization, the
/// unordered items of a `Collection` are represented using the `items` property while ordered items
/// are represented using the `ordered_items` property.
#[derive(Clone, Debug, Default, Deserialize, Serialize, Properties)]
#[serde(rename_all = "camelCase")]
pub struct CollectionProperties {
/// Identifies the items contained in a collection. The items might be ordered or unordered.
///
/// - Range: `Object` | `Link` | Ordered List of [ `Object` | `Link` ]
/// - Functional: false
#[activitystreams(ab(Object, Link))]
pub items: serde_json::Value,
/// A non-negative integer specifying the total number of objects contained by the logical view
/// of the collection.
///
/// This number might not reflect the actual number of items serialized within the `Collection`
/// object instance.
///
/// - Range: `xsd:nonNegativeInteger`
/// - Functional: true
#[serde(skip_serializing_if = "Option::is_none")]
#[activitystreams(concrete(u64), functional)]
total_items: Option<serde_json::Value>,
pub total_items: Option<serde_json::Value>,
/// In a paged `Collection`, indicates the page that contains the most recently updated member
/// items.
///
/// - Range: `CollectionPage` | `OrderedCollectionPage` | `Link`
/// - Functional: true
#[serde(skip_serializing_if = "Option::is_none")]
#[activitystreams(concrete(CollectionPage), ab(Link), functional)]
current: Option<serde_json::Value>,
#[activitystreams(
concrete(UnorderedCollectionPage, OrderedCollectionPage), ab(Link), functional
)]
pub current: Option<serde_json::Value>,
/// In a paged `Collection`, indicates the furthest preceeding page of items in the collection.
///
/// - Range: `CollectionPage` | `OrderedCollectionPage` | `Link`
/// - Functional: true
#[serde(skip_serializing_if = "Option::is_none")]
#[activitystreams(concrete(CollectionPage), ab(Link), functional)]
first: Option<serde_json::Value>,
#[activitystreams(
concrete(UnorderedCollectionPage, OrderedCollectionPage), ab(Link), functional
)]
pub first: Option<serde_json::Value>,
/// In a paged `Collection`, indicates the furthest proceeding page of the collection.
///
/// - Range: `CollectionPage` | `OrderedCollectionPage` | `Link`
/// - Functional: true
#[serde(skip_serializing_if = "Option::is_none")]
#[activitystreams(concrete(CollectionPage), ab(Link), functional)]
last: Option<serde_json::Value>,
#[activitystreams(
concrete(UnorderedCollectionPage, OrderedCollectionPage), ab(Link), functional
)]
pub last: Option<serde_json::Value>,
}
/// The `CollectionPage` type extends from the base `Collection` type and inherits all of it's
/// properties.
#[derive(Clone, Debug, Default, Deserialize, Serialize, Properties)]
#[serde(rename_all = "camelCase")]
pub struct CollectionPageProperties {
/// Identifies the `Collection` to which a `CollectionPage` objects items belong.
///
/// Range: `Collection` | `OrderedCollection` | `Link`
/// Functional: true
#[serde(skip_serializing_if = "Option::is_none")]
#[activitystreams(concrete(Collection), ab(Link), functional)]
part_of: Option<serde_json::Value>,
#[activitystreams(concrete(UnorderedCollection, OrderedCollection), ab(Link), functional)]
pub part_of: Option<serde_json::Value>,
/// In a paged `Collection`, indicates the next page of items.
///
/// - Range: `CollectionPage` | `OrderedCollectionPage` | `Link`
/// - Functional: true
#[serde(skip_serializing_if = "Option::is_none")]
#[activitystreams(concrete(CollectionPage), ab(Link), functional)]
next: Option<serde_json::Value>,
#[activitystreams(concrete(UnorderedCollectionPage), ab(Link), functional)]
pub next: Option<serde_json::Value>,
/// In a paged `Collection`, identifies the previous page of items.
///
/// - Range: `CollectionPage` | `OrderedCollectionPage` | `Link`
/// - Functional: true
#[serde(skip_serializing_if = "Option::is_none")]
#[activitystreams(concrete(CollectionPage), ab(Link), functional)]
prev: Option<serde_json::Value>,
#[activitystreams(concrete(UnorderedCollectionPage), ab(Link), functional)]
pub prev: Option<serde_json::Value>,
}
/// The OrderedCollectionPage type MAY be used to identify a page whose items are strictly ordered.
#[derive(Clone, Debug, Default, Deserialize, Serialize, Properties)]
#[serde(rename_all = "camelCase")]
pub struct OrderedCollectionPageProperties {
/// A non-negative integer value identifying the relative position within the logical view of a
/// strictly ordered collection.
///
/// - Range: `xsd:nonNegativeInteger`
/// - Functional: true
#[serde(skip_serializing_if = "Option::is_none")]
#[activitystreams(concrete(u64), functional)]
start_index: Option<serde_json::Value>,
pub start_index: Option<serde_json::Value>,
}

View file

@ -46,6 +46,7 @@ pub mod properties;
pub use self::activity::{Activity, IntransitiveActivity};
pub use self::actor::Actor;
pub use self::collection::{Collection, CollectionPage};
pub use self::custom_props::{CustomLink, CustomObject};
pub use self::error::Error;
pub use self::link::Link;

View file

@ -17,12 +17,15 @@
* along with ActivityStreams. If not, see <http://www.gnu.org/licenses/>.
*/
//! Namespace for Unit Structs that serialize to strings
use std::fmt;
use serde::{
de::{self, Deserialize, Deserializer, Visitor}, ser::{Serialize, Serializer},
};
/// A Unit Struct that represents the string "Mention"
#[derive(Clone, Debug, Default, UnitString)]
#[activitystreams(Mention)]
pub struct MentionType;

View file

@ -19,19 +19,22 @@
use serde::{de::DeserializeOwned, ser::Serialize};
mod kind;
mod properties;
pub use self::kind::*;
pub use self::properties::*;
pub mod kind;
pub mod properties;
use self::kind::*;
use self::properties::*;
/// The Link is the secondary base type for the Activity Streams vocabulary.
pub trait Link: DeserializeOwned + Serialize {}
/// A specialized Link that represents an @mention.
#[derive(Clone, Debug, Default, Deserialize, Serialize)]
#[serde(rename_all = "camelCase")]
pub struct Mention {
#[serde(rename = "type")]
kind: MentionType,
/// Adds all valid link properties to this struct
#[serde(flatten)]
pub link_props: LinkProperties,
}

View file

@ -17,6 +17,36 @@
* along with ActivityStreams. If not, see <http://www.gnu.org/licenses/>.
*/
//! Namespace for properties of standard link types
//!
//! To use these properties in your own types, you can flatten them into your struct with serde:
//!
//! ```rust
//! # extern crate activitystreams;
//! # extern crate serde;
//! # #[macro_use]
//! # extern crate serde_derive;
//! #
//! # use activitystreams::{link::properties::LinkProperties, Link};
//! #
//! #[derive(Clone, Debug, Serialize, Deserialize)]
//! #[serde(rename_all = "camelCase")]
//! pub struct MyLink {
//! #[serde(rename = "type")]
//! pub kind: String,
//!
//! /// Define a require property for the MyLink type
//! pub my_property: String,
//!
//! #[serde(flatten)]
//! pub link_properties: LinkProperties,
//! }
//!
//! impl Link for MyLink {}
//! #
//! # fn main() {}
//! ```
use mime;
use serde_json;
@ -24,48 +54,127 @@ use error::{Error, Result};
use link::Link;
use object::Object;
/// Define all the properties of the Object base type as described by the Activity Streams
/// vocabulary.
///
/// The properties of the `Link` object are not the properties of the referenced resource, but are
/// provided as hints for rendering agents to understand how to make use of the resource. For
/// example, height and width might represent the desired rendered size of a referenced image,
/// rather than the actual pixel dimensions of the referenced image.
///
/// The target URI of the Link is expressed using the required href property.
///
/// For example, all Objects can contain an image property whose value describes a graphical
/// representation of the containing object. This property will typically be used to provide the URL
/// to an image (e.g. JPEG, GIF or PNG) resource that can be displayed to the user. Any given object
/// might have multiple such visual representations -- multiple screenshots, for instance, or the
/// same image at different resolutions. In Activity Streams 2.0, there are essentially three ways
/// of describing such references.
#[derive(Clone, Debug, Default, Deserialize, Serialize, Properties)]
#[serde(rename_all = "camelCase")]
pub struct LinkProperties {
// TODO: IRI type
/// 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
/// as a string.
///
/// - Range: `anyUri`
/// - Functional: true
#[serde(skip_serializing_if = "Option::is_none")]
#[activitystreams(concrete(String), functional)]
id: Option<serde_json::Value>,
#[serde(skip_serializing_if = "Option::is_none")]
#[activitystreams(concrete(String), functional)]
href: Option<serde_json::Value>,
pub id: Option<serde_json::Value>,
// TODO: rdf:langString
/// 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.
///
/// - Range: `xsd:string` | `rdf:langString`
/// - Functional: false
#[serde(skip_serializing_if = "Option::is_none")]
#[activitystreams(concrete(String))]
rel: Option<serde_json::Value>,
pub name: Option<serde_json::Value>,
/// The target resource pointed to by a Link.
///
/// - Range: `xsd:anyUri`
/// - Functional: true
#[serde(skip_serializing_if = "Option::is_none")]
#[activitystreams(concrete(String), functional)]
media_type: Option<serde_json::Value>,
pub href: Option<serde_json::Value>,
// TODO: lang enum
/// Hints as to the language used by the target resource.
///
/// Value MUST be a [[BCP47](https://tools.ietf.org/html/bcp47)]
/// Language-Tag.
///
/// - Range: [[BCP47](https://tools.ietf.org/html/bcp47)] Language
/// Tag
/// - Functional: true
#[serde(skip_serializing_if = "Option::is_none")]
#[activitystreams(concrete(String), functional)]
pub hreflang: Option<serde_json::Value>,
/// When used on a `Link`, identifies the MIME media type of the referenced resource.
///
/// If not specified, the content property is assumed to contain text/html content.
///
/// - Range: `Mime Media Type`
/// - Functional: true
#[serde(skip_serializing_if = "Option::is_none")]
#[activitystreams(concrete(String), functional)]
pub media_type: Option<serde_json::Value>,
/// A link relation associated with a Link.
///
/// The value MUST conform to both the
/// [[HTML5](https://www.w3.org/TR/html5/)] and [[RFC5988](https://tools.ietf.org/html/rfc5988)]
/// "link relation" definitions.
///
/// In the [[HTML5](https://www.w3.org/TR/html5/)], any string
/// not containing the "space" U+0020, "tab" (U+0009), "LF" (U+000A), "FF" (U+000C), "CR"
/// (U+000D) or "," (U+002C) characters can be used as a valid link relation.
///
/// - Range:
/// [[RFC5988](https://tools.ietf.org/html/rfc5988)] or
/// [[HTML5](https://www.w3.org/TR/html5/)] Link Relation
/// - Functional: false
#[serde(skip_serializing_if = "Option::is_none")]
#[activitystreams(concrete(String))]
name: Option<serde_json::Value>,
// TODO: Lang enum
#[serde(skip_serializing_if = "Option::is_none")]
#[activitystreams(concrete(String), functional)]
hreflang: Option<serde_json::Value>,
pub rel: Option<serde_json::Value>,
/// On a `Link`, specifies a hint as to the rendering height in device-independent pixels of the
/// linked resource.
///
/// - Range: `xsd:nonNegativeInteger`
/// - Functional: true
#[serde(skip_serializing_if = "Option::is_none")]
#[activitystreams(concrete(u64), functional)]
height: Option<serde_json::Value>,
pub height: Option<serde_json::Value>,
/// On a `Link`, specifies a hint as to the rendering width in device-independent pixels of the
/// linked resource.
///
/// - Range: `xsd:nonNegativeInteger`
/// - Functional: true
#[serde(skip_serializing_if = "Option::is_none")]
#[activitystreams(concrete(u64), functional)]
width: Option<serde_json::Value>,
pub width: Option<serde_json::Value>,
/// Identifies an entity that provides a preview of this object.
///
/// - Range: `Object` | `Link`
/// - Functional: false
#[serde(skip_serializing_if = "Option::is_none")]
#[activitystreams(ab(Object, Link))]
preview: Option<serde_json::Value>,
pub preview: Option<serde_json::Value>,
}
impl LinkProperties {
/// 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))

View file

@ -17,6 +17,8 @@
* along with ActivityStreams. If not, see <http://www.gnu.org/licenses/>.
*/
//! Namespace for Object types
use serde::{de::DeserializeOwned, ser::Serialize};
pub mod kind;

View file

@ -228,12 +228,12 @@ pub struct ObjectProperties {
#[activitystreams(concrete(String, UtcTime), functional)]
pub published: Option<serde_json::Value>,
/// Identifies a Collection containing objects considered to be responses to this object.
/// Identifies a `Collection` containing objects considered to be responses to this object.
///
/// - Range: `Object` | `Link`
/// - Functional: false
#[serde(skip_serializing_if = "Option::is_none")]
#[activitystreams(concrete(Collection), functional)]
#[activitystreams(ab(Collection), functional)]
pub replies: Option<serde_json::Value>,
/// The date and time describing the actual or expected starting time of the object.
@ -319,9 +319,9 @@ pub struct ObjectProperties {
#[activitystreams(ab(Object, Link))]
pub bcc: Option<serde_json::Value>,
/// 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.
///
/// - Range: `Mime Media Type`
@ -334,7 +334,8 @@ pub struct ObjectProperties {
/// 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
/// The value MUST be expressed as an xsd:duration as defined by
/// [[xmlschema11-2](https://www.w3.org/TR/xmlschema11-2/)], section
/// 3.3.6 (e.g. a period of 5 seconds is represented as "PT5S").
///
/// - Range: `xsd:duration`