Skip to content

Commit

Permalink
refactor(wincon): Pull out adapters
Browse files Browse the repository at this point in the history
  • Loading branch information
epage committed Sep 26, 2023
1 parent ccc6ee7 commit 46c8dc3
Showing 1 changed file with 59 additions and 17 deletions.
76 changes: 59 additions & 17 deletions crates/anstyle-wincon/src/stream.rs
Original file line number Diff line number Diff line change
Expand Up @@ -105,29 +105,25 @@ impl WinconStream for std::fs::File {

/// Write colored text to the screen
#[derive(Clone, Debug)]
pub(crate) struct ConsoleState {
initial_fg: Option<anstyle::AnsiColor>,
initial_bg: Option<anstyle::AnsiColor>,
last_fg: Option<anstyle::AnsiColor>,
last_bg: Option<anstyle::AnsiColor>,
pub(crate) enum ConsoleState {
Wincon(WinconAdapter),
Pass(PassThroughAdapter),
}

impl ConsoleState {
pub(crate) fn new<S: crate::WinconStream + std::io::Write>(
stream: &S,
) -> std::io::Result<Self> {
let (initial_fg, initial_bg) = match stream.get_colors() {
Ok(ok) => ok,
let adapter = match stream.get_colors() {
Ok((Some(initial_fg), Some(initial_bg))) => {
Self::Wincon(WinconAdapter::new(initial_fg, initial_bg))
}
Ok(_) => Self::Pass(PassThroughAdapter),
Err(err) => {
return Err(err);
}
};
Ok(Self {
initial_fg,
initial_bg,
last_fg: initial_fg,
last_bg: initial_bg,
})
Ok(adapter)
}

pub(crate) fn write<S: crate::WinconStream + std::io::Write>(
Expand All @@ -146,25 +142,71 @@ impl ConsoleState {
&mut self,
stream: &mut S,
) -> std::io::Result<()> {
self.apply(stream, self.initial_fg, self.initial_bg)
self.apply(stream, None, None)
}

fn apply<S: crate::WinconStream + std::io::Write>(
&mut self,
stream: &mut S,
fg: Option<anstyle::AnsiColor>,
bg: Option<anstyle::AnsiColor>,
) -> std::io::Result<()> {
match self {
Self::Wincon(adapter) => adapter.apply(stream, fg, bg),
Self::Pass(adapter) => adapter.apply(stream, fg, bg),
}
}
}

#[derive(Clone, Debug)]
pub(crate) struct PassThroughAdapter;

impl PassThroughAdapter {
fn apply<S: crate::WinconStream + std::io::Write>(
&mut self,
stream: &mut S,
fg: Option<anstyle::AnsiColor>,
bg: Option<anstyle::AnsiColor>,
) -> std::io::Result<()> {
let fg = fg.or(self.initial_fg);
let bg = bg.or(self.initial_bg);
stream.set_colors(fg, bg)?;
Ok(())
}
}

#[derive(Clone, Debug)]
pub(crate) struct WinconAdapter {
initial_fg: anstyle::AnsiColor,
initial_bg: anstyle::AnsiColor,
last_fg: anstyle::AnsiColor,
last_bg: anstyle::AnsiColor,
}

impl WinconAdapter {
fn new(initial_fg: anstyle::AnsiColor, initial_bg: anstyle::AnsiColor) -> Self {
Self {
initial_fg,
initial_bg,
last_fg: initial_fg,
last_bg: initial_bg,
}
}

fn apply<S: crate::WinconStream + std::io::Write>(
&mut self,
stream: &mut S,
fg: Option<anstyle::AnsiColor>,
bg: Option<anstyle::AnsiColor>,
) -> std::io::Result<()> {
let fg = fg.unwrap_or(self.initial_fg);
let bg = bg.unwrap_or(self.initial_bg);
if fg == self.last_fg && bg == self.last_bg {
return Ok(());
}

// Ensure everything is written with the last set of colors before applying the next set
stream.flush()?;

stream.set_colors(fg, bg)?;
stream.set_colors(Some(fg), Some(bg))?;
self.last_fg = fg;
self.last_bg = bg;

Expand Down

0 comments on commit 46c8dc3

Please sign in to comment.