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}