Class: Lutaml::Model::TypeResolver Private
- Inherits:
-
Object
- Object
- Lutaml::Model::TypeResolver
- Defined in:
- lib/lutaml/model/type_resolver.rb
Overview
This class is part of a private API. You should avoid using this class if possible, as it may be removed or be changed in the future.
TypeResolver performs stateless type resolution.
This is an INTERNAL class. Users should use Register and GlobalRegister.
Responsibility: Resolve type names to classes using pure logic
This class:
- Is STATELESS - no instance variables, all methods are class methods
- Contains the single place for type resolution algorithm
- Resolution chain: primary registry → substitutions → fallback contexts
- NO caching, NO global state access
- Easy to test in isolation
Class Method Summary collapse
-
.apply_substitutions(type, context) ⇒ Class
private
Apply substitutions to a resolved type.
-
.available_type_names(context) ⇒ Array<Symbol>
private
Get all available type names from context and fallbacks.
-
.resolvable?(name, context) ⇒ Boolean
private
Check if a type can be resolved without raising an exception.
-
.resolve(name, context, materialize: true) ⇒ Class
private
Resolve a type name to a class using the given context.
-
.resolve_from_fallback(type_name, fallback_context) ⇒ Class?
private
Resolve from a fallback context (recursive).
-
.resolve_or_nil(name, context) ⇒ Class?
private
Try to resolve a type, returning nil if not found.
Class Method Details
.apply_substitutions(type, context) ⇒ Class
This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.
Apply substitutions to a resolved type.
162 163 164 165 166 |
# File 'lib/lutaml/model/type_resolver.rb', line 162 def self.apply_substitutions(type, context) return type if context.nil? || context.substitutions.empty? context.substitution_hash[type] || type end |
.available_type_names(context) ⇒ Array<Symbol>
This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.
Get all available type names from context and fallbacks.
172 173 174 175 176 177 178 179 180 181 182 |
# File 'lib/lutaml/model/type_resolver.rb', line 172 def self.available_type_names(context) names = context.registry.names.dup if context.has_fallbacks? context.fallback_contexts.each do |fallback| names.concat(fallback.registry.names) end end names.uniq.sort end |
.resolvable?(name, context) ⇒ Boolean
This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.
Check if a type can be resolved without raising an exception.
114 115 116 117 118 119 |
# File 'lib/lutaml/model/type_resolver.rb', line 114 def self.resolvable?(name, context) resolve(name, context) true rescue UnknownTypeError false end |
.resolve(name, context, materialize: true) ⇒ Class
This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.
Resolve a type name to a class using the given context.
Resolution order:
- If name is already a Class, return it (pass-through)
- Check primary registry
- Check substitutions (apply if matching)
- Check fallback contexts in order
- Raise UnknownTypeError if not found anywhere
materialize: false resolves only what the registries know without const_get — definition-time validation must not fire autoloads (a pending autoload re-enters the model file being defined and re-evaluates its mapping on the populated state).
58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 |
# File 'lib/lutaml/model/type_resolver.rb', line 58 def self.resolve(name, context, materialize: true) # Apply substitutions even if already a class # This is important for type substitution (e.g., Glaze -> RegisterGlaze) if name.is_a?(Class) return apply_substitutions(name, context) end # Normalize name to symbol type_name = name.to_sym # 1. Check primary registry type = context.lookup_local(type_name) return apply_substitutions(type, context) if type # 2. Check fallback contexts in order if context.has_fallbacks? context.fallback_contexts.each do |fallback_context| type = resolve_from_fallback(type_name, fallback_context) return apply_substitutions(type, context) if type end end # 3. Fall back to legacy Type module's internal registry # This maintains backward compatibility with Type.register() type = Type.lookup_ignoring_fallback(type_name) return apply_substitutions(type, context) if type # 4. Try Type.const_get for CamelCase type names (e.g., "Decimal" -> Type::Decimal) # This maintains backward compatibility with old Register behavior. # Skipped for non-materializing resolution: const_get fires autoloads. if materialize && name.is_a?(String) begin type = Lutaml::Model::Type.const_get(name) return apply_substitutions(type, context) if type rescue NameError # Not a constant in Type module, continue to error end end # 5. Type not found - raise error raise UnknownTypeError.new( type_name, context_id: context.id, available_types: available_type_names(context), ) end |
.resolve_from_fallback(type_name, fallback_context) ⇒ Class?
This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.
Resolve from a fallback context (recursive).
141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 |
# File 'lib/lutaml/model/type_resolver.rb', line 141 def self.resolve_from_fallback(type_name, fallback_context) # Check the fallback's local registry type = fallback_context.lookup_local(type_name) return type if type # Recursively check fallback's fallbacks if fallback_context.has_fallbacks? fallback_context.fallback_contexts.each do |nested_fallback| type = resolve_from_fallback(type_name, nested_fallback) return type if type end end nil end |
.resolve_or_nil(name, context) ⇒ Class?
This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.
Try to resolve a type, returning nil if not found.
130 131 132 133 134 |
# File 'lib/lutaml/model/type_resolver.rb', line 130 def self.resolve_or_nil(name, context) resolve(name, context) rescue UnknownTypeError nil end |