pub struct Registry { /* private fields */ }Expand description
The per-runtime-instance table of type descriptors. Descriptors drive the derived operations and type-directed JSON decode; registration is used by the interpreter now and compiled code later (plan 01).
Two-phase registration (declare, then define) exists because
recursive types across definitions are legal (design §3.8): declare
every member of a cycle first, then define each against the declared
ids. register is the one-shot spelling for the common case.
Implementations§
Source§impl Registry
impl Registry
pub fn new() -> Self
pub fn bool_id(&self) -> TypeId
pub fn declare(&mut self, name: &str) -> Result<TypeId, SoilError>
pub fn define(&mut self, id: TypeId, desc: TypeDesc) -> Result<(), SoilError>
Sourcepub fn register(&mut self, desc: TypeDesc) -> Result<TypeId, SoilError>
pub fn register(&mut self, desc: TypeDesc) -> Result<TypeId, SoilError>
declare + define for the non-recursive common case. Unlike a
bare declare, a failed register leaves no trace: the declared
name is rolled back so the caller can retry with a fixed
descriptor.
pub fn get(&self, id: TypeId) -> Result<&TypeDesc, SoilError>
pub fn lookup(&self, name: &str) -> Option<TypeId>
Sourcepub fn derivable(&self, id: TypeId) -> Result<bool, SoilError>
pub fn derivable(&self, id: TypeId) -> Result<bool, SoilError>
Whether the derived operations exist for this type: false iff its
shape transitively contains a function type (“deriving eq on a
type containing an arrow is a type error”, design §3.7).
The impl plan places this check at define time; it is computed
on demand instead because a member of a type cycle can be defined
while its cycle-mates are still only declared, so the transitive
walk is not possible until the whole cycle is in. The walk is
cycle-safe and cheap at registry scale.