use crate::deserializer::iter::Property;
impl<'a, 'b: 'a> Property<'a, 'b> {
#[must_use]
pub fn class_name(&self) -> Option<&'a str> {
match self {
Property::Object { name, .. } => Some(*name),
Property::Group(group) => match group.first()? {
Property::Object { name, .. } => Some(name),
_ => None,
},
Property::Primitive(_) => None,
}
}
}
#[cfg(test)]
mod tests {
use alloc::vec::Vec;
use crate::deserializer::foundation::test_support::load;
use crate::deserializer::iter::Property;
use crate::deserializer::typedstream::TypedStreamDeserializer;
#[test]
fn class_name_resolves_element_classes() {
let bytes = load("foundation/NSArray");
let mut ts = TypedStreamDeserializer::new(&bytes);
let root = ts.oxidize().unwrap();
let names: Vec<&str> = ts
.resolve_properties(root)
.unwrap()
.filter_map(|group| group.class_name())
.collect();
assert!(names.contains(&"NSString"), "names: {names:?}");
assert!(names.contains(&"NSNumber"), "names: {names:?}");
}
#[test]
fn class_name_on_direct_object() {
let bytes = load("foundation/NSArray");
let mut ts = TypedStreamDeserializer::new(&bytes);
let root = ts.oxidize().unwrap();
let object_names: Vec<&str> = ts
.resolve_properties(root)
.unwrap()
.filter_map(|group| match group {
Property::Group(g) => g.first(),
_ => None,
})
.filter_map(|inner| inner.class_name())
.collect();
assert!(
object_names.contains(&"NSString"),
"names: {object_names:?}"
);
}
#[test]
fn class_name_is_none_for_primitive() {
let bytes = load("foundation/NSArray");
let mut ts = TypedStreamDeserializer::new(&bytes);
let root = ts.oxidize().unwrap();
let has_primitive_group = ts
.resolve_properties(root)
.unwrap()
.any(|group| group.class_name().is_none());
assert!(has_primitive_group);
}
}