Skip to main content

rss_cli/
config.rs

1//! Runtime parameters and policies — the *non-serialized* counterpart to [`crate::model`].
2
3use std::time::Duration;
4
5use chrono::{DateTime, Utc};
6
7use crate::model::ContentFormat;
8
9/// Default User-Agent. Polite, identifies the tool, points at the project.
10pub const DEFAULT_USER_AGENT: &str = concat!(
11    "rss-cli/",
12    env!("CARGO_PKG_VERSION"),
13    " (+https://github.com/AnderEnder/rss-cli)"
14);
15
16/// How the cache should be consulted for a fetch.
17#[derive(Debug, Clone, Copy, PartialEq, Eq, Default)]
18pub enum CachePolicy {
19    /// Default. Always revalidate with a conditional GET (`If-None-Match` /
20    /// `If-Modified-Since`); a `304` serves the cached body.
21    #[default]
22    Revalidate,
23    /// Serve directly from cache without hitting the network if the cached entry is
24    /// younger than this duration; otherwise behave like [`CachePolicy::Revalidate`].
25    MaxAge(Duration),
26    /// Serve the cached entry **without any network call, regardless of age**, if one
27    /// exists; only on a cache miss does it fetch (then behave like [`CachePolicy::Revalidate`]).
28    /// Used by item lookup (`rss show` / MCP `get_item`) so a rolled feed window cannot evict
29    /// an item the caller already saw. Exception to the always-revalidate default — see
30    /// ADR-0014.
31    CacheFirst,
32    /// Ignore the cache entirely (do not read or write it).
33    NoCache,
34}
35
36/// Parameters shared by the CLI and the MCP server for a fetch operation.
37#[derive(Debug, Clone)]
38pub struct FetchParams {
39    pub content_format: ContentFormat,
40    /// Maximum items per feed (most recent first), or `None` for all.
41    pub limit: Option<usize>,
42    /// Maximum characters of extracted `content` per item; longer bodies are truncated on a
43    /// char boundary and flagged `content_truncated`. `None` keeps full content.
44    pub max_content_chars: Option<usize>,
45    /// Only include items published at or after this instant.
46    pub since: Option<DateTime<Utc>>,
47    /// Maximum number of feeds fetched concurrently.
48    pub concurrency: usize,
49    pub timeout: Duration,
50    pub user_agent: String,
51    pub cache_policy: CachePolicy,
52}
53
54impl Default for FetchParams {
55    fn default() -> Self {
56        Self {
57            content_format: ContentFormat::Markdown,
58            limit: None,
59            max_content_chars: None,
60            since: None,
61            concurrency: 8,
62            timeout: Duration::from_secs(30),
63            user_agent: DEFAULT_USER_AGENT.to_string(),
64            cache_policy: CachePolicy::Revalidate,
65        }
66    }
67}