2024-01-11 17:30:55 +11:00
|
|
|
#![allow(dead_code)]
|
|
|
|
|
|
|
|
|
|
// See https://support.google.com/podcast-publishers/answer/9889544
|
|
|
|
|
// for some reasonably guidelines for how a podcast RSS feed should look.
|
|
|
|
|
|
|
|
|
|
use std::fmt;
|
|
|
|
|
use std::borrow::Cow;
|
|
|
|
|
|
|
|
|
|
#[derive(Debug, serde::Deserialize)]
|
|
|
|
|
pub struct Feed<'a> {
|
2025-08-29 21:46:22 +10:00
|
|
|
pub(crate) rss: Rss<'a>,
|
2024-01-11 17:30:55 +11:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#[derive(Debug, serde::Deserialize)]
|
|
|
|
|
pub struct Rss<'a> {
|
2025-08-29 21:46:22 +10:00
|
|
|
pub(crate) channel: Channel<'a>,
|
2024-01-11 17:30:55 +11:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#[derive(Debug, serde::Deserialize)]
|
|
|
|
|
pub struct Channel<'a> {
|
|
|
|
|
#[serde(rename = "item", default)]
|
2025-08-29 21:46:22 +10:00
|
|
|
pub(crate) items: Vec<Item<'a>>,
|
|
|
|
|
pub(crate) link: Option<Cow<'a, str>>,
|
|
|
|
|
pub(crate) title: Cow<'a, str>,
|
|
|
|
|
pub(crate) description: Option<Cow<'a, str>>,
|
2024-01-11 17:30:55 +11:00
|
|
|
#[serde(rename = "{http://www.itunes.com/dtds/podcast-1.0.dtd}itunes:author")]
|
2025-08-29 21:46:22 +10:00
|
|
|
pub(crate) author: Option<Cow<'a, str>>,
|
2024-01-11 17:30:55 +11:00
|
|
|
#[serde(rename = "{http://www.itunes.com/dtds/podcast-1.0.dtd}itunes:summary")]
|
2025-08-29 21:46:22 +10:00
|
|
|
pub(crate) summary: Option<Cow<'a, str>>,
|
2024-01-11 17:30:55 +11:00
|
|
|
#[serde(rename = "{http://www.itunes.com/dtds/podcast-1.0.dtd}itunes:image")]
|
2025-08-29 21:46:22 +10:00
|
|
|
pub(crate) itunes_image: Option<ItunesImage<'a>>,
|
|
|
|
|
pub(crate) image: Option<Image<'a>>,
|
2024-01-11 17:30:55 +11:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#[derive(Debug, serde::Deserialize)]
|
|
|
|
|
pub struct Image<'a> {
|
2025-08-29 21:46:22 +10:00
|
|
|
pub(crate) link: Option<Cow<'a, str>>,
|
|
|
|
|
pub(crate) title: Cow<'a, str>,
|
|
|
|
|
pub(crate) url: Cow<'a, str>,
|
2024-01-11 17:30:55 +11:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#[derive(Debug, serde::Deserialize)]
|
|
|
|
|
pub struct ItunesImage<'a> {
|
|
|
|
|
#[serde(rename = "$attr:href")]
|
2025-08-29 21:46:22 +10:00
|
|
|
pub(crate) href: Cow<'a, str>,
|
2024-01-11 17:30:55 +11:00
|
|
|
}
|
|
|
|
|
|
2025-08-29 21:46:22 +10:00
|
|
|
fn deserialize_publish_date<'de, D: serde::de::Deserializer<'de>> (
|
|
|
|
|
deserializer: D
|
2024-01-11 17:30:55 +11:00
|
|
|
) -> Result<chrono::NaiveDateTime, D::Error> {
|
|
|
|
|
struct Visitor;
|
|
|
|
|
impl<'de> serde::de::Visitor<'de> for Visitor {
|
|
|
|
|
type Value = chrono::NaiveDateTime;
|
|
|
|
|
|
2025-08-29 21:46:22 +10:00
|
|
|
fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
|
2024-01-11 17:30:55 +11:00
|
|
|
formatter.write_str("a string containing json data")
|
|
|
|
|
}
|
|
|
|
|
|
2025-08-29 21:46:22 +10:00
|
|
|
fn visit_str<E: serde::de::Error>(self, input: &str) -> Result<Self::Value, E> {
|
2024-01-11 17:30:55 +11:00
|
|
|
chrono::NaiveDateTime::parse_from_str(
|
|
|
|
|
input,
|
|
|
|
|
"%a, %d %b %Y %H:%M:%S %Z"
|
|
|
|
|
).map_err(E::custom)
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
deserializer.deserialize_any(Visitor)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#[derive(Debug, serde::Deserialize)]
|
|
|
|
|
pub struct Item<'a> {
|
2025-08-29 21:46:22 +10:00
|
|
|
pub(crate) title: Cow<'a, str>,
|
|
|
|
|
pub(crate) enclosure: Option<Enclosure<'a>>,
|
|
|
|
|
pub(crate) description: Option<Cow<'a, str>>,
|
2024-01-11 17:30:55 +11:00
|
|
|
#[serde(rename = "{http://www.itunes.com/dtds/podcast-1.0.dtd}itunes:summary")]
|
2025-08-29 21:46:22 +10:00
|
|
|
pub(crate) summary: Option<Cow<'a, str>>,
|
2024-01-11 17:30:55 +11:00
|
|
|
#[serde(rename = "pubDate", deserialize_with = "deserialize_publish_date")]
|
2025-08-29 21:46:22 +10:00
|
|
|
pub(crate) published: chrono::NaiveDateTime,
|
|
|
|
|
pub(crate) guid: Option<Cow<'a, str>>,
|
2024-01-11 17:30:55 +11:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#[derive(Debug, serde::Deserialize)]
|
|
|
|
|
pub struct Enclosure<'a> {
|
|
|
|
|
#[serde(rename = "$attr:url")]
|
2025-08-29 21:46:22 +10:00
|
|
|
pub(crate) url: Cow<'a, str>,
|
2024-01-11 17:30:55 +11:00
|
|
|
#[serde(rename = "$attr:type")]
|
2025-08-29 21:46:22 +10:00
|
|
|
pub(crate) mime_type: Option<Cow<'a, str>>,
|
2024-02-17 08:37:08 +11:00
|
|
|
//#[serde(rename = "$attr:length")]
|
2025-08-29 21:46:22 +10:00
|
|
|
//pub(crate) length: Option<u64>,
|
2024-01-11 17:30:55 +11:00
|
|
|
}
|
|
|
|
|
|