refactor: write in binary now
cargo devel CI / cargo CI (push) Failing after 1m12s Details

This commit is contained in:
Christoph J. Scherr 2024-09-06 11:27:18 +02:00
parent 23c653e9c0
commit 265ab0902b
Signed by: cscherrNT
GPG Key ID: 8E2B45BC51A27EA7
2 changed files with 63 additions and 35 deletions

View File

@ -35,6 +35,8 @@ pub enum Format {
Octal, Octal,
Base64, Base64,
Base32, Base32,
/// Write raw data to stdout, not text
Raw,
} }
/// Describes what the formatter should do /// Describes what the formatter should do
@ -59,7 +61,7 @@ Author: {author-with-newline}
)] )]
#[clap(group( #[clap(group(
ArgGroup::new("format") ArgGroup::new("format")
.args(&["hex", "bin", "oct", "dec", "base64", "base32"]), .args(&["hex", "bin", "oct", "dec", "base64", "base32", "raw"]),
))] ))]
pub struct FormatOptions { pub struct FormatOptions {
#[arg(short, long)] #[arg(short, long)]
@ -86,6 +88,9 @@ pub struct FormatOptions {
#[arg(short = 's', long)] #[arg(short = 's', long)]
/// format to base64 /// format to base64
base64: bool, base64: bool,
#[arg(short = 'a', long)]
/// format raw, no text
raw: bool,
#[arg(short = 'r', long, default_value_t = 0, value_parser=numf_parser::<NumberType>)] #[arg(short = 'r', long, default_value_t = 0, value_parser=numf_parser::<NumberType>)]
/// output random numbers /// output random numbers
/// ///
@ -148,9 +153,11 @@ impl FormatOptions {
self.dec = false; self.dec = false;
self.hex = false; self.hex = false;
self.base64 = false; self.base64 = false;
self.raw = false;
self.base32 = false; self.base32 = false;
match format { match format {
Format::Bin => self.bin = true, Format::Bin => self.bin = true,
Format::Raw => self.raw = true,
Format::Hex => self.hex = true, Format::Hex => self.hex = true,
Format::Octal => self.oct = true, Format::Octal => self.oct = true,
Format::Base64 => self.base64 = true, Format::Base64 => self.base64 = true,
@ -223,6 +230,7 @@ impl Default for FormatOptions {
oct: false, oct: false,
hex: true, hex: true,
bin: false, bin: false,
raw: false,
base32: false, base32: false,
base64: false, base64: false,
dec: false, dec: false,
@ -234,52 +242,69 @@ impl Default for FormatOptions {
} }
impl Format { impl Format {
pub fn prefix_str(&self) -> String {
String::from_utf8_lossy(&self.prefix()).to_string()
}
/// Get the perfix for that [Format] /// Get the perfix for that [Format]
pub fn prefix(&self) -> String { pub fn prefix(&self) -> Vec<u8> {
match self { match self {
// apperently used nowhere, sometimes 0 is used as a prefix but I // apperently used nowhere, sometimes 0 is used as a prefix but I
// think this makes it more clear that this is decimal // think this makes it more clear that this is decimal
Format::Dec => "0d", Format::Dec => b"0d".to_vec(),
Format::Raw => [].to_vec(), // TODO: find a better way to deal with this
// very common // very common
Format::Hex => "0x", Format::Hex => b"0x".to_vec(),
// very common // very common
Format::Bin => "0b", Format::Bin => b"0b".to_vec(),
// somewhat common // somewhat common
Format::Octal => "0o", Format::Octal => b"0o".to_vec(),
// perl and a few other programs seem to use this too // perl and a few other programs seem to use this too
Format::Base64 => "0s", Format::Base64 => b"0s".to_vec(),
// no idea, I made this up // no idea, I made this up
Format::Base32 => "032s", Format::Base32 => b"032s".to_vec(),
} }
.to_string()
} }
/// format a number with a [Format] and [FormatOptions] /// format a number with a [Format] and [FormatOptions]
pub fn format(&self, num: NumberType, options: &FormatOptions) -> String { pub fn format(&self, num: NumberType, options: &FormatOptions) -> Vec<u8> {
let mut buf = String::new(); let mut buf: Vec<u8> = Vec::new();
if options.prefix() { if options.prefix() {
buf += &self.prefix(); buf.append(&mut self.prefix());
} }
match self { match self {
Format::Hex => { Format::Hex => {
if options.padding() { if options.padding() {
let tmp = &format!("{num:X}"); let tmp = &format!("{num:X}");
buf += &("0".repeat((2 - tmp.len() % 2) % 2) + tmp); let tmp1 = &("0".repeat((2 - tmp.len() % 2) % 2) + tmp);
buf.append(&mut tmp1.as_bytes().to_owned());
} else { } else {
buf += &format!("{num:X}"); buf.append(&mut format!("{num:X}").as_bytes().to_owned());
} }
} }
Format::Bin => { Format::Bin => {
if options.padding() { if options.padding() {
let tmp = &format!("{num:b}"); let tmp = &format!("{num:b}");
buf += &("0".repeat((8 - tmp.len() % 8) % 8) + tmp); let tmp1 = &("0".repeat((8 - tmp.len() % 8) % 8) + tmp);
buf.append(&mut tmp1.as_bytes().to_owned());
} else { } else {
buf += &format!("{num:b}"); buf.append(&mut format!("{num:b}").as_bytes().to_owned());
} }
} }
Format::Octal => buf += &format!("{num:o}"), Format::Octal => buf.append(&mut format!("{num:o}").as_bytes().to_owned()),
Format::Dec => buf += &format!("{num}"), Format::Dec => buf.append(&mut format!("{num}").as_bytes().to_owned()),
Format::Base64 => buf += &fast32::base64::RFC4648.encode(&split::unsigned_to_vec(num)), Format::Base64 => buf.append(
Format::Base32 => buf += &fast32::base32::RFC4648.encode(&split::unsigned_to_vec(num)), &mut fast32::base64::RFC4648
.encode(&split::unsigned_to_vec(num))
.as_bytes()
.to_owned(),
),
Format::Base32 => buf.append(
&mut fast32::base32::RFC4648
.encode(&split::unsigned_to_vec(num))
.as_bytes()
.to_owned(),
),
Format::Raw => buf.append(&mut split::unsigned_to_vec(num)),
} }
buf buf
} }
@ -324,8 +349,8 @@ where
<T as std::convert::TryFrom<u128>>::Error: std::marker::Sync, <T as std::convert::TryFrom<u128>>::Error: std::marker::Sync,
<T as std::convert::TryFrom<u128>>::Error: 'static, <T as std::convert::TryFrom<u128>>::Error: 'static,
{ {
if s.starts_with(&Format::Dec.prefix()) || s.parse::<T>().is_ok() { if s.starts_with(&Format::Dec.prefix_str()) || s.parse::<T>().is_ok() {
let s = match s.strip_prefix(&Format::Dec.prefix()) { let s = match s.strip_prefix(&Format::Dec.prefix_str()) {
Some(sr) => sr, Some(sr) => sr,
None => s, None => s,
}; };
@ -336,8 +361,8 @@ where
Err(anyhow!(e)) Err(anyhow!(e))
} }
} }
} else if s.starts_with(&Format::Hex.prefix()) { } else if s.starts_with(&Format::Hex.prefix_str()) {
let s = match s.strip_prefix(&Format::Hex.prefix()) { let s = match s.strip_prefix(&Format::Hex.prefix_str()) {
Some(sr) => sr, Some(sr) => sr,
None => s, None => s,
}; };
@ -348,8 +373,8 @@ where
Err(anyhow!(e)) Err(anyhow!(e))
} }
} }
} else if s.starts_with(&Format::Octal.prefix()) { } else if s.starts_with(&Format::Octal.prefix_str()) {
let s = match s.strip_prefix(&Format::Octal.prefix()) { let s = match s.strip_prefix(&Format::Octal.prefix_str()) {
Some(sr) => sr, Some(sr) => sr,
None => s, None => s,
}; };
@ -360,8 +385,8 @@ where
Err(anyhow!(e)) Err(anyhow!(e))
} }
} }
} else if s.starts_with(&Format::Bin.prefix()) { } else if s.starts_with(&Format::Bin.prefix_str()) {
let s = match s.strip_prefix(&Format::Bin.prefix()) { let s = match s.strip_prefix(&Format::Bin.prefix_str()) {
Some(sr) => sr, Some(sr) => sr,
None => s, None => s,
}; };
@ -372,8 +397,8 @@ where
Err(anyhow!(e)) Err(anyhow!(e))
} }
} }
} else if s.starts_with(&Format::Base64.prefix()) { } else if s.starts_with(&Format::Base64.prefix_str()) {
let s = match s.strip_prefix(&Format::Base64.prefix()) { let s = match s.strip_prefix(&Format::Base64.prefix_str()) {
Some(sr) => sr, Some(sr) => sr,
None => s, None => s,
}; };
@ -384,8 +409,8 @@ where
Err(anyhow!(e)) Err(anyhow!(e))
} }
} }
} else if s.starts_with(&Format::Base32.prefix()) { } else if s.starts_with(&Format::Base32.prefix_str()) {
let s = match s.strip_prefix(&Format::Base32.prefix()) { let s = match s.strip_prefix(&Format::Base32.prefix_str()) {
Some(sr) => sr, Some(sr) => sr,
None => s, None => s,
}; };

View File

@ -1,4 +1,4 @@
use std::io::{IsTerminal, Read}; use std::io::{stdout, IsTerminal, Read, Write};
use std::process::exit; use std::process::exit;
use clap::{CommandFactory, Parser}; use clap::{CommandFactory, Parser};
@ -61,13 +61,16 @@ fn main() -> anyhow::Result<()> {
exit(1); exit(1);
} }
let mut out: Vec<String> = Vec::new(); let mut out: Vec<Vec<u8>> = Vec::new();
for num in options.numbers() { for num in options.numbers() {
out.push(options.format().format(*num, &options)); out.push(options.format().format(*num, &options));
} }
for o in out { for o in out {
println!("{o}") let mut stdout = std::io::stdout();
stdout.write_all(&o)?;
stdout.write_all(b"\n")?;
stdout.flush()?;
} }
Ok(()) Ok(())
} }