Skip to content

Commit 8de96a4

Browse files
committed
move PropertyDescriptors logic to constructor
1 parent 5d67bb0 commit 8de96a4

File tree

1 file changed

+74
-82
lines changed

1 file changed

+74
-82
lines changed

rbx_binary/src/core.rs

Lines changed: 74 additions & 82 deletions
Original file line numberDiff line numberDiff line change
@@ -342,99 +342,91 @@ pub struct PropertyDescriptors<'db> {
342342
pub serialized: Option<&'db PropertyDescriptor<'db>>,
343343
}
344344

345-
/// Find both the canonical and serialized property descriptors for a given
346-
/// class and property name pair. These might be the same descriptor!
347-
pub fn find_property_descriptors<'db>(
348-
database: &'db ReflectionDatabase<'db>,
349-
class_name: Ustr,
350-
property_name: Ustr,
351-
) -> Option<PropertyDescriptors<'db>> {
352-
let mut class_descriptor = database.classes.get(class_name.as_str())?;
345+
impl<'db> PropertyDescriptors<'db> {
346+
/// Get both the canonical and serialized property descriptors for a given
347+
/// class and property descriptor. The canonical and serialized descriptors
348+
/// might be the same descriptor!
349+
pub fn new(
350+
class_descriptor: &'db ClassDescriptor<'db>,
351+
property_descriptor: &'db PropertyDescriptor<'db>,
352+
) -> Option<PropertyDescriptors<'db>> {
353+
match &property_descriptor.kind {
354+
// This property descriptor is the canonical form of this
355+
// logical property.
356+
PropertyKind::Canonical { serialization } => {
357+
let serialized = find_serialized_from_canonical(
358+
class_descriptor,
359+
property_descriptor,
360+
serialization,
361+
);
362+
363+
Some(PropertyDescriptors {
364+
canonical: property_descriptor,
365+
serialized,
366+
})
367+
}
353368

354-
// We need to find the canonical property descriptor associated with
355-
// the property we're working with.
356-
//
357-
// At each step of the loop, we're checking a new class descriptor to see if
358-
// it has an entry for the property name we're looking for. If that class
359-
// doesn't have the property, we'll check its superclass until we reach the
360-
// root.
361-
loop {
362-
// If this class descriptor knows about this property name, we're pretty
363-
// much done!
364-
if let Some(property_descriptor) = class_descriptor.properties.get(property_name.as_str()) {
365-
match &property_descriptor.kind {
366-
// This property descriptor is the canonical form of this
367-
// logical property. That means we've found one of the two
368-
// descriptors we're looking for!
369-
PropertyKind::Canonical { serialization } => {
370-
let serialized = find_serialized_from_canonical(
371-
class_descriptor,
372-
property_descriptor,
373-
serialization,
374-
);
369+
// This descriptor is an alias for another property. While this
370+
// descriptor might be one of the two descriptors we need to
371+
// return, it's possible that both the canonical and serialized
372+
// forms are different.
373+
PropertyKind::Alias { alias_for } => {
374+
let canonical = class_descriptor.properties.get(alias_for.as_ref()).unwrap();
375+
376+
if let PropertyKind::Canonical { serialization } = &canonical.kind {
377+
let serialized =
378+
find_serialized_from_canonical(class_descriptor, canonical, serialization);
375379

376-
return Some(PropertyDescriptors {
377-
canonical: property_descriptor,
380+
Some(PropertyDescriptors {
381+
canonical,
378382
serialized,
379-
});
380-
}
383+
})
384+
} else {
385+
// If one property in the database calls itself an alias
386+
// of another property, that property must be canonical.
387+
log::error!(
388+
"Property {}.{} is marked as an alias for {}.{}, but the latter is not canonical.",
389+
class_descriptor.name,
390+
property_descriptor.name,
391+
class_descriptor.name,
392+
alias_for
393+
);
381394

382-
// This descriptor is an alias for another property. While this
383-
// descriptor might be one of the two descriptors we need to
384-
// return, it's possible that both the canonical and serialized
385-
// forms are different.
386-
PropertyKind::Alias { alias_for } => {
387-
let canonical = class_descriptor.properties.get(alias_for.as_ref()).unwrap();
388-
389-
if let PropertyKind::Canonical { serialization } = &canonical.kind {
390-
let serialized = find_serialized_from_canonical(
391-
class_descriptor,
392-
canonical,
393-
serialization,
394-
);
395-
396-
return Some(PropertyDescriptors {
397-
canonical,
398-
serialized,
399-
});
400-
} else {
401-
// If one property in the database calls itself an alias
402-
// of another property, that property must be canonical.
403-
log::error!(
404-
"Property {}.{} is marked as an alias for {}.{}, but the latter is not canonical.",
405-
class_descriptor.name,
406-
property_descriptor.name,
407-
class_descriptor.name,
408-
alias_for
409-
);
410-
411-
return None;
412-
}
395+
None
413396
}
414-
415-
// This descriptor is of an unknown kind and we don't know how
416-
// to deal with it -- maybe rbx_binary is out of date?
417-
_ => return None,
418397
}
419-
}
420-
421-
if let Some(superclass_name) = &class_descriptor.superclass {
422-
// If a property descriptor isn't found in our class, check our
423-
// superclass.
424398

425-
class_descriptor = database
426-
.classes
427-
.get(superclass_name)
428-
.expect("Superclass in reflection database didn't exist");
429-
} else {
430-
// This property isn't known by any class in the reflection
431-
// database.
432-
433-
return None;
399+
// This descriptor is of an unknown kind and we don't know how
400+
// to deal with it -- maybe rbx_binary is out of date?
401+
_ => None,
434402
}
435403
}
436404
}
437405

406+
/// Find both the canonical and serialized property descriptors for a given
407+
/// class and property name pair. These might be the same descriptor!
408+
pub fn find_property_descriptors<'db>(
409+
database: &'db ReflectionDatabase<'db>,
410+
class_name: Ustr,
411+
property_name: Ustr,
412+
) -> Option<PropertyDescriptors<'db>> {
413+
let class_descriptor = database.classes.get(class_name.as_str())?;
414+
415+
// We need to find the canonical property descriptor associated with
416+
// the property we're working with. Walk superclasses and
417+
// find a class descriptor which knows about this property name.
418+
let (class, prop) = database
419+
.superclasses_iter(class_descriptor)
420+
.find_map(|class| {
421+
let prop = class.properties.get(property_name.as_str())?;
422+
Some((class, prop))
423+
})?;
424+
425+
// Extract the canonical and serialized property descriptors
426+
// from the class and property descriptors
427+
PropertyDescriptors::new(class, prop)
428+
}
429+
438430
/// Given the canonical property descriptor for a logical property along with
439431
/// its serialization, returns the serialized form of the logical property if
440432
/// this property is serializable.

0 commit comments

Comments
 (0)