Skip to main content

aperture_cli/config/
models.rs

1use serde::{Deserialize, Serialize};
2use std::collections::HashMap;
3
4#[derive(Debug, Clone, Deserialize, Serialize)]
5pub struct GlobalConfig {
6    #[serde(default = "default_timeout_secs_value")]
7    pub default_timeout_secs: u64,
8    #[serde(default)]
9    pub agent_defaults: AgentDefaults,
10    /// Default retry configuration for transient failures
11    #[serde(default)]
12    pub retry_defaults: RetryDefaults,
13    /// Per-API configuration overrides
14    #[serde(default)]
15    pub api_configs: HashMap<String, ApiConfig>,
16}
17
18const fn default_timeout_secs_value() -> u64 {
19    30
20}
21
22#[derive(Debug, Clone, Deserialize, Serialize, Default)]
23pub struct AgentDefaults {
24    #[serde(default)]
25    pub json_errors: bool,
26}
27
28/// Default retry configuration for API requests.
29///
30/// These settings control automatic retry behavior for transient failures.
31/// Set `max_attempts` to 0 to disable retries (the default).
32///
33/// Retryable status codes are determined by the `is_retryable_status` function
34/// in the resilience module (408, 429, 500-504 excluding 501/505).
35#[derive(Debug, Clone, Deserialize, Serialize)]
36pub struct RetryDefaults {
37    /// Maximum number of retry attempts (0 = disabled, 1-10 recommended)
38    #[serde(default)]
39    pub max_attempts: u32,
40    /// Initial delay between retries in milliseconds (default: 500ms)
41    #[serde(default = "default_initial_delay_ms")]
42    pub initial_delay_ms: u64,
43    /// Maximum delay cap in milliseconds (default: 30000ms = 30s)
44    #[serde(default = "default_max_delay_ms")]
45    pub max_delay_ms: u64,
46}
47
48const fn default_initial_delay_ms() -> u64 {
49    500
50}
51
52const fn default_max_delay_ms() -> u64 {
53    30_000
54}
55
56impl Default for RetryDefaults {
57    fn default() -> Self {
58        Self {
59            max_attempts: 0, // Disabled by default
60            initial_delay_ms: default_initial_delay_ms(),
61            max_delay_ms: default_max_delay_ms(),
62        }
63    }
64}
65
66impl Default for GlobalConfig {
67    fn default() -> Self {
68        Self {
69            default_timeout_secs: 30,
70            agent_defaults: AgentDefaults::default(),
71            retry_defaults: RetryDefaults::default(),
72            api_configs: HashMap::new(),
73        }
74    }
75}
76
77/// Per-API configuration for base URLs and environment-specific settings
78#[derive(Debug, Deserialize, Serialize, Clone)]
79pub struct ApiConfig {
80    /// Override base URL for this API
81    pub base_url_override: Option<String>,
82    /// Environment-specific base URLs (e.g., "dev", "staging", "prod")
83    #[serde(default)]
84    pub environment_urls: HashMap<String, String>,
85    /// Whether this spec was added with --strict flag (preserved for reinit)
86    #[serde(default)]
87    pub strict_mode: bool,
88    /// Secret configurations for security schemes (overrides x-aperture-secret extensions)
89    #[serde(default)]
90    pub secrets: HashMap<String, ApertureSecret>,
91}
92
93#[derive(Debug, Deserialize, Serialize, PartialEq, Eq, Clone)]
94#[serde(rename_all = "camelCase")]
95pub struct ApertureSecret {
96    pub source: SecretSource,
97    pub name: String,
98}
99
100#[derive(Debug, Deserialize, Serialize, PartialEq, Eq, Clone)]
101#[serde(rename_all = "camelCase")]
102pub enum SecretSource {
103    Env,
104    // Keychain, // Future option
105}