Skip to content
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
80 changes: 71 additions & 9 deletions src/usda/parser.rs
Original file line number Diff line number Diff line change
Expand Up @@ -290,17 +290,14 @@ impl<'a> Parser<'a> {
};

let mut name_token = self.fetch_next()?;
if specifier == sdf::Specifier::Def || specifier == sdf::Specifier::Class {
if let Some(prim_type) = name_token.clone().try_as_identifier() {
spec.add(FieldKey::TypeName, sdf::Value::Token(prim_type.to_string()));
name_token = self.fetch_next()?;
}
if let Token::Identifier(prim_type) = name_token {
spec.add(FieldKey::TypeName, sdf::Value::Token(prim_type.to_string()));
name_token = self.fetch_next()?;
}

let name = name_token
.clone()
.try_as_string()
.ok_or_else(|| anyhow!("Unexpected token {name_token:?} (want String)"))?;
let Token::String(name) = name_token else {
bail!("Expected prim name string, got {name_token:?}");
};
parent_children.push(name.to_string());
let prim_path = current_path.append_path(name)?;

Expand Down Expand Up @@ -795,6 +792,11 @@ impl<'a> Parser<'a> {
let value = self.parse_bool().context("Unable to parse instanceable flag")?;
spec.add(FieldKey::Instanceable, sdf::Value::Bool(value));
}
"displayName" => {
ensure!(list_op.is_none(), "displayName does not support list ops");
let value = self.fetch_str().context("Unable to parse displayName")?;
spec.add("displayName", sdf::Value::String(value.to_owned()));
}
other => bail!("Unsupported prim metadata: {other}"),
}

Expand Down Expand Up @@ -2569,4 +2571,64 @@ def Scope "Root" {
);
assert_eq!(spec.fields.get("default"), Some(&sdf::Value::IntVec(vec![5, 6, 7])));
}

/// `over` with a type name should parse the type and prim name.
#[test]
fn parse_over_with_type_name() {
let mut parser = Parser::new(
r#"
#usda 1.0

over MfScope "TestOver"
{
}
"#,
);
let data = parser.parse().unwrap();
let path = sdf::path("/TestOver").unwrap();
let spec = data.get(&path).expect("TestOver not found");
assert_eq!(
spec.fields.get(FieldKey::Specifier.as_str()),
Some(&sdf::Value::Specifier(sdf::Specifier::Over))
);
assert_eq!(
spec.fields.get(FieldKey::TypeName.as_str()),
Some(&sdf::Value::Token("MfScope".into()))
);
}

/// Prim metadata `displayName` should be parsed as a string.
#[test]
fn parse_prim_display_name() {
let mut parser = Parser::new(
r#"
#usda 1.0

def Scope "Root" (
displayName = "My Root"
)
{
}
"#,
);
let data = parser.parse().unwrap();
let path = sdf::path("/Root").unwrap();
let spec = data.get(&path).unwrap();
assert_eq!(
spec.fields.get("displayName"),
Some(&sdf::Value::String("My Root".into()))
);
}

#[test]
fn parse_prim_display_name_utf8() {
let input = "#usda 1.0\ndef Scope \"R\" (\n displayName = \"\u{1F680}\"\n)\n{\n}\n";
let mut parser = Parser::new(input);
let data = parser.parse().unwrap();
let spec = data.get(&sdf::path("/R").unwrap()).unwrap();
assert_eq!(
spec.fields.get("displayName"),
Some(&sdf::Value::String("\u{1F680}".into()))
);
}
}