feed/
lib.rs

1// This file is part of feed.
2//
3// Copyright © 2015-2017 Chris Palmer <pennstate5013@gmail.com>
4//
5// This program is free software; you can redistribute it and/or modify
6// it under the terms of the GNU Lesser General Public License as published by
7// the Free Software Foundation; either version 3 of the License, or
8// (at your option) any later version.
9
10
11#![doc(html_root_url = "https://docs.rs/feed/")]
12#![deny(missing_docs)]
13
14
15//! # feed 3.0
16//!
17//! This Library is for parsing through a channels field and creating a `Feed`
18//! struct containing all elements of a `Channel` based on the channels spec.
19//!
20//! ## Usage
21//! Put this in your Cargo.toml:
22//!
23//! ```Toml
24//! [dependencies]
25//! feed = "3.0"
26//! ```
27//!
28//! And put this in your crate root:
29//!
30//! ```
31//! extern crate feed;
32//! ```
33//!
34//! ## Examples
35//!
36//! ### Reading Feeds
37//!
38//! ```
39//! extern crate rss;
40//! extern crate feed;
41//!
42//! use feed::{FromUrl, ChannelGetters};
43//! use rss::Channel;
44//!
45//! fn main()
46//! {
47//!     let url = "https://feedpress.me/usererror.xml";
48//!
49//!     let channel = Channel::from_url(url).unwrap();
50//!     println!("Feed Title: {:?}", channel.title());
51//! }
52//! ```
53//!
54//! ### Writing Feeds
55//!
56//! ```
57//! extern crate feed;
58//!
59//! use feed::ChannelBuilder;
60//!
61//! fn main()
62//! {
63//!     let description = "Ogg Vorbis audio versions of The Linux ".to_owned()
64//!         + "Action Show! A show that covers everything geeks care about in "
65//!         + "the computer industry. Get a solid dose of Linux, gadgets, news "
66//!         + "events and much more!";
67//!
68//!     let channel = ChannelBuilder::new()
69//!         .title("The Linux Action Show! OGG")
70//!         .link("http://www.jupiterbroadcasting.com")
71//!         .description(description.as_ref())
72//!         .finalize().unwrap();
73//!
74//!     println!("Feed: {:?}", channel.to_string());
75//! }
76//! ```
77//!
78//! ### Validating Feeds
79//!
80//! ```
81//! extern crate feed;
82//!
83//! use feed::ChannelBuilder;
84//!
85//! fn main()
86//! {
87//!     let description = "Ogg Vorbis audio versions of The Linux ".to_owned()
88//!         + "Action Show! A show that covers everything geeks care about in "
89//!         + "the computer industry. Get a solid dose of Linux, gadgets, news "
90//!         + "events and much more!";
91//!
92//!     let channel = ChannelBuilder::new()
93//!         .title("The Linux Action Show! OGG")
94//!         .link("http://www.jupiterbroadcasting.com")
95//!         .description(description.as_ref())
96//!         .validate().unwrap()
97//!         .finalize().unwrap();
98//!
99//!     println!("Feed: {:?}", channel.to_string());
100//! }
101//! ```
102//!
103//! ```
104//! extern crate rss;
105//! extern crate feed;
106//!
107//! use feed::{FromUrl, Validate};
108//! use rss::Channel;
109//!
110//! fn main()
111//! {
112//!     let url = "https://feedpress.me/usererror.xml";
113//!
114//!     let channel = Channel::from_url(url).unwrap();
115//!     channel.validate().unwrap();
116//! }
117//! ```
118
119extern crate chrono;
120extern crate curl;
121extern crate mime;
122extern crate rss;
123extern crate url;
124
125
126mod enums;
127pub mod extension;
128pub mod channel;
129mod utils;
130
131
132use rss::{Category, Channel, Cloud, Enclosure, Guid, Image, Item, Source, TextInput};
133use rss::extension::itunes::{ITunesChannelExtension, ITunesItemExtension};
134
135/// The Getter functions for `Category`
136pub trait CategoryGetters
137{
138    /// Get the category that exists under `Category`.
139    fn name(&self) -> String;
140
141
142    /// Get the optional domain that exists under `Category`.
143    fn domain(&self) -> Option<String>;
144}
145
146
147/// This `CategoryBuilder` struct creates the `Category`.
148#[derive(Clone, Default)]
149pub struct CategoryBuilder
150{
151    name: String,
152    domain: Option<String>,
153}
154
155
156/// From Url function for `Channel`
157pub trait FromUrl
158{
159    /// Construct a `Channel` from a `Url`.
160    fn from_url(url: &str) -> Result<Channel, String>;
161}
162
163
164/// Validate function for `Channel`
165pub trait Validate
166{
167    /// Validate `Channel`
168    fn validate(&self) -> Result<Channel, String>;
169}
170
171
172/// The Getter functions for `Channel`
173pub trait ChannelGetters
174{
175    /// Get the title that exists under `Channel`.
176    fn title(&self) -> String;
177
178    /// Get the link that exists under `Channel`.
179    fn link(&self) -> String;
180
181    /// Get the description that exists under `Channel`.
182    fn description(&self) -> String;
183
184    /// Get the optional language that exists under `Channel`.
185    fn language(&self) -> Option<String>;
186
187    /// Get the optional copyright that exists under `Channel`.
188    fn copyright(&self) -> Option<String>;
189
190    /// Get the optional managing editor that exists under `Channel`.
191    fn managing_editor(&self) -> Option<String>;
192
193    /// Get the optional web master that exists under `Channel`.
194    fn webmaster(&self) -> Option<String>;
195
196    /// Get the optional pub date that exists under `Channel`.
197    fn pub_date(&self) -> Option<String>;
198
199    /// Get the optional last build date that exists under `Channel`.
200    fn last_build_date(&self) -> Option<String>;
201
202    /// Get the categories that exists under `Channel`.
203    fn categories(&self) -> Vec<Category>;
204
205    /// Get the optional generator that exists under `Channel`.
206    fn generator(&self) -> Option<String>;
207
208    /// Get the optional docs that exists under `Channel`.
209    fn docs(&self) -> Option<String>;
210
211    /// Get the optional cloud that exists under `Channel`.
212    fn cloud(&self) -> Option<Cloud>;
213
214    /// Get the optional ttl that exists under `Channel`.
215    fn ttl(&self) -> Option<String>;
216
217    /// Get the optional image that exists under `Channel`.
218    fn image(&self) -> Option<Image>;
219
220    /// Get the optional text input that exists under `Channel`.
221    fn text_input(&self) -> Option<TextInput>;
222
223    /// Get the optional rating that exists under `Channel`.
224    fn rating(&self) -> Option<String>;
225
226    /// Get the skip hours that exists under `Channel`.
227    fn skip_hours(&self) -> Vec<String>;
228
229    /// Get the skip days that exists under `Channel`.
230    fn skip_days(&self) -> Vec<String>;
231
232    /// Get the items that exists under `Channel`.
233    fn items(&self) -> Vec<Item>;
234
235    /// Get the optional `ITunesChannelExtension` under `Channel`.
236    fn itunes_ext(&self) -> Option<ITunesChannelExtension>;
237}
238
239
240/// This `ChannelBuilder` struct creates the `Channel`.
241#[derive(Clone, Default)]
242pub struct ChannelBuilder
243{
244    title: String,
245    link: String,
246    description: String,
247    language: Option<String>,
248    copyright: Option<String>,
249    managing_editor: Option<String>,
250    webmaster: Option<String>,
251    pub_date: Option<String>,
252    last_build_date: Option<String>,
253    categories: Vec<Category>,
254    generator: Option<String>,
255    docs: Option<String>,
256    cloud: Option<Cloud>,
257    ttl: Option<i64>,
258    image: Option<Image>,
259    rating: Option<String>,
260    text_input: Option<TextInput>,
261    skip_hours: Vec<i64>,
262    skip_days: Vec<String>,
263    items: Vec<Item>,
264    itunes_ext: Option<ITunesChannelExtension>,
265}
266
267
268/// The Getter functions for `Cloud`
269pub trait CloudGetters
270{
271    /// Get the domain that exists under `Cloud`.
272    fn domain(&self) -> String;
273
274    /// Get the port that exists under `Cloud`.
275    fn port(&self) -> String;
276
277    /// Get the path that exists under `Cloud`.
278    fn path(&self) -> String;
279
280    /// Get the register procedure that exists under `Cloud`.
281    fn register_procedure(&self) -> String;
282
283    /// Get the protocol that exists under `Cloud`.
284    fn protocol(&self) -> String;
285}
286
287
288/// This `CloudBuilder` struct creates the `Cloud`.
289#[derive(Clone, Default)]
290pub struct CloudBuilder
291{
292    domain: String,
293    port: i64,
294    path: String,
295    register_procedure: String,
296    protocol: String,
297}
298
299
300/// The Getter functions for `Enclosure`
301pub trait EnclosureGetters
302{
303    /// Get the url that exists under `Enclosure`.
304    fn url(&self) -> String;
305
306    /// Get the length that exists under `Enclosure`.
307    fn length(&self) -> String;
308
309    /// Get the enclosure type that exists under `Enclosure`.
310    fn mime_type(&self) -> String;
311}
312
313
314/// This `EnclosureBuilder` struct creates the `Enclosure`.
315#[derive(Clone, Default)]
316pub struct EnclosureBuilder
317{
318    url: String,
319    length: i64,
320    mime_type: String,
321}
322
323
324/// The Getter functions for `Guid`
325pub trait GuidGetters
326{
327    /// Get the permalink that exists under `Guid`.
328    fn is_permalink(&self) -> bool;
329
330    /// Get the guid that exists under `Guid`.
331    fn value(&self) -> String;
332}
333
334
335/// This `GuidBuilder` struct creates the `Guid`.
336#[derive(Clone, Default)]
337pub struct GuidBuilder
338{
339    is_permalink: Option<bool>,
340    value: String,
341}
342
343
344/// The Getter functions for `Image`
345pub trait ImageGetters
346{
347    /// Get the url that exists under `Image`.
348    fn url(&self) -> String;
349
350    /// Get the title that exists under `Image`.
351    fn title(&self) -> String;
352
353    /// Get the link that exists under `Image`.
354    fn link(&self) -> String;
355
356    /// Get the width that exists under `Image`.
357    fn width(&self) -> Option<String>;
358
359    /// Get the height that exists under `Image`.
360    fn height(&self) -> Option<String>;
361
362    /// Get the description that exists under `Image`.
363    fn description(&self) -> Option<String>;
364}
365
366
367/// This `ImageBuilder` struct creates the `Image`.
368#[derive(Clone, Default)]
369pub struct ImageBuilder
370{
371    url: String,
372    title: String,
373    link: String,
374    width: Option<i64>,
375    height: Option<i64>,
376    description: Option<String>,
377}
378
379
380/// The Getter functions for `Item`
381pub trait ItemGetters
382{
383    /// Get the optional title that exists under `Item`.
384    fn title(&self) -> Option<String>;
385
386    /// Get the optional link that exists under `Item`.
387    fn link(&self) -> Option<String>;
388
389    /// Get the optional description that exists under `Item`.
390    fn description(&self) -> Option<String>;
391
392    /// Get the optional author that exists under `Item`.
393    fn author(&self) -> Option<String>;
394
395    /// Get the categories that exists under `Item`.
396    fn categories(&self) -> Vec<Category>;
397
398    /// Get the optional comments that exists under `Item`.
399    fn comments(&self) -> Option<String>;
400
401    /// Get the optional enclosure that exists under `Item`.
402    fn enclosure(&self) -> Option<Enclosure>;
403
404    /// Get the optional guid that exists under `Item`.
405    fn guid(&self) -> Option<Guid>;
406
407    /// Get the optional pub date that exists under `Item`.
408    fn pub_date(&self) -> Option<String>;
409
410    /// Get the optional source that exists under `Item`.
411    fn source(&self) -> Option<Source>;
412
413    /// Get the optional `ITunesItemExtension` under `Item`.
414    fn itunes_ext(&self) -> Option<ITunesItemExtension>;
415}
416
417
418/// This `ItemBuilder` struct creates the `Item`.
419#[derive(Clone, Default)]
420pub struct ItemBuilder
421{
422    title: Option<String>,
423    link: Option<String>,
424    description: Option<String>,
425    author: Option<String>,
426    categories: Vec<Category>,
427    comments: Option<String>,
428    enclosure: Option<Enclosure>,
429    guid: Option<Guid>,
430    pub_date: Option<String>,
431    source: Option<Source>,
432    itunes_ext: Option<ITunesItemExtension>,
433}
434
435
436/// The Getter functions for `Source`
437pub trait SourceGetters
438{
439    /// Get the url that exists under `Source`.
440    fn url(&self) -> String;
441
442    /// Get the source that exists under `Source`.
443    fn title(&self) -> Option<String>;
444}
445
446
447/// This `SourceBuilder` struct creates the `Source`.
448#[derive(Clone, Default)]
449pub struct SourceBuilder
450{
451    url: String,
452    title: Option<String>,
453}
454
455
456/// The Getter functions for `TextInput`
457pub trait TextInputGetters
458{
459    /// Get the title that exists under `TextInput`.
460    fn title(&self) -> String;
461
462    /// Get the description that exists under `TextInput`.
463    fn description(&self) -> String;
464
465    /// Get the name that exists under `TextInput`.
466    fn name(&self) -> String;
467
468    /// Get the link that exists under `TextInput`.
469    fn link(&self) -> String;
470}
471
472
473/// This `TextInputBuilder` struct creates the `TextInput`.
474#[derive(Clone, Default)]
475pub struct TextInputBuilder
476{
477    title: String,
478    description: String,
479    name: String,
480    link: String,
481}