pub mod binding;
pub mod book;
pub mod content;
pub mod def;
pub mod manifest;
pub mod material;
pub mod recipe;
pub mod sound;
pub mod tags;
pub mod texture;
pub mod yres;
pub mod yui;
use yog_data::Diagnostic;
use yog_data::{Schema, Shape, Value};
use yog_ids::{Format, file};
macro_rules! with_type {
($format:expr, $t:ident => $body:expr, else $none:expr) => {
match $format {
Format::Block => {
type $t = content::BlockFile;
$body
}
Format::Item => {
type $t = content::ItemFile;
$body
}
Format::Entity => {
type $t = yog_registry::EntityDef;
$body
}
Format::Recipe => {
type $t = recipe::RecipeFile;
$body
}
Format::Sound => {
type $t = sound::SoundFile;
$body
}
Format::Book => {
type $t = book::Book;
$body
}
Format::Def => {
type $t = def::Def;
$body
}
Format::Res => {
type $t = yres::YresFile;
$body
}
Format::Model => {
type $t = yog_body::format::ModelFile;
$body
}
Format::Anim => {
type $t = yog_body::format::AnimFile;
$body
}
Format::Font => {
type $t = yog_font::Font;
$body
}
Format::Texture => {
type $t = texture::TextureFile;
$body
}
Format::Material => {
type $t = material::MaterialFile;
$body
}
Format::Ui | Format::Data | Format::Mod | Format::Script | Format::Nanites => $none,
}
};
}
#[must_use]
pub fn shape(format: Format) -> Option<Shape> {
with_type!(format, T => Some(T::shape()), else None)
}
#[must_use]
pub fn problems(format: Format, value: &Value) -> Vec<Diagnostic> {
with_type!(format, T => yog_data::from_value::<T>(value).err().unwrap_or_default(), else Vec::new())
}
#[must_use]
pub fn shape_of(name: &str) -> Option<Shape> {
if name == file::MANIFEST {
return Some(manifest::ManifestFile::shape());
}
shape(Format::of(name)?)
}
pub fn names() -> impl Iterator<Item = &'static str> {
Format::ALL
.iter()
.filter(|f| shape(**f).is_some())
.map(|f| f.ext())
.chain([file::MANIFEST])
}
#[cfg(test)]
mod tests {
#[test]
fn every_format_describes_itself() {
for name in super::names() {
let d = super::shape_of(name).unwrap().describe();
assert!(d.get("root").is_some(), "{name}");
}
}
}