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