generated from PlexSheep/rs-base
Compare commits
17 commits
826c3c7893
...
f3d7d807d5
Author | SHA1 | Date | |
---|---|---|---|
|
f3d7d807d5 | ||
c33b4ad1ed | |||
d315e24034 | |||
|
887a29d86a | ||
e210b688f8 | |||
727b84e56b | |||
|
d7372b93a3 | ||
e92af8acfa | |||
23c653e9c0 | |||
03a2243a3e | |||
71f1f2ba08 | |||
c5790f9d79 | |||
|
93a27564c6 | ||
3926be8aac | |||
8fbc612f5a | |||
|
950c26a35c | ||
0923bf5247 |
4 changed files with 243 additions and 106 deletions
|
@ -1,6 +1,6 @@
|
|||
[package]
|
||||
name = "numf"
|
||||
version = "0.3.3"
|
||||
version = "0.4.0"
|
||||
edition = "2021"
|
||||
publish = true
|
||||
authors = ["Christoph J. Scherr <software@cscherr.de>"]
|
||||
|
@ -17,6 +17,6 @@ categories = ["command-line-utilities", "encoding"]
|
|||
anyhow = "1.0.83"
|
||||
clap = { version = "4.5.4", features = ["derive"] }
|
||||
fast32 = "1.0.2"
|
||||
libpt = { version = "0.5.1", features = ["bintols"], default-features = false }
|
||||
libpt = { version = "0.6.0", features = ["bintols", "log", "cli"] }
|
||||
num = "0.4.3"
|
||||
|
||||
rand = "0.8.5"
|
||||
|
|
177
src/format.rs
177
src/format.rs
|
@ -13,28 +13,45 @@
|
|||
//! options.set_prefix(true);
|
||||
//! options.set_padding(true);
|
||||
//!
|
||||
//! assert_eq!(Format::Hex.format(0x1337, &options), "0x1337");
|
||||
//! assert_eq!(Format::Base32.format(0x41414242, &options), "032sIFAUEQQ=");
|
||||
//! assert_eq!(Format::Base64.format(0x41414242, &options), "0sQUFCQg==");
|
||||
//! assert_eq!(Format::Hex.format_str(0x1337, &options), "0x1337");
|
||||
//! assert_eq!(Format::Base32.format_str(0x41414242, &options), "032sIFAUEQQ=");
|
||||
//! assert_eq!(Format::Base64.format_str(0x41414242, &options), "0sQUFCQg==");
|
||||
//! // sometimes you might need the raw bytes instead of a String
|
||||
//! assert_eq!(Format::Raw.format(0x1337, &options), vec![0x13, 0x37]);
|
||||
//! assert_eq!(Format::Hex.format(0x1337, &options), vec![48, 120, 49, 51, 51, 55]);
|
||||
//! ```
|
||||
|
||||
#![allow(dead_code)] // this is exported to lib.rs
|
||||
#![allow(dead_code)]
|
||||
use std::fmt::Display;
|
||||
|
||||
// this is exported to lib.rs
|
||||
use anyhow::anyhow;
|
||||
use clap::{ArgGroup, Parser};
|
||||
use libpt::bintols::{join, split};
|
||||
use libpt::cli::args::VerbosityLevel;
|
||||
use libpt::log::{debug, trace};
|
||||
|
||||
/// The number type [numf](crate) uses
|
||||
pub type NumberType = u128;
|
||||
|
||||
/// formats supported by numf
|
||||
#[derive(Copy, Clone, Debug, Hash, PartialEq, Eq)]
|
||||
#[derive(Copy, Clone, Debug, Hash, PartialEq, Eq, Default)]
|
||||
pub enum Format {
|
||||
Dec,
|
||||
#[default]
|
||||
Hex,
|
||||
Bin,
|
||||
Octal,
|
||||
Base64,
|
||||
Base32,
|
||||
/// Write raw data to stdout, not text
|
||||
Raw,
|
||||
}
|
||||
|
||||
impl Display for Format {
|
||||
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||
write!(f, "{self:?}")
|
||||
}
|
||||
}
|
||||
|
||||
/// Describes what the formatter should do
|
||||
|
@ -59,7 +76,7 @@ Author: {author-with-newline}
|
|||
)]
|
||||
#[clap(group(
|
||||
ArgGroup::new("format")
|
||||
.args(&["hex", "bin", "oct", "dec", "base64", "base32"]),
|
||||
.args(&["hex", "bin", "oct", "dec", "base64", "base32", "raw"]),
|
||||
))]
|
||||
pub struct FormatOptions {
|
||||
#[arg(short, long)]
|
||||
|
@ -71,7 +88,7 @@ pub struct FormatOptions {
|
|||
/// 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)]
|
||||
#[arg(short = 'x', long)]
|
||||
/// format to hexadecimal
|
||||
hex: bool,
|
||||
#[arg(short, long)]
|
||||
|
@ -86,6 +103,19 @@ pub struct FormatOptions {
|
|||
#[arg(short = 's', long)]
|
||||
/// format to base64
|
||||
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>)]
|
||||
/// output random numbers
|
||||
///
|
||||
/// Add a user defined amount of cryptographically pseudorandom numbers to the number list.
|
||||
rand: NumberType,
|
||||
#[arg(long, default_value_t = NumberType::MAX, value_parser=numf_parser::<NumberType>)]
|
||||
/// max for the random numbers
|
||||
///
|
||||
/// Generated numbers will not be lower than this. Only has an effect with --rand set.
|
||||
rand_max: NumberType,
|
||||
#[arg(short = 'z', long)]
|
||||
/// format to base32
|
||||
base32: bool,
|
||||
|
@ -109,11 +139,15 @@ pub struct FormatOptions {
|
|||
///
|
||||
/// The numbers may be left empty at first, if numbers are provided from the stdin.
|
||||
numbers: Vec<NumberType>,
|
||||
|
||||
#[command(flatten)]
|
||||
pub(crate) verbosity: VerbosityLevel,
|
||||
}
|
||||
|
||||
impl FormatOptions {
|
||||
/// get the format that the user has configured
|
||||
pub fn format(&self) -> Format {
|
||||
trace!("self.hex: {}", self.hex);
|
||||
if self.oct {
|
||||
Format::Octal
|
||||
} else if self.bin {
|
||||
|
@ -126,8 +160,12 @@ impl FormatOptions {
|
|||
Format::Base32
|
||||
} else if self.hex {
|
||||
Format::Hex
|
||||
} else if self.raw {
|
||||
Format::Raw
|
||||
} else {
|
||||
unreachable!()
|
||||
// none was explicitly selected
|
||||
debug!("no mode was explicitly selected, going with the default");
|
||||
Format::default()
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -138,9 +176,11 @@ impl FormatOptions {
|
|||
self.dec = false;
|
||||
self.hex = false;
|
||||
self.base64 = false;
|
||||
self.raw = false;
|
||||
self.base32 = false;
|
||||
match format {
|
||||
Format::Bin => self.bin = true,
|
||||
Format::Raw => self.raw = true,
|
||||
Format::Hex => self.hex = true,
|
||||
Format::Octal => self.oct = true,
|
||||
Format::Base64 => self.base64 = true,
|
||||
|
@ -183,6 +223,26 @@ impl FormatOptions {
|
|||
pub fn push_number(&mut self, value: NumberType) {
|
||||
self.numbers.push(value)
|
||||
}
|
||||
|
||||
/// get rand
|
||||
pub fn rand(&self) -> NumberType {
|
||||
self.rand
|
||||
}
|
||||
|
||||
/// set amount of extra random numbers manually
|
||||
pub fn set_rand(&mut self, rand: NumberType) {
|
||||
self.rand = rand;
|
||||
}
|
||||
|
||||
/// get highes allowed random value
|
||||
pub fn rand_max(&self) -> NumberType {
|
||||
self.rand_max
|
||||
}
|
||||
|
||||
/// set highes allowed random value
|
||||
pub fn set_rand_max(&mut self, rand_max: NumberType) {
|
||||
self.rand_max = rand_max;
|
||||
}
|
||||
}
|
||||
|
||||
impl Default for FormatOptions {
|
||||
|
@ -191,63 +251,94 @@ impl Default for FormatOptions {
|
|||
padding: false,
|
||||
prefix: false,
|
||||
oct: false,
|
||||
hex: true,
|
||||
hex: false,
|
||||
bin: false,
|
||||
raw: false,
|
||||
base32: false,
|
||||
base64: false,
|
||||
dec: false,
|
||||
numbers: vec![],
|
||||
rand: 0,
|
||||
rand_max: NumberType::MAX,
|
||||
verbosity: VerbosityLevel::default(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl Format {
|
||||
pub fn prefix_str(&self) -> String {
|
||||
String::from_utf8_lossy(&self.prefix()).to_string()
|
||||
}
|
||||
|
||||
/// Get the perfix for that [Format]
|
||||
pub fn prefix(&self) -> String {
|
||||
pub fn prefix(&self) -> Vec<u8> {
|
||||
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",
|
||||
Format::Dec => b"0d".to_vec(),
|
||||
Format::Raw => [].to_vec(), // TODO: find a better way to deal with this
|
||||
// very common
|
||||
Format::Hex => "0x",
|
||||
Format::Hex => b"0x".to_vec(),
|
||||
// very common
|
||||
Format::Bin => "0b",
|
||||
Format::Bin => b"0b".to_vec(),
|
||||
// somewhat common
|
||||
Format::Octal => "0o",
|
||||
Format::Octal => b"0o".to_vec(),
|
||||
// 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
|
||||
Format::Base32 => "032s",
|
||||
Format::Base32 => b"032s".to_vec(),
|
||||
}
|
||||
.to_string()
|
||||
}
|
||||
/// format a number with a [Format] and [FormatOptions] to [String]
|
||||
pub fn format_str(&self, num: NumberType, options: &FormatOptions) -> String {
|
||||
String::from_utf8_lossy(&self.format(num, options)).to_string()
|
||||
}
|
||||
|
||||
/// format a number with a [Format] and [FormatOptions]
|
||||
pub fn format(&self, num: NumberType, options: &FormatOptions) -> String {
|
||||
let mut buf = String::new();
|
||||
pub fn format(&self, num: NumberType, options: &FormatOptions) -> Vec<u8> {
|
||||
debug!("formatting mode: {self}");
|
||||
let mut buf: Vec<u8> = Vec::new();
|
||||
if options.prefix() {
|
||||
buf += &self.prefix();
|
||||
buf.append(&mut self.prefix());
|
||||
}
|
||||
match self {
|
||||
Format::Hex => {
|
||||
if options.padding() {
|
||||
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 {
|
||||
buf += &format!("{num:X}");
|
||||
buf.append(&mut format!("{num:X}").as_bytes().to_owned());
|
||||
}
|
||||
}
|
||||
Format::Bin => {
|
||||
if options.padding() {
|
||||
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 {
|
||||
buf += &format!("{num:b}");
|
||||
buf.append(&mut format!("{num:b}").as_bytes().to_owned());
|
||||
}
|
||||
}
|
||||
Format::Octal => buf += &format!("{num:o}"),
|
||||
Format::Dec => buf += &format!("{num}"),
|
||||
Format::Base64 => buf += &fast32::base64::RFC4648.encode(&split::unsigned_to_vec(num)),
|
||||
Format::Base32 => buf += &fast32::base32::RFC4648.encode(&split::unsigned_to_vec(num)),
|
||||
Format::Octal => buf.append(&mut format!("{num:o}").as_bytes().to_owned()),
|
||||
Format::Dec => buf.append(&mut format!("{num}").as_bytes().to_owned()),
|
||||
Format::Base64 => buf.append(
|
||||
&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)),
|
||||
Format::Raw => {
|
||||
debug!("do the raw thing");
|
||||
buf.append(&mut split::unsigned_to_vec(num))
|
||||
}
|
||||
}
|
||||
buf
|
||||
}
|
||||
|
@ -292,8 +383,8 @@ where
|
|||
<T as std::convert::TryFrom<u128>>::Error: std::marker::Sync,
|
||||
<T as std::convert::TryFrom<u128>>::Error: 'static,
|
||||
{
|
||||
if s.starts_with(&Format::Dec.prefix()) || s.parse::<T>().is_ok() {
|
||||
let s = match s.strip_prefix(&Format::Dec.prefix()) {
|
||||
if s.starts_with(&Format::Dec.prefix_str()) || s.parse::<T>().is_ok() {
|
||||
let s = match s.strip_prefix(&Format::Dec.prefix_str()) {
|
||||
Some(sr) => sr,
|
||||
None => s,
|
||||
};
|
||||
|
@ -304,8 +395,8 @@ where
|
|||
Err(anyhow!(e))
|
||||
}
|
||||
}
|
||||
} else if s.starts_with(&Format::Hex.prefix()) {
|
||||
let s = match s.strip_prefix(&Format::Hex.prefix()) {
|
||||
} else if s.starts_with(&Format::Hex.prefix_str()) {
|
||||
let s = match s.strip_prefix(&Format::Hex.prefix_str()) {
|
||||
Some(sr) => sr,
|
||||
None => s,
|
||||
};
|
||||
|
@ -316,8 +407,8 @@ where
|
|||
Err(anyhow!(e))
|
||||
}
|
||||
}
|
||||
} else if s.starts_with(&Format::Octal.prefix()) {
|
||||
let s = match s.strip_prefix(&Format::Octal.prefix()) {
|
||||
} else if s.starts_with(&Format::Octal.prefix_str()) {
|
||||
let s = match s.strip_prefix(&Format::Octal.prefix_str()) {
|
||||
Some(sr) => sr,
|
||||
None => s,
|
||||
};
|
||||
|
@ -328,8 +419,8 @@ where
|
|||
Err(anyhow!(e))
|
||||
}
|
||||
}
|
||||
} else if s.starts_with(&Format::Bin.prefix()) {
|
||||
let s = match s.strip_prefix(&Format::Bin.prefix()) {
|
||||
} else if s.starts_with(&Format::Bin.prefix_str()) {
|
||||
let s = match s.strip_prefix(&Format::Bin.prefix_str()) {
|
||||
Some(sr) => sr,
|
||||
None => s,
|
||||
};
|
||||
|
@ -340,8 +431,8 @@ where
|
|||
Err(anyhow!(e))
|
||||
}
|
||||
}
|
||||
} else if s.starts_with(&Format::Base64.prefix()) {
|
||||
let s = match s.strip_prefix(&Format::Base64.prefix()) {
|
||||
} else if s.starts_with(&Format::Base64.prefix_str()) {
|
||||
let s = match s.strip_prefix(&Format::Base64.prefix_str()) {
|
||||
Some(sr) => sr,
|
||||
None => s,
|
||||
};
|
||||
|
@ -352,8 +443,8 @@ where
|
|||
Err(anyhow!(e))
|
||||
}
|
||||
}
|
||||
} else if s.starts_with(&Format::Base32.prefix()) {
|
||||
let s = match s.strip_prefix(&Format::Base32.prefix()) {
|
||||
} else if s.starts_with(&Format::Base32.prefix_str()) {
|
||||
let s = match s.strip_prefix(&Format::Base32.prefix_str()) {
|
||||
Some(sr) => sr,
|
||||
None => s,
|
||||
};
|
||||
|
@ -364,6 +455,12 @@ where
|
|||
Err(anyhow!(e))
|
||||
}
|
||||
}
|
||||
} else if s.starts_with(&Format::Raw.prefix_str()) {
|
||||
let s = match s.strip_prefix(&Format::Raw.prefix_str()) {
|
||||
Some(sr) => sr,
|
||||
None => s,
|
||||
};
|
||||
todo!("reading raw not implemented")
|
||||
} else {
|
||||
let e = "could not determine the format of the value".to_string();
|
||||
Err(anyhow!(e))
|
||||
|
|
48
src/main.rs
48
src/main.rs
|
@ -1,28 +1,35 @@
|
|||
//! # numf
|
||||
//!
|
||||
//! This binary should just take any amount of numbers and print them out formatted to some other
|
||||
//! system.
|
||||
|
||||
use std::io::{IsTerminal, Read};
|
||||
use std::io::{IsTerminal, Read, Write};
|
||||
use std::process::exit;
|
||||
|
||||
use clap::{CommandFactory, Parser};
|
||||
|
||||
mod format;
|
||||
use crate::format::{numf_parser, Format};
|
||||
use format::*;
|
||||
use numf::format::numf_parser;
|
||||
use libpt::log::debug;
|
||||
|
||||
fn main() {
|
||||
fn main() -> anyhow::Result<()> {
|
||||
// try to read from stdin first, appending the numbers we read to the FormatOptions
|
||||
let mut options = FormatOptions::parse();
|
||||
let _logger = libpt::log::Logger::builder()
|
||||
.set_level(options.verbosity.level())
|
||||
.display_time(false)
|
||||
.build()
|
||||
.map_err(|e| {
|
||||
eprintln!("could not initialize logger: {e}");
|
||||
});
|
||||
debug!("logger active");
|
||||
|
||||
let mut stdin_nums = Vec::new();
|
||||
let stdin = std::io::stdin();
|
||||
// only accept numbers from stdin if the stdin is not an interactive terminal
|
||||
if !stdin.is_terminal() {
|
||||
match stdin.lock().read_to_end(&mut stdin_nums) {
|
||||
Ok(_) => {
|
||||
let whole: String = match String::from_utf8(stdin_nums) {
|
||||
Ok(r) => r,
|
||||
Err(e) => {
|
||||
eprintln!("{}", FormatOptions::command().render_usage());
|
||||
eprintln!("stdin for this program only accepts text: {e:#?}");
|
||||
exit(1);
|
||||
}
|
||||
|
@ -32,6 +39,7 @@ fn main() {
|
|||
let number = match numf_parser(s) {
|
||||
Ok(n) => n,
|
||||
Err(e) => {
|
||||
eprintln!("{}", FormatOptions::command().render_usage());
|
||||
eprintln!("could not parse number from stdin: {e:#?}");
|
||||
exit(2);
|
||||
}
|
||||
|
@ -40,23 +48,41 @@ fn main() {
|
|||
}
|
||||
}
|
||||
Err(e) => {
|
||||
eprintln!("{}", FormatOptions::command().render_usage());
|
||||
eprintln!("could not read from stdin: {e:#?}");
|
||||
exit(2);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
// add random numbers to the number list, according to how many are requested
|
||||
if options.rand() > 0 {
|
||||
use rand::prelude::*;
|
||||
let mut rand = rand::rngs::OsRng;
|
||||
for _i in 0..options.rand() {
|
||||
options.push_number(rand.gen_range(0..options.rand_max()));
|
||||
}
|
||||
}
|
||||
|
||||
// exit with error if no numbers are to be formatted
|
||||
if options.numbers().is_empty() {
|
||||
format!("{}", FormatOptions::command().render_usage());
|
||||
eprintln!("{}", FormatOptions::command().render_usage());
|
||||
eprintln!("no numbers have been provided");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
let mut out: Vec<String> = Vec::new();
|
||||
let mut out: Vec<Vec<u8>> = Vec::new();
|
||||
|
||||
for num in options.numbers() {
|
||||
out.push(options.format().format(*num, &options));
|
||||
}
|
||||
for o in out {
|
||||
println!("{o}")
|
||||
let mut stdout = std::io::stdout();
|
||||
stdout.write_all(&o)?;
|
||||
if options.format() != Format::Raw {
|
||||
stdout.write_all(b"\n")?;
|
||||
}
|
||||
stdout.flush()?;
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
|
|
118
tests/format.rs
118
tests/format.rs
|
@ -3,42 +3,42 @@ use numf::format::*;
|
|||
#[test]
|
||||
fn format() {
|
||||
let options = FormatOptions::default();
|
||||
assert_eq!(Format::Dec.format(1337, &options), "1337");
|
||||
assert_eq!(Format::Dec.format_str(1337, &options), "1337");
|
||||
assert_eq!(
|
||||
Format::Dec.format(u128::MAX, &options),
|
||||
Format::Dec.format_str(u128::MAX, &options),
|
||||
format!("{}", u128::MAX)
|
||||
);
|
||||
|
||||
assert_eq!(Format::Hex.format(0x1337, &options), "1337");
|
||||
assert_eq!(Format::Hex.format_str(0x1337, &options), "1337");
|
||||
assert_eq!(
|
||||
Format::Hex.format(u128::MAX, &options),
|
||||
Format::Hex.format_str(u128::MAX, &options),
|
||||
format!("{:X}", u128::MAX)
|
||||
);
|
||||
|
||||
assert_eq!(
|
||||
Format::Bin.format(0b1010001001010010010100111, &options),
|
||||
Format::Bin.format_str(0b1010001001010010010100111, &options),
|
||||
"1010001001010010010100111"
|
||||
);
|
||||
assert_eq!(
|
||||
Format::Bin.format(u128::MAX, &options),
|
||||
Format::Bin.format_str(u128::MAX, &options),
|
||||
format!("{:b}", u128::MAX)
|
||||
);
|
||||
|
||||
assert_eq!(Format::Octal.format(0o13377331, &options), "13377331");
|
||||
assert_eq!(Format::Octal.format_str(0o13377331, &options), "13377331");
|
||||
assert_eq!(
|
||||
Format::Octal.format(u128::MAX, &options),
|
||||
Format::Octal.format_str(u128::MAX, &options),
|
||||
format!("{:o}", u128::MAX)
|
||||
);
|
||||
|
||||
assert_eq!(Format::Base32.format(0x41414242, &options), "IFAUEQQ=");
|
||||
assert_eq!(Format::Base32.format_str(0x41414242, &options), "IFAUEQQ=");
|
||||
assert_eq!(
|
||||
Format::Base32.format(0x4141414141414141, &options),
|
||||
Format::Base32.format_str(0x4141414141414141, &options),
|
||||
"IFAUCQKBIFAUC==="
|
||||
);
|
||||
|
||||
assert_eq!(Format::Base64.format(0x41414242, &options), "QUFCQg==");
|
||||
assert_eq!(Format::Base64.format_str(0x41414242, &options), "QUFCQg==");
|
||||
assert_eq!(
|
||||
Format::Base64.format(0x4141414141414141, &options),
|
||||
Format::Base64.format_str(0x4141414141414141, &options),
|
||||
"QUFBQUFBQUE="
|
||||
);
|
||||
}
|
||||
|
@ -48,47 +48,47 @@ fn format_padding() {
|
|||
let mut options = FormatOptions::default();
|
||||
options.set_padding(true);
|
||||
|
||||
assert_eq!(Format::Dec.format(1337, &options), "1337");
|
||||
assert_eq!(Format::Dec.format_str(1337, &options), "1337");
|
||||
assert_eq!(
|
||||
Format::Dec.format(u128::MAX, &options),
|
||||
Format::Dec.format_str(u128::MAX, &options),
|
||||
format!("{}", u128::MAX)
|
||||
);
|
||||
|
||||
assert_eq!(Format::Hex.format(0xFFF, &options), "0FFF");
|
||||
assert_eq!(Format::Hex.format(0xFFFF, &options), "FFFF");
|
||||
assert_eq!(Format::Hex.format_str(0xFFF, &options), "0FFF");
|
||||
assert_eq!(Format::Hex.format_str(0xFFFF, &options), "FFFF");
|
||||
assert_eq!(
|
||||
Format::Hex.format(u128::MAX, &options),
|
||||
Format::Hex.format_str(u128::MAX, &options),
|
||||
format!("{:X}", u128::MAX)
|
||||
);
|
||||
|
||||
assert_eq!(
|
||||
Format::Bin.format(0b11110000_00001111, &options),
|
||||
Format::Bin.format_str(0b11110000_00001111, &options),
|
||||
"1111000000001111"
|
||||
);
|
||||
assert_eq!(
|
||||
Format::Bin.format(0b110000_00001111, &options),
|
||||
Format::Bin.format_str(0b110000_00001111, &options),
|
||||
"0011000000001111"
|
||||
);
|
||||
assert_eq!(
|
||||
Format::Bin.format(u128::MAX, &options),
|
||||
Format::Bin.format_str(u128::MAX, &options),
|
||||
format!("{:b}", u128::MAX)
|
||||
);
|
||||
|
||||
assert_eq!(Format::Octal.format(0o13377331, &options), "13377331");
|
||||
assert_eq!(Format::Octal.format_str(0o13377331, &options), "13377331");
|
||||
assert_eq!(
|
||||
Format::Octal.format(u128::MAX, &options),
|
||||
Format::Octal.format_str(u128::MAX, &options),
|
||||
format!("{:o}", u128::MAX)
|
||||
);
|
||||
|
||||
assert_eq!(Format::Base32.format(0x41414242, &options), "IFAUEQQ=");
|
||||
assert_eq!(Format::Base32.format_str(0x41414242, &options), "IFAUEQQ=");
|
||||
assert_eq!(
|
||||
Format::Base32.format(0x4141414141414141, &options),
|
||||
Format::Base32.format_str(0x4141414141414141, &options),
|
||||
"IFAUCQKBIFAUC==="
|
||||
);
|
||||
|
||||
assert_eq!(Format::Base64.format(0x41414242, &options), "QUFCQg==");
|
||||
assert_eq!(Format::Base64.format_str(0x41414242, &options), "QUFCQg==");
|
||||
assert_eq!(
|
||||
Format::Base64.format(0x4141414141414141, &options),
|
||||
Format::Base64.format_str(0x4141414141414141, &options),
|
||||
"QUFBQUFBQUE="
|
||||
);
|
||||
}
|
||||
|
@ -98,42 +98,48 @@ fn format_prefix() {
|
|||
let mut options = FormatOptions::default();
|
||||
options.set_prefix(true);
|
||||
|
||||
assert_eq!(Format::Dec.format(1337, &options), "0d1337");
|
||||
assert_eq!(Format::Dec.format_str(1337, &options), "0d1337");
|
||||
assert_eq!(
|
||||
Format::Dec.format(u128::MAX, &options),
|
||||
Format::Dec.format_str(u128::MAX, &options),
|
||||
format!("0d{}", u128::MAX)
|
||||
);
|
||||
|
||||
assert_eq!(Format::Hex.format(0x1337, &options), "0x1337");
|
||||
assert_eq!(Format::Hex.format_str(0x1337, &options), "0x1337");
|
||||
assert_eq!(
|
||||
Format::Hex.format(u128::MAX, &options),
|
||||
Format::Hex.format_str(u128::MAX, &options),
|
||||
format!("0x{:X}", u128::MAX)
|
||||
);
|
||||
|
||||
assert_eq!(
|
||||
Format::Bin.format(0b1010001001010010010100111, &options),
|
||||
Format::Bin.format_str(0b1010001001010010010100111, &options),
|
||||
"0b1010001001010010010100111"
|
||||
);
|
||||
assert_eq!(
|
||||
Format::Bin.format(u128::MAX, &options),
|
||||
Format::Bin.format_str(u128::MAX, &options),
|
||||
format!("0b{:b}", u128::MAX)
|
||||
);
|
||||
|
||||
assert_eq!(Format::Octal.format(0o13377331, &options), "0o13377331");
|
||||
assert_eq!(Format::Octal.format_str(0o13377331, &options), "0o13377331");
|
||||
assert_eq!(
|
||||
Format::Octal.format(u128::MAX, &options),
|
||||
Format::Octal.format_str(u128::MAX, &options),
|
||||
format!("0o{:o}", u128::MAX)
|
||||
);
|
||||
|
||||
assert_eq!(Format::Base32.format(0x41414242, &options), "032sIFAUEQQ=");
|
||||
assert_eq!(
|
||||
Format::Base32.format(0x4141414141414141, &options),
|
||||
Format::Base32.format_str(0x41414242, &options),
|
||||
"032sIFAUEQQ="
|
||||
);
|
||||
assert_eq!(
|
||||
Format::Base32.format_str(0x4141414141414141, &options),
|
||||
"032sIFAUCQKBIFAUC==="
|
||||
);
|
||||
|
||||
assert_eq!(Format::Base64.format(0x41414242, &options), "0sQUFCQg==");
|
||||
assert_eq!(
|
||||
Format::Base64.format(0x4141414141414141, &options),
|
||||
Format::Base64.format_str(0x41414242, &options),
|
||||
"0sQUFCQg=="
|
||||
);
|
||||
assert_eq!(
|
||||
Format::Base64.format_str(0x4141414141414141, &options),
|
||||
"0sQUFBQUFBQUE="
|
||||
);
|
||||
}
|
||||
|
@ -144,47 +150,53 @@ fn format_padded_prefix() {
|
|||
options.set_prefix(true);
|
||||
options.set_padding(true);
|
||||
|
||||
assert_eq!(Format::Dec.format(1337, &options), "0d1337");
|
||||
assert_eq!(Format::Dec.format_str(1337, &options), "0d1337");
|
||||
assert_eq!(
|
||||
Format::Dec.format(u128::MAX, &options),
|
||||
Format::Dec.format_str(u128::MAX, &options),
|
||||
format!("0d{}", u128::MAX)
|
||||
);
|
||||
|
||||
assert_eq!(Format::Hex.format(0xFFF, &options), "0x0FFF");
|
||||
assert_eq!(Format::Hex.format(0xFFFF, &options), "0xFFFF");
|
||||
assert_eq!(Format::Hex.format_str(0xFFF, &options), "0x0FFF");
|
||||
assert_eq!(Format::Hex.format_str(0xFFFF, &options), "0xFFFF");
|
||||
assert_eq!(
|
||||
Format::Hex.format(u128::MAX, &options),
|
||||
Format::Hex.format_str(u128::MAX, &options),
|
||||
format!("0x{:X}", u128::MAX)
|
||||
);
|
||||
|
||||
assert_eq!(
|
||||
Format::Bin.format(0b11110000_00001111, &options),
|
||||
Format::Bin.format_str(0b11110000_00001111, &options),
|
||||
"0b1111000000001111"
|
||||
);
|
||||
assert_eq!(
|
||||
Format::Bin.format(0b110000_00001111, &options),
|
||||
Format::Bin.format_str(0b110000_00001111, &options),
|
||||
"0b0011000000001111"
|
||||
);
|
||||
assert_eq!(
|
||||
Format::Bin.format(u128::MAX, &options),
|
||||
Format::Bin.format_str(u128::MAX, &options),
|
||||
format!("0b{:b}", u128::MAX)
|
||||
);
|
||||
|
||||
assert_eq!(Format::Octal.format(0o13377331, &options), "0o13377331");
|
||||
assert_eq!(Format::Octal.format_str(0o13377331, &options), "0o13377331");
|
||||
assert_eq!(
|
||||
Format::Octal.format(u128::MAX, &options),
|
||||
Format::Octal.format_str(u128::MAX, &options),
|
||||
format!("0o{:o}", u128::MAX)
|
||||
);
|
||||
|
||||
assert_eq!(Format::Base32.format(0x41414242, &options), "032sIFAUEQQ=");
|
||||
assert_eq!(
|
||||
Format::Base32.format(0x4141414141414141, &options),
|
||||
Format::Base32.format_str(0x41414242, &options),
|
||||
"032sIFAUEQQ="
|
||||
);
|
||||
assert_eq!(
|
||||
Format::Base32.format_str(0x4141414141414141, &options),
|
||||
"032sIFAUCQKBIFAUC==="
|
||||
);
|
||||
|
||||
assert_eq!(Format::Base64.format(0x41414242, &options), "0sQUFCQg==");
|
||||
assert_eq!(
|
||||
Format::Base64.format(0x4141414141414141, &options),
|
||||
Format::Base64.format_str(0x41414242, &options),
|
||||
"0sQUFCQg=="
|
||||
);
|
||||
assert_eq!(
|
||||
Format::Base64.format_str(0x4141414141414141, &options),
|
||||
"0sQUFBQUFBQUE="
|
||||
);
|
||||
}
|
||||
|
@ -197,6 +209,8 @@ fn set_format_checker() {
|
|||
assert_eq!(options.format(), Format::Base32);
|
||||
options.set_format(Format::Base64);
|
||||
assert_eq!(options.format(), Format::Base64);
|
||||
options.set_format(Format::Raw);
|
||||
assert_eq!(options.format(), Format::Raw);
|
||||
}
|
||||
|
||||
#[test]
|
||||
|
|
Reference in a new issue