use crate::isa::Byte;
use std::fmt::{self, Debug, Display, Formatter};
#[repr(transparent)]
#[derive(Copy)]
#[derive_const(
Clone,
Default,
Eq,
Ord,
PartialEq,
PartialOrd,
)]
pub struct Word(u16);
impl Word {
pub const BITS: u32 = 16;
#[inline(always)]
#[must_use]
pub const fn from_u16(value: u16) -> Self {
Self(value)
}
#[inline]
#[must_use]
pub const fn from_i16(value: i16) -> Self {
Self(value.cast_unsigned())
}
#[inline]
#[must_use]
pub const fn from_be(value: Self) -> Self {
Self(u16::from_be(value.0))
}
#[inline]
#[must_use]
pub const fn from_ne_bytes(bytes: [u8; size_of::<Self>()]) -> Self {
Self(u16::from_ne_bytes(bytes))
}
#[inline]
#[must_use]
pub const fn from_be_bytes(bytes: [u8; size_of::<Self>()]) -> Self {
Self(u16::from_be_bytes(bytes))
}
#[inline(always)]
#[must_use]
pub const fn as_u16(self) -> u16 {
self.0
}
#[inline]
#[must_use]
pub const fn as_i16(self) -> i16 {
self.0.cast_signed()
}
#[inline]
#[must_use]
pub const fn to_be(self) -> Self {
Self(self.0.to_be())
}
#[inline]
#[must_use]
pub const fn to_ne_bytes(self) -> [u8; size_of::<Self>()] {
self.0.to_ne_bytes()
}
#[inline]
#[must_use]
pub const fn to_be_bytes(self) -> [u8; size_of::<Self>()] {
self.0.to_be_bytes()
}
}
impl Debug for Word {
fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
let prefix = match self.as_u16().max(1).ilog(16) {
0 => "$...",
1 => "$..",
2 => "$.",
3 => "$",
_ => {
unreachable!();
}
};
write!(f, "{prefix}{:x}", self.as_u16())
}
}
impl Display for Word {
#[inline]
fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
Debug::fmt(self, f)
}
}
const impl From<Byte> for Word {
#[inline]
fn from(value: Byte) -> Self {
Self::from_u16(value.as_u8().into())
}
}
const impl From<i16> for Word {
#[inline(always)]
fn from(value: i16) -> Self {
Self::from_i16(value)
}
}
const impl From<i8> for Word {
#[inline]
fn from(value: i8) -> Self {
Self::from_i16(value.into())
}
}
const impl From<u16> for Word {
#[inline(always)]
fn from(value: u16) -> Self {
Self::from_u16(value)
}
}
const impl From<u8> for Word {
#[inline]
fn from(value: u8) -> Self {
Self::from_u16(value.into())
}
}