1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
use std::borrow::Cow;
use std::default::Default;
use std::io;
use chrono::{DateTime, FixedOffset};
use parser::base::{DecodeResult, XmlElement, XmlName};
use schema::{Entity, FromSchemaReader, Mergeable};
use util::set_default;
use super::{ATOM_XMLNS, Category, Link, Person, Text, parse_datetime};
/// Common metadata shared by `Source`, `Entry`, and `Feed`.
pub struct Metadata {
/// The URI that conveys a permanent, universally unique identifier for an
/// entry or feed. It corresponds to `atom:id` element of :rfc:`4287#section-4.2.6` (section 4.2.6).
pub id: String,
/// The human-readable title for an entry or feed.
/// It corresponds to `atom:title` element of :rfc:`4287#section-4.2.14` (section 4.2.14).
pub title: Text,
/// The list of :class:`Link` objects that define a reference from an entry
/// or feed to a web resource. It corresponds to `atom:link` element of
/// :rfc:`4287#section-4.2.7` (section 4.2.7).
pub links: Vec<Link>,
/// The datetime value with a fixed timezone offset, indicating the most
/// recent instant in time when the entry was modified in a way the
/// publisher considers significant. Therefore, not all modifications
/// necessarily result in a changed `updated_at` value.
/// It corresponds to `atom:updated` element of :rfc:`4287#section-4.2.15` (section 4.2.15).
pub updated_at: DateTime<FixedOffset>,
/// The list of `Person` values which indicates the author of the entry or
/// feed. It corresponds to `atom:author` element of :rfc:`4287#section-4.2.1` (section 4.2.1).
pub authors: Vec<Person>,
/// The list of `Person` values which indicates a person or other entity
/// who contributed to the entry or feed. It corresponds to
/// `atom:contributor` element of :rfc:`4287#section-4.2.3` (section 4.2.3).
pub contributors: Vec<Person>,
/// The list of `Category` values that conveys information about categories
/// associated with an entry or feed. It corresponds to `atom:category`
/// element of :rfc:`4287#section-4.2.2` (section 4.2.2).
pub categories: Vec<Category>,
/// The text field that conveys information about rights held in and of an
/// entry or feed. It corresponds to `atom:rights` element of
/// :rfc:`4287#section-4.2.10` (section 4.2.10).
pub rights: Option<Text>,
}
impl Metadata {
pub fn new_inherited(id: String, title: Text, updated_at: DateTime<FixedOffset>) -> Metadata {
Metadata {
id: id,
title: title,
updated_at: updated_at,
..Default::default()
}
}
}
impl Default for Metadata {
fn default() -> Metadata {
use chrono::{DateTime, NaiveDateTime};
let default_datetime = DateTime::from_utc(
NaiveDateTime::from_num_seconds_from_unix_epoch(0, 0),
FixedOffset::east(0)
);
Metadata {
id: Default::default(),
title: Default::default(),
links: Default::default(),
updated_at: default_datetime,
authors: Default::default(),
contributors: Default::default(),
categories: Default::default(),
rights: Default::default(),
}
}
}
impl FromSchemaReader for Metadata {
fn match_child<B: io::BufRead>(&mut self, name: &XmlName,
child: XmlElement<B>) -> DecodeResult<()> {
match (name.namespace_ref(), &name.local_name[..]) {
(Some(ATOM_XMLNS), "id") => {
self.id = try!(child.read_whole_text());
}
(Some(ATOM_XMLNS), "title") => {
try!(self.title.read_from(child));
}
(Some(ATOM_XMLNS), "link") => {
self.links.push(try!(FromSchemaReader::build_from(child)));
}
(Some(ATOM_XMLNS), "updated") => {
self.updated_at = try!(parse_datetime(child));
}
(Some(ATOM_XMLNS), "modified") => {
self.updated_at = try!(parse_datetime(child));
}
(Some(ATOM_XMLNS), "author") => {
match try!(FromSchemaReader::build_from(child)) {
Some(p) => self.authors.push(p),
None => { }
}
}
(Some(ATOM_XMLNS), "contributor") => {
match try!(FromSchemaReader::build_from(child)) {
Some(p) => self.contributors.push(p),
None => { }
}
}
(Some(ATOM_XMLNS), "category") => {
self.categories.push(try!(FromSchemaReader::build_from(child)));
}
(Some(ATOM_XMLNS), "rights") => {
*set_default(&mut self.rights) = try!(FromSchemaReader::build_from(child));
}
_ => { }
}
Ok(())
}
}
impl Entity for Metadata {
type Id = str;
fn entity_id(&self) -> Cow<str> {
Cow::Borrowed(&self.id)
}
}
impl_mergeable!(Metadata, id, title, links, updated_at, authors,
contributors, categories, rights);