use crate::Result;
use super::ModelAPI;
#[derive(Debug, Clone, Copy, Default, PartialEq, Eq)]
pub enum KindValidation {
None,
#[default]
ModelHierarchy,
}
impl ModelAPI {
pub fn is_kind(&self, base: &str, validation: KindValidation) -> Result<bool> {
let kinds = self.stage().schema_registry().kinds();
if !self.kind()?.is_some_and(|kind| kinds.is_a(&kind, base)) {
return Ok(false);
}
Ok(validation == KindValidation::None || !kinds.is_model(base) || self.is_model()?)
}
}
#[cfg(test)]
mod tests {
use super::*;
use crate::kind;
use crate::usd::{SchemaFamily, SchemaRegistry, Stage};
use KindValidation::{ModelHierarchy, None as Unvalidated};
fn model(stage: &Stage, path: &str) -> Result<ModelAPI> {
Ok(ModelAPI::from_prim_unchecked(stage.prim(path)?))
}
#[test]
fn is_kind_validation() -> Result<()> {
let stage = Stage::builder().in_memory("model.usda")?;
stage.define_prim("/Parent")?;
stage.define_prim("/Parent/Child")?.set_kind("component")?;
let child = model(&stage, "/Parent/Child")?;
assert!(!child.is_model()?);
assert!(!child.is_kind("component", ModelHierarchy)?);
assert!(!child.is_kind("model", ModelHierarchy)?);
assert!(child.is_kind("component", Unvalidated)?);
assert!(child.is_kind("model", Unvalidated)?);
stage.prim("/Parent")?.set_kind("assembly")?;
assert!(child.is_model()?);
assert!(child.is_kind("component", ModelHierarchy)?);
assert!(child.is_kind("model", ModelHierarchy)?);
let parent = model(&stage, "/Parent")?;
assert!(parent.is_kind("group", ModelHierarchy)?);
assert!(!parent.is_kind("component", Unvalidated)?);
stage.define_prim("/Parent/Child/Inner")?.set_kind("component")?;
let inner = model(&stage, "/Parent/Child/Inner")?;
assert!(!inner.is_model()?);
assert!(!inner.is_kind("component", ModelHierarchy)?);
assert!(inner.is_kind("component", Unvalidated)?);
stage.define_prim("/Parent/Child/Part")?.set_kind("subcomponent")?;
let part = model(&stage, "/Parent/Child/Part")?;
assert!(!part.is_model()?);
assert!(part.is_kind("subcomponent", ModelHierarchy)?);
assert!(part.is_kind("subcomponent", Unvalidated)?);
assert!(!part.is_kind("model", Unvalidated)?);
let bare = model(&stage, "/Parent/Child/Bare")?;
assert!(!bare.is_kind("model", Unvalidated)?);
Ok(())
}
#[test]
fn is_kind_declared() -> Result<()> {
static SITE: &SchemaFamily<'_> = &SchemaFamily::new("site", &[]).kinds(kind::tests::SITE);
let stage = Stage::builder()
.schema_registry(SchemaRegistry::builder().register(SITE).build()?)
.in_memory("declared.usda")?;
stage.define_prim("/Show")?.set_kind("chargroup")?;
stage.define_prim("/Show/Hero")?.set_kind("prop")?;
stage.define_prim("/Loose")?;
stage.define_prim("/Loose/Hero")?.set_kind("prop")?;
let show = model(&stage, "/Show")?;
assert!(show.is_kind("assembly", ModelHierarchy)? && show.is_kind("group", ModelHierarchy)?);
assert!(show.is_kind("chargroup", ModelHierarchy)?);
let hero = model(&stage, "/Show/Hero")?;
assert!(hero.is_kind("component", ModelHierarchy)? && hero.is_kind("prop", ModelHierarchy)?);
assert!(!hero.is_kind("chargroup", Unvalidated)?);
let loose = model(&stage, "/Loose/Hero")?;
assert!(!loose.is_kind("prop", ModelHierarchy)?);
assert!(loose.is_kind("prop", Unvalidated)?);
Ok(())
}
}