Skip to main content

systemprompt_cli/
cli_settings.rs

1use std::env;
2
3#[derive(Debug, Clone, Copy, PartialEq, Eq)]
4pub enum OutputFormat {
5    Table,
6    Json,
7    Yaml,
8}
9
10#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord)]
11pub enum VerbosityLevel {
12    Quiet,
13    Normal,
14    Verbose,
15    Debug,
16}
17
18#[derive(Debug, Clone, Copy, PartialEq, Eq)]
19#[allow(dead_code)]
20pub enum ColorMode {
21    Auto,
22    Always,
23    Never,
24}
25
26#[derive(Debug, Clone)]
27pub struct CliConfig {
28    pub output_format: OutputFormat,
29    pub verbosity: VerbosityLevel,
30    pub color_mode: ColorMode,
31    pub interactive: bool,
32    pub profile_override: Option<String>,
33}
34
35impl Default for CliConfig {
36    fn default() -> Self {
37        Self {
38            output_format: OutputFormat::Table,
39            verbosity: VerbosityLevel::Normal,
40            color_mode: ColorMode::Auto,
41            interactive: true,
42            profile_override: None,
43        }
44    }
45}
46
47impl CliConfig {
48    pub fn new() -> Self {
49        let mut config = Self::default();
50        config.apply_environment_variables();
51        config
52    }
53
54    pub const fn with_output_format(mut self, format: OutputFormat) -> Self {
55        self.output_format = format;
56        self
57    }
58
59    pub const fn with_verbosity(mut self, level: VerbosityLevel) -> Self {
60        self.verbosity = level;
61        self
62    }
63
64    pub const fn with_color_mode(mut self, mode: ColorMode) -> Self {
65        self.color_mode = mode;
66        self
67    }
68
69    pub const fn with_interactive(mut self, interactive: bool) -> Self {
70        self.interactive = interactive;
71        self
72    }
73
74    pub fn with_profile_override(mut self, profile: Option<String>) -> Self {
75        self.profile_override = profile;
76        self
77    }
78
79    fn apply_environment_variables(&mut self) {
80        if let Ok(format) = env::var("SYSTEMPROMPT_OUTPUT_FORMAT") {
81            self.output_format = match format.to_lowercase().as_str() {
82                "json" => OutputFormat::Json,
83                "yaml" => OutputFormat::Yaml,
84                "table" => OutputFormat::Table,
85                _ => self.output_format,
86            };
87        }
88
89        if let Ok(level) = env::var("SYSTEMPROMPT_LOG_LEVEL") {
90            self.verbosity = match level.to_lowercase().as_str() {
91                "quiet" => VerbosityLevel::Quiet,
92                "normal" => VerbosityLevel::Normal,
93                "verbose" => VerbosityLevel::Verbose,
94                "debug" => VerbosityLevel::Debug,
95                _ => self.verbosity,
96            };
97        }
98
99        if env::var("SYSTEMPROMPT_NO_COLOR").is_ok() || env::var("NO_COLOR").is_ok() {
100            self.color_mode = ColorMode::Never;
101        }
102
103        if env::var("SYSTEMPROMPT_NON_INTERACTIVE").is_ok() {
104            self.interactive = false;
105        }
106    }
107
108    pub fn should_use_color(&self) -> bool {
109        match self.color_mode {
110            ColorMode::Always => true,
111            ColorMode::Never => false,
112            ColorMode::Auto => atty::is(atty::Stream::Stdout),
113        }
114    }
115
116    pub fn is_json_output(&self) -> bool {
117        self.output_format == OutputFormat::Json
118    }
119
120    pub fn should_show_verbose(&self) -> bool {
121        self.verbosity >= VerbosityLevel::Verbose
122    }
123
124    pub fn is_interactive(&self) -> bool {
125        self.interactive && atty::is(atty::Stream::Stdin) && atty::is(atty::Stream::Stdout)
126    }
127
128    pub const fn output_format(&self) -> OutputFormat {
129        self.output_format
130    }
131}
132
133thread_local! {
134    static CLI_CONFIG: std::cell::RefCell<CliConfig> = std::cell::RefCell::new(CliConfig::new());
135}
136
137pub fn set_global_config(config: CliConfig) {
138    CLI_CONFIG.with(|c| {
139        *c.borrow_mut() = config;
140    });
141}
142
143pub fn get_global_config() -> CliConfig {
144    CLI_CONFIG.with(|c| c.borrow().clone())
145}