feedparser_rs/namespace/
dublin_core.rs1use crate::types::{Entry, FeedMeta, Person, Tag};
20use crate::util::date::parse_date;
21
22pub const DC_NAMESPACE: &str = "http://purl.org/dc/elements/1.1/";
24
25pub fn handle_feed_element(element: &str, text: &str, feed: &mut FeedMeta) {
33 match element {
34 "creator" => {
35 feed.author = Some(text.into());
37 feed.dc_creator = Some(text.into());
39 feed.authors.push(Person::from_name(text));
41 }
42 "date" => {
43 if let Some(dt) = parse_date(text) {
44 if feed.published.is_none() {
45 feed.published = Some(dt);
46 feed.published_str = Some(text.to_string());
47 }
48 feed.updated = Some(dt);
50 feed.updated_str = Some(text.to_string());
51 }
52 }
53 "subject" => {
54 feed.tags.push(Tag::new(text));
56 }
57 "description" if feed.subtitle.is_none() => {
58 feed.subtitle = Some(text.to_string());
59 }
60 "publisher" => {
61 if feed.publisher.is_none() {
62 feed.publisher = Some(text.into());
63 }
64 feed.dc_publisher = Some(text.into());
65 }
66 "rights" => {
67 if feed.rights.is_none() {
68 feed.rights = Some(text.to_string());
69 }
70 feed.dc_rights = Some(text.to_string());
71 }
72 "title" if feed.title.is_none() => {
73 feed.title = Some(text.to_string());
74 }
75 "language" if feed.language.is_none() => {
76 feed.language = Some(text.into());
77 }
78 "identifier" if feed.id.is_none() => {
79 feed.id = Some(text.to_string());
80 }
81 "contributor" => {
82 feed.contributors.push(Person::from_name(text));
84 }
85 _ => {
86 }
88 }
89}
90
91pub fn handle_entry_element(element: &str, text: &str, entry: &mut Entry) {
99 match element {
100 "creator" => {
101 entry.dc_creator = Some(text.into());
103 entry.authors.push(Person::from_name(text));
104 }
105 "date" => {
106 if let Some(dt) = parse_date(text) {
107 entry.dc_date = Some(dt);
108 if entry.published.is_none() {
109 entry.published = Some(dt);
110 entry.published_str = Some(text.to_string());
111 }
112 entry.updated = Some(dt);
114 entry.updated_str = Some(text.to_string());
115 }
116 }
117 "subject" => {
118 entry.dc_subject.push(text.to_string());
119 entry.tags.push(Tag::new(text));
120 }
121 "description" if entry.summary.is_none() => {
122 entry.summary = Some(text.to_string());
123 }
124 "title" if entry.title.is_none() => {
125 entry.title = Some(text.to_string());
126 }
127 "identifier" if entry.id.is_none() => {
128 entry.id = Some(text.into());
129 }
130 "contributor" => {
131 entry.contributors.push(Person::from_name(text));
132 }
133 "rights" => {
134 if entry.rights.is_none() {
135 entry.rights = Some(text.to_string());
136 }
137 entry.dc_rights = Some(text.to_string());
138 }
139 _ => {
140 }
142 }
143}
144
145#[cfg(test)]
146mod tests {
147 use super::*;
148
149 #[test]
150 fn test_dc_creator_feed() {
151 let mut feed = FeedMeta::default();
152 handle_feed_element("creator", "John Doe", &mut feed);
153
154 assert_eq!(feed.author.as_deref(), Some("John Doe"));
155 assert_eq!(feed.authors.len(), 1);
156 assert_eq!(feed.authors[0].name.as_deref(), Some("John Doe"));
157 }
158
159 #[test]
160 fn test_dc_multiple_creators() {
161 let mut feed = FeedMeta::default();
162 handle_feed_element("creator", "Alice", &mut feed);
163 handle_feed_element("creator", "Bob", &mut feed);
164
165 assert_eq!(feed.author.as_deref(), Some("Bob"));
167 assert_eq!(feed.authors.len(), 2);
169 }
170
171 #[test]
172 fn test_dc_date() {
173 let mut feed = FeedMeta::default();
174 handle_feed_element("date", "2024-01-15T10:30:00Z", &mut feed);
175
176 assert!(feed.updated.is_some());
177 }
178
179 #[test]
180 fn test_dc_subject() {
181 let mut feed = FeedMeta::default();
182 handle_feed_element("subject", "Technology", &mut feed);
183 handle_feed_element("subject", "Programming", &mut feed);
184
185 assert_eq!(feed.tags.len(), 2);
186 assert_eq!(feed.tags[0].term, "Technology");
187 assert_eq!(feed.tags[1].term, "Programming");
188 }
189
190 #[test]
191 fn test_dc_description() {
192 let mut feed = FeedMeta::default();
193 handle_feed_element("description", "Test description", &mut feed);
194
195 assert_eq!(feed.subtitle.as_deref(), Some("Test description"));
196 }
197
198 #[test]
199 fn test_dc_fallback_title() {
200 let mut feed = FeedMeta::default();
201 handle_feed_element("title", "DC Title", &mut feed);
202
203 assert_eq!(feed.title.as_deref(), Some("DC Title"));
204
205 feed.title = Some("RSS Title".to_string());
207 handle_feed_element("title", "DC Title 2", &mut feed);
208
209 assert_eq!(feed.title.as_deref(), Some("RSS Title"));
210 }
211
212 #[test]
213 fn test_entry_dc_elements() {
214 let mut entry = Entry::default();
215
216 handle_entry_element("creator", "Jane Doe", &mut entry);
217 handle_entry_element("subject", "Tech", &mut entry);
218 handle_entry_element("description", "Entry summary", &mut entry);
219
220 assert_eq!(entry.dc_creator.as_deref(), Some("Jane Doe"));
222 assert_eq!(entry.tags.len(), 1);
223 assert_eq!(entry.summary.as_deref(), Some("Entry summary"));
224 }
225
226 #[test]
227 fn test_entry_updated_and_published_from_dc_date() {
228 let mut entry = Entry::default();
229 handle_entry_element("date", "2024-01-15T10:30:00Z", &mut entry);
230
231 assert!(entry.updated.is_some());
232 assert!(entry.published.is_some());
233 }
234
235 #[test]
236 fn test_entry_dc_rights_sets_both_fields() {
237 let mut entry = Entry::default();
238 handle_entry_element("rights", "Copyright 2024 Example", &mut entry);
239
240 assert_eq!(entry.rights.as_deref(), Some("Copyright 2024 Example"));
241 assert_eq!(entry.dc_rights.as_deref(), Some("Copyright 2024 Example"));
242 }
243
244 #[test]
245 fn test_entry_dc_rights_does_not_overwrite_rights() {
246 let mut entry = Entry {
247 rights: Some("Atom rights".to_string()),
248 ..Default::default()
249 };
250 handle_entry_element("rights", "DC rights", &mut entry);
251
252 assert_eq!(entry.rights.as_deref(), Some("Atom rights"));
254 assert_eq!(entry.dc_rights.as_deref(), Some("DC rights"));
255 }
256}