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
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}