use concinnity_core::components::sdf_volume::SDF_PARAMS_LEN;
pub fn check(name: &str, args: &serde_json::Value) -> Result<(), String> {
check_args(args).map_err(|e| format!("Asset '{}': {}", name, e))
}
fn check_args(args: &serde_json::Value) -> Result<(), String> {
if crate::source_args::current_platform_source_arg(args).is_none() {
let platform_key = concinnity_core::platform::Platform::current().key();
return Err(format!(
"SdfVolume requires a `fragment_shader` or a `fragment_shaders` \
entry for backend \"{platform_key}\" (a path to a shader file \
declaring map + shade)"
));
}
if let Some(params) = args.get("params").and_then(|v| v.as_array())
&& params.len() > SDF_PARAMS_LEN
{
return Err(format!(
"SdfVolume `params` is {} entries; max is {} \
(extra entries would be ignored)",
params.len(),
SDF_PARAMS_LEN
));
}
Ok(())
}
#[cfg(test)]
mod tests {
use super::*;
fn platform_ext() -> &'static str {
concinnity_core::platform::Platform::current().key()
}
#[test]
fn check_requires_fragment_shader() {
let args = serde_json::json!({});
assert!(check_args(&args).is_err());
let args = serde_json::json!({"fragment_shader": ""});
assert!(check_args(&args).is_err());
let args =
serde_json::json!({"fragment_shader": format!("shaders/blob.{}", platform_ext())});
assert!(check_args(&args).is_ok());
}
#[test]
fn check_rejects_oversized_params() {
let mut params = vec![0.0; SDF_PARAMS_LEN + 1];
params[0] = 1.0;
let args = serde_json::json!({
"fragment_shader": format!("shaders/blob.{}", platform_ext()),
"params": params,
});
assert!(check_args(&args).is_err());
}
#[test]
fn check_accepts_short_params() {
let args = serde_json::json!({
"fragment_shader": format!("shaders/blob.{}", platform_ext()),
"params": [1.0, 2.0, 3.0],
});
assert!(check_args(&args).is_ok());
}
#[test]
fn check_rejects_source_for_other_backend_only() {
let other_ext = match platform_ext() {
"metal" => "hlsl",
_ => "metal",
};
let args = serde_json::json!({ "fragment_shader": format!("shaders/blob.{other_ext}") });
assert!(check_args(&args).is_err());
}
#[test]
fn check_accepts_sources_map_with_current_backend() {
let args = serde_json::json!({
"fragment_shaders": {
"metal": "shaders/blob.metal",
"hlsl": "shaders/blob.hlsl",
"glsl": "shaders/blob.glsl",
}
});
assert!(check_args(&args).is_ok());
}
#[test]
fn check_rejects_sources_map_without_current_backend() {
let other_ext = match platform_ext() {
"metal" => "hlsl",
_ => "metal",
};
let args = serde_json::json!({
"fragment_shaders": { other_ext: format!("shaders/blob.{other_ext}") }
});
assert!(check_args(&args).is_err());
}
}