use std::{cmp, fmt};
use crate::element::ParseAs;
#[derive(Copy, Clone, Debug, Default, PartialEq, Eq, PartialOrd, Ord, Hash)]
pub struct Mode(
).
pub u8,
);
impl Mode {
pub const OPEN: Self = Self(0);
pub const SECURE: Self = Self(1);
pub const LOCKED: Self = Self(2);
pub const RESET: Self = Self(3);
pub const SECURE_ONCE: Self = Self(4);
pub const PERM_OPEN: Self = Self(5);
pub const PERM_SECURE: Self = Self(6);
pub const PERM_LOCKED: Self = Self(7);
pub const ROOM_NAME: Self = Self(10);
pub const ROOM_DESC: Self = Self(11);
pub const ROOM_EXITS: Self = Self(12);
pub const WELCOME_TEXT: Self = Self(19);
pub const USER_DEFINED_MIN: Self = Self(20);
pub const USER_DEFINED_MAX: Self = Self(99);
}
impl Mode {
#[inline]
pub const fn is_open(self) -> bool {
const OPEN: u8 = Mode::OPEN.0;
const PERM_OPEN: u8 = Mode::PERM_OPEN.0;
const MIN_USER_DEFINED: u8 = Mode::USER_DEFINED_MIN.0;
matches!(self.0, OPEN | PERM_OPEN | MIN_USER_DEFINED..)
}
#[inline]
pub const fn is_locked(self) -> bool {
matches!(self, Self::LOCKED | Self::PERM_LOCKED)
}
#[inline]
pub const fn is_automapping(self) -> bool {
matches!(self.0, 10..=19)
}
#[inline]
pub const fn parse_as(self) -> Option<ParseAs> {
match self {
Self::ROOM_NAME => Some(ParseAs::RoomName),
Self::ROOM_DESC => Some(ParseAs::RoomDesc),
Self::ROOM_EXITS => Some(ParseAs::RoomExit),
_ => None,
}
}
#[inline]
pub const fn is_user_defined(self) -> bool {
const MIN: u8 = Mode::USER_DEFINED_MIN.0;
const MAX: u8 = Mode::USER_DEFINED_MAX.0;
matches!(self.0, MIN..=MAX)
}
}
impl PartialEq<u8> for Mode {
fn eq(&self, other: &u8) -> bool {
self.0 == *other
}
}
impl PartialEq<Mode> for u8 {
fn eq(&self, other: &Mode) -> bool {
*self == other.0
}
}
impl PartialOrd<u8> for Mode {
fn partial_cmp(&self, other: &u8) -> Option<cmp::Ordering> {
self.0.partial_cmp(other)
}
}
impl PartialOrd<Mode> for u8 {
fn partial_cmp(&self, other: &Mode) -> Option<cmp::Ordering> {
self.partial_cmp(&other.0)
}
}
impl PartialEq<usize> for Mode {
fn eq(&self, other: &usize) -> bool {
usize::from(self.0) == *other
}
}
impl PartialEq<Mode> for usize {
fn eq(&self, other: &Mode) -> bool {
*self == usize::from(other.0)
}
}
impl PartialOrd<usize> for Mode {
fn partial_cmp(&self, other: &usize) -> Option<cmp::Ordering> {
usize::from(self.0).partial_cmp(other)
}
}
impl PartialOrd<Mode> for usize {
fn partial_cmp(&self, other: &Mode) -> Option<cmp::Ordering> {
self.partial_cmp(&usize::from(other.0))
}
}
impl fmt::Display for Mode {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
self.0.fmt(f)
}
}
impl From<Mode> for usize {
fn from(value: Mode) -> Self {
value.0.into()
}
}
#[derive(Debug, Copy, Clone, PartialEq, Eq)]
pub struct ModeRangeError(pub(crate) ());
impl fmt::Display for ModeRangeError {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
f.write_str("MXP mode must be between 0 and 99")
}
}
macro_rules! impl_try_from_unsigned {
($t:ty) => {
impl TryFrom<$t> for Mode {
type Error = ModeRangeError;
fn try_from(value: $t) -> Result<Self, Self::Error> {
if value <= 99 {
#[allow(clippy::cast_possible_truncation)]
Ok(Self(value as u8))
} else {
Err(ModeRangeError(()))
}
}
}
};
}
macro_rules! impl_try_from_signed {
($t:ty) => {
impl TryFrom<$t> for Mode {
type Error = ModeRangeError;
fn try_from(value: $t) -> Result<Self, Self::Error> {
#[allow(clippy::manual_range_contains)]
if value >= 0 && value <= 99 {
#[allow(clippy::cast_sign_loss, clippy::cast_possible_truncation)]
Ok(Self(value as u8))
} else {
Err(ModeRangeError(()))
}
}
}
};
}
impl_try_from_unsigned!(u8);
impl_try_from_unsigned!(u16);
impl_try_from_unsigned!(u32);
impl_try_from_unsigned!(u64);
impl_try_from_unsigned!(usize);
impl_try_from_signed!(i8);
impl_try_from_signed!(i16);
impl_try_from_signed!(i32);
impl_try_from_signed!(i64);
impl_try_from_signed!(isize);