Skip to content

Commit b5d7bbf

Browse files
epagedjc
authored andcommitted
refactor: Move style building out of ColorableTerminal
1 parent 05b3872 commit b5d7bbf

File tree

6 files changed

+63
-65
lines changed

6 files changed

+63
-65
lines changed

src/cli/common.rs

Lines changed: 10 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ use std::path::{Path, PathBuf};
77
use std::sync::LazyLock;
88
use std::{cmp, env};
99

10-
use anstyle::AnsiColor;
10+
use anstyle::{AnsiColor, Style};
1111
use anyhow::{Context, Result, anyhow};
1212
use git_testament::{git_testament, render_testament};
1313
use tracing::{error, info, warn};
@@ -18,7 +18,7 @@ use crate::{
1818
dist::{TargetTriple, ToolchainDesc},
1919
errors::RustupError,
2020
install::UpdateStatus,
21-
process::{Attr, Process},
21+
process::Process,
2222
toolchain::{LocalToolchainName, Toolchain, ToolchainName},
2323
utils,
2424
};
@@ -203,11 +203,13 @@ fn show_channel_updates(
203203
for (pkg, banner, width, color, version, previous_version) in data {
204204
let padding = max_width - width;
205205
let padding: String = " ".repeat(padding);
206-
let _ = write!(t.lock(), " {padding}");
207-
let _ = t.attr(Attr::Bold);
208-
if let Some(color) = color {
209-
let _ = t.fg(color);
206+
let style = match color {
207+
Some(color) => color.on_default(),
208+
None => Style::new(),
210209
}
210+
.bold();
211+
let _ = write!(t.lock(), " {padding}");
212+
let _ = t.style(&style);
211213
let _ = write!(t.lock(), "{pkg} {banner}");
212214
let _ = t.reset();
213215
let _ = write!(t.lock(), " - {version}");
@@ -257,9 +259,10 @@ pub(super) fn list_items(
257259
process: &Process,
258260
) -> Result<utils::ExitCode> {
259261
let mut t = process.stdout();
262+
let bold = Style::new().bold();
260263
for (name, installed) in items {
261264
if installed && !installed_only && !quiet {
262-
t.attr(Attr::Bold)?;
265+
t.style(&bold)?;
263266
writeln!(t.lock(), "{name} (installed)")?;
264267
t.reset()?;
265268
} else if installed || !installed_only {

src/cli/markdown.rs

Lines changed: 24 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,10 @@
11
// Write Markdown to the terminal
22
use std::io::Write;
33

4-
use anstyle::AnsiColor;
4+
use anstyle::{AnsiColor, Style};
55
use pulldown_cmark::{Event, Tag, TagEnd};
66

7-
use crate::process::{Attr, ColorableTerminal};
7+
use crate::process::ColorableTerminal;
88

99
// Handles the wrapping of text written to the console
1010
struct LineWrapper<'a> {
@@ -96,6 +96,7 @@ struct LineFormatter<'a> {
9696
is_code_block: bool,
9797
wrapper: LineWrapper<'a>,
9898
attrs: Vec<Attr>,
99+
style: Style,
99100
}
100101

101102
impl<'a> LineFormatter<'a> {
@@ -104,18 +105,21 @@ impl<'a> LineFormatter<'a> {
104105
is_code_block: false,
105106
wrapper: LineWrapper::new(w, indent, margin),
106107
attrs: Vec::new(),
108+
style: Style::new(),
107109
}
108110
}
109111
fn push_attr(&mut self, attr: Attr) {
110112
self.attrs.push(attr);
111-
let _ = self.wrapper.w.attr(attr);
113+
attr.apply_to(&mut self.style);
114+
let _ = self.wrapper.w.style(&self.style);
112115
}
113116
fn pop_attr(&mut self) {
114117
self.attrs.pop();
115-
let _ = self.wrapper.w.reset();
118+
self.style = Style::new();
116119
for attr in &self.attrs {
117-
let _ = self.wrapper.w.attr(*attr);
120+
attr.apply_to(&mut self.style);
118121
}
122+
let _ = self.wrapper.w.style(&self.style);
119123
}
120124

121125
fn start_tag(&mut self, tag: Tag<'a>) {
@@ -240,6 +244,21 @@ impl<'a> LineFormatter<'a> {
240244
}
241245
}
242246

247+
#[derive(Copy, Clone, Debug)]
248+
pub enum Attr {
249+
Bold,
250+
ForegroundColor(AnsiColor),
251+
}
252+
253+
impl Attr {
254+
fn apply_to(&self, style: &mut Style) {
255+
match self {
256+
Self::Bold => *style = style.bold(),
257+
Self::ForegroundColor(color) => *style = style.fg_color(Some((*color).into())),
258+
}
259+
}
260+
}
261+
243262
pub(crate) fn md<S: AsRef<str>>(t: &mut ColorableTerminal, content: S) {
244263
let mut f = LineFormatter::new(t, 0, 79);
245264
let parser = pulldown_cmark::Parser::new(content.as_ref());

src/cli/rustup_mode.rs

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ use std::{
1010
time::Duration,
1111
};
1212

13+
use anstyle::Style;
1314
use anyhow::{Context, Error, Result, anyhow};
1415
use clap::{Args, CommandFactory, Parser, Subcommand, ValueEnum, builder::PossibleValue};
1516
use clap_complete::Shell;
@@ -39,7 +40,7 @@ use crate::{
3940
},
4041
errors::RustupError,
4142
install::{InstallMethod, UpdateStatus},
42-
process::{Attr, ColorableTerminal, Process},
43+
process::{ColorableTerminal, Process},
4344
toolchain::{
4445
CustomToolchainName, DistributableToolchain, LocalToolchainName,
4546
MaybeResolvableToolchainName, ResolvableLocalToolchainName, ResolvableToolchainName,
@@ -1072,10 +1073,12 @@ async fn which(
10721073
async fn show(cfg: &Cfg<'_>, verbose: bool) -> Result<utils::ExitCode> {
10731074
common::warn_if_host_is_emulated(cfg.process);
10741075

1076+
let bold = Style::new().bold();
1077+
10751078
// Print host triple
10761079
{
10771080
let mut t = cfg.process.stdout();
1078-
t.attr(Attr::Bold)?;
1081+
t.style(&bold)?;
10791082
write!(t.lock(), "Default host: ")?;
10801083
t.reset()?;
10811084
writeln!(t.lock(), "{}", cfg.get_default_host_triple()?)?;
@@ -1084,7 +1087,7 @@ async fn show(cfg: &Cfg<'_>, verbose: bool) -> Result<utils::ExitCode> {
10841087
// Print rustup home directory
10851088
{
10861089
let mut t = cfg.process.stdout();
1087-
t.attr(Attr::Bold)?;
1090+
t.style(&bold)?;
10881091
write!(t.lock(), "rustup home: ")?;
10891092
t.reset()?;
10901093
writeln!(t.lock(), "{}", cfg.rustup_dir.display())?;
@@ -1193,7 +1196,8 @@ async fn show(cfg: &Cfg<'_>, verbose: bool) -> Result<utils::ExitCode> {
11931196
}
11941197

11951198
fn print_header(t: &mut ColorableTerminal, s: &str) -> Result<(), Error> {
1196-
t.attr(Attr::Bold)?;
1199+
let bold = Style::new().bold();
1200+
t.style(&bold)?;
11971201
{
11981202
let mut term_lock = t.lock();
11991203
writeln!(term_lock, "{s}")?;

src/cli/self_update.rs

Lines changed: 9 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,7 @@ use std::process::Command;
4040
use std::str::FromStr;
4141
use std::{fmt, fs};
4242

43-
use anstyle::AnsiColor;
43+
use anstyle::{AnsiColor, Style};
4444
use anyhow::{Context, Result, anyhow};
4545
use cfg_if::cfg_if;
4646
use clap::ValueEnum;
@@ -63,7 +63,7 @@ use crate::{
6363
download::download_file,
6464
errors::RustupError,
6565
install::UpdateStatus,
66-
process::{Attr, Process},
66+
process::Process,
6767
toolchain::{
6868
DistributableToolchain, MaybeOfficialToolchainName, ResolvableToolchainName, Toolchain,
6969
ToolchainName,
@@ -1364,17 +1364,21 @@ pub(crate) async fn check_rustup_update(dl_cfg: &DownloadCfg<'_>) -> anyhow::Res
13641364
// Get available rustup version
13651365
let available_version = get_available_rustup_version(dl_cfg).await?;
13661366

1367-
let _ = t.attr(Attr::Bold);
1367+
let bold = Style::new().bold();
1368+
let yellow = AnsiColor::Yellow.on_default().bold();
1369+
let green = AnsiColor::Green.on_default().bold();
1370+
1371+
let _ = t.style(&bold);
13681372
write!(t.lock(), "rustup - ")?;
13691373

13701374
Ok(if current_version != available_version {
1371-
let _ = t.fg(AnsiColor::Yellow);
1375+
let _ = t.style(&yellow);
13721376
write!(t.lock(), "Update available")?;
13731377
let _ = t.reset();
13741378
writeln!(t.lock(), " : {current_version} -> {available_version}")?;
13751379
true
13761380
} else {
1377-
let _ = t.fg(AnsiColor::Green);
1381+
let _ = t.style(&green);
13781382
write!(t.lock(), "Up to date")?;
13791383
let _ = t.reset();
13801384
writeln!(t.lock(), " : {current_version}")?;

src/process.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@ use crate::cli::log;
2828

2929
mod file_source;
3030
mod terminal_source;
31-
pub use terminal_source::{Attr, ColorableTerminal};
31+
pub use terminal_source::ColorableTerminal;
3232

3333
/// Allows concrete types for the process abstraction.
3434
#[derive(Clone, Debug)]

src/process/terminal_source.rs

Lines changed: 11 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -9,10 +9,10 @@ use std::{
99
sync::{Arc, Mutex, MutexGuard},
1010
};
1111

12-
use anstyle::AnsiColor;
13-
use anstyle_termcolor::to_termcolor_color;
12+
use anstyle::Style;
13+
use anstyle_termcolor::to_termcolor_spec;
1414
use termcolor::ColorChoice;
15-
use termcolor::{ColorSpec, StandardStream, StandardStreamLock, WriteColor};
15+
use termcolor::{StandardStream, StandardStreamLock, WriteColor};
1616

1717
use super::Process;
1818
#[cfg(feature = "test")]
@@ -60,12 +60,8 @@ impl ColorableTerminal {
6060
_ => ColorChoice::Never,
6161
};
6262
let inner = match stream {
63-
StreamSelector::Stdout => {
64-
TerminalInner::StandardStream(StandardStream::stdout(choice), ColorSpec::new())
65-
}
66-
StreamSelector::Stderr => {
67-
TerminalInner::StandardStream(StandardStream::stderr(choice), ColorSpec::new())
68-
}
63+
StreamSelector::Stdout => TerminalInner::StandardStream(StandardStream::stdout(choice)),
64+
StreamSelector::Stderr => TerminalInner::StandardStream(StandardStream::stderr(choice)),
6965
#[cfg(feature = "test")]
7066
StreamSelector::TestWriter(w) => TerminalInner::TestWriter(w, choice),
7167
#[cfg(all(test, feature = "test"))]
@@ -99,7 +95,7 @@ impl ColorableTerminal {
9995
addr_of_mut!((*ptr).guard).write((*ptr).inner.lock().unwrap());
10096
// let locked = match *guard {....}
10197
addr_of_mut!((*ptr).locked).write(match (*ptr).guard.deref_mut() {
102-
TerminalInner::StandardStream(s, _) => {
98+
TerminalInner::StandardStream(s) => {
10399
let locked = s.lock();
104100
TerminalInnerLocked::StandardStream(locked)
105101
}
@@ -111,39 +107,17 @@ impl ColorableTerminal {
111107
}
112108
}
113109

114-
pub fn fg(&mut self, color: AnsiColor) -> io::Result<()> {
110+
pub fn style(&mut self, new: &Style) -> io::Result<()> {
115111
match self.inner.lock().unwrap().deref_mut() {
116-
TerminalInner::StandardStream(s, spec) => {
117-
spec.set_fg(Some(to_termcolor_color(color.into())));
118-
s.set_color(spec)
119-
}
120-
#[cfg(feature = "test")]
121-
TerminalInner::TestWriter(_, _) => Ok(()),
122-
}
123-
}
124-
125-
pub fn attr(&mut self, attr: Attr) -> io::Result<()> {
126-
match self.inner.lock().unwrap().deref_mut() {
127-
TerminalInner::StandardStream(s, spec) => {
128-
match attr {
129-
Attr::Bold => spec.set_bold(true),
130-
Attr::ForegroundColor(color) => {
131-
spec.set_fg(Some(to_termcolor_color(color.into())))
132-
}
133-
};
134-
s.set_color(spec)
135-
}
112+
TerminalInner::StandardStream(s) => s.set_color(&to_termcolor_spec(*new)),
136113
#[cfg(feature = "test")]
137114
TerminalInner::TestWriter(_, _) => Ok(()),
138115
}
139116
}
140117

141118
pub fn reset(&mut self) -> io::Result<()> {
142119
match self.inner.lock().unwrap().deref_mut() {
143-
TerminalInner::StandardStream(s, color) => {
144-
color.clear();
145-
s.reset()
146-
}
120+
TerminalInner::StandardStream(s) => s.reset(),
147121
#[cfg(feature = "test")]
148122
TerminalInner::TestWriter(_, _) => Ok(()),
149123
}
@@ -311,7 +285,7 @@ impl TerminalInnerLocked {
311285

312286
/// Internal state for ColorableTerminal
313287
enum TerminalInner {
314-
StandardStream(StandardStream, ColorSpec),
288+
StandardStream(StandardStream),
315289
#[cfg(feature = "test")]
316290
#[allow(dead_code)] // ColorChoice only read in test code
317291
TestWriter(TestWriter, ColorChoice),
@@ -320,7 +294,7 @@ enum TerminalInner {
320294
impl TerminalInner {
321295
fn as_write(&mut self) -> &mut dyn io::Write {
322296
match self {
323-
TerminalInner::StandardStream(s, _) => s,
297+
TerminalInner::StandardStream(s) => s,
324298
#[cfg(feature = "test")]
325299
TerminalInner::TestWriter(w, _) => w,
326300
}
@@ -358,12 +332,6 @@ impl StreamSelector {
358332
}
359333
}
360334

361-
#[derive(Copy, Clone, Debug)]
362-
pub enum Attr {
363-
Bold,
364-
ForegroundColor(AnsiColor),
365-
}
366-
367335
#[cfg(test)]
368336
mod tests {
369337
use std::collections::HashMap;

0 commit comments

Comments
 (0)