use crate::NiceWrapper;
use std::num::{
NonZeroU64,
NonZeroUsize,
};
const SIZE: usize = 26;
macro_rules! inner {
($sep:expr) => ([b'0', b'0', $sep, b'0', b'0', b'0', $sep, b'0', b'0', b'0', $sep, b'0', b'0', b'0', $sep, b'0', b'0', b'0', $sep, b'0', b'0', b'0', $sep, b'0', b'0', b'0']);
}
pub type NiceU64 = NiceWrapper<SIZE>;
impl From<usize> for NiceU64 {
#[allow(clippy::cast_possible_truncation)] #[allow(clippy::only_used_in_recursion)] fn from(num: usize) -> Self {
#[cfg(target_pointer_width = "128")]
assert!(num <= 18_446_744_073_709_551_615);
Self::from(num as u64)
}
}
super::nice_default!(NiceU64, inner!(b','), SIZE);
super::nice_from_nz!(NiceU64, NonZeroU64, NonZeroUsize);
super::nice_parse!(NiceU64, u64);
impl NiceU64 {
#[must_use]
pub fn with_separator(num: u64, sep: u8) -> Self {
assert!(sep.is_ascii(), "Invalid separator.");
let mut out = Self {
inner: inner!(sep),
from: SIZE,
};
out.parse(num);
out
}
}
#[cfg(test)]
mod tests {
use super::*;
use num_format::{ToFormattedString, Locale};
#[test]
fn t_nice_u64() {
#[cfg(not(miri))]
const SAMPLE_SIZE: usize = 1_000_000;
#[cfg(miri)]
const SAMPLE_SIZE: usize = 1000;
assert_eq!(NiceU64::from(0_u64).as_str(), "0");
assert_eq!(NiceU64::default(), NiceU64::from(0_u64));
assert_eq!(NiceU64::default(), NiceU64::from(0_usize));
assert_eq!(
NiceU64::from(u64::MAX).as_str(),
u64::MAX.to_formatted_string(&Locale::en),
);
assert_eq!(NiceU64::empty().as_bytes(), <&[u8]>::default());
assert_eq!(NiceU64::empty().as_str(), "");
let foo: Option<u64> = None;
assert_eq!(NiceU64::default(), NiceU64::from(foo));
let foo = Some(13_u64);
assert_eq!(NiceU64::from(13_u64), NiceU64::from(foo));
let foo: Option<usize> = None;
assert_eq!(NiceU64::default(), NiceU64::from(foo));
let foo = Some(13_usize);
assert_eq!(NiceU64::from(13_usize), NiceU64::from(foo));
let one = NiceU64::from(10_u64);
let two = NiceU64::from(90_u64);
assert_eq!(one.cmp(&two), std::cmp::Ordering::Less);
assert_eq!(one.cmp(&one), std::cmp::Ordering::Equal);
assert_eq!(two.cmp(&one), std::cmp::Ordering::Greater);
let rng = fastrand::Rng::new();
for i in std::iter::repeat_with(|| rng.u64(..)).take(SAMPLE_SIZE) {
assert_eq!(
NiceU64::from(i).as_str(),
i.to_formatted_string(&Locale::en),
);
}
}
#[test]
fn t_nice_nonzero_u64() {
assert_eq!(NiceU64::default(), NiceU64::from(NonZeroU64::new(0)));
assert_eq!(NiceU64::from(50_u64), NiceU64::from(NonZeroU64::new(50)));
assert_eq!(NiceU64::from(50_u64), NiceU64::from(NonZeroU64::new(50).unwrap()));
assert_eq!(NiceU64::default(), NiceU64::from(NonZeroUsize::new(0)));
assert_eq!(NiceU64::from(50_u64), NiceU64::from(NonZeroUsize::new(50)));
assert_eq!(NiceU64::from(50_u64), NiceU64::from(NonZeroUsize::new(50).unwrap()));
let foo: Option<NonZeroU64> = None;
assert_eq!(NiceU64::from(foo), NiceU64::default());
let foo = NonZeroU64::new(13);
assert_eq!(NiceU64::from(13_u64), NiceU64::from(foo));
let foo: Option<NonZeroUsize> = None;
assert_eq!(NiceU64::from(foo), NiceU64::default());
let foo = NonZeroUsize::new(13);
assert_eq!(NiceU64::from(13_usize), NiceU64::from(foo));
}
#[test]
fn t_as() {
let num = NiceU64::from(12_345_678_912_345_u64);
assert_eq!(num.as_str(), String::from(num));
assert_eq!(num.as_bytes(), Vec::<u8>::from(num));
}
}