Skip to main content

tsz_checker/types/
object_type.rs

1//! Object Type Utilities Module
2//!
3//! Thin wrappers for object type queries, delegating to solver via `query_boundaries`.
4
5use crate::query_boundaries::class_type::object_shape_for_type;
6use crate::state::CheckerState;
7use tsz_solver::TypeId;
8
9impl<'a> CheckerState<'a> {
10    /// Get the type of a property by name.
11    ///
12    /// Returns the property type if found, or None otherwise.
13    pub fn get_object_property_type(
14        &self,
15        object_type: TypeId,
16        property_name: &str,
17    ) -> Option<TypeId> {
18        let shape = object_shape_for_type(self.ctx.types, object_type)?;
19        let name_atom = self.ctx.types.intern_string(property_name);
20        shape
21            .properties
22            .iter()
23            .find(|prop| prop.name == name_atom)
24            .map(|prop| prop.type_id)
25    }
26
27    /// Check if an object has a specific property.
28    ///
29    /// Returns true if the property exists on the object.
30    pub fn object_has_property(&self, object_type: TypeId, property_name: &str) -> bool {
31        self.get_object_property_type(object_type, property_name)
32            .is_some()
33    }
34
35    /// Check if a property is optional.
36    ///
37    /// Returns true if the property is marked as optional.
38    pub fn is_property_optional(&self, object_type: TypeId, property_name: &str) -> bool {
39        if let Some(shape) = object_shape_for_type(self.ctx.types, object_type) {
40            let name_atom = self.ctx.types.intern_string(property_name);
41            shape
42                .properties
43                .iter()
44                .find(|prop| prop.name == name_atom)
45                .is_some_and(|prop| prop.optional)
46        } else {
47            false
48        }
49    }
50}