diff --git a/src/format.rs b/src/format.rs index fe425df..f4b1dc8 100644 --- a/src/format.rs +++ b/src/format.rs @@ -2,6 +2,7 @@ use libpt::bintols::split; pub type Num = u128; +/// formats supported by numf #[derive(Copy, Clone, Debug)] pub enum Format { Dec, @@ -12,6 +13,32 @@ pub enum Format { Base32, } +/// Options to use when formatting a number +/// +/// Used by [Format::format]. +#[derive(Debug, Clone, Copy, PartialEq, Eq, Default)] +pub struct FormatOptions { + /// add a prefix to the formatted number, such as `0x` for hex + prefix: bool, + /// fill the formatted number with zeros (or the equivalent) to make a whole byte + padding: bool, +} + +impl FormatOptions { + /// set prefix + pub fn prefix(mut self, value: bool) -> Self { + self.prefix = value; + self + } + /// set padding + /// + /// Does not apply to all formats + pub fn padding(mut self, value: bool) -> Self { + self.padding = value; + self + } +} + impl Format { pub fn prefix(&self) -> String { match self { @@ -31,17 +58,27 @@ impl Format { } .to_string() } - pub fn format(&self, num: Num, prefix: bool) -> String { + pub fn format(&self, num: Num, options: FormatOptions) -> String { let mut buf = String::new(); - if prefix { + if options.prefix { buf += &self.prefix(); } match self { Format::Hex => { - buf += &format!("{num:X}"); + if options.padding { + let tmp = &format!("{num:X}"); + buf += &("0".repeat((2 - tmp.len() % 2) % 2) + tmp); + } else { + buf += &format!("{num:X}"); + } } Format::Bin => { - buf += &format!("{num:b}"); + if options.padding { + let tmp = &format!("{num:b}"); + buf += &("0".repeat((8 - tmp.len() % 8) % 8) + tmp); + } else { + buf += &format!("{num:b}"); + } } Format::Octal => { buf += &format!("{num:o}"); diff --git a/src/main.rs b/src/main.rs index 927ddfb..8559138 100644 --- a/src/main.rs +++ b/src/main.rs @@ -32,6 +32,12 @@ struct Cli { #[arg(short, long)] /// add a prefix (like "0x" for hex) prefix: bool, + #[arg(short = 'P', long)] + /// add a padding to make the number at least one byte long + /// + /// For example, `0b1100` will be `0b00001100` with this. + /// This does not apply to all formats, only hexadecimal and binary. + padding: bool, #[arg(short = 'x', long, default_value_t = true)] /// format to hexadecimal hex: bool, @@ -79,11 +85,14 @@ impl Cli { fn main() { let cli = Cli::parse(); + let options: FormatOptions = FormatOptions::default() + .padding(cli.padding) + .prefix(cli.prefix); let mut out: Vec = Vec::new(); for num in &cli.numbers { - out.push(cli.format().format(*num, cli.prefix)); + out.push(cli.format().format(*num, options)); } for o in out { println!("{o}")