interner: minimal working version

This commit is contained in:
Ryan Chandler 2022-08-08 11:47:17 +01:00
parent 37733dce29
commit 08ca5a7295
No known key found for this signature in database
GPG Key ID: F113BCADDB3B0CCA

View File

@ -1,14 +1,52 @@
pub fn add(left: usize, right: usize) -> usize {
left + right
use std::collections::HashMap;
#[derive(Debug, PartialEq)]
#[repr(transparent)]
pub struct Symbol(u32);
#[derive(Debug, Default)]
pub struct Interner {
map: HashMap<String, u32>,
storage: Vec<String>,
}
impl Interner {
pub fn intern(&mut self, name: &str) -> Symbol {
if let Some(&index) = self.map.get(name) {
return Symbol(index);
}
let index = self.map.len() as u32;
self.map.insert(name.to_string(), index);
self.storage.push(name.to_string());
Symbol(index)
}
pub fn get(&self, symbol: Symbol) -> &str {
self.storage[symbol.0 as usize].as_str()
}
}
#[cfg(test)]
mod tests {
use super::*;
use crate::{Interner, Symbol};
#[test]
fn it_works() {
let result = add(2, 2);
assert_eq!(result, 4);
fn it_can_intern_a_string() {
let mut interner = Interner::default();
assert_eq!(interner.intern("Hello, world!"), Symbol(0));
assert_eq!(interner.intern("Hello, world!"), Symbol(0));
}
}
#[test]
fn it_can_retrieve_an_interned_string() {
let mut interner = Interner::default();
let symbol = interner.intern("Hello, world!");
assert_eq!(interner.get(symbol), "Hello, world!");
}
}