catalog.rs

2.1 kB · rust · 65 lines

1use super::universe::bang;2use mrlycore::tile::{classics, Catalog, Source};3use std::collections::BTreeMap;4use std::sync::{Mutex, OnceLock};56/// Returns the canonical design codes of a dimension, computed once and cached for the process.7pub fn universe_codes(dimension: usize) -> &'static [u128] {8    static CACHE: OnceLock<Mutex<BTreeMap<usize, &'static [u128]>>> = OnceLock::new();9    let cache = CACHE.get_or_init(|| Mutex::new(BTreeMap::new()));10    let mut guard = cache.lock().unwrap();11    if let Some(codes) = guard.get(&dimension) {12        return codes;13    }14    let codes: Vec<u128> = bang(dimension)15        .canonical()16        .into_iter()17        .map(|design| design.i)18        .collect();19    let leaked: &'static [u128] = Box::leak(codes.into_boxed_slice());20    guard.insert(dimension, leaked);21    leaked22}2324/// Builds the tile sources a catalog names at a dimension.25pub fn sources(catalog: &Catalog, dimension: usize) -> Vec<Source> {26    match catalog {27        Catalog::Classics => classics(dimension)28            .into_iter()29            .map(Source::Classic)30            .collect(),31        Catalog::Universe => universe_codes(dimension)32            .iter()33            .map(|&code| Source::Code(code))34            .collect(),35        Catalog::Codes(list) => list.iter().map(|&code| Source::Code(code)).collect(),36    }37}3839#[cfg(test)]40mod tests {41    use super::*;42    use mrlycore::tile::{CLASSICS_2D, CLASSICS_3D};43    #[test]44    fn catalog_classics_are_named_designs() {45        assert_eq!(46            sources(&Catalog::Classics, 2),47            CLASSICS_2D48                .into_iter()49                .map(Source::Classic)50                .collect::<Vec<_>>()51        );52        assert_eq!(53            sources(&Catalog::Classics, 3),54            CLASSICS_3D55                .into_iter()56                .map(Source::Classic)57                .collect::<Vec<_>>()58        );59    }60    #[test]61    fn catalog_universe_has_full_orbit_counts() {62        assert_eq!(sources(&Catalog::Universe, 2).len(), 6);63        assert_eq!(sources(&Catalog::Universe, 3).len(), 22);64    }65}