diff --git a/README.md b/README.md index 1c49fd5..339bf2e 100644 --- a/README.md +++ b/README.md @@ -1,12 +1,37 @@ # enc-check # +## Installation ## + +`cargo install enc-check` + ## Usage ## Inspect character encodings. -`enc-check asdᚢ𐌰` +``` +enc-check --help + +Usage: enc-check [OPTIONS] <-8|-6> + +Arguments: + + The string to inspect + +Options: + -8 + Inspect utf-8 + -6 + Inspect utf-16 + -j, --json + Output as json. Useful as a command line tool + -h, --help + Print help +``` + ``` +enc-check -8 asdᚢ𐌰 + ┌───────┬───────┬───────────┬──────┬─────┬─────┬──────────┐ │ U+dec │ U+hex │ character │ byte │ hex │ dec │ bin │ ├───────┼───────┼───────────┼──────┼─────┼─────┼──────────┤ @@ -23,6 +48,3 @@ Inspect character encodings. └───────┴───────┴───────────┴──────┴─────┴─────┴──────────┘ ``` -## Installation ## - -`cargo install enc-check` diff --git a/src/main.rs b/src/main.rs index 7788397..53fa65b 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,17 +1,9 @@ -use clap::Parser; +use clap::{Parser, Args}; use tabled::{ builder::Builder, settings::{Modify, object::Rows, Alignment, Style} }; -#[derive(Parser)] -struct CliArgs { - name: String, - - #[arg(short = 'j', long = "json", action)] - json: bool, -} - struct StringDetail { characters: Vec, len: usize, @@ -39,11 +31,26 @@ impl StringDetail{ details } + fn parse_utf16(query: &String) -> Self { + let mut details:StringDetail = StringDetail::default(); + for i in query.chars() { + let mut bytes = [0; 2]; + i.encode_utf16(&mut bytes); + details.push_utf16(Some(i), bytes[0]); + if bytes[1] != 0x00000000 { + details.push_utf16(None, bytes[1]); + } + } + + details + } + fn default() -> Self { Self { characters: Vec::new(), len: 0 } } - fn push(&mut self, character:Option, byte:u8){ self.characters + fn push(&mut self, character:Option, byte:u8){ + self.characters .push(CharacterDetail { byte_index: self.len, character, @@ -52,6 +59,12 @@ impl StringDetail{ self.len += 1; } + fn push_utf16(&mut self, character:Option, byte: u16){ + let bytes = byte.to_be_bytes(); + self.push(character, bytes[0]); + self.push(None, bytes[1]); + } + fn print_table(&self) { let mut table_builder = Builder::default(); table_builder.set_header(StringDetail::table_header()); @@ -115,11 +128,42 @@ impl StringDetail{ } +#[derive(Parser)] +#[command(next_line_help = true)] +struct CliArgs { + /// The string to inspect + name: String, + + #[command(flatten)] + inspect: InspectArgs, + + /// Output as json. Useful as a command line tool + #[arg(short = 'j', long = "json", action)] + json: bool, +} + +#[derive(Args)] +#[group(required = true, multiple = false)] +struct InspectArgs { + /// Inspect utf-8 + #[arg(short = '8', action)] + utf8: bool, + + /// Inspect utf-16 + #[arg(short = '6', action)] + utf16: bool, +} + + fn main() { let cli = CliArgs::parse(); - let utf8 = StringDetail::parse_utf8(&cli.name); + let details = match cli.inspect.utf8 { + true => StringDetail::parse_utf8(&cli.name), + false => StringDetail::parse_utf16(&cli.name) + }; + match cli.json { - false => utf8.print_table(), - _ => panic!("Not yet implemented!!"), + false => details.print_table(), + true => panic!("Output as json is not yet implemented") } }