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