pub struct SchemaGraph { /* private fields */ }Expand description
Case-insensitive lookup over a parsed schema’s declarations.
EXPRESS identifiers are case-insensitive, and Part 21 records conventionally
spell entity names in upper case (MYENTITY) while schema sources spell
them in mixed case (MyEntity). Every lookup here folds case so callers can
pass whichever spelling they hold.
Implementations§
Source§impl SchemaGraph
impl SchemaGraph
Sourcepub fn resolve_complex(&self, names: &[&str]) -> ComplexLayout<'_>
pub fn resolve_complex(&self, names: &[&str]) -> ComplexLayout<'_>
Resolves a complex entity instance’s partial records against this schema (ISO 10303-21:2016 §12.2.5.3, the external mapping).
names are the partial record names in the order the instance
writes them, e.g. ["BOUNDED_CURVE", "B_SPLINE_CURVE", ...]. Matching
is case-insensitive. Each resolved part’s slots are the explicit
attributes its entity itself declares – compare them with the
partial record’s parameters one to one.
Never fails: unknown, repeated, misordered or missing types are
reported through ComplexLayout::issues and every part that could
be resolved still is.
Source§impl SchemaGraph
impl SchemaGraph
Sourcepub fn new(parsed: ParsedSchema) -> Self
pub fn new(parsed: ParsedSchema) -> Self
Indexes a parsed schema for querying.
Sourcepub fn from_express(source: &str) -> Self
pub fn from_express(source: &str) -> Self
Parses EXPRESS source and indexes it in one step.
Sourcepub fn entity_count(&self) -> usize
pub fn entity_count(&self) -> usize
How many entity declarations the schema holds.
Sourcepub fn type_count(&self) -> usize
pub fn type_count(&self) -> usize
How many type declarations the schema holds.
Sourcepub fn entity(&self, name: &str) -> Option<&EntityDef>
pub fn entity(&self, name: &str) -> Option<&EntityDef>
The entity declaration for name, if the schema declares one.
Sourcepub fn type_def(&self, name: &str) -> Option<&TypeDef>
pub fn type_def(&self, name: &str) -> Option<&TypeDef>
The type declaration for name, if the schema declares one.
Sourcepub fn entity_names(&self) -> impl Iterator<Item = &str>
pub fn entity_names(&self) -> impl Iterator<Item = &str>
Every entity name the schema declares, in unspecified order.
Callers needing determinism must sort: the underlying map order is deliberately not promised.
Sourcepub fn is_a(&self, name: &str, ancestor: &str) -> bool
pub fn is_a(&self, name: &str, ancestor: &str) -> bool
Whether name is ancestor, or inherits from it.
Reflexive for declared entities, matching EXPRESS subtype semantics where a type belongs to its own subtype set. An entity the schema never declares is not a subtype of anything, including itself – otherwise a typo would silently satisfy every check made against it.
Sourcepub fn direct_supertypes(&self, name: &str) -> Vec<&str>
pub fn direct_supertypes(&self, name: &str) -> Vec<&str>
The direct supertypes of name, in SUBTYPE OF order.
Empty for a root entity and for an entity the schema never declares.
Sourcepub fn supertypes(&self, name: &str) -> Vec<&str>
pub fn supertypes(&self, name: &str) -> Vec<&str>
Every ancestor of name, each once.
Depth-first in SUBTYPE OF order: a parent, then that parent’s own
ancestors, then the next parent. For single inheritance this is the
chain nearest parent first. Excludes name itself.
A supertype the schema names but never declares is still reported –
a consumer checking is_a against a partial schema should see the
declared relationship – but cannot be walked past. Terminates on a
malformed cyclic schema: each entity is visited once, and the walk is
bounded in depth.
Sourcepub fn direct_subtypes(&self, name: &str) -> Vec<&str>
pub fn direct_subtypes(&self, name: &str) -> Vec<&str>
Entities declaring SUBTYPE OF (name) directly, sorted by name.
Excludes name itself. Names a supertype the schema never declares
the same way Self::supertypes does: if A SUBTYPE OF (Missing),
then direct_subtypes("Missing") is ["A"], keeping the two
directions consistent on a partial schema.
Sourcepub fn subtypes(&self, name: &str) -> Vec<&str>
pub fn subtypes(&self, name: &str) -> Vec<&str>
Every entity that inherits from name, at any depth.
The downward counterpart of Self::supertypes: excludes name
itself, and y is in subtypes(x) exactly when is_a(y, x) holds
for y != x. Order is a depth-first pre-order with siblings sorted by
name, so the result is deterministic across runs and platforms.
Terminates on a malformed cyclic schema: each entity is visited once.
Sourcepub fn attributes(&self, name: &str) -> Vec<&Attribute>
pub fn attributes(&self, name: &str) -> Vec<&Attribute>
Every attribute slot in Part 21 positional order, inherited first.
See the module documentation for why this ordering is load-bearing.
ISO 10303-21:2016 §12.2.5.2: each supertype is laid out in
SUBTYPE OF order, its own supertypes first, and a supertype reached
a second time (the diamond of multiple inheritance) contributes
nothing more – “all references after the first one shall be ignored”.
Derived redeclarations are included: they keep their inherited
position and are written * in a Part 21 record. Use
EntityDef::is_derived on the owning entity to tell them apart.
Explicit redeclarations (SELF\X.a : T;) add no slot (§12.2.8); the
parser keeps them out of EntityDef::attributes.
Sourcepub fn attribute_names(&self, name: &str) -> Vec<&str>
pub fn attribute_names(&self, name: &str) -> Vec<&str>
Attribute names in positional order.
The bridge a positional-to-named mapping needs: slot i is called
names[i].
Sourcepub fn resolve_defined(&self, name: &str) -> String
pub fn resolve_defined(&self, name: &str) -> String
Resolves a defined type to the base it ultimately aliases.
A chain such as PositiveCount -> Count -> INTEGER resolves to
INTEGER. Returns the final right-hand side; for a declaration that is
not an alias, that is the type’s own name. Bounded like the supertype
walk so a cyclic alias cannot hang.
The right-hand side is returned verbatim, including any aggregate
syntax (LIST [1:?] OF X): discarding it here would throw away the
aggregate fact entirely, and callers that want the base scalar can
match on the text they receive.