winbrew_ui/
builder.rs

1use super::Ui;
2use crate::theme;
3use std::io::{self, BufWriter, Write};
4use tracing::warn;
5
6#[derive(Default)]
7pub(crate) struct ConfigOverrides {
8    pub color: Option<bool>,
9    pub default_yes: Option<bool>,
10}
11
12pub struct UiBuilder<W: Write> {
13    out: W,
14    err: Box<dyn Write>,
15    color_enabled: Option<bool>,
16    default_yes: Option<bool>,
17    config_overrides: ConfigOverrides,
18    settings: super::UiSettings,
19}
20
21impl UiBuilder<io::Stdout> {
22    pub fn new(settings: super::UiSettings) -> Self {
23        UiBuilder {
24            out: io::stdout(),
25            err: Box::new(io::stderr()),
26            color_enabled: None,
27            default_yes: None,
28            config_overrides: ConfigOverrides::default(),
29            settings,
30        }
31    }
32}
33
34impl Default for UiBuilder<io::Stdout> {
35    fn default() -> Self {
36        UiBuilder {
37            out: io::stdout(),
38            err: Box::new(io::stderr()),
39            color_enabled: None,
40            default_yes: None,
41            config_overrides: ConfigOverrides::default(),
42            settings: super::UiSettings::default(),
43        }
44    }
45}
46
47impl<W: Write> UiBuilder<W> {
48    pub fn with_writer(out: W, settings: super::UiSettings) -> Self {
49        UiBuilder {
50            out,
51            err: Box::new(io::stderr()),
52            color_enabled: None,
53            default_yes: None,
54            config_overrides: ConfigOverrides::default(),
55            settings,
56        }
57    }
58
59    pub fn with_error_writer(mut self, err: Box<dyn Write>) -> Self {
60        self.err = err;
61        self
62    }
63
64    pub fn with_config(mut self, key: &str, value: bool) -> Self {
65        match key {
66            "color" => self.config_overrides.color = Some(value),
67            "default_yes" => self.config_overrides.default_yes = Some(value),
68            _ => {
69                warn!("unknown config key: {key}");
70            }
71        }
72        self
73    }
74
75    pub fn color_enabled(mut self, color: bool) -> Self {
76        self.color_enabled = Some(color);
77        self
78    }
79
80    pub fn default_yes(mut self, default_yes: bool) -> Self {
81        self.default_yes = Some(default_yes);
82        self
83    }
84
85    pub fn build(self) -> Ui<W> {
86        let no_color_env = std::env::var_os("NO_COLOR").is_some();
87
88        let config_color = self
89            .color_enabled
90            .or(self.config_overrides.color)
91            .or(Some(self.settings.color_enabled));
92
93        let color_enabled = if no_color_env {
94            false
95        } else {
96            config_color.unwrap_or(true)
97        };
98
99        let default_yes = self
100            .default_yes
101            .or(self.config_overrides.default_yes)
102            .or(Some(self.settings.default_yes))
103            .unwrap_or(false);
104
105        let spinner_style = theme::make_spinner_style(color_enabled);
106        let progress_style = theme::make_progress_style(color_enabled);
107
108        Ui {
109            out: BufWriter::new(self.out),
110            err: self.err,
111            color_enabled,
112            default_yes,
113            spinner_style,
114            progress_style,
115        }
116    }
117}