Get suffix from IdentId or Symbol

IdentId will now reserve the MSB for flagging whether the ident
is suffixed with a `!`.
We will use this later to constrain identifiers to be effectful or pure.
This commit is contained in:
Agus Zubiaga 2024-10-16 10:08:11 -03:00
parent 69e026f8bb
commit 2c8571537e
No known key found for this signature in database
2 changed files with 131 additions and 42 deletions

View file

@ -362,3 +362,60 @@ impl fmt::Display for Uppercase {
fmt::Display::fmt(&self.0, f)
}
}
#[derive(Copy, Clone, Debug, PartialEq)]
pub enum IdentSuffix {
None,
Bang,
}
impl IdentSuffix {
#[inline(always)]
pub const fn from_name(name: &str) -> Self {
// Checking bytes directly so it can be const.
// This should be fine since the suffix is ASCII.
let bytes = name.as_bytes();
let len = bytes.len();
debug_assert!(len > 0, "Ident name must not be empty");
if bytes[len - 1] == ('!' as u8) {
IdentSuffix::Bang
} else {
IdentSuffix::None
}
}
pub fn is_suffixed(&self) -> bool {
match self {
IdentSuffix::None => false,
IdentSuffix::Bang => true,
}
}
}
#[cfg(test)]
mod suffix_test {
use crate::ident::IdentSuffix;
#[test]
fn ends_with_bang() {
assert_eq!(IdentSuffix::from_name("foo!"), IdentSuffix::Bang)
}
#[test]
fn ends_without_bang() {
assert_eq!(IdentSuffix::from_name("foo"), IdentSuffix::None)
}
#[test]
fn invalid() {
assert_eq!(IdentSuffix::from_name("foo!bar"), IdentSuffix::None)
}
#[test]
#[should_panic]
fn empty_panics() {
IdentSuffix::from_name("");
}
}