Add helper for generating anonymous labels

This commit is contained in:
2025-06-17 01:22:18 -07:00
parent 0b2fc58fae
commit 73ca64e4e9
+31 -1
View File
@@ -27,6 +27,7 @@ impl LabelId {
pub struct Registry { pub struct Registry {
label_transforms: HashMap<LabelId, Transform>, label_transforms: HashMap<LabelId, Transform>,
existing: HashSet<CompactString>, existing: HashSet<CompactString>,
anonymous_counter: CompactString,
} }
enum Transform { enum Transform {
@@ -61,6 +62,7 @@ impl Registry {
Self { Self {
label_transforms, label_transforms,
existing, existing,
anonymous_counter: "_".into(),
} }
} }
@@ -103,6 +105,15 @@ impl Registry {
candidate candidate
} }
pub fn gen_anonymous(&mut self) -> CompactString {
while self.existing.contains(&self.anonymous_counter) {
increment(&mut self.anonymous_counter);
}
let result = self.anonymous_counter.clone();
increment(&mut self.anonymous_counter);
result
}
fn preferred_name(label: &LabelName) -> CompactString { fn preferred_name(label: &LabelName) -> CompactString {
let src = if let Some(local) = &label.local { let src = if let Some(local) = &label.local {
local local
@@ -183,7 +194,7 @@ fn increment(s: &mut CompactString) {
mod test { mod test {
use std::collections::HashSet; use std::collections::HashSet;
use compact_str::CompactString; use compact_str::{CompactString, CompactStringExt};
use insta::assert_snapshot; use insta::assert_snapshot;
use crate::labels::{parse::LabelName, sanitize::Registry}; use crate::labels::{parse::LabelName, sanitize::Registry};
@@ -299,4 +310,23 @@ mod test {
LabelName { namespace: None, name: "foo2bar", local: None } => foo_bar LabelName { namespace: None, name: "foo2bar", local: None } => foo_bar
"#); "#);
} }
#[test]
fn test_gen_anonymous() {
let mut registry = Registry::new();
for letter in ["a", "e", "i"] {
registry.sanitize(&LabelName {
namespace: None,
name: letter.into(),
local: None,
});
}
let result: Vec<_> = (0..10).map(|_| registry.gen_anonymous()).collect();
let result = result.join(", ");
// It's safer if anonymous labels don't start with a digit.
// If one ever did, it could change `#take gems 123@f` to something
// like `#take gems 1230`, altering how the ZZT-OOP parses.
assert_snapshot!(result, @"_, b, c, d, f, g, h, j, k, l");
}
} }