use core::fmt;
use crate::core::matter::code::NumberCode;
use crate::core::primitives::ordinal::Ordinal;
#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
pub struct Number {
code: NumberCode,
value: u128,
}
impl Number {
#[must_use]
pub const fn new(value: u128) -> Self {
let code = NumberCode::for_value(value);
Self { code, value }
}
#[must_use]
pub const fn with_code(code: NumberCode, value: u128) -> Self {
Self { code, value }
}
#[must_use]
pub const fn code(&self) -> &NumberCode {
&self.code
}
#[must_use]
pub const fn value(&self) -> u128 {
self.value
}
}
impl fmt::LowerHex for Number {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
fmt::LowerHex::fmt(&self.value, f)
}
}
impl Ordinal for Number {
fn num(&self) -> u128 {
self.value
}
}
#[cfg(test)]
mod tests {
use alloc::format;
use alloc::string::ToString;
use super::*;
use crate::core::matter::code::NumberCode;
#[test]
fn number_picks_smallest_code() {
let n_short = Number::new(255);
assert_eq!(*n_short.code(), NumberCode::Short);
assert_eq!(n_short.value(), 255);
let n_long = Number::new(0xFFFF_FFFF);
assert_eq!(*n_long.code(), NumberCode::Long);
let n_big = Number::new(u128::from(u64::MAX));
assert_eq!(*n_big.code(), NumberCode::Big);
}
#[test]
fn number_zero() {
let n = Number::new(0);
assert_eq!(*n.code(), NumberCode::Short);
assert_eq!(n.value(), 0);
}
#[test]
fn number_renders_minimal_hex_via_ordinal_and_lowerhex() {
let n = Number::new(255);
assert_eq!(n.numh().to_string(), "ff");
assert_eq!(format!("{n:x}"), "ff");
assert_eq!(Number::new(0).numh().to_string(), "0");
assert_eq!(Number::new(u128::MAX).num(), u128::MAX);
}
#[test]
fn number_is_copy() {
fn assert_copy<T: Copy>() {}
assert_copy::<Number>();
}
}