Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
40 changes: 25 additions & 15 deletions crates/anstream/src/strip.rs
Original file line number Diff line number Diff line change
Expand Up @@ -50,23 +50,11 @@ impl<S> std::io::Write for StripStream<S>
where
S: RawStream,
{
#[inline]
fn write(&mut self, buf: &[u8]) -> std::io::Result<usize> {
let initial_state = self.state.clone();

for printable in self.state.strip_next(buf) {
let possible = printable.len();
let written = self.raw.write(printable)?;
if possible != written {
let divergence = &printable[written..];
let offset = offset_to(buf, divergence);
let consumed = &buf[offset..];
self.state = initial_state;
self.state.strip_next(consumed).last();
return Ok(offset);
}
}
Ok(buf.len())
write(&mut self.raw, &mut self.state, buf)
}

#[inline]
fn flush(&mut self) -> std::io::Result<()> {
self.raw.flush()
Expand All @@ -87,6 +75,28 @@ where
// Not bothering with `write_fmt` as it just calls `write_all`
}

fn write(
raw: &mut dyn std::io::Write,
state: &mut StripBytes,
buf: &[u8],
) -> std::io::Result<usize> {
let initial_state = state.clone();

for printable in state.strip_next(buf) {
let possible = printable.len();
let written = raw.write(printable)?;
if possible != written {
let divergence = &printable[written..];
let offset = offset_to(buf, divergence);
let consumed = &buf[offset..];
*state = initial_state;
state.strip_next(consumed).last();
return Ok(offset);
}
}
Ok(buf.len())
}

#[inline]
fn offset_to(total: &[u8], subslice: &[u8]) -> usize {
let total = total.as_ptr();
Expand Down
21 changes: 12 additions & 9 deletions crates/anstyle-roff/tests/test_roff.rs
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
use anstyle::{AnsiColor, Color, Style};
use anstyle::Style;

#[test]
fn test_ansi_color_output() {
let style = Style::new()
.fg_color(Some(Color::Ansi(AnsiColor::Red)))
.bg_color(Some(Color::Ansi(AnsiColor::Blue)));
let text = format!("{}{}", style.render(), "test");
// HACK: cansi doesn't properly merge separate sequences
// let style = AnsiColor::Red.on(AnsiColor::Blue);
// let text = format!("{}{}", style.render(), "test");
let text = "\u{1b}[31;44mtest".to_owned();
let roff_doc = anstyle_roff::to_roff(&text);
snapbox::assert_eq_path("tests/roffs/ansi_color.roff", roff_doc.to_roff());
}
Expand All @@ -14,6 +14,7 @@ fn test_ansi_color_output() {
fn test_bold_output() {
let style = Style::new().bold();
let text = format!("{}{}", style.render(), "test");
dbg!(&text);
let roff_doc = anstyle_roff::to_roff(&text);

snapbox::assert_eq_path("tests/roffs/bold.roff", roff_doc.to_roff());
Expand All @@ -23,17 +24,19 @@ fn test_bold_output() {
fn test_italic_output() {
let style = Style::new().italic();
let text = format!("{}{}", style.render(), "test");
dbg!(&text);

let roff_doc = anstyle_roff::to_roff(&text);
snapbox::assert_eq_path("tests/roffs/italic.roff", roff_doc.to_roff());
}

#[test]
fn test_bright_color_output_as_bold() {
let style = Style::new()
.fg_color(Some(Color::Ansi(AnsiColor::BrightRed)))
.bg_color(Some(Color::Ansi(AnsiColor::Blue)));
let text = format!("{}{}", style.render(), "test");
// HACK: cansi doesn't properly merge separate sequences
// let style = AnsiColor::BrightRed.on(AnsiColor::Blue);
// let text = format!("{}{}", style.render(), "test");
let text = "\u{1b}[91;44mtest".to_owned();
dbg!(&text);
let roff_doc = anstyle_roff::to_roff(&text);
snapbox::assert_eq_path("tests/roffs/bright_ansi_colors.roff", roff_doc.to_roff());
}
Loading