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<String>,
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" if !text.is_empty() => {
93 if feed.syndication.is_none() {
94 feed.syndication = Some(Box::new(SyndicationMeta::default()));
95 }
96 if let Some(syn) = &mut feed.syndication {
97 syn.update_frequency = Some(text.to_string());
98 }
99 }
100 "updateBase" => {
101 if feed.syndication.is_none() {
102 feed.syndication = Some(Box::new(SyndicationMeta::default()));
103 }
104 if let Some(syn) = &mut feed.syndication {
105 syn.update_base = Some(text.to_string());
106 }
107 }
108 _ => {
109 }
111 }
112}
113
114#[cfg(test)]
115mod tests {
116 use super::*;
117
118 #[test]
119 fn test_update_period_parse() {
120 assert_eq!(UpdatePeriod::parse("hourly"), Some(UpdatePeriod::Hourly));
121 assert_eq!(UpdatePeriod::parse("daily"), Some(UpdatePeriod::Daily));
122 assert_eq!(UpdatePeriod::parse("weekly"), Some(UpdatePeriod::Weekly));
123 assert_eq!(UpdatePeriod::parse("monthly"), Some(UpdatePeriod::Monthly));
124 assert_eq!(UpdatePeriod::parse("yearly"), Some(UpdatePeriod::Yearly));
125 assert_eq!(UpdatePeriod::parse("invalid"), None);
126 }
127
128 #[test]
129 fn test_update_period_case_insensitive() {
130 assert_eq!(UpdatePeriod::parse("HOURLY"), Some(UpdatePeriod::Hourly));
131 assert_eq!(UpdatePeriod::parse("Daily"), Some(UpdatePeriod::Daily));
132 assert_eq!(UpdatePeriod::parse("WeeKLY"), Some(UpdatePeriod::Weekly));
133 }
134
135 #[test]
136 fn test_update_period_as_str() {
137 assert_eq!(UpdatePeriod::Hourly.as_str(), "hourly");
138 assert_eq!(UpdatePeriod::Daily.as_str(), "daily");
139 assert_eq!(UpdatePeriod::Weekly.as_str(), "weekly");
140 assert_eq!(UpdatePeriod::Monthly.as_str(), "monthly");
141 assert_eq!(UpdatePeriod::Yearly.as_str(), "yearly");
142 }
143
144 #[test]
145 fn test_handle_update_period() {
146 let mut feed = FeedMeta::default();
147
148 handle_feed_element("updatePeriod", "daily", &mut feed);
149
150 assert!(feed.syndication.is_some());
151 let syn = feed.syndication.as_ref().unwrap();
152 assert_eq!(syn.update_period, Some(UpdatePeriod::Daily));
153 }
154
155 #[test]
156 fn test_handle_update_frequency() {
157 let mut feed = FeedMeta::default();
158
159 handle_feed_element("updateFrequency", "2", &mut feed);
160
161 assert!(feed.syndication.is_some());
162 let syn = feed.syndication.as_ref().unwrap();
163 assert_eq!(syn.update_frequency, Some("2".to_string()));
164 }
165
166 #[test]
167 fn test_handle_update_base() {
168 let mut feed = FeedMeta::default();
169
170 handle_feed_element("updateBase", "2024-12-18T00:00:00Z", &mut feed);
171
172 assert!(feed.syndication.is_some());
173 let syn = feed.syndication.as_ref().unwrap();
174 assert_eq!(syn.update_base.as_deref(), Some("2024-12-18T00:00:00Z"));
175 }
176
177 #[test]
178 fn test_handle_multiple_elements() {
179 let mut feed = FeedMeta::default();
180
181 handle_feed_element("updatePeriod", "hourly", &mut feed);
182 handle_feed_element("updateFrequency", "1", &mut feed);
183 handle_feed_element("updateBase", "2024-01-01T00:00:00Z", &mut feed);
184
185 let syn = feed.syndication.as_ref().unwrap();
186 assert_eq!(syn.update_period, Some(UpdatePeriod::Hourly));
187 assert_eq!(syn.update_frequency, Some("1".to_string()));
188 assert_eq!(syn.update_base.as_deref(), Some("2024-01-01T00:00:00Z"));
189 }
190
191 #[test]
192 fn test_handle_invalid_frequency() {
193 let mut feed = FeedMeta::default();
194
195 handle_feed_element("updateFrequency", "not-a-number", &mut feed);
196
197 let syn = feed.syndication.as_ref().unwrap();
199 assert_eq!(syn.update_frequency, Some("not-a-number".to_string()));
200 }
201
202 #[test]
203 fn test_handle_unknown_element() {
204 let mut feed = FeedMeta::default();
205
206 handle_feed_element("unknown", "value", &mut feed);
207
208 assert!(feed.syndication.is_none());
209 }
210}