Skip to content

Commit 5c1498e

Browse files
committed
Add RSS Entry conversions
Add Guid type since the RSS Guid is more detailed than the Atom one.
1 parent e941306 commit 5c1498e

File tree

3 files changed

+85
-4
lines changed

3 files changed

+85
-4
lines changed

src/entry.rs

Lines changed: 50 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,22 +1,24 @@
11
use atom_syndication as atom;
22
use rss;
33

4+
use std::str::FromStr;
45
use chrono::{DateTime, UTC};
56
use category::Category;
67
use link::Link;
78
use person::Person;
9+
use guid::Guid;
810

911
enum EntryData {
1012
Atom(atom::Entry),
11-
RSS(rss::Item),
13+
Rss(rss::Item),
1214
}
1315

1416
pub struct Entry {
1517
// If created from an Atom or RSS entry, this is the original contents
1618
source_data: Option<EntryData>,
1719

1820
// `id` in Atom (required), and `guid` in RSS
19-
pub id: Option<String>,
21+
pub id: Option<Guid>,
2022
// `title` in Atom and RSS, optional only in RSS
2123
pub title: Option<String>,
2224
// `updated` in Atom (required), not present in RSS
@@ -40,13 +42,15 @@ pub struct Entry {
4042
pub authors: Vec<Person>,
4143
// `contributors` in Atom, not present in RSS (produces an empty Vec)
4244
pub contributors: Vec<Person>,
45+
// not present in Atom (produces None), `comments` in RSS
46+
pub comments: Option<String>,
4347
}
4448

4549
impl From<atom::Entry> for Entry {
4650
fn from(entry: atom::Entry) -> Self {
4751
Entry {
4852
source_data: Some(EntryData::Atom(entry.clone())),
49-
id: Some(entry.id),
53+
id: Some(Guid::from_id(entry.id)),
5054
title: Some(entry.title),
5155
updated: DateTime::parse_from_rfc3339(entry.updated.as_str())
5256
.map(|date| date.with_timezone(&UTC))
@@ -60,6 +64,7 @@ impl From<atom::Entry> for Entry {
6064
categories: entry.categories.into_iter().map(|category| category.into()).collect(),
6165
authors: entry.authors.into_iter().map(|person| person.into()).collect(),
6266
contributors: entry.contributors.into_iter().map(|person| person.into()).collect(),
67+
comments: None,
6368
}
6469
}
6570
}
@@ -71,10 +76,11 @@ impl From<Entry> for atom::Entry {
7176
} else {
7277
atom::Entry {
7378
// TODO: How should we handle a missing id?
74-
id: entry.id.unwrap_or_else(|| String::from("")),
79+
id: entry.id.unwrap_or_else(|| Guid::from_id("".into())).id,
7580
title: entry.title.unwrap_or_else(|| String::from("")),
7681
updated: entry.updated.to_rfc3339(),
7782
published: entry.published.map(|date| date.to_rfc3339()),
83+
// TODO: Figure out this thing...
7884
source: None,
7985
summary: entry.summary,
8086
content: entry.content,
@@ -86,3 +92,43 @@ impl From<Entry> for atom::Entry {
8692
}
8793
}
8894
}
95+
96+
impl From<rss::Item> for Entry {
97+
fn from(entry: rss::Item) -> Self {
98+
let entry_clone = entry.clone();
99+
let date = entry.pub_date.and_then(|d| DateTime::from_str(&d[..]).ok());
100+
Entry {
101+
source_data: Some(EntryData::Rss(entry_clone)),
102+
id: entry.guid.map(|id| id.into()),
103+
title: entry.title,
104+
updated: date.clone().unwrap_or_else(UTC::now),
105+
published: date,
106+
summary: None,
107+
content: entry.description,
108+
links: entry.link.into_iter().map(Link::from_href).collect(),
109+
categories: entry.categories.into_iter().map(|category| category.into()).collect(),
110+
authors: entry.author.into_iter().map(Person::from_name).collect(),
111+
contributors: vec![],
112+
comments: entry.comments,
113+
}
114+
}
115+
}
116+
117+
impl From<Entry> for rss::Item {
118+
fn from(entry: Entry) -> rss::Item {
119+
if let Some(EntryData::Rss(entry)) = entry.source_data {
120+
entry
121+
} else {
122+
rss::Item {
123+
guid: entry.id.map(|id| id.into()),
124+
title: entry.title,
125+
author: entry.authors.into_iter().next().map(|person| person.name),
126+
pub_date: entry.published.map(|date| date.to_rfc2822()),
127+
description: entry.content,
128+
link: entry.links.into_iter().next().map(|link| link.href),
129+
categories: entry.categories.into_iter().map(|category| category.into()).collect(),
130+
comments: entry.comments,
131+
}
132+
}
133+
}
134+
}

src/guid.rs

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
use rss;
2+
3+
pub struct Guid {
4+
pub is_permalink: bool,
5+
pub id: String,
6+
}
7+
8+
impl Guid {
9+
pub fn from_id(id: String) -> Guid {
10+
Guid {
11+
is_permalink: true,
12+
id: id,
13+
}
14+
}
15+
}
16+
17+
impl From<rss::Guid> for Guid {
18+
fn from(id: rss::Guid) -> Guid {
19+
Guid {
20+
is_permalink: id.is_perma_link,
21+
id: id.value,
22+
}
23+
}
24+
}
25+
26+
impl From<Guid> for rss::Guid {
27+
fn from(id: Guid) -> rss::Guid {
28+
rss::Guid {
29+
is_perma_link: id.is_permalink,
30+
value: id.id,
31+
}
32+
}
33+
}

src/lib.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,10 +8,12 @@ mod entry;
88
mod feed;
99
mod link;
1010
mod generator;
11+
mod guid;
1112

1213
pub use ::category::Category;
1314
pub use ::person::Person;
1415
pub use ::entry::Entry;
1516
pub use ::feed::Feed;
1617
pub use ::link::Link;
1718
pub use ::generator::Generator;
19+
pub use ::guid::Guid;

0 commit comments

Comments
 (0)