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/)"
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}