use super::ByteOrder;
use core::fmt;
pub struct Number {
pub value: Vec<u8>,
pub negative: bool,
pub byte_order: ByteOrder,
}
impl Number {
pub fn new(mut value: Vec<u8>, byte_order: ByteOrder) -> Self {
match byte_order {
ByteOrder::BigEndian => {
let start = value
.iter()
.position(|&b| b != 0)
.unwrap_or(value.len().saturating_sub(1));
value.drain(..start);
}
ByteOrder::LittleEndian => {
let end = value.iter().rposition(|&b| b != 0).map_or(1, |i| i + 1);
value.truncate(end);
}
}
Self {
value,
negative: false,
byte_order,
}
}
pub fn new_signed(value: Vec<u8>, negative: bool, byte_order: ByteOrder) -> Self {
let number = Self::new(value, byte_order);
let negative = negative && !matches!(number.value.as_slice(), [] | [0]);
Self { negative, ..number }
}
pub fn new_from_u8(value: u8, byte_order: ByteOrder) -> Self {
Self::new(vec![value], byte_order)
}
pub fn new_from_u16(value: u16, byte_order: ByteOrder) -> Self {
let bytes = match byte_order {
ByteOrder::BigEndian => value.to_be_bytes().to_vec(),
ByteOrder::LittleEndian => value.to_le_bytes().to_vec(),
};
Self::new(bytes, byte_order)
}
pub fn new_from_u32(value: u32, byte_order: ByteOrder) -> Self {
let bytes = match byte_order {
ByteOrder::BigEndian => value.to_be_bytes().to_vec(),
ByteOrder::LittleEndian => value.to_le_bytes().to_vec(),
};
Self::new(bytes, byte_order)
}
pub fn new_from_u64(value: u64, byte_order: ByteOrder) -> Self {
let bytes = match byte_order {
ByteOrder::BigEndian => value.to_be_bytes().to_vec(),
ByteOrder::LittleEndian => value.to_le_bytes().to_vec(),
};
Self::new(bytes, byte_order)
}
pub fn new_from_u128(value: u128, byte_order: ByteOrder) -> Self {
let bytes = match byte_order {
ByteOrder::BigEndian => value.to_be_bytes().to_vec(),
ByteOrder::LittleEndian => value.to_le_bytes().to_vec(),
};
Self::new(bytes, byte_order)
}
pub fn new_from_usize(value: usize, byte_order: ByteOrder) -> Self {
let bytes = match byte_order {
ByteOrder::BigEndian => value.to_be_bytes().to_vec(),
ByteOrder::LittleEndian => value.to_le_bytes().to_vec(),
};
Self::new(bytes, byte_order)
}
pub fn new_from_i8_vec(value: Vec<i8>, byte_order: ByteOrder) -> Self {
Self::new(value.iter().map(|&x| x as u8).collect(), byte_order)
}
pub fn new_from_i8(value: i8, byte_order: ByteOrder) -> Self {
Self {
negative: value < 0,
..Self::new_from_u8(value.unsigned_abs(), byte_order)
}
}
pub fn new_from_i16(value: i16, byte_order: ByteOrder) -> Self {
Self {
negative: value < 0,
..Self::new_from_u16(value.unsigned_abs(), byte_order)
}
}
pub fn new_from_i32(value: i32, byte_order: ByteOrder) -> Self {
Self {
negative: value < 0,
..Self::new_from_u32(value.unsigned_abs(), byte_order)
}
}
pub fn new_from_i64(value: i64, byte_order: ByteOrder) -> Self {
Self {
negative: value < 0,
..Self::new_from_u64(value.unsigned_abs(), byte_order)
}
}
pub fn new_from_i128(value: i128, byte_order: ByteOrder) -> Self {
Self {
negative: value < 0,
..Self::new_from_u128(value.unsigned_abs(), byte_order)
}
}
pub fn new_from_isize(value: isize, byte_order: ByteOrder) -> Self {
Self {
negative: value < 0,
..Self::new_from_usize(value.unsigned_abs(), byte_order)
}
}
pub fn new_from_str(value: &str, byte_order: ByteOrder) -> Self {
Self::new(value.as_bytes().to_vec(), byte_order)
}
pub fn is_negative(&self) -> bool {
self.negative
}
pub fn byte_order(&self) -> ByteOrder {
self.byte_order
}
}
impl Clone for Number {
#[inline]
fn clone(&self) -> Self {
Number {
value: self.value.clone(),
negative: self.negative,
byte_order: self.byte_order,
}
}
#[inline]
fn clone_from(&mut self, source: &Self) {
self.value.clone_from(&source.value);
self.negative = source.negative;
self.byte_order = source.byte_order;
}
}
impl Default for Number {
#[inline]
fn default() -> Self {
Number {
value: Vec::new(),
negative: false,
byte_order: ByteOrder::LittleEndian,
}
}
}
impl fmt::Debug for Number {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
fmt::Display::fmt(self, f)
}
}