activitystreams_types/object/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 object 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::Object;
26//! use activitystreams_types::object::properties::ObjectProperties;
27//! use serde_derive::{Deserialize, Serialize};
28//!
29//! #[derive(Clone, Debug, Serialize, Deserialize)]
30//! #[serde(rename_all = "camelCase")]
31//! pub struct MyObject {
32//! #[serde(rename = "type")]
33//! pub kind: String,
34//!
35//! /// Define a require property for the MyObject type
36//! pub my_property: String,
37//!
38//! #[serde(flatten)]
39//! pub object_properties: ObjectProperties,
40//! }
41//!
42//! impl Object for MyObject {}
43//! #
44//! # fn main() {}
45//! ```
46
47use activitystreams_derive::Properties;
48use activitystreams_traits::{Collection, Error, Link, Object, Result};
49use chrono::{offset::Utc, DateTime};
50use serde_derive::{Deserialize, Serialize};
51
52use crate::object::Image;
53
54/// Alias chrono::DateTime<Utc> for use in derive macros
55pub type UtcTime = DateTime<Utc>;
56
57/// Define all the properties of the Object base type as described by the Activity Streams
58/// vocabulary.
59///
60/// In addition to having a global identifier (expressed as an absolute IRI using the id property)
61/// and an "object type" (expressed using the type property), all instances of the Object type share
62/// a common set of properties normatively defined by the Activity Vocabulary.
63///
64/// This struct does not provide an optional `type` property, if you are implementing your own
65/// object type, you must supply your own type. This crate's provided object types all supply their
66/// own `type` properties as Unit Structs with custom serde behaviour.
67///
68/// All properties are optional (including the id and type).
69#[derive(Clone, Debug, Default, Deserialize, Serialize, Properties)]
70#[serde(rename_all = "camelCase")]
71pub struct ObjectProperties {
72 // TODO: IRI type
73 /// Provides the globally unique identifier for an Object or Link.
74 ///
75 /// The `id` property is expressed as an absolute IRI in the spec, but for now is represented
76 /// as a string.
77 ///
78 /// - Range: `anyUri`
79 /// - Functional: true
80 #[serde(skip_serializing_if = "Option::is_none")]
81 #[serde(alias = "@id")]
82 #[activitystreams(concrete(String), functional)]
83 pub id: Option<serde_json::Value>,
84
85 /// Identifies a resource attached or related to an object that potentially requires special
86 /// handling.
87 ///
88 /// The intent is to provide a model that is at least semantically similar to attachments in
89 /// email.
90 ///
91 /// - Range: `Object` | `Link`
92 /// - Functional: false
93 #[serde(skip_serializing_if = "Option::is_none")]
94 #[activitystreams(ab(Object, Link), concrete(String))]
95 pub attachment: Option<serde_json::Value>,
96
97 /// Identifies one or more entities to which this object is attributed.
98 ///
99 /// The attributed entities might not be Actors. For instance, an object might be attributed to
100 /// the completion of another activity.
101 ///
102 /// - Range: `Object` | `Link`
103 /// - Functional: false
104 #[serde(skip_serializing_if = "Option::is_none")]
105 #[activitystreams(ab(Object, Link), concrete(String))]
106 pub attributed_to: Option<serde_json::Value>,
107
108 /// Identifies one or more entities that represent the total population of entities for which
109 /// the object can considered to be relevant.
110 ///
111 /// - Range: `Object` | `Link`
112 /// - Functional: false
113 #[serde(skip_serializing_if = "Option::is_none")]
114 #[activitystreams(ab(Object, Link), concrete(String))]
115 pub audience: Option<serde_json::Value>,
116
117 // TODO: rdf:langString
118 /// The content or textual representation of the Object encoded as a JSON string.
119 ///
120 /// By default, the value of content is HTML. The mediaType property can be used in the object
121 /// to indicate a different content type.
122 ///
123 /// The content MAY be expressed using multiple language-tagged values.
124 ///
125 /// - Range: `xsd:string` | `rdf:langString`
126 /// - Functional: false
127 #[serde(skip_serializing_if = "Option::is_none")]
128 #[activitystreams(concrete(String))]
129 pub content: Option<serde_json::Value>,
130
131 /// Identifies the context within which the object exists or an activity was performed.
132 ///
133 /// The notion of "context" used is intentionally vague. The intended function is to serve as a
134 /// means of grouping objects and activities that share a common originating context or purpose.
135 /// An example could be all activities relating to a common project or event.
136 ///
137 /// - Range: `Object` | `Link`
138 /// - Functional: false
139 #[serde(skip_serializing_if = "Option::is_none", rename = "@context")]
140 #[activitystreams(ab(Object, Link), concrete(String))]
141 pub context: Option<serde_json::Value>,
142
143 // TODO: rdf:langString
144 /// A simple, human-readable, plain-text name for the object.
145 ///
146 /// HTML markup MUST NOT be included. The name MAY be expressed using multiple language-tagged
147 /// values.
148 ///
149 /// - Range: `xsd:string` | `rdf:langString`
150 /// - Functional: false
151 #[serde(skip_serializing_if = "Option::is_none")]
152 #[serde(alias = "displayName")]
153 #[activitystreams(concrete(String))]
154 pub name: Option<serde_json::Value>,
155
156 /// The date and time describing the actual or expected ending time of the object.
157 ///
158 /// When used with an Activity object, for instance, the endTime property specifies the moment
159 /// the activity concluded or is expected to conclude.
160 ///
161 /// - Range: `xsd:dateTime`
162 /// - Functional: true
163 #[serde(skip_serializing_if = "Option::is_none")]
164 #[activitystreams(concrete(String, UtcTime), functional)]
165 pub end_time: Option<serde_json::Value>,
166
167 /// Identifies the entity (e.g. an application) that generated the object.
168 ///
169 /// - Range: `Object` | `Link`
170 /// - Functional: false
171 #[serde(skip_serializing_if = "Option::is_none")]
172 #[activitystreams(ab(Object, Link), concrete(String))]
173 pub generator: Option<serde_json::Value>,
174
175 /// Indicates an entity that describes an icon for this object.
176 ///
177 /// The image should have an aspect ratio of one (horizontal) to one (vertical) and should be
178 /// suitable for presentation at a small size.
179 ///
180 /// - Range: `Image` | `Link`
181 /// - Functional: false
182 #[serde(skip_serializing_if = "Option::is_none")]
183 #[activitystreams(ab(Object, Link), concrete(Image, String))]
184 pub icon: Option<serde_json::Value>,
185
186 /// Indicates an entity that describes an image for this object.
187 ///
188 /// Unlike the icon property, there are no aspect ratio or display size limitations assumed.
189 ///
190 /// - Range: `Image` | `Link`
191 /// - Functional: false
192 #[serde(skip_serializing_if = "Option::is_none")]
193 #[activitystreams(ab(Object, Link), concrete(Image, String))]
194 pub image: Option<serde_json::Value>,
195
196 /// Indicates one or more entities for which this object is considered a response.
197 ///
198 /// - Range: `Object` | `Link`
199 /// - Functional: false
200 #[serde(skip_serializing_if = "Option::is_none")]
201 #[activitystreams(ab(Object, Link), concrete(String))]
202 pub in_reply_to: Option<serde_json::Value>,
203
204 /// Indicates one or more physical or logical locations associated with the object.
205 ///
206 /// - Range: `Object` | `Link`
207 /// - Functional: false
208 #[serde(skip_serializing_if = "Option::is_none")]
209 #[activitystreams(ab(Object, Link), concrete(String))]
210 pub location: Option<serde_json::Value>,
211
212 /// Identifies an entity that provides a preview of this object.
213 ///
214 /// - Range: `Object` | `Link`
215 /// - Functional: false
216 #[serde(skip_serializing_if = "Option::is_none")]
217 #[activitystreams(ab(Object, Link), concrete(String))]
218 pub preview: Option<serde_json::Value>,
219
220 /// The date and time at which the object was published.
221 ///
222 /// - Range: `xsd:dateTime`
223 /// - Functional: true
224 #[serde(skip_serializing_if = "Option::is_none")]
225 #[activitystreams(concrete(String, UtcTime), functional)]
226 pub published: Option<serde_json::Value>,
227
228 /// Identifies a `Collection` containing objects considered to be responses to this object.
229 ///
230 /// - Range: `Object` | `Link`
231 /// - Functional: false
232 #[serde(skip_serializing_if = "Option::is_none")]
233 #[activitystreams(ab(Collection), concrete(String), functional)]
234 pub replies: Option<serde_json::Value>,
235
236 /// The date and time describing the actual or expected starting time of the object.
237 ///
238 /// When used with an `Activity` object, for instance, the `start_time` property specifies the
239 /// moment the activity began or is scheduled to begin.
240 ///
241 /// - Range: `Object` | `Link`
242 /// - Functional: true
243 #[serde(skip_serializing_if = "Option::is_none")]
244 #[activitystreams(concrete(String, UtcTime), functional)]
245 pub start_time: Option<serde_json::Value>,
246
247 // TODO: rdf:langString
248 /// A natural language summarization of the object encoded as HTML.
249 ///
250 /// Multiple language tagged summaries MAY be provided.
251 ///
252 /// - Range: `xsd:string` | `rdf:langString`
253 /// - Functional: false
254 #[serde(skip_serializing_if = "Option::is_none")]
255 #[activitystreams(concrete(String))]
256 pub summary: Option<serde_json::Value>,
257
258 /// One or more "tags" that have been associated with an objects. A tag can be any kind of
259 /// `Object`.
260 ///
261 /// The key difference between attachment and tag is that the former implies association by
262 /// inclusion, while the latter implies associated by reference.
263 ///
264 /// - Range: `Object` | `Link`
265 /// - Functional: false
266 #[serde(skip_serializing_if = "Option::is_none")]
267 #[activitystreams(ab(Object, Link), concrete(String))]
268 pub tag: Option<serde_json::Value>,
269
270 /// The date and time at which the object was updated,
271 ///
272 /// - Range: `xsd:dateTime`
273 /// - Functional: true
274 #[serde(skip_serializing_if = "Option::is_none")]
275 #[activitystreams(concrete(String, UtcTime), functional)]
276 pub updated: Option<serde_json::Value>,
277
278 /// Identifies one or more links to representations of the object.
279 ///
280 /// - Range: `xsd:anyUri` | `Link`
281 /// - Functional: false
282 #[serde(skip_serializing_if = "Option::is_none")]
283 #[activitystreams(concrete(String), ab(Link))]
284 pub url: Option<serde_json::Value>,
285
286 /// Identifies an entity considered to be part of the public primary audience of an `Object`.
287 ///
288 /// - Range: `Object` | `Link`
289 /// - Functional: false
290 #[serde(skip_serializing_if = "Option::is_none")]
291 #[activitystreams(ab(Object, Link), concrete(String))]
292 pub to: Option<serde_json::Value>,
293
294 /// Identifies an `Object` that is part of the private primary audience of this `Object`.
295 ///
296 /// - Range: `Object` | `Link`
297 /// - Functional: false
298 #[serde(skip_serializing_if = "Option::is_none")]
299 #[activitystreams(ab(Object, Link), concrete(String))]
300 pub bto: Option<serde_json::Value>,
301
302 /// Identifies an `Object` that is part of the public secondary audience of this `Object`.
303 ///
304 /// - Range: `Object` | `Link`
305 /// - Functional: false
306 #[serde(skip_serializing_if = "Option::is_none")]
307 #[activitystreams(ab(Object, Link), concrete(String))]
308 pub cc: Option<serde_json::Value>,
309
310 /// Identifies one or more `Objects` that are part of the private secondary audience of this
311 /// `Object`.
312 ///
313 /// - Range: `Object` | `Link`
314 /// - Functional: false
315 #[serde(skip_serializing_if = "Option::is_none")]
316 #[activitystreams(ab(Object, Link), concrete(String))]
317 pub bcc: Option<serde_json::Value>,
318
319 /// When used on an `Object`, identifies the MIME media type of the value of the content
320 /// property.
321 ///
322 /// If not specified, the content property is assumed to contain text/html content.
323 ///
324 /// - Range: `Mime Media Type`
325 /// - Functional: true
326 #[serde(skip_serializing_if = "Option::is_none")]
327 #[activitystreams(concrete(String), functional)]
328 pub media_type: Option<serde_json::Value>,
329
330 // TODO: xsd:duration
331 /// When the object describes a time-bound resource, such as an audio or video, a meeting, etc,
332 /// the duration property indicates the object's approximate duration.
333 ///
334 /// The value MUST be expressed as an xsd:duration as defined by
335 /// [[xmlschema11-2](https://www.w3.org/TR/xmlschema11-2/)], section
336 /// 3.3.6 (e.g. a period of 5 seconds is represented as "PT5S").
337 ///
338 /// - Range: `xsd:duration`
339 /// - Functional: true
340 #[serde(skip_serializing_if = "Option::is_none")]
341 #[activitystreams(concrete(String), functional)]
342 pub duration: Option<serde_json::Value>,
343}
344
345impl ObjectProperties {
346 /// Fetch a typed `Mime` struct from the `media_type` field.
347 pub fn media_type(&self) -> Result<mime::Mime> {
348 self.media_type_string()
349 .and_then(|s| s.parse().map_err(|_| Error::Deserialize))
350 }
351}
352
353/// Define all the properties of the Location type as described by the Activity Streams vocabulary.
354#[derive(Clone, Debug, Default, Deserialize, Serialize, Properties)]
355#[serde(rename_all = "camelCase")]
356pub struct PlaceProperties {
357 /// Indicates the accuracy of position coordinates on a `Place` objects.
358 ///
359 /// Expressed in properties of percentage. e.g. "94.0" means "94.0% accurate".
360 ///
361 /// - Range: `xsd:float` [>= 0.0f, <= 100.0f]
362 /// - Functional: true
363 #[serde(skip_serializing_if = "Option::is_none")]
364 #[activitystreams(concrete(f64), functional)]
365 pub accuracy: Option<serde_json::Value>,
366
367 /// Indicates the altitude of a place. The measurement units is indicated using the units
368 /// property.
369 ///
370 /// If units is not specified, the default is assumed to be "m" indicating meters.
371 ///
372 /// - Range: `xsd:float`
373 /// - Functional: true
374 #[serde(skip_serializing_if = "Option::is_none")]
375 #[activitystreams(concrete(f64), functional)]
376 pub altitude: Option<serde_json::Value>,
377
378 /// The latitude of a place.
379 ///
380 /// - Range: `xsd:float`
381 /// - Functional: true
382 #[serde(skip_serializing_if = "Option::is_none")]
383 #[activitystreams(concrete(f64), functional)]
384 pub latitude: Option<serde_json::Value>,
385
386 /// The longitude of a place.
387 ///
388 /// - Range: `xsd:float`
389 /// - Functional: true
390 #[serde(skip_serializing_if = "Option::is_none")]
391 #[activitystreams(concrete(f64), functional)]
392 pub longitude: Option<serde_json::Value>,
393
394 /// The radius from the given latitude and longitude for a Place.
395 ///
396 /// The units is expressed by the units property. If units is not specified, the default is
397 /// assumed to be "m" indicating "meters".
398 ///
399 /// - Range: `xsd:float`
400 /// - Functional: true
401 #[serde(skip_serializing_if = "Option::is_none")]
402 #[activitystreams(concrete(f64), functional)]
403 pub radius: Option<serde_json::Value>,
404
405 /// Specifies the measurement units for the radius and altitude properties on a `Place` object.
406 ///
407 /// If not specified, the default is assumed to be "m" for "meters".
408 ///
409 /// - Range: `xsd:float`
410 /// - Functional: true
411 #[serde(skip_serializing_if = "Option::is_none")]
412 #[activitystreams(concrete(String), functional)]
413 pub units: Option<serde_json::Value>,
414}
415
416/// Define all the properties of the Profile type as described by the Activity Streams vocabulary.
417#[derive(Clone, Debug, Default, Deserialize, Serialize, Properties)]
418#[serde(rename_all = "camelCase")]
419pub struct ProfileProperties {
420 /// On a `Profile` object, the describes property identifies the object described by the
421 /// `Profile`.
422 ///
423 /// - Range: `Object`
424 /// - Functional: true
425 #[activitystreams(ab(Object), concrete(String), functional)]
426 pub describes: serde_json::Value,
427}
428
429/// Define all the properties of the Relationship type as described by the Activity Streams
430/// vocabulary.
431#[derive(Clone, Debug, Default, Deserialize, Serialize, Properties)]
432#[serde(rename_all = "camelCase")]
433pub struct RelationshipProperties {
434 /// On a `Relationship` object, the subject property identifies one of the connected
435 /// individuals.
436 ///
437 /// For instance, for a `Relationship` object describing "John is related to Sally", subject
438 /// would refer to John.
439 ///
440 /// - Range: `Object` | `Link`
441 /// - Functional: true
442 #[activitystreams(ab(Object, Link), concrete(String), functional)]
443 subject: serde_json::Value,
444
445 /// When used within a `Relationship` describes the entity to which the subject is related.
446 ///
447 /// - Range: `Object` | `Link`
448 /// - Functional: false
449 #[activitystreams(ab(Object, Link), concrete(String))]
450 object: serde_json::Value,
451
452 /// On a `Relationship` object, the relationship property identifies the kind of relationship
453 /// that exists between subject and object.
454 ///
455 /// - Range: `Object`
456 /// - Functional: false
457 #[activitystreams(ab(Object), concrete(String))]
458 relationship: serde_json::Value,
459}
460
461/// Define all the properties of the Tombstone type as described by the Activity Streams vocabulary.
462#[derive(Clone, Debug, Default, Deserialize, Serialize, Properties)]
463#[serde(rename_all = "camelCase")]
464pub struct TombstoneProperties {
465 /// On a `Tombstone` object, the formerType property identifies the type of the object that was
466 /// deleted.
467 ///
468 /// - Range: `Object`
469 /// - Functional: false
470 #[serde(skip_serializing_if = "Option::is_none")]
471 #[activitystreams(ab(Object), concrete(String))]
472 pub former_type: Option<serde_json::Value>,
473
474 /// On a `Tombstone` object, the deleted property is a timestamp for when the object was
475 /// deleted.
476 ///
477 /// - Range: `xsd:dateTime`
478 /// - Functional: true
479 #[serde(skip_serializing_if = "Option::is_none")]
480 #[activitystreams(concrete(String, UtcTime), functional)]
481 pub deleted: Option<serde_json::Value>,
482}