knave 0.11.5

A small Lisp for humans and agents that infers types and ownership and compiles to readable Rust
Documentation
use std::cell::RefCell;

pub struct FreshLifetimes {
    reserved: Vec<String>,
    issued: RefCell<Vec<String>>,
}

impl FreshLifetimes {
    const LETTERS: usize = 26;

    pub fn new(reserved: Vec<String>) -> Self {
        Self {
            reserved,
            issued: RefCell::new(Vec::new()),
        }
    }

    pub fn issue(&self) -> String {
        let mut used = self.reserved.clone();
        used.extend(self.issued.borrow().iter().cloned());
        let name = Self::unused_name(&used);
        self.issued.borrow_mut().push(name.clone());
        name
    }

    pub fn issued(&self) -> Vec<String> {
        self.issued.borrow().clone()
    }

    pub fn unused_name(used: &[String]) -> String {
        let mut position = 0;
        loop {
            let name = if position < Self::LETTERS {
                format!(
                    "'{}",
                    char::from(b'a' + u8::try_from(position).expect("fewer than 26"))
                )
            } else {
                format!("'a{position}")
            };
            if !used.contains(&name) {
                return name;
            }
            position += 1;
        }
    }
}