#[repr(u8)]
#[derive(Debug, Clone, Copy, Eq, PartialEq)]
#[expect(missing_docs, reason = "Self-explanatory.")]
pub enum NiceSeparator {
Apostrophe = b'\'',
Comma = b',',
Dash = b'-',
Period = b'.',
Space = b' ',
Underscore = b'_',
}
impl NiceSeparator {
pub(super) const fn as_nice_char(self) -> NiceChar {
match self {
Self::Apostrophe => NiceChar::Apostrophe,
Self::Comma => NiceChar::Comma,
Self::Dash => NiceChar::Dash,
Self::Period => NiceChar::Period,
Self::Space => NiceChar::Space,
Self::Underscore => NiceChar::Underscore,
}
}
}
macro_rules! nice_chars {
(@from_digit $($fn:ident $ty:ident),+ $(,)+) => (
impl NiceChar {
$(
#[inline(always)]
#[must_use]
pub(super) const fn $fn(src: $ty) -> Self {
match src % 10 {
0 => Self::Digit0,
1 => Self::Digit1,
2 => Self::Digit2,
3 => Self::Digit3,
4 => Self::Digit4,
5 => Self::Digit5,
6 => Self::Digit6,
7 => Self::Digit7,
8 => Self::Digit8,
9 => Self::Digit9,
_ => unreachable!(),
}
}
)+
}
);
($($k:ident $v:literal),+ $(,)?) => (
#[repr(u8)]
#[derive(Debug, Clone, Copy, Eq, Hash, Ord, PartialEq, PartialOrd)]
pub(super) enum NiceChar {
$($k = $v,)+
}
impl NiceChar {
#[expect(unsafe_code, reason = "For transmute.")]
#[inline(always)]
#[must_use]
pub(super) const fn as_bytes(src: &[Self]) -> &[u8] {
const {
assert!(
align_of::<&[Self]>() == align_of::<&[u8]>() &&
size_of::<&[Self]>() == size_of::<&[u8]>(),
"BUG: NiceChar and u8 have different layouts?!",
);
}
unsafe { std::mem::transmute::<&[Self], &[u8]>(src) }
}
#[expect(unsafe_code, reason = "For transmute.")]
#[inline(always)]
#[must_use]
pub(super) const fn as_str(src: &[Self]) -> &str {
unsafe { std::str::from_utf8_unchecked(Self::as_bytes(src)) }
}
}
nice_chars! {
@from_digit
from_digit_u8 u8,
from_digit_u16 u16,
from_digit_u32 u32,
from_digit_u64 u64,
}
);
}
nice_chars!(
Space b' ', Percent b'%', Apostrophe b'\'', Comma b',', Dash b'-', Period b'.', Digit0 b'0',
Digit1 b'1',
Digit2 b'2',
Digit3 b'3',
Digit4 b'4',
Digit5 b'5',
Digit6 b'6',
Digit7 b'7',
Digit8 b'8',
Digit9 b'9',
Colon b':', Lt b'<', Gt b'>', LowerA b'a', LowerC b'c', LowerD b'd', LowerE b'e', LowerH b'h', LowerI b'i', LowerM b'm', LowerN b'n', LowerO b'o', LowerR b'r', LowerS b's', LowerT b't', LowerU b'u', LowerY b'y', Underscore b'_', );