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