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}