From ee4f08c5cf8937c1ed5d433480bc18928ecacb3e Mon Sep 17 00:00:00 2001 From: Jordan Petridis Date: Sun, 26 Nov 2017 23:30:56 +0200 Subject: [PATCH] Implemented a BuildPattern for NewModels. Swiched stuff to pub(crate). Added a Constructor for NewModels in order to make their fields private. Also added getter methods that are mainly used in Unit tests. --- hammond-data/src/feed.rs | 2 +- hammond-data/src/models/insertables.rs | 325 +++++++++++++++++++------ hammond-data/src/parser.rs | 269 ++++++++------------ 3 files changed, 356 insertions(+), 240 deletions(-) diff --git a/hammond-data/src/feed.rs b/hammond-data/src/feed.rs index 48ae6a8..e853ed1 100644 --- a/hammond-data/src/feed.rs +++ b/hammond-data/src/feed.rs @@ -52,7 +52,7 @@ impl Feed { episodes.into_iter().for_each(|x| { let e = x.index(&con); if let Err(err) = e { - error!("Failed to index episode: {:?}.", x.title); + error!("Failed to index episode: {:?}.", x.title()); error!("Error msg: {}", err); }; }); diff --git a/hammond-data/src/models/insertables.rs b/hammond-data/src/models/insertables.rs index fabfc5e..2e151ce 100644 --- a/hammond-data/src/models/insertables.rs +++ b/hammond-data/src/models/insertables.rs @@ -35,7 +35,7 @@ impl Insert for NewSource { } impl NewSource { - pub fn new_with_uri(uri: &str) -> NewSource { + pub(crate) fn new_with_uri(uri: &str) -> NewSource { let uri = url_cleaner(uri); NewSource { uri, @@ -55,84 +55,21 @@ impl NewSource { } // Look out for when tryinto lands into stable. - pub fn into_source(self) -> Result { + pub(crate) fn into_source(self) -> Result { self.index()?; dbqueries::get_source_from_uri(&self.uri) } } -#[derive(Insertable, AsChangeset)] -#[table_name = "episode"] -#[derive(Debug, Clone, Default)] -pub(crate) struct NewEpisode { - pub title: Option, - pub uri: String, - pub description: Option, - pub published_date: Option, - pub length: Option, - pub guid: Option, - pub epoch: i32, - pub podcast_id: i32, -} - -impl Insert for NewEpisode { - fn insert(&self, con: &SqliteConnection) -> QueryResult { - use schema::episode::dsl::*; - diesel::insert_into(episode).values(self).execute(&*con) - } -} - -impl Update for NewEpisode { - fn update(&self, con: &SqliteConnection, episode_id: i32) -> QueryResult { - use schema::episode::dsl::*; - - diesel::update(episode.filter(id.eq(episode_id))) - .set(self) - .execute(&*con) - } -} - -impl NewEpisode { - // TODO: Currently using diesel from master git. - // Watch out for v0.99.0 beta and change the toml. - // TODO: Refactor into batch indexes instead. - pub fn into_episode(self, con: &SqliteConnection) -> Result { - self.index(con)?; - Ok(dbqueries::get_episode_from_uri(con, &self.uri)?) - } - - pub fn index(&self, con: &SqliteConnection) -> QueryResult<()> { - let ep = dbqueries::get_episode_from_uri(con, &self.uri.clone()); - - match ep { - Ok(foo) => { - if foo.podcast_id() != self.podcast_id { - error!("NEP pid: {}, EP pid: {}", self.podcast_id, foo.podcast_id()); - }; - - if foo.title() != self.title.as_ref().map(|x| x.as_str()) - || foo.published_date() != self.published_date.as_ref().map(|x| x.as_str()) - { - self.update(con, *foo.id())?; - } - } - Err(_) => { - self.insert(con)?; - } - } - Ok(()) - } -} - #[derive(Insertable, AsChangeset)] #[table_name = "podcast"] #[derive(Debug, Clone)] pub(crate) struct NewPodcast { - pub title: String, - pub link: String, - pub description: String, - pub image_uri: Option, - pub source_id: i32, + title: String, + link: String, + description: String, + image_uri: Option, + source_id: i32, } impl Insert for NewPodcast { @@ -154,12 +91,12 @@ impl Update for NewPodcast { impl NewPodcast { // Look out for when tryinto lands into stable. - pub fn into_podcast(self) -> Result { + pub(crate) fn into_podcast(self) -> Result { self.index()?; Ok(dbqueries::get_podcast_from_source_id(self.source_id)?) } - pub fn index(&self) -> Result<()> { + pub(crate) fn index(&self) -> Result<()> { let pd = dbqueries::get_podcast_from_source_id(self.source_id); let db = connection(); @@ -183,3 +120,247 @@ impl NewPodcast { Ok(()) } } + +#[derive(Debug, Default)] +pub(crate) struct NewPodcastBuilder { + title: String, + link: String, + description: String, + image_uri: Option, + source_id: i32, +} + +impl NewPodcastBuilder { + pub(crate) fn new() -> NewPodcastBuilder { + NewPodcastBuilder::default() + } + + pub(crate) fn title(mut self, s: String) -> NewPodcastBuilder { + self.title = s; + self + } + + pub(crate) fn link(mut self, s: String) -> NewPodcastBuilder { + self.link = s; + self + } + + pub(crate) fn description(mut self, s: String) -> NewPodcastBuilder { + self.description = s; + self + } + + pub(crate) fn image_uri(mut self, s: Option) -> NewPodcastBuilder { + self.image_uri = s; + self + } + + pub(crate) fn source_id(mut self, s: i32) -> NewPodcastBuilder { + self.source_id = s; + self + } + + pub(crate) fn build(self) -> NewPodcast { + NewPodcast { + title: self.title, + link: self.link, + description: self.description, + image_uri: self.image_uri, + source_id: self.source_id, + } + } +} + +#[allow(dead_code)] +// Ignore the following geters. They are used in unit tests mainly. +impl NewPodcast { + pub(crate) fn source_id(&self) -> i32 { + self.source_id + } + + pub(crate) fn title(&self) -> &str { + &self.title + } + + pub(crate) fn link(&self) -> &str { + &self.link + } + + pub(crate) fn description(&self) -> &str { + &self.description + } + + pub(crate) fn image_uri(&self) -> Option<&str> { + self.image_uri.as_ref().map(|s| s.as_str()) + } +} + +#[derive(Insertable, AsChangeset)] +#[table_name = "episode"] +#[derive(Debug, Clone, Default)] +pub(crate) struct NewEpisode { + title: Option, + uri: String, + description: Option, + published_date: Option, + length: Option, + guid: Option, + epoch: i32, + podcast_id: i32, +} + +impl Insert for NewEpisode { + fn insert(&self, con: &SqliteConnection) -> QueryResult { + use schema::episode::dsl::*; + diesel::insert_into(episode).values(self).execute(&*con) + } +} + +impl Update for NewEpisode { + fn update(&self, con: &SqliteConnection, episode_id: i32) -> QueryResult { + use schema::episode::dsl::*; + + diesel::update(episode.filter(id.eq(episode_id))) + .set(self) + .execute(&*con) + } +} + +impl NewEpisode { + // TODO: Currently using diesel from master git. + // Watch out for v0.99.0 beta and change the toml. + // TODO: Refactor into batch indexes instead. + pub(crate) fn into_episode(self, con: &SqliteConnection) -> Result { + self.index(con)?; + Ok(dbqueries::get_episode_from_uri(con, &self.uri)?) + } + + pub(crate) fn index(&self, con: &SqliteConnection) -> QueryResult<()> { + let ep = dbqueries::get_episode_from_uri(con, &self.uri.clone()); + + match ep { + Ok(foo) => { + if foo.podcast_id() != self.podcast_id { + error!("NEP pid: {}, EP pid: {}", self.podcast_id, foo.podcast_id()); + }; + + if foo.title() != self.title.as_ref().map(|x| x.as_str()) + || foo.published_date() != self.published_date.as_ref().map(|x| x.as_str()) + { + self.update(con, *foo.id())?; + } + } + Err(_) => { + self.insert(con)?; + } + } + Ok(()) + } +} + +#[derive(Debug, Default)] +pub(crate) struct NewEpisodeBuilder { + title: Option, + uri: String, + description: Option, + published_date: Option, + length: Option, + guid: Option, + epoch: i32, + podcast_id: i32, +} + +impl NewEpisodeBuilder { + pub(crate) fn new() -> NewEpisodeBuilder { + NewEpisodeBuilder::default() + } + + pub(crate) fn title(mut self, s: Option) -> NewEpisodeBuilder { + self.title = s; + self + } + + pub(crate) fn uri(mut self, s: String) -> NewEpisodeBuilder { + self.uri = s; + self + } + + pub(crate) fn description(mut self, s: Option) -> NewEpisodeBuilder { + self.description = s; + self + } + + pub(crate) fn published_date(mut self, s: Option) -> NewEpisodeBuilder { + self.published_date = s; + self + } + + pub(crate) fn length(mut self, s: Option) -> NewEpisodeBuilder { + self.length = s; + self + } + + pub(crate) fn guid(mut self, s: Option) -> NewEpisodeBuilder { + self.guid = s; + self + } + + pub(crate) fn epoch(mut self, s: i32) -> NewEpisodeBuilder { + self.epoch = s; + self + } + + pub(crate) fn podcast_id(mut self, s: i32) -> NewEpisodeBuilder { + self.podcast_id = s; + self + } + + pub(crate) fn build(self) -> NewEpisode { + NewEpisode { + title: self.title, + uri: self.uri, + description: self.description, + published_date: self.published_date, + length: self.length, + guid: self.guid, + epoch: self.epoch, + podcast_id: self.podcast_id, + } + } +} + +#[allow(dead_code)] +// Ignore the following geters. They are used in unit tests mainly. +impl NewEpisode { + pub(crate) fn title(&self) -> Option<&str> { + self.title.as_ref().map(|s| s.as_str()) + } + + pub(crate) fn uri(&self) -> &str { + self.uri.as_ref() + } + + pub(crate) fn description(&self) -> Option<&str> { + self.description.as_ref().map(|s| s.as_str()) + } + + pub(crate) fn published_date(&self) -> Option<&str> { + self.published_date.as_ref().map(|s| s.as_str()) + } + + pub(crate) fn guid(&self) -> Option<&str> { + self.guid.as_ref().map(|s| s.as_str()) + } + + pub(crate) fn epoch(&self) -> i32 { + self.epoch + } + + pub(crate) fn length(&self) -> Option { + self.length + } + + pub(crate) fn podcast_id(&self) -> i32 { + self.podcast_id + } +} diff --git a/hammond-data/src/parser.rs b/hammond-data/src/parser.rs index b3b8d2f..f71a4e4 100644 --- a/hammond-data/src/parser.rs +++ b/hammond-data/src/parser.rs @@ -1,7 +1,7 @@ use rss::{Channel, Item}; use rfc822_sanitizer::parse_from_rfc2822_with_fallback; -use models::insertables::{NewEpisode, NewPodcast}; +use models::insertables::{NewEpisode, NewEpisodeBuilder, NewPodcast, NewPodcastBuilder}; use utils::url_cleaner; use errors::*; @@ -20,13 +20,13 @@ pub(crate) fn new_podcast(chan: &Channel, source_id: i32) -> NewPodcast { chan.image().map(|foo| url_cleaner(foo.url())) }; - NewPodcast { - title, - link, - description, - image_uri, - source_id, - } + NewPodcastBuilder::new() + .title(title) + .description(description) + .link(link) + .image_uri(image_uri) + .source_id(source_id) + .build() } /// Parses an `rss::Item` into a `NewEpisode` Struct. @@ -60,16 +60,18 @@ pub(crate) fn new_episode(item: &Item, parent_id: i32) -> Result { let length = item.enclosure().map(|x| x.length().parse().unwrap_or(0)); - Ok(NewEpisode { - title, - uri, - description, - length, - published_date: pub_date, - epoch, - guid, - podcast_id: parent_id, - }) + Ok( + NewEpisodeBuilder::new() + .title(title) + .uri(uri) + .description(description) + .length(length) + .published_date(pub_date) + .epoch(epoch) + .guid(guid) + .podcast_id(parent_id) + .build(), + ) } @@ -93,16 +95,15 @@ mod tests { newsmakers who challenge our preconceptions about the world we live in."; let pd = new_podcast(&channel, 0); - assert_eq!(pd.title, "Intercepted with Jeremy Scahill".to_string()); - assert_eq!(pd.link, "https://theintercept.com/podcasts".to_string()); - assert_eq!(pd.description, descr.to_string()); + assert_eq!(pd.title(), "Intercepted with Jeremy Scahill"); + assert_eq!(pd.link(), "https://theintercept.com/podcasts"); + assert_eq!(pd.description(), descr); assert_eq!( - pd.image_uri, + pd.image_uri(), Some( "http://static.megaphone.fm/podcasts/d5735a50-d904-11e6-8532-73c7de466ea6/image/\ uploads_2F1484252190700-qhn5krasklbce3dh-a797539282700ea0298a3a26f7e49b0b_\ 2FIntercepted_COVER%2B_281_29.png" - .to_string() ), ); } @@ -117,12 +118,12 @@ mod tests { interest."; let pd = new_podcast(&channel, 0); - assert_eq!(pd.title, "The Breakthrough".to_string()); - assert_eq!(pd.link, "http://www.propublica.org/podcast".to_string()); - assert_eq!(pd.description, descr.to_string()); + assert_eq!(pd.title(), "The Breakthrough"); + assert_eq!(pd.link(), "http://www.propublica.org/podcast"); + assert_eq!(pd.description(), descr); assert_eq!( - pd.image_uri, - Some("http://www.propublica.org/images/podcast_logo_2.png".to_string()), + pd.image_uri(), + Some("http://www.propublica.org/images/podcast_logo_2.png"), ); } @@ -136,12 +137,12 @@ mod tests { Linux."; let pd = new_podcast(&channel, 0); - assert_eq!(pd.title, "LINUX Unplugged Podcast".to_string()); - assert_eq!(pd.link, "http://www.jupiterbroadcasting.com/".to_string()); - assert_eq!(pd.description, descr.to_string()); + assert_eq!(pd.title(), "LINUX Unplugged Podcast"); + assert_eq!(pd.link(), "http://www.jupiterbroadcasting.com/"); + assert_eq!(pd.description(), descr); assert_eq!( - pd.image_uri, - Some("http://www.jupiterbroadcasting.com/images/LASUN-Badge1400.jpg".to_string(),) + pd.image_uri(), + Some("http://www.jupiterbroadcasting.com/images/LASUN-Badge1400.jpg") ); } @@ -153,15 +154,15 @@ mod tests { let pd = new_podcast(&channel, 0); let descr = "A weekly discussion of Rust RFCs"; - assert_eq!(pd.title, "Request For Explanation".to_string()); + assert_eq!(pd.title(), "Request For Explanation"); assert_eq!( - pd.link, - "https://request-for-explanation.github.io/podcast/".to_string() + pd.link(), + "https://request-for-explanation.github.io/podcast/" ); - assert_eq!(pd.description, descr.to_string()); + assert_eq!(pd.description(), descr); assert_eq!( - pd.image_uri, - Some("https://request-for-explanation.github.io/podcast/podcast.png".to_string()), + pd.image_uri(), + Some("https://request-for-explanation.github.io/podcast/podcast.png"), ); } @@ -178,22 +179,13 @@ mod tests { performs."; let i = new_episode(&firstitem, 0).unwrap(); - assert_eq!(i.title, Some("The Super Bowl of Racism".to_string())); - assert_eq!( - i.uri, - "http://traffic.megaphone.fm/PPY6458293736.mp3".to_string() - ); - assert_eq!(i.description, Some(descr.to_string())); - assert_eq!(i.length, Some(66738886)); - assert_eq!( - i.guid, - Some("7df4070a-9832-11e7-adac-cb37b05d5e24".to_string()) - ); - assert_eq!( - i.published_date, - Some("Wed, 13 Sep 2017 10:00:00 +0000".to_string()) - ); - assert_eq!(i.epoch, 1505296800); + assert_eq!(i.title(), Some("The Super Bowl of Racism")); + assert_eq!(i.uri(), "http://traffic.megaphone.fm/PPY6458293736.mp3"); + assert_eq!(i.description(), Some(descr)); + assert_eq!(i.length(), Some(66738886)); + assert_eq!(i.guid(), Some("7df4070a-9832-11e7-adac-cb37b05d5e24")); + assert_eq!(i.published_date(), Some("Wed, 13 Sep 2017 10:00:00 +0000")); + assert_eq!(i.epoch(), 1505296800); let second = channel.items().iter().nth(1).unwrap(); let i2 = new_episode(&second, 0).unwrap(); @@ -207,24 +199,15 @@ mod tests { Caracas-based band, La Pequeña Revancha, talk about her music and hopes for \ Venezuela."; assert_eq!( - i2.title, - Some("Atlas Golfed — U.S.-Backed Think Tanks Target Latin America".to_string(),) + i2.title(), + Some("Atlas Golfed — U.S.-Backed Think Tanks Target Latin America") ); - assert_eq!( - i2.uri, - "http://traffic.megaphone.fm/FL5331443769.mp3".to_string() - ); - assert_eq!(i2.description, Some(descr2.to_string())); - assert_eq!(i2.length, Some(67527575)); - assert_eq!( - i2.guid, - Some("7c207a24-e33f-11e6-9438-eb45dcf36a1d".to_string()) - ); - assert_eq!( - i2.published_date, - Some("Wed, 9 Aug 2017 10:00:00 +0000".to_string()) - ); - assert_eq!(i2.epoch, 1502272800); + assert_eq!(i2.uri(), "http://traffic.megaphone.fm/FL5331443769.mp3"); + assert_eq!(i2.description(), Some(descr2)); + assert_eq!(i2.length(), Some(67527575)); + assert_eq!(i2.guid(), Some("7c207a24-e33f-11e6-9438-eb45dcf36a1d")); + assert_eq!(i2.published_date(), Some("Wed, 9 Aug 2017 10:00:00 +0000")); + assert_eq!(i2.epoch(), 1502272800); } #[test] @@ -238,31 +221,24 @@ mod tests { let i = new_episode(&firstitem, 0).unwrap(); assert_eq!( - i.title, - Some( - "The Breakthrough: Hopelessness and Exploitation Inside Homes for Mentally Ill" - .to_string(), - ) + i.title(), + Some("The Breakthrough: Hopelessness and Exploitation Inside Homes for Mentally Ill") ); assert_eq!( - i.uri, - "http://tracking.feedpress.it/link/10581/6726758/20170908-cliff-levy.mp3".to_string(), + i.uri(), + "http://tracking.feedpress.it/link/10581/6726758/20170908-cliff-levy.mp3", ); - assert_eq!(i.description, Some(descr.to_string())); - assert_eq!(i.length, Some(33396551)); + assert_eq!(i.description(), Some(descr)); + assert_eq!(i.length(), Some(33396551)); assert_eq!( - i.guid, + i.guid(), Some( "https://www.propublica.org/podcast/\ the-breakthrough-hopelessness-exploitation-homes-for-mentally-ill#134472" - .to_string(), ) ); - assert_eq!( - i.published_date, - Some("Fri, 8 Sep 2017 12:00:00 +0000".to_string()) - ); - assert_eq!(i.epoch, 1504872000); + assert_eq!(i.published_date(), Some("Fri, 8 Sep 2017 12:00:00 +0000")); + assert_eq!(i.epoch(), 1504872000); let second = channel.items().iter().nth(1).unwrap(); let i2 = new_episode(&second, 0).unwrap(); @@ -271,29 +247,25 @@ mod tests { the mounting signs of a doomed campaign.

"; assert_eq!( - i2.title, + i2.title(), Some("The Breakthrough: Behind the Scenes of Hillary Clinton’s Failed Bid for \ - President".to_string()) + President") ); assert_eq!( - i2.uri, + i2.uri(), "http://tracking.feedpress.it/link/10581/6726759/16_JohnAllen-CRAFT.mp3".to_string(), ); - assert_eq!(i2.description, Some(descr2.to_string())); - assert_eq!(i2.length, Some(17964071)); + assert_eq!(i2.description(), Some(descr2)); + assert_eq!(i2.length(), Some(17964071)); assert_eq!( - i2.guid, + i2.guid(), Some( "https://www.propublica.\ org/podcast/the-breakthrough-hillary-clinton-failed-presidential-bid#133721" - .to_string(), ) ); - assert_eq!( - i2.published_date, - Some("Fri, 25 Aug 2017 12:00:00 +0000".to_string()) - ); - assert_eq!(i2.epoch, 1503662400); + assert_eq!(i2.published_date(), Some("Fri, 25 Aug 2017 12:00:00 +0000")); + assert_eq!(i2.epoch(), 1503662400); } #[test] @@ -308,26 +280,16 @@ mod tests { blaming open source & the Beard just saved the show. It’s a really packed episode!"; let i = new_episode(&firstitem, 0).unwrap(); + assert_eq!(i.title(), Some("Hacking Devices with Kali Linux | LUP 214")); assert_eq!( - i.title, - Some("Hacking Devices with Kali Linux | LUP 214".to_string()) - ); - assert_eq!( - i.uri, + i.uri(), "http://www.podtrac.com/pts/redirect.mp3/traffic.libsyn.com/jnite/lup-0214.mp3" - .to_string(), ); - assert_eq!(i.description, Some(descr.to_string())); - assert_eq!(i.length, Some(46479789)); - assert_eq!( - i.guid, - Some("78A682B4-73E8-47B8-88C0-1BE62DD4EF9D".to_string()) - ); - assert_eq!( - i.published_date, - Some("Tue, 12 Sep 2017 22:24:42 -0700".to_string()) - ); - assert_eq!(i.epoch, 1505280282); + assert_eq!(i.description(), Some(descr)); + assert_eq!(i.length(), Some(46479789)); + assert_eq!(i.guid(), Some("78A682B4-73E8-47B8-88C0-1BE62DD4EF9D")); + assert_eq!(i.published_date(), Some("Tue, 12 Sep 2017 22:24:42 -0700")); + assert_eq!(i.epoch(), 1505280282); let second = channel.items().iter().nth(1).unwrap(); let i2 = new_episode(&second, 0).unwrap(); @@ -338,23 +300,16 @@ mod tests { future.

\n\n

Plus we chat with Wimpy about the Ubuntu Rally in NYC, \ Microsoft’s sneaky move to turn Windows 10 into the “ULTIMATE LINUX \ RUNTIME”, community news & more!

"; - assert_eq!(i2.title, Some("Gnome Does it Again | LUP 213".to_string())); + assert_eq!(i2.title(), Some("Gnome Does it Again | LUP 213")); assert_eq!( - i2.uri, + i2.uri(), "http://www.podtrac.com/pts/redirect.mp3/traffic.libsyn.com/jnite/lup-0213.mp3" - .to_string(), ); - assert_eq!(i2.description, Some(descr2.to_string())); - assert_eq!(i2.length, Some(36544272)); - assert_eq!( - i2.guid, - Some("1CE57548-B36C-4F14-832A-5D5E0A24E35B".to_string()) - ); - assert_eq!( - i2.published_date, - Some("Tue, 5 Sep 2017 20:57:27 -0700".to_string()) - ); - assert_eq!(i2.epoch, 1504670247); + assert_eq!(i2.description(), Some(descr2)); + assert_eq!(i2.length(), Some(36544272)); + assert_eq!(i2.guid(), Some("1CE57548-B36C-4F14-832A-5D5E0A24E35B")); + assert_eq!(i2.published_date(), Some("Tue, 5 Sep 2017 20:57:27 -0700")); + assert_eq!(i2.epoch(), 1504670247); } #[test] @@ -368,30 +323,20 @@ mod tests { \"Non-lexical lifetimes\""; let i = new_episode(&firstitem, 0).unwrap(); + assert_eq!(i.title(), Some("Episode #9 - A Once in a Lifetime RFC")); assert_eq!( - i.title, - Some("Episode #9 - A Once in a Lifetime RFC".to_string()) - ); - assert_eq!( - i.uri, + i.uri(), "http://request-for-explanation.github.\ io/podcast/ep9-a-once-in-a-lifetime-rfc/episode.mp3" - .to_string(), ); - assert_eq!(i.description, Some(descr.to_string())); - assert_eq!(i.length, Some(15077388)); + assert_eq!(i.description(), Some(descr)); + assert_eq!(i.length(), Some(15077388)); assert_eq!( - i.guid, - Some( - "https://request-for-explanation.github.io/podcast/ep9-a-once-in-a-lifetime-rfc/" - .to_string(), - ) + i.guid(), + Some("https://request-for-explanation.github.io/podcast/ep9-a-once-in-a-lifetime-rfc/") ); - assert_eq!( - i.published_date, - Some("Mon, 28 Aug 2017 15:00:00 -0700".to_string()) - ); - assert_eq!(i.epoch, 1503957600); + assert_eq!(i.published_date(), Some("Mon, 28 Aug 2017 15:00:00 -0700")); + assert_eq!(i.epoch(), 1503957600); let second = channel.items().iter().nth(8).unwrap(); let i2 = new_episode(&second, 0).unwrap(); @@ -399,29 +344,19 @@ mod tests { let descr2 = "This week we look at RFC 2071 \"Add \ impl Trait type alias and variable declarations\""; + assert_eq!(i2.title(), Some("Episode #8 - An Existential Crisis")); assert_eq!( - i2.title, - Some("Episode #8 - An Existential Crisis".to_string()) - ); - assert_eq!( - i2.uri, + i2.uri(), "http://request-for-explanation.github.io/podcast/ep8-an-existential-crisis/episode.\ mp3" - .to_string(), ); - assert_eq!(i2.description, Some(descr2.to_string())); - assert_eq!(i2.length, Some(13713219)); + assert_eq!(i2.description(), Some(descr2)); + assert_eq!(i2.length(), Some(13713219)); assert_eq!( - i2.guid, - Some( - "https://request-for-explanation.github.io/podcast/ep8-an-existential-crisis/" - .to_string(), - ) + i2.guid(), + Some("https://request-for-explanation.github.io/podcast/ep8-an-existential-crisis/") ); - assert_eq!( - i2.published_date, - Some("Tue, 15 Aug 2017 17:00:00 -0700".to_string()) - ); - assert_eq!(i2.epoch, 1502841600); + assert_eq!(i2.published_date(), Some("Tue, 15 Aug 2017 17:00:00 -0700")); + assert_eq!(i2.epoch(), 1502841600); } }