mod minimal_world;
use crate::spec::AssetSpec;
pub struct WorldTemplate {
pub name: &'static str,
pub title: &'static str,
pub description: &'static str,
build: fn() -> Vec<AssetSpec>,
}
impl WorldTemplate {
pub fn assets(&self) -> Vec<AssetSpec> {
(self.build)()
}
}
pub const TEMPLATES: &[WorldTemplate] = &[WorldTemplate {
name: "minimal-3d-world",
title: "Minimal 3D World",
description: "A lit room with a camera and sky.",
build: minimal_world::assets,
}];
pub fn by_name(name: &str) -> Option<&'static WorldTemplate> {
TEMPLATES.iter().find(|t| t.name == name)
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn every_template_builds_well_formed_specs() {
for t in TEMPLATES {
let specs = t.assets();
assert!(!specs.is_empty(), "template '{}' has no assets", t.name);
for s in &specs {
assert!(
!s.name.is_empty(),
"template '{}' has an unnamed asset",
t.name
);
assert!(
!s.fields.is_empty(),
"template '{}' asset '{}' sets no args",
t.name,
s.name
);
}
}
}
#[test]
fn names_are_unique_and_resolvable() {
for (i, t) in TEMPLATES.iter().enumerate() {
assert_eq!(by_name(t.name).map(|r| r.name), Some(t.name));
for other in &TEMPLATES[i + 1..] {
assert_ne!(t.name, other.name, "duplicate template name '{}'", t.name);
}
}
assert!(by_name("does-not-exist").is_none());
}
#[test]
fn asset_names_within_a_template_are_unique() {
for t in TEMPLATES {
let mut names: Vec<String> = t.assets().into_iter().map(|s| s.name).collect();
names.sort();
let before = names.len();
names.dedup();
assert_eq!(
before,
names.len(),
"template '{}' has duplicate asset names",
t.name
);
}
}
}