pub(crate) mod colors;
pub(crate) mod input;
pub use colors::*;
pub use input::*;
use std::io::{self, BufReader, Read, Write};
pub enum Base {
Binary,
Octal,
Decimal,
Hexadecimal,
}
#[derive(Copy, Clone)]
pub enum ByteCategory {
Null,
AsciiPrintable,
AsciiWhitespace,
AsciiOther,
NonAscii,
}
#[derive(Copy, Clone)]
#[non_exhaustive]
pub enum CharacterTable {
Default,
CP437,
}
#[derive(Copy, Clone)]
pub enum Endianness {
Little,
Big,
}
#[derive(PartialEq)]
enum Squeezer {
Print,
Delete,
Ignore,
Disabled,
}
#[derive(Copy, Clone)]
struct Byte(u8);
impl Byte {
fn category(self) -> ByteCategory {
if self.0 == 0x00 {
ByteCategory::Null
} else if self.0.is_ascii_graphic() {
ByteCategory::AsciiPrintable
} else if self.0.is_ascii_whitespace() {
ByteCategory::AsciiWhitespace
} else if self.0.is_ascii() {
ByteCategory::AsciiOther
} else {
ByteCategory::NonAscii
}
}
fn color(self) -> &'static [u8] {
use crate::ByteCategory::*;
match self.category() {
Null => COLOR_NULL,
AsciiPrintable => COLOR_ASCII_PRINTABLE,
AsciiWhitespace => COLOR_ASCII_WHITESPACE,
AsciiOther => COLOR_ASCII_OTHER,
NonAscii => COLOR_NONASCII,
}
}
fn as_char(self, character_table: CharacterTable) -> char {
use crate::ByteCategory::*;
match character_table {
CharacterTable::Default => match self.category() {
Null => '⋄',
AsciiPrintable => self.0 as char,
AsciiWhitespace if self.0 == 0x20 => ' ',
AsciiWhitespace => '_',
AsciiOther => '•',
NonAscii => '×',
},
CharacterTable::CP437 => CP437[self.0 as usize],
}
}
}
struct BorderElements {
left_corner: char,
horizontal_line: char,
column_separator: char,
right_corner: char,
}
#[derive(Clone, Copy)]
pub enum BorderStyle {
Unicode,
Ascii,
None,
}
impl BorderStyle {
fn header_elems(&self) -> Option<BorderElements> {
match self {
BorderStyle::Unicode => Some(BorderElements {
left_corner: '┌',
horizontal_line: '─',
column_separator: '┬',
right_corner: '┐',
}),
BorderStyle::Ascii => Some(BorderElements {
left_corner: '+',
horizontal_line: '-',
column_separator: '+',
right_corner: '+',
}),
BorderStyle::None => None,
}
}
fn footer_elems(&self) -> Option<BorderElements> {
match self {
BorderStyle::Unicode => Some(BorderElements {
left_corner: '└',
horizontal_line: '─',
column_separator: '┴',
right_corner: '┘',
}),
BorderStyle::Ascii => Some(BorderElements {
left_corner: '+',
horizontal_line: '-',
column_separator: '+',
right_corner: '+',
}),
BorderStyle::None => None,
}
}
fn outer_sep(&self) -> char {
match self {
BorderStyle::Unicode => '│',
BorderStyle::Ascii => '|',
BorderStyle::None => ' ',
}
}
fn inner_sep(&self) -> char {
match self {
BorderStyle::Unicode => '┊',
BorderStyle::Ascii => '|',
BorderStyle::None => ' ',
}
}
}
pub struct PrinterBuilder<'a, Writer: Write> {
writer: &'a mut Writer,
show_color: bool,
show_char_panel: bool,
show_position_panel: bool,
border_style: BorderStyle,
use_squeeze: bool,
panels: u64,
group_size: u8,
base: Base,
endianness: Endianness,
character_table: CharacterTable,
}
impl<'a, Writer: Write> PrinterBuilder<'a, Writer> {
pub fn new(writer: &'a mut Writer) -> Self {
PrinterBuilder {
writer,
show_color: true,
show_char_panel: true,
show_position_panel: true,
border_style: BorderStyle::Unicode,
use_squeeze: true,
panels: 2,
group_size: 1,
base: Base::Hexadecimal,
endianness: Endianness::Big,
character_table: CharacterTable::Default,
}
}
pub fn show_color(mut self, show_color: bool) -> Self