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

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.

Returns:

  • (Boolean)


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.

Returns:

  • (Boolean)


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