feedparser_rs/namespace/
syndication.rs1use crate::types::FeedMeta;
14
15pub const SYNDICATION_NAMESPACE: &str = "http://purl.org/rss/1.0/modules/syndication/";
17
18#[derive(Debug, Clone, Copy, PartialEq, Eq)]
20pub enum UpdatePeriod {
21 Hourly,
23 Daily,
25 Weekly,
27 Monthly,
29 Yearly,
31}
32
33impl UpdatePeriod {
34 #[must_use]
38 pub fn parse(s: &str) -> Option<Self> {
39 match s.to_lowercase().as_str() {
40 "hourly" => Some(Self::Hourly),
41 "daily" => Some(Self::Daily),
42 "weekly" => Some(Self::Weekly),
43 "monthly" => Some(Self::Monthly),
44 "yearly" => Some(Self::Yearly),
45 _ => None,
46 }
47 }
48
49 #[must_use]
51 pub const fn as_str(&self) -> &'static str {
52 match self {
53 Self::Hourly => "hourly",
54 Self::Daily => "daily",
55 Self::Weekly => "weekly",
56 Self::Monthly => "monthly",
57 Self::Yearly => "yearly",
58 }
59 }
60}
61
62#[derive(Debug, Clone, Default)]
64pub struct SyndicationMeta {
65 pub update_period: Option<UpdatePeriod>,
67 pub update_frequency: Option<u32>,
69 pub update_base: Option<String>,
71}
72
73pub fn handle_feed_element(element: &str, text: &str, feed: &mut FeedMeta) {
81 match element {
82 "updatePeriod" => {
83 if let Some(period) = UpdatePeriod::parse(text) {
84 if feed.syndication.is_none() {
85 feed.syndication = Some(Box::new(SyndicationMeta::default()));
86 }
87 if let Some(syn) = &mut feed.syndication {
88 syn.update_period = Some(period);
89 }
90 }
91 }
92 "updateFrequency" => {
93 if let Ok(freq) = text.parse::<u32>() {
94 if feed.syndication.is_none() {
95 feed.syndication = Some(Box::new(SyndicationMeta::default()));
96 }
97 if let Some(syn) = &mut feed.syndication {
98 syn.update_frequency = Some(freq);
99 }
100 }
101 }
102 "updateBase" => {
103 if feed.syndication.is_none() {
104 feed.syndication = Some(Box::new(SyndicationMeta::default()));
105 }
106 if let Some(syn) = &mut feed.syndication {
107 syn.update_base = Some(text.to_string());
108 }
109 }
110 _ => {
111 }
113 }
114}
115
116#[cfg(test)]
117mod tests {
118 use super::*;
119
120 #[test]
121 fn test_update_period_parse() {
122 assert_eq!(UpdatePeriod::parse("hourly"), Some(UpdatePeriod::Hourly));
123 assert_eq!(UpdatePeriod::parse("daily"), Some(UpdatePeriod::Daily));
124 assert_eq!(UpdatePeriod::parse("weekly"), Some(UpdatePeriod::Weekly));
125 assert_eq!(UpdatePeriod::parse("monthly"), Some(UpdatePeriod::Monthly));
126 assert_eq!(UpdatePeriod::parse("yearly"), Some(UpdatePeriod::Yearly));
127 assert_eq!(UpdatePeriod::parse("invalid"), None);
128 }
129
130 #[test]
131 fn test_update_period_case_insensitive() {
132 assert_eq!(UpdatePeriod::parse("HOURLY"), Some(UpdatePeriod::Hourly));
133 assert_eq!(UpdatePeriod::parse("Daily"), Some(UpdatePeriod::Daily));
134 assert_eq!(UpdatePeriod::parse("WeeKLY"), Some(UpdatePeriod::Weekly));
135 }
136
137 #[test]
138 fn test_update_period_as_str() {
139 assert_eq!(UpdatePeriod::Hourly.as_str(), "hourly");
140 assert_eq!(UpdatePeriod::Daily.as_str(), "daily");
141 assert_eq!(UpdatePeriod::Weekly.as_str(), "weekly");
142 assert_eq!(UpdatePeriod::Monthly.as_str(), "monthly");
143 assert_eq!(UpdatePeriod::Yearly.as_str(), "yearly");
144 }
145
146 #[test]
147 fn test_handle_update_period() {
148 let mut feed = FeedMeta::default();
149
150 handle_feed_element("updatePeriod", "daily", &mut feed);
151
152 assert!(feed.syndication.is_some());
153 let syn = feed.syndication.as_ref().unwrap();
154 assert_eq!(syn.update_period, Some(UpdatePeriod::Daily));
155 }
156
157 #[test]
158 fn test_handle_update_frequency() {
159 let mut feed = FeedMeta::default();
160
161 handle_feed_element("updateFrequency", "2", &mut feed);
162
163 assert!(feed.syndication.is_some());
164 let syn = feed.syndication.as_ref().unwrap();
165 assert_eq!(syn.update_frequency, Some(2));
166 }
167
168 #[test]
169 fn test_handle_update_base() {
170 let mut feed = FeedMeta::default();
171
172 handle_feed_element("updateBase", "2024-12-18T00:00:00Z", &mut feed);
173
174 assert!(feed.syndication.is_some());
175 let syn = feed.syndication.as_ref().unwrap();
176 assert_eq!(syn.update_base.as_deref(), Some("2024-12-18T00:00:00Z"));
177 }
178
179 #[test]
180 fn test_handle_multiple_elements() {
181 let mut feed = FeedMeta::default();
182
183 handle_feed_element("updatePeriod", "hourly", &mut feed);
184 handle_feed_element("updateFrequency", "1", &mut feed);
185 handle_feed_element("updateBase", "2024-01-01T00:00:00Z", &mut feed);
186
187 let syn = feed.syndication.as_ref().unwrap();
188 assert_eq!(syn.update_period, Some(UpdatePeriod::Hourly));
189 assert_eq!(syn.update_frequency, Some(1));
190 assert_eq!(syn.update_base.as_deref(), Some("2024-01-01T00:00:00Z"));
191 }
192
193 #[test]
194 fn test_handle_invalid_frequency() {
195 let mut feed = FeedMeta::default();
196
197 handle_feed_element("updateFrequency", "not-a-number", &mut feed);
198
199 assert!(feed.syndication.is_none());
201 }
202
203 #[test]
204 fn test_handle_unknown_element() {
205 let mut feed = FeedMeta::default();
206
207 handle_feed_element("unknown", "value", &mut feed);
208
209 assert!(feed.syndication.is_none());
210 }
211}