Skip to main content

rs_histver/
options.rs

1use std::time::Duration;
2
3use crate::constants::{
4    default_user_agent, DEFAULT_MAX_CONCURRENCY, DEFAULT_PROBE_DAYS, DEFAULT_TIMEOUT_SECS,
5};
6
7/// Options for fetching Rust release data.
8///
9/// All fields have sensible defaults, so `FetchOptions::default()` or
10/// `FetchOptions::new()` gives a reasonable starting configuration.
11///
12/// # Examples
13///
14/// ```ignore
15/// use rs_histver::{fetch_releases, FetchOptions};
16///
17/// // Default options
18/// let releases = fetch_releases("stable", FetchOptions::default()).await?;
19///
20/// // Full history from RELEASES.md
21/// let releases = fetch_releases("stable",
22///     FetchOptions::new().full_history(true)
23/// ).await?;
24///
25/// // Probe recent 7 days of nightly releases
26/// let releases = fetch_releases("nightly",
27///     FetchOptions::new().probe_days(7)
28/// ).await?;
29/// ```
30#[derive(Debug, Clone)]
31pub struct FetchOptions {
32    /// Stable channel: use RELEASES.md for full historical data (default: false = GitHub API)
33    pub full_history: bool,
34    /// Beta/Nightly channels: probe recent N days (default: 30)
35    pub probe_days: u32,
36    /// HTTP request timeout (default: 15 seconds)
37    pub timeout: Duration,
38    /// Maximum concurrent HTTP requests (default: 10)
39    pub max_concurrency: usize,
40    /// User-Agent header string
41    pub user_agent: String,
42}
43
44impl Default for FetchOptions {
45    fn default() -> Self {
46        Self {
47            full_history: false,
48            probe_days: DEFAULT_PROBE_DAYS,
49            timeout: Duration::from_secs(DEFAULT_TIMEOUT_SECS),
50            max_concurrency: DEFAULT_MAX_CONCURRENCY,
51            user_agent: default_user_agent(),
52        }
53    }
54}
55
56impl FetchOptions {
57    /// Create a new `FetchOptions` with default values.
58    #[must_use]
59    pub fn new() -> Self {
60        Self::default()
61    }
62
63    /// Enable RELEASES.md full history mode (stable only).
64    #[must_use]
65    pub fn full_history(mut self, v: bool) -> Self {
66        self.full_history = v;
67        self
68    }
69
70    /// Set the number of days to probe for beta/nightly channels.
71    #[must_use]
72    pub fn probe_days(mut self, days: u32) -> Self {
73        self.probe_days = days;
74        self
75    }
76
77    /// Set the HTTP request timeout.
78    #[must_use]
79    pub fn timeout(mut self, d: Duration) -> Self {
80        self.timeout = d;
81        self
82    }
83
84    /// Set the maximum number of concurrent HTTP requests.
85    #[must_use]
86    pub fn max_concurrency(mut self, n: usize) -> Self {
87        self.max_concurrency = n;
88        self
89    }
90
91    /// Set a custom User-Agent header.
92    #[must_use]
93    pub fn user_agent(mut self, ua: impl Into<String>) -> Self {
94        self.user_agent = ua.into();
95        self
96    }
97}
98
99/// Network configuration for HTTP fetcher requests.
100///
101/// Created automatically from [`FetchOptions`] by [`fetch_releases`].
102/// For low-level use with [`create_fetcher`], use [`NetworkConfig::new()`]
103/// or construct via struct literal.
104///
105/// # Examples
106///
107/// ```ignore
108/// use rs_histver::{create_fetcher, NetworkConfig, ReleaseFetcher};
109///
110/// let network = NetworkConfig::new()
111///     .timeout_secs(30)
112///     .max_concurrency(5);
113/// let fetcher = create_fetcher("stable", false, 30)?;
114/// let releases = fetcher.fetch(&network).await?;
115/// ```
116#[derive(Debug, Clone)]
117pub struct NetworkConfig {
118    pub timeout: u64,
119    pub max_concurrency: usize,
120    pub user_agent: String,
121}
122
123impl Default for NetworkConfig {
124    fn default() -> Self {
125        Self {
126            timeout: DEFAULT_TIMEOUT_SECS,
127            max_concurrency: DEFAULT_MAX_CONCURRENCY,
128            user_agent: default_user_agent(),
129        }
130    }
131}
132
133impl NetworkConfig {
134    /// Create a new `NetworkConfig` with default values.
135    #[must_use]
136    pub fn new() -> Self {
137        Self::default()
138    }
139
140    /// Set the HTTP request timeout in seconds.
141    #[must_use]
142    pub fn timeout_secs(mut self, secs: u64) -> Self {
143        self.timeout = secs;
144        self
145    }
146
147    /// Set the maximum number of concurrent HTTP requests.
148    #[must_use]
149    pub fn max_concurrency(mut self, n: usize) -> Self {
150        self.max_concurrency = n;
151        self
152    }
153
154    /// Set a custom User-Agent header.
155    #[must_use]
156    pub fn user_agent(mut self, ua: impl Into<String>) -> Self {
157        self.user_agent = ua.into();
158        self
159    }
160}
161
162impl From<&FetchOptions> for NetworkConfig {
163    fn from(opts: &FetchOptions) -> Self {
164        Self {
165            timeout: opts.timeout.as_secs(),
166            max_concurrency: opts.max_concurrency,
167            user_agent: opts.user_agent.clone(),
168        }
169    }
170}