Skip to content
Merged
Show file tree
Hide file tree
Changes from 4 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
2 changes: 1 addition & 1 deletion .github/workflows/CICD.yml
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
name: CICD

env:
MIN_SUPPORTED_RUST_VERSION: "1.46.0"
MIN_SUPPORTED_RUST_VERSION: "1.50.0"
CICD_INTERMEDIATES_DIR: "_cicd-intermediates"

on:
Expand Down
11 changes: 10 additions & 1 deletion examples/simple.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,9 +12,18 @@ fn main() {
let mut handle = stdout.lock();

let show_color = true;
let show_char_table = true;
let show_position_indicator = true;
let use_squeezing = false;
let border_style = BorderStyle::Unicode;

let mut printer = Printer::new(&mut handle, show_color, border_style, use_squeezing);
let mut printer = Printer::new(
&mut handle,
show_color,
show_char_table,
show_position_indicator,
border_style,
use_squeezing,
);
printer.print_all(&input[..]).unwrap();
}
38 changes: 37 additions & 1 deletion src/bin/hexyl.rs
Original file line number Diff line number Diff line change
Expand Up @@ -104,24 +104,46 @@ fn run() -> Result<(), AnyhowError> {
.takes_value(true)
.value_name("WHEN")
.possible_values(&["always", "auto", "never"])
.default_value_if("plain", None, "never")
.default_value("always")
.help(
"When to use colors. The auto-mode only displays colors if the output \
goes to an interactive terminal",
),
)
.arg(
Arg::with_name("plain")
.short("p")
.long("plain")
.help("Display output with --no-chars, --no-position, and --border=none."),
Comment thread
mkatychev marked this conversation as resolved.
Outdated
)
.arg(
Arg::with_name("border")
.long("border")
.takes_value(true)
.value_name("STYLE")
.possible_values(&["unicode", "ascii", "none"])
.default_value_if("plain", None, "none")
Comment thread
sharkdp marked this conversation as resolved.
.default_value("unicode")
.help(
"Whether to draw a border with Unicode characters, ASCII characters, \
or none at all",
),
)
.arg(
Arg::with_name("no_chars")
.short("C")
.long("no-chars")
Comment thread
mkatychev marked this conversation as resolved.
Outdated
.conflicts_with("plain")
Comment thread
mkatychev marked this conversation as resolved.
Outdated
.help("Whether to display the character table on the right."),
)
.arg(
Arg::with_name("no_position")
Comment thread
mkatychev marked this conversation as resolved.
.short("P")
.long("no-position")
.conflicts_with("plain")
Comment thread
mkatychev marked this conversation as resolved.
Outdated
.help("Whether to display the position indicator on the left."),
)
.arg(
Arg::with_name("display_offset")
.short("o")
Expand Down Expand Up @@ -237,6 +259,13 @@ fn run() -> Result<(), AnyhowError> {

let squeeze = !matches.is_present("nosqueezing");

// -nc true && false
// -plain true && false
Comment thread
mkatychev marked this conversation as resolved.
Outdated
let show_char_table = !matches.is_present("no_chars") && !matches.is_present("plain");

let show_position_indicator =
!matches.is_present("no_position") && !matches.is_present("plain");

let display_offset: u64 = matches
.value_of("display_offset")
.map(|s| {
Expand All @@ -251,7 +280,14 @@ fn run() -> Result<(), AnyhowError> {
let stdout = io::stdout();
let mut stdout_lock = stdout.lock();

let mut printer = Printer::new(&mut stdout_lock, show_color, border_style, squeeze);
let mut printer = Printer::new(
&mut stdout_lock,
show_color,
show_char_table,
show_position_indicator,
border_style,
squeeze,
);
printer.display_offset(skip_offset + display_offset);
printer.print_all(&mut reader).map_err(|e| anyhow!(e))?;

Expand Down
191 changes: 111 additions & 80 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -146,6 +146,8 @@ pub struct Printer<'a, Writer: Write> {
buffer_line: Vec<u8>,
writer: &'a mut Writer,
show_color: bool,
show_char_table: bool,
show_position_indicator: bool,
border_style: BorderStyle,
header_was_printed: bool,
byte_hex_table: Vec<String>,
Expand All @@ -158,6 +160,8 @@ impl<'a, Writer: Write> Printer<'a, Writer> {
pub fn new(
writer: &'a mut Writer,
show_color: bool,
show_char_table: bool,
show_position_indicator: bool,
border_style: BorderStyle,
use_squeeze: bool,
) -> Printer<'a, Writer> {
Expand All @@ -167,6 +171,8 @@ impl<'a, Writer: Write> Printer<'a, Writer> {
buffer_line: vec![],
writer,
show_color,
show_char_table,
show_position_indicator,
border_style,
header_was_printed: false,
byte_hex_table: (0u8..=u8::max_value())
Expand All @@ -179,16 +185,20 @@ impl<'a, Writer: Write> Printer<'a, Writer> {
}
})
.collect(),
byte_char_table: (0u8..=u8::max_value())
.map(|i| {
let byte_char = format!("{}", Byte(i).as_char());
if show_color {
Byte(i).color().paint(byte_char).to_string()
} else {
byte_char
}
byte_char_table: show_char_table
.then(|| {
Comment thread
mkatychev marked this conversation as resolved.
(0u8..=u8::max_value())
.map(|i| {
let byte_char = format!("{}", Byte(i).as_char());
if show_color {
Byte(i).color().paint(byte_char).to_string()
} else {
byte_char
}
})
.collect()
})
.collect(),
.unwrap_or_default(),
squeezer: Squeezer::new(use_squeeze),
display_offset: 0,
}
Expand All @@ -199,41 +209,38 @@ impl<'a, Writer: Write> Printer<'a, Writer> {
self
}

pub fn header(&mut self) {
if let Some(border_elements) = self.border_style.header_elems() {
let h = border_elements.horizontal_line;
let h8 = h.to_string().repeat(8);
let h25 = h.to_string().repeat(25);
fn write_border(&mut self, border_elements: BorderElements) {
let h = border_elements.horizontal_line;
let c = border_elements.column_separator;
let l = border_elements.left_corner;
let r = border_elements.right_corner;
let h8 = h.to_string().repeat(8);
let h25 = h.to_string().repeat(25);

writeln!(
self.writer,
"{l}{h8}{c}{h25}{c}{h25}{c}{h8}{c}{h8}{r}",
l = border_elements.left_corner,
c = border_elements.column_separator,
r = border_elements.right_corner,
h8 = h8,
h25 = h25
)
.ok();
if self.show_position_indicator {
write!(self.writer, "{l}{h8}{c}", l = l, c = c, h8 = h8).ok();
} else {
write!(self.writer, "{}", l).ok();
}

write!(self.writer, "{h25}{c}{h25}", c = c, h25 = h25).ok();

if self.show_char_table {
writeln!(self.writer, "{c}{h8}{c}{h8}{r}", c = c, h8 = h8, r = r).ok();
} else {
writeln!(self.writer, "{r}", r = r).ok();
}
}

pub fn footer(&mut self) {
if let Some(border_elements) = self.border_style.footer_elems() {
let h = border_elements.horizontal_line;
let h8 = h.to_string().repeat(8);
let h25 = h.to_string().repeat(25);
pub fn header(&mut self) {
if let Some(e) = self.border_style.header_elems() {
self.write_border(e)
}
}

writeln!(
self.writer,
"{l}{h8}{c}{h25}{c}{h25}{c}{h8}{c}{h8}{r}",
l = border_elements.left_corner,
c = border_elements.column_separator,
r = border_elements.right_corner,
h8 = h8,
h25 = h25
)
.ok();
pub fn footer(&mut self) {
if let Some(e) = self.border_style.footer_elems() {
self.write_border(e)
}
}

Expand All @@ -242,6 +249,10 @@ impl<'a, Writer: Write> Printer<'a, Writer> {
self.header();
self.header_was_printed = true;
}
if !self.show_position_indicator {
write!(&mut self.buffer_line, "{} ", self.border_style.outer_sep()).ok();
return;
}

let style = COLOR_OFFSET.normal();
let byte_index = format!("{:08x}", self.idx - 1 + self.display_offset);
Expand All @@ -259,6 +270,51 @@ impl<'a, Writer: Write> Printer<'a, Writer> {
);
}

pub fn print_char_table(&mut self) {
let len = self.raw_line.len();

if !self.show_char_table {
// just write newline if character table is hidden
writeln!(&mut self.buffer_line).ok();
return;
}

let mut idx = 1;
for &b in self.raw_line.iter() {
let _ = write!(
&mut self.buffer_line,
"{}",
self.byte_char_table[b as usize]
);

if idx == 8 {
let _ = write!(&mut self.buffer_line, "{}", self.border_style.inner_sep());
}

idx += 1;
}

if len < 8 {
let _ = writeln!(
&mut self.buffer_line,
"{0:1$}{3}{0:2$}{4}",
"",
8 - len,
8,
self.border_style.inner_sep(),
self.border_style.outer_sep(),
);
} else {
let _ = writeln!(
&mut self.buffer_line,
"{0:1$}{2}",
"",
16 - len,
self.border_style.outer_sep()
);
}
}

pub fn print_byte(&mut self, b: u8) -> io::Result<()> {
if self.idx % 16 == 1 {
self.print_position_indicator();
Expand Down Expand Up @@ -327,43 +383,10 @@ impl<'a, Writer: Write> Printer<'a, Writer> {
self.border_style.outer_sep()
);
}

let mut idx = 1;
for &b in self.raw_line.iter() {
let _ = write!(
&mut self.buffer_line,
"{}",
self.byte_char_table[b as usize]
);

if idx == 8 {
let _ = write!(&mut self.buffer_line, "{}", self.border_style.inner_sep());
}

idx += 1;
}

if len < 8 {
let _ = writeln!(
&mut self.buffer_line,
"{0:1$}{3}{0:2$}{4}",
"",
8 - len,
8,
self.border_style.inner_sep(),
self.border_style.outer_sep(),
);
} else {
let _ = writeln!(
&mut self.buffer_line,
"{0:1$}{2}",
"",
16 - len,
self.border_style.outer_sep()
);
}
}

self.print_char_table();

match squeeze_action {
SqueezeAction::Print => {
self.buffer_line.clear();
Expand Down Expand Up @@ -431,11 +454,19 @@ impl<'a, Writer: Write> Printer<'a, Writer> {

if !self.header_was_printed() {
self.header();
writeln!(
if self.show_position_indicator {
write!(self.writer, "{0:9}", "│").ok();
}
write!(
self.writer,
"│ │ No content to print │ │ │ │"
"{0:2}{1:24}{0}{0:>26}",
"│", "No content to print"
)
.ok();
if self.show_char_table {
write!(self.writer, "{0:>9}{0:>9}", "│").ok();
}
writeln!(self.writer).ok();
}
self.footer();

Expand All @@ -450,14 +481,14 @@ mod tests {

use super::*;

fn assert_print_all_output<Reader: Read>(input: Reader, expected_string: String) -> () {
fn assert_print_all_output<Reader: Read>(input: Reader, expected_string: String) {
let mut output = vec![];
let mut printer = Printer::new(&mut output, false, BorderStyle::Unicode, true);
let mut printer = Printer::new(&mut output, false, true, true, BorderStyle::Unicode, true);

printer.print_all(input).unwrap();

let actual_string: &str = str::from_utf8(&output).unwrap();
assert_eq!(actual_string, expected_string)
assert_eq!(actual_string, expected_string,)
}

#[test]
Expand Down Expand Up @@ -497,7 +528,7 @@ mod tests {

let mut output = vec![];
let mut printer: Printer<Vec<u8>> =
Printer::new(&mut output, false, BorderStyle::Unicode, true);
Printer::new(&mut output, false, true, true, BorderStyle::Unicode, true);
printer.display_offset(0xdeadbeef);

printer.print_all(input).unwrap();
Expand Down
Loading