diff --git a/Cargo.toml b/Cargo.toml index 9f77ac8..2e4b40a 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -14,6 +14,7 @@ keywords = ["cli"] [dependencies] anyhow = "1.0.83" +base64 = "0.22.1" clap = { version = "4.5.4", features = ["derive"] } clap-num = "1.1.1" diff --git a/src/format.rs b/src/format.rs index baaea0b..909af1e 100644 --- a/src/format.rs +++ b/src/format.rs @@ -1,3 +1,5 @@ +use base64::prelude::*; + pub type Num = u128; #[derive(Copy, Clone, Debug)] @@ -6,15 +8,23 @@ pub enum Format { Hex, Bin, Octal, + Base64, } impl Format { pub fn prefix(&self) -> String { match self { + // apperently used nowhere, sometimes 0 is used as a prefix but I + // think this makes it more clear that this is decimal Format::Dec => "0d", + // very common Format::Hex => "0x", + // very common Format::Bin => "0b", + // somewhat common Format::Octal => "0o", + // perl and a few other programs seem to use this too + Format::Base64 => "0s", } .to_string() } @@ -36,7 +46,20 @@ impl Format { Format::Dec => { buf += &format!("{num}"); } + Format::Base64 => buf += &BASE64_STANDARD.encode(u128_to_u8_slice(num)), } buf } } + +fn u128_to_u8_slice(mut num: u128) -> Vec { + if num == 0 { + return vec![0]; + } + let mut buf: Vec = Vec::new(); + while num > 0 { + buf.push(num as u8); + num >>= 8; + } + buf +} diff --git a/src/main.rs b/src/main.rs index 7f5595e..babac9e 100644 --- a/src/main.rs +++ b/src/main.rs @@ -13,7 +13,7 @@ use format::*; #[clap(author, version, about, long_about = None)] #[clap(group( ArgGroup::new("format") - .args(&["hex", "bin", "oct", "dec"]), + .args(&["hex", "bin", "oct", "dec", "base64"]), ))] struct Cli { #[arg(short, long)] @@ -31,6 +31,9 @@ struct Cli { #[arg(short, long)] /// format to octal oct: bool, + #[arg(short = 's', long)] + /// format to base64 + base64: bool, #[clap(value_parser=maybe_hex::, required=true)] /// at least one number that should be formatted /// @@ -46,6 +49,8 @@ impl Cli { Format::Bin } else if self.dec { Format::Dec + } else if self.base64 { + Format::Base64 } else if self.hex { Format::Hex } else {