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 ‘input` and yields the decoded value, or `nil` if `type` isn’t specializable.
- #emit_helpers(structs, registry) ⇒ Object
-
#encode_expr(type, value_expr, registry) ⇒ Object
Ruby expression that encodes ‘value_expr` to the wire form, or `nil` if the encoder is identity (caller skips the wrap) or the type isn’t specializable (caller falls back to the cache).
-
#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.
-
#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.
-
#specializable_field?(type, registry, seen) ⇒ Boolean
Predicate used by ‘Record.specializable_struct` when checking field types.
-
#type_label(type) ⇒ Object
Human-readable label for error messages on container types.
Instance Method Details
#args_of(type) ⇒ Object
83 84 85 86 87 88 89 |
# File 'lib/jade/codegen/boundary/specialized.rb', line 83 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
57 58 59 |
# File 'lib/jade/codegen/boundary/specialized.rb', line 57 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
61 62 63 |
# File 'lib/jade/codegen/boundary/specialized.rb', line 61 def emit_helpers(structs, registry) Record.emit_helpers(structs, registry) end |
#encode_expr(type, value_expr, registry) ⇒ Object
Ruby expression that encodes ‘value_expr` to the wire form, or `nil` if the encoder is identity (caller skips the wrap) or the type isn’t specializable (caller falls back to the cache).
34 35 36 37 38 |
# File 'lib/jade/codegen/boundary/specialized.rb', line 34 def encode_expr(type, value_expr, registry) 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.
43 44 45 |
# File 'lib/jade/codegen/boundary/specialized.rb', line 43 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.
70 71 72 73 74 75 76 77 78 79 80 81 |
# File 'lib/jade/codegen/boundary/specialized.rb', line 70 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.
50 51 52 53 54 55 |
# File 'lib/jade/codegen/boundary/specialized.rb', line 50 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.
92 93 94 95 96 97 98 99 100 101 102 |
# File 'lib/jade/codegen/boundary/specialized.rb', line 92 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 |