use crate::platform::is_syscall_error;
use crate::Error;
use core::fmt::Formatter;
use core::ops::{BitAnd, BitAndAssign, BitOr, BitOrAssign};
#[repr(transparent)]
#[derive(Debug, Copy, Clone, Eq, PartialEq, Ord, PartialOrd, Hash)]
pub struct NonNegativeI32(pub(crate) i32);
impl core::fmt::Display for NonNegativeI32 {
#[inline]
fn fmt(&self, f: &mut Formatter<'_>) -> core::fmt::Result {
self.0.fmt(f)
}
}
impl Default for NonNegativeI32 {
fn default() -> Self {
Self::ZERO
}
}
impl NonNegativeI32 {
pub const MAX: Self = Self(i32::MAX);
pub const ZERO: Self = Self(0);
#[inline]
#[must_use]
pub const fn value(self) -> i32 {
self.0
}
#[inline]
pub const fn try_new(val: i32) -> Result<Self, i32> {
if val >= 0 {
Ok(Self(val))
} else {
Err(val)
}
}
#[inline]
#[must_use]
pub const fn comptime_checked_new(val: i32) -> Self {
assert!(
val >= 0,
"Tried to comptime create a NonNegativeI32 from a value less than zero"
);
Self(val)
}
#[inline]
#[expect(clippy::cast_possible_wrap, clippy::cast_possible_truncation)]
pub(crate) const fn coerce_from_register(
val: usize,
err_msg: &'static str,
) -> Result<Self, Error> {
if is_syscall_error(val) {
let res = val as i32;
Err(Error::with_code(err_msg, 0 - res))
} else {
Ok(Self(val as i32))
}
}
#[inline]
#[must_use]
#[expect(clippy::cast_sign_loss)]
pub const fn into_u32(self) -> u32 {
self.0 as u32
}
#[inline]
#[must_use]
#[expect(clippy::cast_sign_loss)]
pub const fn into_u64(self) -> u64 {
self.0 as u64
}
#[inline]
#[must_use]
#[expect(clippy::cast_sign_loss)]
pub const fn into_u128(self) -> u128 {
self.0 as u128
}
#[inline]
#[must_use]
#[expect(clippy::cast_sign_loss)]
pub const fn into_usize(self) -> usize {
self.0 as usize
}
}
impl BitAnd for NonNegativeI32 {
type Output = Self;
#[inline]
fn bitand(self, rhs: Self) -> Self::Output {
Self(self.0.bitand(rhs.0))
}
}
impl BitAndAssign for NonNegativeI32 {
#[inline]
fn bitand_assign(&mut self, rhs: Self) {
self.0.bitand_assign(rhs.0);
}
}
impl BitOr for NonNegativeI32 {
type Output = Self;
#[inline]
fn bitor(self, rhs: Self) -> Self::Output {
Self(self.0.bitor(rhs.0))
}
}
impl BitOrAssign for NonNegativeI32 {
#[inline]
fn bitor_assign(&mut self, rhs: Self) {
self.0.bitor_assign(rhs.0);
}
}