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