use std::collections::BTreeMap;
use proc_macro2::Span;
use syn::Ident;
use super::IdentGenerator;
#[derive(Debug, Default, Clone)]
pub struct CountingIdentGenerator {
idents: BTreeMap<Option<&'static str>, usize>,
}
impl CountingIdentGenerator {
pub fn new() -> Self {
Default::default()
}
}
impl IdentGenerator for CountingIdentGenerator {
fn generate(&mut self, prefix: Option<&'static str>, span: Span) -> Ident {
let counter = self.idents.entry(prefix).or_default();
*counter += 1;
if let Some(ident) = prefix {
Ident::new(format!("C_{ident}_{counter}").as_str(), span)
} else {
Ident::new(format!("C_{counter}").as_str(), span)
}
}
}
#[cfg(test)]
mod test {
use proc_macro2::Span;
use syn::Ident;
use crate::ident_generator::IdentGenerator;
use super::CountingIdentGenerator;
#[test]
fn ident() {
let mut ident_gen = CountingIdentGenerator::new();
for i in 1..=100 {
assert_eq!(
ident_gen.ident(),
Ident::new(format!("C_{i}").as_str(), Span::call_site())
);
}
}
#[test]
fn prefixed() {
let mut ident_gen = CountingIdentGenerator::new();
for i in 1..=100 {
assert_eq!(
ident_gen.prefixed("prefix"),
Ident::new(format!("C_prefix_{i}").as_str(), Span::call_site())
);
}
}
#[test]
fn spanned() {
let mut ident_gen = CountingIdentGenerator::new();
assert_eq!(
ident_gen.spanned(Span::mixed_site()),
Ident::new("C_1", Span::mixed_site())
);
}
#[test]
fn prefixed_spanned() {
let mut ident_gen = CountingIdentGenerator::new();
for i in 1..=100 {
assert_eq!(
ident_gen.generate(Some("prefix"), Span::mixed_site()),
Ident::new(format!("C_prefix_{i}").as_str(), Span::mixed_site())
);
}
}
}