feed_rs/lib.rs
1#![doc(html_root_url = "https://docs.rs/rss/")]
2//! This crate provides a parser and common data model over Atom, RSS and JSON Feed content.
3//!
4//! The parser will automatically detect the type of content (XML vs. JSON) and the feed format (Atom vs. RSS).
5//!
6//! It populates a unified data model over all feed formats, attempting to find a balance between:
7//! * convenience of a single field where semantic equivalence exists e.g. "description" from RSS 2 and "subtitle" from Atom are semantically equivalent and mapped to the same field
8//! * the real world where mandatory fields may not be specified and data may not be in the correct form
9//!
10//! The parser errs on the side of leniency with the outcome that certain fields are represented as `Option<T>` in the model, even though they may be mandatory in one of the specifications.
11//!
12//! It uses [quick-xml](https://crates.io/crates/quick-xml) - a light-weight, streaming XML parser to minimise memory usage and avoids copying (clone) where possible.
13//!
14//! # Usage
15//!
16//! The `parser::parse` method accepts any source that implements the `Read` trait.
17//! For example, to process a string:
18//!
19//! ```rust,no_run
20//! use feed_rs::parser;
21//!
22//! let example_rss = r#"<?xml version="1.0" encoding="UTF-8" ?>
23//! <rss version="2.0">
24//! <channel>
25//! <title>RSS Title</title>
26//! <description>This is an example of an RSS feed</description>
27//! <link>http://www.example.com/main.html</link>
28//! <lastBuildDate>Mon, 06 Sep 2010 00:01:00 +0000</lastBuildDate>
29//! <pubDate>Sun, 06 Sep 2009 16:20:00 +0000</pubDate>
30//! <ttl>1800</ttl>
31//!
32//! <item>
33//! <title>Example entry</title>
34//! <description>Here is some text containing an interesting description.</description>
35//! <link>http://www.example.com/blog/post/1</link>
36//! <guid isPermaLink="true">7bd204c6-1655-4c27-aeee-53f933c5395f</guid>
37//! <pubDate>Sun, 06 Sep 2009 16:20:00 +0000</pubDate>
38//! </item>
39//!
40//! </channel>
41//! </rss>"#;
42//!
43//! let feed = parser::parse(example_rss.as_bytes()).unwrap();
44//!```
45//!
46//! Or from a file:
47//!
48//! ```rust,no_run
49//! use std::fs::File;
50//! use std::io::BufReader;
51//! use feed_rs::parser;
52//!
53//! let file = File::open("example.xml").unwrap();
54//! let feed = parser::parse(BufReader::new(file)).unwrap();
55//! ```
56//!
57//! ## Parser configuration
58//!
59//! The default parser configuration provides sensible defaults, such as lenient timestamp parsing. You may change this behaviour and configure other parser behaviour with the `parser::Builder`.
60//! For example, to enable content sanitisation:
61//!
62//! ```rust,no_run
63//! use std::fs::File;
64//! use std::io::BufReader;
65//! use feed_rs::parser;
66//!
67//! let file = File::open("example.xml").unwrap();
68//! let parser = parser::Builder::new()
69//! .sanitize_content(true)
70//! .build();
71//! let feed = parser.parse(BufReader::new(file)).unwrap();
72//! ```
73
74// TODO review the Rust doc guidelines and fix up links
75// TODO improve tests with Coverage analysis e.g. https://github.com/mozilla/grcov
76
77#![forbid(unsafe_code)]
78// Standard names like MediaRSS and JSON are used throughout this crate
79#![allow(clippy::upper_case_acronyms)]
80
81#[macro_use]
82extern crate serde;
83extern crate core;
84
85mod util;
86mod xml;
87
88pub mod model;
89pub mod parser;