concinnity-cook 0.19.9

Authored world model, validation, and the asset cook pipeline that bakes a Concinnity world into a blob
Documentation
/// Check a `Prop`'s authored args.
pub(crate) fn check(name: &str, args: &serde_json::Value) -> Result<(), String> {
    let has_model = !args
        .get("model")
        .and_then(|v| v.as_str())
        .unwrap_or("")
        .is_empty();
    let has_mesh = !args
        .get("mesh")
        .and_then(|v| v.as_str())
        .unwrap_or("")
        .is_empty();
    let has_prefab = !args
        .get("prefab")
        .and_then(|v| v.as_str())
        .unwrap_or("")
        .is_empty();
    if has_prefab && (has_model || has_mesh) {
        return Err(format!(
            "Asset '{}': Prop with 'prefab' cannot also set 'model' or 'mesh'",
            name
        ));
    }
    if !has_model && !has_mesh && !has_prefab {
        return Err(format!(
            "Asset '{}': Prop requires either a 'prefab', 'model', or 'mesh' field",
            name
        ));
    }
    super::physics::check_collider_shape(name, args)
}

#[cfg(test)]
mod tests {
    use super::*;

    #[test]
    fn model_only_passes() {
        assert!(check("p", &serde_json::json!({ "model": "m" })).is_ok());
    }

    #[test]
    fn prefab_only_passes() {
        assert!(check("p", &serde_json::json!({ "prefab": "pf" })).is_ok());
    }

    #[test]
    fn prefab_with_model_conflicts() {
        let err = check("p", &serde_json::json!({ "prefab": "pf", "model": "m" })).unwrap_err();
        assert!(err.contains("cannot also set"), "got: {err}");
    }

    #[test]
    fn prefab_with_mesh_conflicts() {
        let err = check("p", &serde_json::json!({ "prefab": "pf", "mesh": "m" })).unwrap_err();
        assert!(err.contains("cannot also set"), "got: {err}");
    }

    #[test]
    fn missing_all_sources_is_an_error() {
        let err = check("p", &serde_json::json!({})).unwrap_err();
        assert!(err.contains("requires either"), "got: {err}");
    }

    #[test]
    fn empty_string_source_is_treated_as_absent() {
        let err = check("p", &serde_json::json!({ "model": "" })).unwrap_err();
        assert!(err.contains("requires either"), "got: {err}");
    }
}