#[allow(unused_imports)]
use crate::Arbi;
use core::fmt;
#[derive(Debug, Copy, Clone)]
pub struct Base(pub(crate) u8);
#[derive(Debug)]
pub enum BaseError {
InvalidBase,
}
impl fmt::Display for BaseError {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
match self {
BaseError::InvalidBase => {
write!(f, "Base must be in the range [2, 36]")
}
}
}
}
#[cfg(feature = "std")]
impl std::error::Error for BaseError {}
#[cfg(feature = "std")]
#[cfg(test)]
mod std_tests {
use super::BaseError;
use std::error::Error;
#[test]
fn test_error_trait() {
let err: BaseError = BaseError::InvalidBase;
assert!(err.source().is_none());
}
}
impl TryFrom<u8> for Base {
type Error = BaseError;
fn try_from(value: u8) -> Result<Self, Self::Error> {
if (2..=36).contains(&value) {
Ok(Base(value))
} else {
Err(BaseError::InvalidBase)
}
}
}
impl From<Base> for u8 {
fn from(value: Base) -> u8 {
#[allow(clippy::useless_conversion)]
value.value().into()
}
}
impl From<Base> for u32 {
fn from(value: Base) -> u32 {
value.value().into()
}
}
impl From<Base> for i32 {
fn from(value: Base) -> i32 {
value.value().into()
}
}
impl TryFrom<usize> for Base {
type Error = BaseError;
fn try_from(value: usize) -> Result<Self, Self::Error> {
let as_u8: Result<u8, _> = value.try_into();
match as_u8 {
Err(_) => Err(BaseError::InvalidBase),
Ok(the_u8) => the_u8.try_into(),
}
}
}
impl TryFrom<i32> for Base {
type Error = BaseError;
fn try_from(value: i32) -> Result<Self, Self::Error> {
let as_u8: Result<u8, _> = value.try_into();
match as_u8 {
Err(_) => Err(BaseError::InvalidBase),
Ok(the_u8) => the_u8.try_into(),
}
}
}
impl TryFrom<u32> for Base {
type Error = BaseError;
fn try_from(value: u32) -> Result<Self, Self::Error> {
let as_u8: Result<u8, _> = value.try_into();
match as_u8 {
Err(_) => Err(BaseError::InvalidBase),
Ok(the_u8) => the_u8.try_into(),
}
}
}
impl Base {
#[inline]
pub fn new(value: u8) -> Result<Self, BaseError> {
value.try_into()
}
#[inline]
pub fn value(self) -> u8 {
self.0
}
}
pub const BASE10: Base = Base(10);
pub const B10: Base = Base(10);
pub const BIN: Base = Base(2);
pub const OCT: Base = Base(8);
pub const DEC: Base = Base(10);
pub const HEX: Base = Base(16);
pub const B36: Base = Base(36);