feedparser_rs/namespace/
content.rs

1/// Content Module for RSS 1.0
2///
3/// Namespace: <http://purl.org/rss/1.0/modules/content/>
4/// Prefix: content
5///
6/// This module provides parsing support for the Content namespace,
7/// commonly used in `WordPress` and other RSS feeds to provide full
8/// HTML content separate from the summary.
9///
10/// Elements:
11/// - `content:encoded` → adds to entry.content with type "text/html"
12use crate::types::{Content, Entry};
13
14/// Content namespace URI
15pub const CONTENT_NAMESPACE: &str = "http://purl.org/rss/1.0/modules/content/";
16
17/// Handle Content namespace element at entry level
18///
19/// # Arguments
20///
21/// * `element` - Local name of the element (without namespace prefix)
22/// * `text` - Text content of the element
23/// * `entry` - Entry to update
24pub fn handle_entry_element(element: &str, text: &str, entry: &mut Entry) {
25    if element == "encoded" {
26        // content:encoded → add to entry.content as HTML
27        entry.content.push(Content {
28            value: text.to_string(),
29            content_type: Some("text/html".into()),
30            language: None,
31            base: None,
32        });
33    }
34}
35
36#[cfg(test)]
37mod tests {
38    use super::*;
39
40    #[test]
41    fn test_content_encoded() {
42        let mut entry = Entry::default();
43        let html = r"<p>Full HTML content with <strong>formatting</strong>.</p>";
44
45        handle_entry_element("encoded", html, &mut entry);
46
47        assert_eq!(entry.content.len(), 1);
48        assert_eq!(entry.content[0].value, html);
49        assert_eq!(entry.content[0].content_type.as_deref(), Some("text/html"));
50    }
51
52    #[test]
53    fn test_multiple_content_encoded() {
54        let mut entry = Entry::default();
55
56        handle_entry_element("encoded", "<p>First content</p>", &mut entry);
57        handle_entry_element("encoded", "<p>Second content</p>", &mut entry);
58
59        assert_eq!(entry.content.len(), 2);
60    }
61
62    #[test]
63    fn test_content_with_cdata() {
64        let mut entry = Entry::default();
65        // CDATA markers are typically stripped by XML parser before we see it
66        let html = r"<p>Content from <![CDATA[...]]></p>";
67
68        handle_entry_element("encoded", html, &mut entry);
69
70        assert!(!entry.content.is_empty());
71    }
72
73    #[test]
74    fn test_ignore_unknown_elements() {
75        let mut entry = Entry::default();
76
77        handle_entry_element("unknown", "test", &mut entry);
78
79        assert!(entry.content.is_empty());
80    }
81}