winbrew_ui/
lib.rs

1//! Terminal presentation primitives for WinBrew.
2//!
3//! `winbrew-ui` owns the interactive state used by CLI command handlers: color
4//! mode, confirmation defaults, spinner styles, progress rendering, and output
5//! writers. Keeping this crate separate from app logic prevents business code
6//! from depending on terminal behavior.
7
8#![allow(missing_docs)]
9
10mod builder;
11mod interact;
12mod log;
13mod progress;
14mod table;
15mod theme;
16
17/// Builder for `Ui` instances.
18pub use builder::UiBuilder;
19pub use progress::ProgressHandle;
20pub use progress::SpinnerGuard;
21
22use indicatif::ProgressStyle;
23use std::io::{self, BufWriter, Write};
24use std::sync::Arc;
25
26/// Terminal-backed presentation state used by CLI command handlers.
27pub struct Ui<W: Write> {
28    pub(crate) out: BufWriter<W>,
29    pub(crate) err: Box<dyn Write>,
30    pub(crate) color_enabled: bool,
31    pub(crate) default_yes: bool,
32    pub(crate) spinner_style: Arc<ProgressStyle>,
33    pub(crate) progress_style: Arc<ProgressStyle>,
34}
35
36impl Ui<io::Stdout> {
37    /// Create a UI that writes to stdout and stderr.
38    pub fn new(settings: UiSettings) -> Self {
39        UiBuilder::new(settings).build()
40    }
41}
42
43impl<W: Write> Ui<W> {
44    /// Create a UI with an explicit writer, which is primarily useful in tests.
45    pub fn with_writer(writer: W, settings: UiSettings) -> Self {
46        UiBuilder::with_writer(writer, settings).build()
47    }
48}
49
50impl Default for Ui<io::Stdout> {
51    fn default() -> Self {
52        let settings = UiSettings::default();
53        let spinner_style = crate::theme::make_spinner_style(settings.color_enabled);
54        let progress_style = crate::theme::make_progress_style(settings.color_enabled);
55
56        Ui {
57            out: BufWriter::new(io::stdout()),
58            err: Box::new(io::stderr()),
59            color_enabled: settings.color_enabled,
60            default_yes: settings.default_yes,
61            spinner_style,
62            progress_style,
63        }
64    }
65}
66
67#[derive(Debug, Clone, Copy, PartialEq, Eq)]
68/// Presentation settings for the terminal UI.
69pub struct UiSettings {
70    pub color_enabled: bool,
71    pub default_yes: bool,
72}
73
74impl Default for UiSettings {
75    fn default() -> Self {
76        Self {
77            color_enabled: true,
78            default_yes: false,
79        }
80    }
81}