activitystreams_types/link/properties.rs
1/*
2 * This file is part of ActivityStreams Types.
3 *
4 * Copyright © 2018 Riley Trautman
5 *
6 * ActivityStreams Types is free software: you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation, either version 3 of the License, or
9 * (at your option) any later version.
10 *
11 * ActivityStreams Types is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with ActivityStreams Types. If not, see <http://www.gnu.org/licenses/>.
18 */
19
20//! Namespace for properties of standard link types
21//!
22//! To use these properties in your own types, you can flatten them into your struct with serde:
23//!
24//! ```rust
25//! use activitystreams_traits::Link;
26//! use activitystreams_types::link::properties::LinkProperties;
27//! use serde_derive::{Deserialize, Serialize};
28//!
29//! #[derive(Clone, Debug, Serialize, Deserialize)]
30//! #[serde(rename_all = "camelCase")]
31//! pub struct MyLink {
32//! #[serde(rename = "type")]
33//! pub kind: String,
34//!
35//! /// Define a require property for the MyLink type
36//! pub my_property: String,
37//!
38//! #[serde(flatten)]
39//! pub link_properties: LinkProperties,
40//! }
41//!
42//! impl Link for MyLink {}
43//! #
44//! # fn main() {}
45//! ```
46
47use activitystreams_derive::Properties;
48use activitystreams_traits::{Error, Link, Object, Result};
49use serde_derive::{Deserialize, Serialize};
50
51/// Define all the properties of the Object base type as described by the Activity Streams
52/// vocabulary.
53///
54/// The properties of the `Link` object are not the properties of the referenced resource, but are
55/// provided as hints for rendering agents to understand how to make use of the resource. For
56/// example, height and width might represent the desired rendered size of a referenced image,
57/// rather than the actual pixel dimensions of the referenced image.
58///
59/// The target URI of the Link is expressed using the required href property.
60///
61/// For example, all Objects can contain an image property whose value describes a graphical
62/// representation of the containing object. This property will typically be used to provide the URL
63/// to an image (e.g. JPEG, GIF or PNG) resource that can be displayed to the user. Any given object
64/// might have multiple such visual representations -- multiple screenshots, for instance, or the
65/// same image at different resolutions. In Activity Streams 2.0, there are essentially three ways
66/// of describing such references.
67#[derive(Clone, Debug, Default, Deserialize, Serialize, Properties)]
68#[serde(rename_all = "camelCase")]
69pub struct LinkProperties {
70 // TODO: IRI type
71 /// Provides the globally unique identifier for an Object or Link.
72 ///
73 /// The `id` property is expressed as an absolute IRI in the spec, but for now is represented
74 /// as a string.
75 ///
76 /// - Range: `anyUri`
77 /// - Functional: true
78 #[serde(skip_serializing_if = "Option::is_none")]
79 #[activitystreams(concrete(String), functional)]
80 pub id: Option<serde_json::Value>,
81
82 /// Identifies the context within which the object exists or an activity was performed.
83 ///
84 /// The notion of "context" used is intentionally vague. The intended function is to serve as a
85 /// means of grouping objects and activities that share a common originating context or purpose.
86 /// An example could be all activities relating to a common project or event.
87 ///
88 /// - Range: `Object` | `Link`
89 /// - Functional: false
90 #[serde(skip_serializing_if = "Option::is_none", rename = "@context")]
91 #[activitystreams(ab(Object, Link), concrete(String))]
92 pub context: Option<serde_json::Value>,
93
94 // TODO: rdf:langString
95 /// A simple, human-readable, plain-text name for the object.
96 ///
97 /// HTML markup MUST NOT be included. The name MAY be expressed using multiple language-tagged
98 /// values.
99 ///
100 /// - Range: `xsd:string` | `rdf:langString`
101 /// - Functional: false
102 #[serde(skip_serializing_if = "Option::is_none")]
103 #[activitystreams(concrete(String))]
104 pub name: Option<serde_json::Value>,
105
106 /// The target resource pointed to by a Link.
107 ///
108 /// - Range: `xsd:anyUri`
109 /// - Functional: true
110 #[serde(skip_serializing_if = "Option::is_none")]
111 #[activitystreams(concrete(String), functional)]
112 pub href: Option<serde_json::Value>,
113
114 // TODO: lang enum
115 /// Hints as to the language used by the target resource.
116 ///
117 /// Value MUST be a [[BCP47](https://tools.ietf.org/html/bcp47)]
118 /// Language-Tag.
119 ///
120 /// - Range: [[BCP47](https://tools.ietf.org/html/bcp47)] Language
121 /// Tag
122 /// - Functional: true
123 #[serde(skip_serializing_if = "Option::is_none")]
124 #[activitystreams(concrete(String), functional)]
125 pub hreflang: Option<serde_json::Value>,
126
127 /// When used on a `Link`, identifies the MIME media type of the referenced resource.
128 ///
129 /// If not specified, the content property is assumed to contain text/html content.
130 ///
131 /// - Range: `Mime Media Type`
132 /// - Functional: true
133 #[serde(skip_serializing_if = "Option::is_none")]
134 #[activitystreams(concrete(String), functional)]
135 pub media_type: Option<serde_json::Value>,
136
137 /// A link relation associated with a Link.
138 ///
139 /// The value MUST conform to both the
140 /// [[HTML5](https://www.w3.org/TR/html5/)] and [[RFC5988](https://tools.ietf.org/html/rfc5988)]
141 /// "link relation" definitions.
142 ///
143 /// In the [[HTML5](https://www.w3.org/TR/html5/)], any string
144 /// not containing the "space" U+0020, "tab" (U+0009), "LF" (U+000A), "FF" (U+000C), "CR"
145 /// (U+000D) or "," (U+002C) characters can be used as a valid link relation.
146 ///
147 /// - Range:
148 /// [[RFC5988](https://tools.ietf.org/html/rfc5988)] or
149 /// [[HTML5](https://www.w3.org/TR/html5/)] Link Relation
150 /// - Functional: false
151 #[serde(skip_serializing_if = "Option::is_none")]
152 #[activitystreams(concrete(String))]
153 pub rel: Option<serde_json::Value>,
154
155 /// On a `Link`, specifies a hint as to the rendering height in device-independent pixels of the
156 /// linked resource.
157 ///
158 /// - Range: `xsd:nonNegativeInteger`
159 /// - Functional: true
160 #[serde(skip_serializing_if = "Option::is_none")]
161 #[activitystreams(concrete(u64), functional)]
162 pub height: Option<serde_json::Value>,
163
164 /// On a `Link`, specifies a hint as to the rendering width in device-independent pixels of the
165 /// linked resource.
166 ///
167 /// - Range: `xsd:nonNegativeInteger`
168 /// - Functional: true
169 #[serde(skip_serializing_if = "Option::is_none")]
170 #[activitystreams(concrete(u64), functional)]
171 pub width: Option<serde_json::Value>,
172
173 /// Identifies an entity that provides a preview of this object.
174 ///
175 /// - Range: `Object` | `Link`
176 /// - Functional: false
177 #[serde(skip_serializing_if = "Option::is_none")]
178 #[activitystreams(ab(Object, Link), concrete(String))]
179 pub preview: Option<serde_json::Value>,
180}
181
182impl LinkProperties {
183 /// Fetch a typed `Mime` struct from the `media_type` field.
184 pub fn media_type(&self) -> Result<mime::Mime> {
185 self.media_type_string()
186 .and_then(|s| s.parse().map_err(|_| Error::Deserialize))
187 }
188}