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