Module: Jade::Codegen::Boundary::Specialized
- Extended by:
- Specialized
- Included in:
- Specialized
- Defined in:
- lib/jade/codegen/boundary/specialized.rb,
lib/jade/codegen/boundary/specialized/list.rb,
lib/jade/codegen/boundary/specialized/maybe.rb,
lib/jade/codegen/boundary/specialized/record.rb,
lib/jade/codegen/boundary/specialized/scalar.rb
Overview
Emits inline boundary code for known-shape types — scalars,
List(specializable), Maybe(specializable), and structs whose
fields are all specializable. Bypasses Decode::Runner and the
descriptor cache.
This module is the dispatcher: each shape (Scalar, List,
Maybe, Record) lives in its own file under specialized/,
exposing decode / encode / specializable? methods that the
dispatcher tries in order. Shapes that contain other types
(List, Maybe, Record) recurse back through the dispatcher.
Defined Under Namespace
Modules: List, Maybe, Record, Scalar
Instance Method Summary collapse
- #args_of(type) ⇒ Object
- #collect_helpers(body, registry) ⇒ Object
-
#decode_expr(type, input, registry) ⇒ Object
Ruby expression that validates
inputand yields the decoded value, orniliftypeisn't specializable. - #emit_helpers(structs, registry) ⇒ Object
-
#encode_expr(type, value_expr, registry) ⇒ Object
How to encode
value_exprto the wire form:. -
#identity_encoder?(type) ⇒ Boolean
True when the encoder for
typeproduces output equal to the input — the boundary wrapper can skip the encode call entirely. -
#qname_of(type) ⇒ Object
Both
Type::Application(from inferred boundary types) andSymbol::TypeApplication(from struct field declarations) carry the same constructor/args shape; normalize to a qname string. -
#specializable_field?(type, registry, seen) ⇒ Boolean
Predicate used by
Record.specializable_structwhen checking field types. -
#type_label(type) ⇒ Object
Human-readable label for error messages on container types.
Instance Method Details
#args_of(type) ⇒ Object
87 88 89 90 91 92 93 |
# File 'lib/jade/codegen/boundary/specialized.rb', line 87 def args_of(type) case type in Type::Application(args:) then args in Symbol::TypeApplication(args:) then args else nil end end |
#collect_helpers(body, registry) ⇒ Object
61 62 63 |
# File 'lib/jade/codegen/boundary/specialized.rb', line 61 def collect_helpers(body, registry) Record.collect_helpers(body, registry) end |
#decode_expr(type, input, registry) ⇒ Object
Ruby expression that validates input and yields the decoded
value, or nil if type isn't specializable.
24 25 26 27 28 29 |
# File 'lib/jade/codegen/boundary/specialized.rb', line 24 def decode_expr(type, input, registry) Scalar.decode(type, input) || List.decode(type, input, registry) || Maybe.decode(type, input, registry) || Record.decode(type, input, registry) end |
#emit_helpers(structs, registry) ⇒ Object
65 66 67 |
# File 'lib/jade/codegen/boundary/specialized.rb', line 65 def emit_helpers(structs, registry) Record.emit_helpers(structs, registry) end |
#encode_expr(type, value_expr, registry) ⇒ Object
How to encode value_expr to the wire form:
String inline expression
:identity the value is already wire-shaped; emit it unchanged
nil not specializable; fall back to the cached encoder
36 37 38 39 40 41 42 |
# File 'lib/jade/codegen/boundary/specialized.rb', line 36 def encode_expr(type, value_expr, registry) return :identity if identity_encoder?(type) Record.encode(type, value_expr, registry) || List.encode(type, value_expr, registry) || Maybe.encode(type, value_expr, registry) end |
#identity_encoder?(type) ⇒ Boolean
True when the encoder for type produces output equal to the
input — the boundary wrapper can skip the encode call entirely.
Recursive: List(t) is identity iff t is.
47 48 49 |
# File 'lib/jade/codegen/boundary/specialized.rb', line 47 def identity_encoder?(type) Scalar.identity_encoder?(type) || List.identity_encoder?(type) end |
#qname_of(type) ⇒ Object
Both Type::Application (from inferred boundary types) and
Symbol::TypeApplication (from struct field declarations) carry
the same constructor/args shape; normalize to a qname string.
74 75 76 77 78 79 80 81 82 83 84 85 |
# File 'lib/jade/codegen/boundary/specialized.rb', line 74 def qname_of(type) case type in Type::Application(constructor: Type::Constructor(name:)) name in Symbol::TypeApplication(constructor: Symbol::TypeRef(module_name:, name: n)) "#{module_name}.#{n}" else nil end end |
#specializable_field?(type, registry, seen) ⇒ Boolean
Predicate used by Record.specializable_struct when checking
field types. The seen set carries struct qnames we're already
inside, threaded through container shapes for cycle detection.
54 55 56 57 58 59 |
# File 'lib/jade/codegen/boundary/specialized.rb', line 54 def specializable_field?(type, registry, seen) Scalar.specializable?(type, registry, seen) || List.specializable?(type, registry, seen) || Maybe.specializable?(type, registry, seen) || Record.specializable?(type, registry, seen) end |
#type_label(type) ⇒ Object
Human-readable label for error messages on container types.
96 97 98 99 100 101 102 103 104 105 106 |
# File 'lib/jade/codegen/boundary/specialized.rb', line 96 def type_label(type) if (qname = Scalar.qname_for(type)) Scalar::LABEL[qname] elsif (inner = List.inner_of(type)) "List(#{type_label(inner)})" elsif (inner = Maybe.inner_of(type)) "Maybe(#{type_label(inner)})" else (qname_of(type) || 'value').split('.').last end end |