use crate::vm::{Byte, Word};
use std::fmt::{self, Debug, Display, Formatter};
#[repr(transparent)]
#[derive(Copy)]
#[derive_const(
Clone,
Default,
Eq,
Ord,
PartialEq,
PartialOrd,
)]
pub struct Long(u32);
impl Long {
#[inline(always)]
#[must_use]
pub const fn from_u32(value: u32) -> Self {
Self(value)
}
#[inline]
#[must_use]
pub const fn from_i32(value: i32) -> Self {
Self(value.cast_unsigned())
}
#[inline]
#[must_use]
pub const fn from_be(value: Self) -> Self {
Self(u32::from_be(value.0))
}
#[inline]
#[must_use]
pub const fn from_ne_bytes(bytes: [u8; size_of::<Self>()]) -> Self {
Self(u32::from_ne_bytes(bytes))
}
#[inline]
#[must_use]
pub const fn from_be_bytes(bytes: [u8; size_of::<Self>()]) -> Self {
Self(u32::from_be_bytes(bytes))
}
#[inline(always)]
#[must_use]
pub const fn as_u32(self) -> u32 {
self.0
}
#[inline]
#[must_use]
pub const fn as_i32(self) -> i32 {
self.0.cast_signed()
}
#[inline]
#[must_use]
pub const fn as_usize(self) -> usize {
self.0 as usize
}
#[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 Long {
#[inline]
fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
let low = self.as_u32() & 0xFFFF;
let high = self.as_u32() >> 16;
write!(f, "0x{high:04X}_{low:04X}")
}
}
impl Display for Long {
#[inline]
fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
Debug::fmt(self, f)
}
}
const impl From<Byte> for Long {
#[inline]
fn from(value: Byte) -> Self {
Self::from_u32(value.as_u8().into())
}
}
const impl From<i16> for Long {
#[inline]
fn from(value: i16) -> Self {
Self::from_i32(value.into())
}
}
const impl From<i32> for Long {
#[inline(always)]
fn from(value: i32) -> Self {
Self::from_i32(value)
}
}
const impl From<i8> for Long {
#[inline]
fn from(value: i8) -> Self {
Self::from_i32(value.into())
}
}
const impl From<u16> for Long {
#[inline]
fn from(value: u16) -> Self {
Self::from_u32(value.into())
}
}
const impl From<u32> for Long {
#[inline(always)]
fn from(value: u32) -> Self {
Self::from_u32(value)
}
}
const impl From<u8> for Long {
#[inline]
fn from(value: u8) -> Self {
Self::from_u32(value.into())
}
}
const impl From<Word> for Long {
#[inline]
fn from(value: Word) -> Self {
Self::from_u32(value.as_u16().into())
}
}