diff --git a/src/lib.rs b/src/lib.rs index 324821a..5181804 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -20,6 +20,264 @@ const COLOR_ASCII_WHITESPACE: &[u8] = colors::Green::ANSI_FG.as_bytes(); const COLOR_ASCII_OTHER: &[u8] = colors::Green::ANSI_FG.as_bytes(); const COLOR_NONASCII: &[u8] = colors::Yellow::ANSI_FG.as_bytes(); const COLOR_RESET: &[u8] = colors::Default::ANSI_FG.as_bytes(); +const COLORS_XTERM: [&[u8]; 256] = [ + colors::xterm::UserBlack::ANSI_FG.as_bytes(), + colors::xterm::UserRed::ANSI_FG.as_bytes(), + colors::xterm::UserGreen::ANSI_FG.as_bytes(), + colors::xterm::UserYellow::ANSI_FG.as_bytes(), + colors::xterm::UserBlue::ANSI_FG.as_bytes(), + colors::xterm::UserMagenta::ANSI_FG.as_bytes(), + colors::xterm::UserCyan::ANSI_FG.as_bytes(), + colors::xterm::UserWhite::ANSI_FG.as_bytes(), + colors::xterm::UserBrightBlack::ANSI_FG.as_bytes(), + colors::xterm::UserBrightRed::ANSI_FG.as_bytes(), + colors::xterm::UserBrightGreen::ANSI_FG.as_bytes(), + colors::xterm::UserBrightYellow::ANSI_FG.as_bytes(), + colors::xterm::UserBrightBlue::ANSI_FG.as_bytes(), + colors::xterm::UserBrightMagenta::ANSI_FG.as_bytes(), + colors::xterm::UserBrightCyan::ANSI_FG.as_bytes(), + colors::xterm::UserBrightWhite::ANSI_FG.as_bytes(), + colors::xterm::Black::ANSI_FG.as_bytes(), + colors::xterm::StratosBlue::ANSI_FG.as_bytes(), + colors::xterm::NavyBlue::ANSI_FG.as_bytes(), + colors::xterm::MidnightBlue::ANSI_FG.as_bytes(), + colors::xterm::DarkBlue::ANSI_FG.as_bytes(), + colors::xterm::Blue::ANSI_FG.as_bytes(), + colors::xterm::CamaroneGreen::ANSI_FG.as_bytes(), + colors::xterm::BlueStone::ANSI_FG.as_bytes(), + colors::xterm::OrientBlue::ANSI_FG.as_bytes(), + colors::xterm::EndeavourBlue::ANSI_FG.as_bytes(), + colors::xterm::ScienceBlue::ANSI_FG.as_bytes(), + colors::xterm::BlueRibbon::ANSI_FG.as_bytes(), + colors::xterm::JapaneseLaurel::ANSI_FG.as_bytes(), + colors::xterm::DeepSeaGreen::ANSI_FG.as_bytes(), + colors::xterm::Teal::ANSI_FG.as_bytes(), + colors::xterm::DeepCerulean::ANSI_FG.as_bytes(), + colors::xterm::LochmaraBlue::ANSI_FG.as_bytes(), + colors::xterm::AzureRadiance::ANSI_FG.as_bytes(), + colors::xterm::LightJapaneseLaurel::ANSI_FG.as_bytes(), + colors::xterm::Jade::ANSI_FG.as_bytes(), + colors::xterm::PersianGreen::ANSI_FG.as_bytes(), + colors::xterm::BondiBlue::ANSI_FG.as_bytes(), + colors::xterm::Cerulean::ANSI_FG.as_bytes(), + colors::xterm::LightAzureRadiance::ANSI_FG.as_bytes(), + colors::xterm::DarkGreen::ANSI_FG.as_bytes(), + colors::xterm::Malachite::ANSI_FG.as_bytes(), + colors::xterm::CaribbeanGreen::ANSI_FG.as_bytes(), + colors::xterm::LightCaribbeanGreen::ANSI_FG.as_bytes(), + colors::xterm::RobinEggBlue::ANSI_FG.as_bytes(), + colors::xterm::Aqua::ANSI_FG.as_bytes(), + colors::xterm::Green::ANSI_FG.as_bytes(), + colors::xterm::DarkSpringGreen::ANSI_FG.as_bytes(), + colors::xterm::SpringGreen::ANSI_FG.as_bytes(), + colors::xterm::LightSpringGreen::ANSI_FG.as_bytes(), + colors::xterm::BrightTurquoise::ANSI_FG.as_bytes(), + colors::xterm::Cyan::ANSI_FG.as_bytes(), + colors::xterm::Rosewood::ANSI_FG.as_bytes(), + colors::xterm::PompadourMagenta::ANSI_FG.as_bytes(), + colors::xterm::PigmentIndigo::ANSI_FG.as_bytes(), + colors::xterm::DarkPurple::ANSI_FG.as_bytes(), + colors::xterm::ElectricIndigo::ANSI_FG.as_bytes(), + colors::xterm::ElectricPurple::ANSI_FG.as_bytes(), + colors::xterm::VerdunGreen::ANSI_FG.as_bytes(), + colors::xterm::ScorpionOlive::ANSI_FG.as_bytes(), + colors::xterm::Lilac::ANSI_FG.as_bytes(), + colors::xterm::ScampiIndigo::ANSI_FG.as_bytes(), + colors::xterm::Indigo::ANSI_FG.as_bytes(), + colors::xterm::DarkCornflowerBlue::ANSI_FG.as_bytes(), + colors::xterm::DarkLimeade::ANSI_FG.as_bytes(), + colors::xterm::GladeGreen::ANSI_FG.as_bytes(), + colors::xterm::JuniperGreen::ANSI_FG.as_bytes(), + colors::xterm::HippieBlue::ANSI_FG.as_bytes(), + colors::xterm::HavelockBlue::ANSI_FG.as_bytes(), + colors::xterm::CornflowerBlue::ANSI_FG.as_bytes(), + colors::xterm::Limeade::ANSI_FG.as_bytes(), + colors::xterm::FernGreen::ANSI_FG.as_bytes(), + colors::xterm::SilverTree::ANSI_FG.as_bytes(), + colors::xterm::Tradewind::ANSI_FG.as_bytes(), + colors::xterm::ShakespeareBlue::ANSI_FG.as_bytes(), + colors::xterm::DarkMalibuBlue::ANSI_FG.as_bytes(), + colors::xterm::DarkBrightGreen::ANSI_FG.as_bytes(), + colors::xterm::DarkPastelGreen::ANSI_FG.as_bytes(), + colors::xterm::PastelGreen::ANSI_FG.as_bytes(), + colors::xterm::DownyTeal::ANSI_FG.as_bytes(), + colors::xterm::Viking::ANSI_FG.as_bytes(), + colors::xterm::MalibuBlue::ANSI_FG.as_bytes(), + colors::xterm::BrightGreen::ANSI_FG.as_bytes(), + colors::xterm::DarkScreaminGreen::ANSI_FG.as_bytes(), + colors::xterm::ScreaminGreen::ANSI_FG.as_bytes(), + colors::xterm::DarkAquamarine::ANSI_FG.as_bytes(), + colors::xterm::Aquamarine::ANSI_FG.as_bytes(), + colors::xterm::LightAquamarine::ANSI_FG.as_bytes(), + colors::xterm::Maroon::ANSI_FG.as_bytes(), + colors::xterm::DarkFreshEggplant::ANSI_FG.as_bytes(), + colors::xterm::LightFreshEggplant::ANSI_FG.as_bytes(), + colors::xterm::Purple::ANSI_FG.as_bytes(), + colors::xterm::ElectricViolet::ANSI_FG.as_bytes(), + colors::xterm::LightElectricViolet::ANSI_FG.as_bytes(), + colors::xterm::Brown::ANSI_FG.as_bytes(), + colors::xterm::CopperRose::ANSI_FG.as_bytes(), + colors::xterm::StrikemasterPurple::ANSI_FG.as_bytes(), + colors::xterm::DelugePurple::ANSI_FG.as_bytes(), + colors::xterm::DarkMediumPurple::ANSI_FG.as_bytes(), + colors::xterm::DarkHeliotropePurple::ANSI_FG.as_bytes(), + colors::xterm::Olive::ANSI_FG.as_bytes(), + colors::xterm::ClayCreekOlive::ANSI_FG.as_bytes(), + colors::xterm::DarkGray::ANSI_FG.as_bytes(), + colors::xterm::WildBlueYonder::ANSI_FG.as_bytes(), + colors::xterm::ChetwodeBlue::ANSI_FG.as_bytes(), + colors::xterm::SlateBlue::ANSI_FG.as_bytes(), + colors::xterm::LightLimeade::ANSI_FG.as_bytes(), + colors::xterm::ChelseaCucumber::ANSI_FG.as_bytes(), + colors::xterm::BayLeaf::ANSI_FG.as_bytes(), + colors::xterm::GulfStream::ANSI_FG.as_bytes(), + colors::xterm::PoloBlue::ANSI_FG.as_bytes(), + colors::xterm::LightMalibuBlue::ANSI_FG.as_bytes(), + colors::xterm::Pistachio::ANSI_FG.as_bytes(), + colors::xterm::LightPastelGreen::ANSI_FG.as_bytes(), + colors::xterm::DarkFeijoaGreen::ANSI_FG.as_bytes(), + colors::xterm::VistaBlue::ANSI_FG.as_bytes(), + colors::xterm::Bermuda::ANSI_FG.as_bytes(), + colors::xterm::DarkAnakiwaBlue::ANSI_FG.as_bytes(), + colors::xterm::ChartreuseGreen::ANSI_FG.as_bytes(), + colors::xterm::LightScreaminGreen::ANSI_FG.as_bytes(), + colors::xterm::DarkMintGreen::ANSI_FG.as_bytes(), + colors::xterm::MintGreen::ANSI_FG.as_bytes(), + colors::xterm::LighterAquamarine::ANSI_FG.as_bytes(), + colors::xterm::AnakiwaBlue::ANSI_FG.as_bytes(), + colors::xterm::BrightRed::ANSI_FG.as_bytes(), + colors::xterm::DarkFlirt::ANSI_FG.as_bytes(), + colors::xterm::Flirt::ANSI_FG.as_bytes(), + colors::xterm::LightFlirt::ANSI_FG.as_bytes(), + colors::xterm::DarkViolet::ANSI_FG.as_bytes(), + colors::xterm::BrightElectricViolet::ANSI_FG.as_bytes(), + colors::xterm::RoseofSharonOrange::ANSI_FG.as_bytes(), + colors::xterm::MatrixPink::ANSI_FG.as_bytes(), + colors::xterm::TapestryPink::ANSI_FG.as_bytes(), + colors::xterm::FuchsiaPink::ANSI_FG.as_bytes(), + colors::xterm::MediumPurple::ANSI_FG.as_bytes(), + colors::xterm::Heliotrope::ANSI_FG.as_bytes(), + colors::xterm::PirateGold::ANSI_FG.as_bytes(), + colors::xterm::MuesliOrange::ANSI_FG.as_bytes(), + colors::xterm::PharlapPink::ANSI_FG.as_bytes(), + colors::xterm::Bouquet::ANSI_FG.as_bytes(), + colors::xterm::Lavender::ANSI_FG.as_bytes(), + colors::xterm::LightHeliotrope::ANSI_FG.as_bytes(), + colors::xterm::BuddhaGold::ANSI_FG.as_bytes(), + colors::xterm::OliveGreen::ANSI_FG.as_bytes(), + colors::xterm::HillaryOlive::ANSI_FG.as_bytes(), + colors::xterm::SilverChalice::ANSI_FG.as_bytes(), + colors::xterm::WistfulLilac::ANSI_FG.as_bytes(), + colors::xterm::MelroseLilac::ANSI_FG.as_bytes(), + colors::xterm::RioGrandeGreen::ANSI_FG.as_bytes(), + colors::xterm::ConiferGreen::ANSI_FG.as_bytes(), + colors::xterm::Feijoa::ANSI_FG.as_bytes(), + colors::xterm::PixieGreen::ANSI_FG.as_bytes(), + colors::xterm::JungleMist::ANSI_FG.as_bytes(), + colors::xterm::LightAnakiwaBlue::ANSI_FG.as_bytes(), + colors::xterm::Lime::ANSI_FG.as_bytes(), + colors::xterm::GreenYellow::ANSI_FG.as_bytes(), + colors::xterm::LightMintGreen::ANSI_FG.as_bytes(), + colors::xterm::Celadon::ANSI_FG.as_bytes(), + colors::xterm::AeroBlue::ANSI_FG.as_bytes(), + colors::xterm::FrenchPassLightBlue::ANSI_FG.as_bytes(), + colors::xterm::GuardsmanRed::ANSI_FG.as_bytes(), + colors::xterm::RazzmatazzCerise::ANSI_FG.as_bytes(), + colors::xterm::MediumVioletRed::ANSI_FG.as_bytes(), + colors::xterm::HollywoodCerise::ANSI_FG.as_bytes(), + colors::xterm::DarkPurplePizzazz::ANSI_FG.as_bytes(), + colors::xterm::BrighterElectricViolet::ANSI_FG.as_bytes(), + colors::xterm::TennOrange::ANSI_FG.as_bytes(), + colors::xterm::RomanOrange::ANSI_FG.as_bytes(), + colors::xterm::CranberryPink::ANSI_FG.as_bytes(), + colors::xterm::HopbushPink::ANSI_FG.as_bytes(), + colors::xterm::Orchid::ANSI_FG.as_bytes(), + colors::xterm::LighterHeliotrope::ANSI_FG.as_bytes(), + colors::xterm::MangoTango::ANSI_FG.as_bytes(), + colors::xterm::Copperfield::ANSI_FG.as_bytes(), + colors::xterm::SeaPink::ANSI_FG.as_bytes(), + colors::xterm::CanCanPink::ANSI_FG.as_bytes(), + colors::xterm::LightOrchid::ANSI_FG.as_bytes(), + colors::xterm::BrightHeliotrope::ANSI_FG.as_bytes(), + colors::xterm::DarkCorn::ANSI_FG.as_bytes(), + colors::xterm::DarkTachaOrange::ANSI_FG.as_bytes(), + colors::xterm::TanBeige::ANSI_FG.as_bytes(), + colors::xterm::ClamShell::ANSI_FG.as_bytes(), + colors::xterm::ThistlePink::ANSI_FG.as_bytes(), + colors::xterm::Mauve::ANSI_FG.as_bytes(), + colors::xterm::Corn::ANSI_FG.as_bytes(), + colors::xterm::TachaOrange::ANSI_FG.as_bytes(), + colors::xterm::DecoOrange::ANSI_FG.as_bytes(), + colors::xterm::PaleGoldenrod::ANSI_FG.as_bytes(), + colors::xterm::AltoBeige::ANSI_FG.as_bytes(), + colors::xterm::FogPink::ANSI_FG.as_bytes(), + colors::xterm::ChartreuseYellow::ANSI_FG.as_bytes(), + colors::xterm::Canary::ANSI_FG.as_bytes(), + colors::xterm::Honeysuckle::ANSI_FG.as_bytes(), + colors::xterm::ReefPaleYellow::ANSI_FG.as_bytes(), + colors::xterm::SnowyMint::ANSI_FG.as_bytes(), + colors::xterm::OysterBay::ANSI_FG.as_bytes(), + colors::xterm::Red::ANSI_FG.as_bytes(), + colors::xterm::DarkRose::ANSI_FG.as_bytes(), + colors::xterm::Rose::ANSI_FG.as_bytes(), + colors::xterm::LightHollywoodCerise::ANSI_FG.as_bytes(), + colors::xterm::PurplePizzazz::ANSI_FG.as_bytes(), + colors::xterm::Fuchsia::ANSI_FG.as_bytes(), + colors::xterm::BlazeOrange::ANSI_FG.as_bytes(), + colors::xterm::BittersweetOrange::ANSI_FG.as_bytes(), + colors::xterm::WildWatermelon::ANSI_FG.as_bytes(), + colors::xterm::DarkHotPink::ANSI_FG.as_bytes(), + colors::xterm::HotPink::ANSI_FG.as_bytes(), + colors::xterm::PinkFlamingo::ANSI_FG.as_bytes(), + colors::xterm::FlushOrange::ANSI_FG.as_bytes(), + colors::xterm::Salmon::ANSI_FG.as_bytes(), + colors::xterm::VividTangerine::ANSI_FG.as_bytes(), + colors::xterm::PinkSalmon::ANSI_FG.as_bytes(), + colors::xterm::DarkLavenderRose::ANSI_FG.as_bytes(), + colors::xterm::BlushPink::ANSI_FG.as_bytes(), + colors::xterm::YellowSea::ANSI_FG.as_bytes(), + colors::xterm::TexasRose::ANSI_FG.as_bytes(), + colors::xterm::Tacao::ANSI_FG.as_bytes(), + colors::xterm::Sundown::ANSI_FG.as_bytes(), + colors::xterm::CottonCandy::ANSI_FG.as_bytes(), + colors::xterm::LavenderRose::ANSI_FG.as_bytes(), + colors::xterm::Gold::ANSI_FG.as_bytes(), + colors::xterm::Dandelion::ANSI_FG.as_bytes(), + colors::xterm::GrandisCaramel::ANSI_FG.as_bytes(), + colors::xterm::Caramel::ANSI_FG.as_bytes(), + colors::xterm::CosmosSalmon::ANSI_FG.as_bytes(), + colors::xterm::PinkLace::ANSI_FG.as_bytes(), + colors::xterm::Yellow::ANSI_FG.as_bytes(), + colors::xterm::LaserLemon::ANSI_FG.as_bytes(), + colors::xterm::DollyYellow::ANSI_FG.as_bytes(), + colors::xterm::PortafinoYellow::ANSI_FG.as_bytes(), + colors::xterm::Cumulus::ANSI_FG.as_bytes(), + colors::xterm::White::ANSI_FG.as_bytes(), + colors::xterm::DarkCodGray::ANSI_FG.as_bytes(), + colors::xterm::CodGray::ANSI_FG.as_bytes(), + colors::xterm::LightCodGray::ANSI_FG.as_bytes(), + colors::xterm::DarkMineShaft::ANSI_FG.as_bytes(), + colors::xterm::MineShaft::ANSI_FG.as_bytes(), + colors::xterm::LightMineShaft::ANSI_FG.as_bytes(), + colors::xterm::DarkTundora::ANSI_FG.as_bytes(), + colors::xterm::Tundora::ANSI_FG.as_bytes(), + colors::xterm::ScorpionGray::ANSI_FG.as_bytes(), + colors::xterm::DarkDoveGray::ANSI_FG.as_bytes(), + colors::xterm::DoveGray::ANSI_FG.as_bytes(), + colors::xterm::Boulder::ANSI_FG.as_bytes(), + colors::xterm::Gray::ANSI_FG.as_bytes(), + colors::xterm::LightGray::ANSI_FG.as_bytes(), + colors::xterm::DustyGray::ANSI_FG.as_bytes(), + colors::xterm::NobelGray::ANSI_FG.as_bytes(), + colors::xterm::DarkSilverChalice::ANSI_FG.as_bytes(), + colors::xterm::LightSilverChalice::ANSI_FG.as_bytes(), + colors::xterm::DarkSilver::ANSI_FG.as_bytes(), + colors::xterm::Silver::ANSI_FG.as_bytes(), + colors::xterm::DarkAlto::ANSI_FG.as_bytes(), + colors::xterm::Alto::ANSI_FG.as_bytes(), + colors::xterm::Mercury::ANSI_FG.as_bytes(), + colors::xterm::GalleryGray::ANSI_FG.as_bytes(), +]; #[rustfmt::skip] const CP437: [char; 256] = [ @@ -73,6 +331,7 @@ pub enum ByteCategory { #[non_exhaustive] pub enum CharacterTable { AsciiOnly, + Block, CP437, } @@ -108,15 +367,17 @@ impl Byte { } } - fn color(self) -> &'static [u8] { + fn color(self, character_table: CharacterTable) -> &'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, + match character_table { + CharacterTable::AsciiOnly | CharacterTable::CP437 => match self.category() { + Null => COLOR_NULL, + AsciiPrintable => COLOR_ASCII_PRINTABLE, + AsciiWhitespace => COLOR_ASCII_WHITESPACE, + AsciiOther => COLOR_ASCII_OTHER, + NonAscii => COLOR_NONASCII, + }, + CharacterTable::Block => COLORS_XTERM[self.0 as usize], } } @@ -131,7 +392,8 @@ impl Byte { AsciiOther => '•', NonAscii => '×', }, - CharacterTable::CP437 => CP437[self.0.to_ne_bytes()[0] as usize], + CharacterTable::CP437 => CP437[self.0 as usize], + CharacterTable::Block => '█', } } } @@ -327,6 +589,8 @@ pub struct Printer<'a, Writer: Write> { base_digits: u8, /// Whether to show groups in little or big endian format. endianness: Endianness, + /// The character table to reference for the character panel. + character_table: CharacterTable, } impl<'a, Writer: Write> Printer<'a, Writer> { @@ -380,6 +644,7 @@ impl<'a, Writer: Write> Printer<'a, Writer> { Base::Hexadecimal => 2, }, endianness, + character_table, } } @@ -495,9 +760,11 @@ impl<'a, Writer: Write> Printer<'a, Writer> { Squeezer::Print | Squeezer::Delete => self.writer.write_all(b" ")?, Squeezer::Ignore | Squeezer::Disabled => { if let Some(&b) = self.line_buf.get(i as usize) { - if self.show_color && self.curr_color != Some(Byte(b).color()) { - self.writer.write_all(Byte(b).color())?; - self.curr_color = Some(Byte(b).color()); + if self.show_color + && self.curr_color != Some(Byte(b).color(self.character_table)) + { + self.writer.write_all(Byte(b).color(self.character_table))?; + self.curr_color = Some(Byte(b).color(self.character_table)); } self.writer .write_all(self.byte_char_panel[b as usize].as_bytes())?; @@ -564,9 +831,9 @@ impl<'a, Writer: Write> Printer<'a, Writer> { if i % (self.group_size as usize) == 0 { self.writer.write_all(b" ")?; } - if self.show_color && self.curr_color != Some(Byte(b).color()) { - self.writer.write_all(Byte(b).color())?; - self.curr_color = Some(Byte(b).color()); + if self.show_color && self.curr_color != Some(Byte(b).color(self.character_table)) { + self.writer.write_all(Byte(b).color(self.character_table))?; + self.curr_color = Some(Byte(b).color(self.character_table)); } self.writer .write_all(self.byte_hex_panel[b as usize].as_bytes())?; diff --git a/src/main.rs b/src/main.rs index cbf452b..9117e45 100644 --- a/src/main.rs +++ b/src/main.rs @@ -216,12 +216,13 @@ fn run() -> Result<()> { Arg::new("character-table") .long("character-table") .value_name("FORMAT") - .value_parser(["codepage-437", "ascii-only"]) + .value_parser(["codepage-437", "ascii-only", "block"]) .default_value("ascii-only") .help( "The character table that should be used. 'ascii-only' \ - will show dots for non-ASCII characters, and 'codepage-437' \ - will use Code page 437 for those characters." + will show dots for non-ASCII characters, 'codepage-437' \ + will use Code page 437 for those characters, and 'block' \ + will show unique colored blocks for each byte." ), ) .arg( @@ -489,6 +490,7 @@ fn run() -> Result<()> { { "ascii-only" => CharacterTable::AsciiOnly, "codepage-437" => CharacterTable::CP437, + "block" => CharacterTable::Block, _ => unreachable!(), };