Skip to main content

rama_http/protocols/rss/
error.rs

1//! Error types returned by the RSS / Atom streaming readers.
2
3use std::fmt;
4
5use super::Feed;
6use super::atom::AtomFeed;
7use super::rss2::Rss2Feed;
8
9/// Returned when the document cannot be turned into a feed at all — either
10/// nothing recognisable as an RSS 2.0 / Atom 1.0 root was seen, or strict
11/// mode rejected a structural violation in the header.
12#[derive(Debug, Clone, PartialEq, Eq)]
13pub struct FeedParseError {
14    pub message: String,
15}
16
17impl FeedParseError {
18    pub(super) fn new(msg: impl Into<String>) -> Self {
19        Self {
20            message: msg.into(),
21        }
22    }
23}
24
25impl fmt::Display for FeedParseError {
26    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
27        write!(f, "feed parse error: {}", self.message)
28    }
29}
30
31impl std::error::Error for FeedParseError {}
32
33/// Returned by [`Rss2FeedStream::collect`], [`AtomFeedStream::collect`] and
34/// [`FeedStream::collect`] when an item / entry fails to parse partway
35/// through the stream. The `partial` feed holds the header that was parsed
36/// at stream construction *and* every item / entry that succeeded before
37/// the failure, so callers can keep what's salvageable.
38///
39/// Use [`Rss2FeedStream::collect_lossy`] / [`AtomFeedStream::collect_lossy`]
40/// /[`FeedStream::collect_lossy`] when per-item errors should be skipped
41/// silently instead of short-circuiting.
42///
43/// [`Rss2FeedStream::collect`]: super::Rss2FeedStream::collect
44/// [`AtomFeedStream::collect`]: super::AtomFeedStream::collect
45/// [`FeedStream::collect`]: super::FeedStream::collect
46/// [`Rss2FeedStream::collect_lossy`]: super::Rss2FeedStream::collect_lossy
47/// [`AtomFeedStream::collect_lossy`]: super::AtomFeedStream::collect_lossy
48/// [`FeedStream::collect_lossy`]: super::FeedStream::collect_lossy
49#[derive(Debug, Clone, PartialEq)]
50pub struct CollectError<F> {
51    /// The underlying per-item parse error.
52    pub error: FeedParseError,
53    /// The header plus every item / entry that was parsed before the error.
54    /// The header is always populated; the items list may be empty if the
55    /// failure happened on the very first item.
56    pub partial: F,
57}
58
59impl<F: fmt::Debug> fmt::Display for CollectError<F> {
60    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
61        write!(f, "collect failed: {} (partial feed retained)", self.error)
62    }
63}
64
65impl<F: fmt::Debug> std::error::Error for CollectError<F> {
66    fn source(&self) -> Option<&(dyn std::error::Error + 'static)> {
67        Some(&self.error)
68    }
69}
70
71/// Per-format convenience alias.
72pub type Rss2CollectError = CollectError<Rss2Feed>;
73/// Per-format convenience alias.
74pub type AtomCollectError = CollectError<AtomFeed>;
75/// Format-agnostic alias.
76pub type FeedCollectError = CollectError<Feed>;