#[derive(serde::Serialize, serde::Deserialize, Debug, PartialEq, Eq, Clone, Copy, Hash)]
pub struct Tag(i64);
impl Tag {
pub(crate) fn from(id: i64) -> Tag {
Tag(id)
}
pub fn new() -> Tag {
unsafe {
COUNTER = (COUNTER + 1) % 0xFFFFFFFFFFFFFF;
Tag(COUNTER)
}
}
pub fn none() -> Tag {
Tag(0)
}
pub fn special(id: i64) -> Option<Tag> {
if (64..=128).contains(&id) {
Some(Tag(id))
} else {
None
}
}
pub fn id(&self) -> i64 {
self.0
}
}
static mut COUNTER: i64 = 128;
impl Tag {}
impl Default for Tag {
fn default() -> Self {
Self::new()
}
}
#[cfg(test)]
mod tests {
use lunatic_test::test;
use super::Tag;
#[test]
fn tag_increments() {
assert_eq!(Tag::new(), Tag(129));
assert_eq!(Tag::new(), Tag(130));
assert_eq!(Tag::new(), Tag(131));
assert_eq!(Tag::new(), Tag(132));
}
#[test]
fn test_special_tag() {
assert!(Tag::special(64).is_some());
assert!(Tag::special(128).is_some());
assert!(Tag::special(63).is_none());
assert!(Tag::special(129).is_none());
assert_eq!(Tag::none(), Tag::none());
}
}