use crate::shared_symbol_table::SharedSymbolTable;
use std::collections::{BTreeMap, HashMap};
pub trait Catalog {
fn get_table(&self, name: &str) -> Option<&SharedSymbolTable>;
fn get_table_with_version(&self, name: &str, version: usize) -> Option<&SharedSymbolTable>;
}
#[derive(Default)]
#[allow(dead_code)] pub struct MapCatalog {
tables_by_name: HashMap<String, BTreeMap<usize, SharedSymbolTable>>,
}
impl Catalog for MapCatalog {
fn get_table(&self, name: &str) -> Option<&SharedSymbolTable> {
if name.is_empty() {
return None;
}
let versions: &BTreeMap<usize, SharedSymbolTable> = self.tables_by_name.get(name)?;
let (_highest_version, table) = versions.iter().next_back()?;
Some(table)
}
fn get_table_with_version(&self, name: &str, version: usize) -> Option<&SharedSymbolTable> {
if name.is_empty() {
return None;
}
let versions: &BTreeMap<usize, SharedSymbolTable> = self.tables_by_name.get(name)?;
versions.get(&version)
}
}
#[allow(dead_code)] impl MapCatalog {
pub fn new() -> Self {
Self {
tables_by_name: HashMap::new(),
}
}
pub fn insert_table(&mut self, table: SharedSymbolTable) {
match self.tables_by_name.get_mut(table.name()) {
None => {
let mut versions: BTreeMap<usize, SharedSymbolTable> = BTreeMap::new();
let table_name = table.name().to_owned();
versions.insert(table.version(), table);
self.tables_by_name.insert(table_name, versions);
}
Some(versions) => {
versions.insert(table.version(), table);
}
};
}
}
#[derive(Debug, Clone, Default)]
pub struct EmptyCatalog;
impl Catalog for EmptyCatalog {
fn get_table(&self, _name: &str) -> Option<&SharedSymbolTable> {
None
}
fn get_table_with_version(&self, _name: &str, _version: usize) -> Option<&SharedSymbolTable> {
None
}
}
#[cfg(test)]
mod tests {
use crate::catalog::{Catalog, MapCatalog};
use crate::shared_symbol_table::SharedSymbolTable;
use crate::{IonResult, Symbol};
#[test]
fn get_table_with_name_test() -> IonResult<()> {
let sst = SharedSymbolTable::new(
"T".to_string(),
1,
vec![Symbol::owned("foo"), Symbol::owned("bar")],
)?;
let mut catalog = MapCatalog::new();
catalog.insert_table(sst);
assert!(catalog.get_table("T").is_some());
assert!(catalog.get_table("S").is_none());
Ok(())
}
#[test]
fn get_table_with_version_test() -> IonResult<()> {
let sst = SharedSymbolTable::new(
"T".to_string(),
1,
vec![Symbol::owned("foo"), Symbol::owned("bar")],
)?;
let mut catalog = MapCatalog::new();
catalog.insert_table(sst);
assert!(catalog.get_table_with_version("T", 1).is_some());
assert!(catalog.get_table_with_version("T", 2).is_none());
Ok(())
}
}