diff --git a/src/parse.rs b/src/parse.rs index 3a75f7f..52409b7 100644 --- a/src/parse.rs +++ b/src/parse.rs @@ -1,11 +1,11 @@ -use crate::basic::{Bool, BoolType, Float, Integer, Number, NumberConstraint}; -use crate::itunes; +use crate::basic::{self, Bool, BoolType, Float, Integer, Number, NumberConstraint}; use crate::language::Language; use crate::mime; use crate::podcast; use crate::rss; use crate::strings::{Url, UrlConstraint}; use crate::time::{DateTime, TimeFormat}; +use crate::{itunes, GuidValue}; /// Used when values cannot be deserialized. /// @@ -263,6 +263,11 @@ fn parse_channel(channel: roxmltree::Node) -> rss::Channel { (Some(NS_PODCAST_1 | NS_PODCAST_2), "txt") => { new_channel.podcast_txt.push(parse_podcast_txt(child)); } + (Some(NS_PODCAST_1 | NS_PODCAST_2), "remoteItem") => { + new_channel + .podcast_remote_item + .push(parse_podcast_remote_item(child)); + } _ => {} } @@ -613,6 +618,32 @@ pub fn parse_podcast_person(person: roxmltree::Node) -> podcast::Person { new_person } +pub fn parse_podcast_remote_item(remote_item: roxmltree::Node) -> podcast::RemoteItem { + let mut new_remote_item = podcast::RemoteItem { + ..Default::default() + }; + + for attribute in remote_item.attributes() { + match attribute.name() { + "feedGuid" => new_remote_item.feed_guid = Some(podcast::Guid::parse(attribute.value())), + "feedUrl" => { + new_remote_item.feed_url = + Some(Url::parse(attribute.value(), UrlConstraint::AnyProtocol)) + } + "itemGuid" => { + new_remote_item.item_guid = Some(GuidValue::parse( + attribute.value(), + &Some(basic::Bool::Ok(false)), + )) + } + "medium" => new_remote_item.medium = Some(podcast::Medium::parse(attribute.value())), + _ => {} + } + } + + new_remote_item +} + pub fn parse_podcast_location(location: roxmltree::Node) -> podcast::Location { let mut new_location = podcast::Location { ..Default::default() diff --git a/src/podcast.rs b/src/podcast.rs index 970df57..95189fa 100644 --- a/src/podcast.rs +++ b/src/podcast.rs @@ -4,6 +4,7 @@ use crate::language::Language; use crate::mime; use crate::strings::Url; use crate::time::DateTime; +use crate::GuidValue; mod transcript; pub use transcript::Rel as TranscriptRel; @@ -259,3 +260,12 @@ pub struct Txt { pub purpose: Option, pub value: Option, } + +/// This element provides a way to "point" to another feed or an item in another feed in order to obtain some sort of data that the other feed or feed item has. +#[derive(Debug, PartialEq, Eq, Default)] +pub struct RemoteItem { + pub feed_guid: Option, + pub feed_url: Option, + pub item_guid: Option, + pub medium: Option, +} diff --git a/src/rss.rs b/src/rss.rs index e9d54d3..d9c8ace 100644 --- a/src/rss.rs +++ b/src/rss.rs @@ -63,6 +63,7 @@ pub struct Channel { pub podcast_live_item: Vec, pub podcast_block: Vec, pub podcast_txt: Vec, + pub podcast_remote_item: Vec, } /// Podcast episode. diff --git a/tests/data/podcast_namespace_example.xml b/tests/data/podcast_namespace_example.xml index c48283a..7028ddb 100644 --- a/tests/data/podcast_namespace_example.xml +++ b/tests/data/podcast_namespace_example.xml @@ -44,6 +44,13 @@ https://example.com/images/pci_avatar-massive.jpg + + diff --git a/tests/tests.rs b/tests/tests.rs index 20c9372..49d6598 100644 --- a/tests/tests.rs +++ b/tests/tests.rs @@ -434,6 +434,14 @@ fn deserialize() { value: Some("Austin, TX".to_string()), }], podcast_medium: vec![podcast::Medium::Podcast], + podcast_remote_item: vec![ + podcast::RemoteItem { + feed_guid: Some(podcast::Guid::Ok("ff519475-6e90-5231-91a0-37d092088d88".into())), + feed_url: Some(Url::Ok(url::Url::parse("https://media.rss.com/joemartinmusic/feed.xml").unwrap())), + item_guid: Some(GuidValue::Text("e75771b1-e8d4-4133-9392-c579822247d9".into())), + medium: Some(podcast::Medium::Music), + } + ], podcast_value: vec![podcast::Value { type_: Some(podcast::ValueType::Lightning), method: Some(podcast::ValueMethod::Keysend),