Skip to content

Commit

Permalink
refactor(wincon): Pull out platform-specific code
Browse files Browse the repository at this point in the history
  • Loading branch information
epage committed Sep 26, 2023
1 parent 46c8dc3 commit 5646a28
Show file tree
Hide file tree
Showing 2 changed files with 50 additions and 42 deletions.
52 changes: 10 additions & 42 deletions crates/anstyle-wincon/src/stream.rs
Original file line number Diff line number Diff line change
Expand Up @@ -106,7 +106,7 @@ impl WinconStream for std::fs::File {
/// Write colored text to the screen
#[derive(Clone, Debug)]
pub(crate) enum ConsoleState {
Wincon(WinconAdapter),
Wincon(StdioAdapter),
Pass(PassThroughAdapter),
}

Expand All @@ -116,7 +116,7 @@ impl ConsoleState {
) -> std::io::Result<Self> {
let adapter = match stream.get_colors() {
Ok((Some(initial_fg), Some(initial_bg))) => {
Self::Wincon(WinconAdapter::new(initial_fg, initial_bg))
Self::Wincon(StdioAdapter::new(initial_fg, initial_bg))
}
Ok(_) => Self::Pass(PassThroughAdapter),
Err(err) => {
Expand Down Expand Up @@ -162,33 +162,8 @@ impl ConsoleState {
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<()> {
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 new(_initial_fg: anstyle::AnsiColor, _initial_bg: anstyle::AnsiColor) -> Self {
Self
}

fn apply<S: crate::WinconStream + std::io::Write>(
Expand All @@ -197,23 +172,16 @@ impl WinconAdapter {
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(Some(fg), Some(bg))?;
self.last_fg = fg;
self.last_bg = bg;

stream.set_colors(fg, bg)?;
Ok(())
}
}

#[cfg(windows)]
use crate::windows::WinconAdapter as StdioAdapter;
#[cfg(not(windows))]
use PassThroughAdapter as StdioAdapter;

#[cfg(windows)]
mod wincon {
use std::os::windows::io::AsHandle;
Expand Down
40 changes: 40 additions & 0 deletions crates/anstyle-wincon/src/windows.rs
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,46 @@ pub fn get_colors<S: AsHandle>(
Ok((fg, bg))
}

#[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 {
pub(crate) fn new(initial_fg: anstyle::AnsiColor, initial_bg: anstyle::AnsiColor) -> Self {
Self {
initial_fg,
initial_bg,
last_fg: initial_fg,
last_bg: initial_bg,
}
}

pub(crate) 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(Some(fg), Some(bg))?;
self.last_fg = fg;
self.last_bg = bg;

Ok(())
}
}
mod inner {
use windows_sys::Win32::System::Console::CONSOLE_CHARACTER_ATTRIBUTES;
use windows_sys::Win32::System::Console::CONSOLE_SCREEN_BUFFER_INFO;
Expand Down

0 comments on commit 5646a28

Please sign in to comment.