Module: Jade::Interop::Boundary

Extended by:
Boundary
Included in:
Boundary
Defined in:
lib/jade/interop/boundary.rb

Instance Method Summary collapse

Instance Method Details

#array(label, v) ⇒ Object

Validates that v is an Array but doesn't check element types — used when the per-element decoder isn't a simple is_a? (e.g. nested structs). The caller maps a decoder over the result.



47
48
49
# File 'lib/jade/interop/boundary.rb', line 47

def array(label, v)
  v.is_a?(::Array) ? v : type_error!(label, v)
end

#bool(label, v) ⇒ Object



32
33
34
# File 'lib/jade/interop/boundary.rb', line 32

def bool(label, v)
  v == true || v == false ? v : type_error!(label, v)
end

#decode_or_raise(decoder, value) ⇒ Object

Boundary-side decode: succeed → return the value, fail → raise. The Result wrap/unwrap that user-level Decode.from_value uses is dead weight at the boundary because failure always raises anyway. Skipping it removes one allocation per arg per Ruby→Jade call.



14
15
16
17
18
# File 'lib/jade/interop/boundary.rb', line 14

def decode_or_raise(decoder, value)
  Jade::Decode::Runner.run!(decoder, value) do |error|
    raise Jade::Interop::DecodeError.new(error, value)
  end
end

#float(label, v) ⇒ Object



36
37
38
# File 'lib/jade/interop/boundary.rb', line 36

def float(label, v)
  ::Numeric === v ? v.to_f : type_error!(label, v)
end

#hash(label, v) ⇒ Object



51
52
53
54
55
56
57
# File 'lib/jade/interop/boundary.rb', line 51

def hash(label, v)
  case v
  when ::Hash then string_keyed!(label, v)
  when ::Data then v.to_h.transform_keys(&:to_s)
  else type_error!(label, v)
  end
end

#integer(label, v) ⇒ Object

Specialized fast-path validators. Emitted by codegen for known-shape argument types in place of the generic decode_or_raise path — avoids constructing a Decoder descriptor and walking the interpreter for primitives.



24
25
26
# File 'lib/jade/interop/boundary.rb', line 24

def integer(label, v)
  ::Integer === v ? v : type_error!(label, v)
end

#list_of(klass, label, v) ⇒ Object



40
41
42
# File 'lib/jade/interop/boundary.rb', line 40

def list_of(klass, label, v)
  v.is_a?(::Array) && v.all? { klass === _1 } ? v : type_error!(label, v)
end

#string(label, v) ⇒ Object



28
29
30
# File 'lib/jade/interop/boundary.rb', line 28

def string(label, v)
  ::String === v ? v.dup : type_error!(label, v)
end

#string_keyed!(label, v) ⇒ Object

Mixed keys are a real shape mismatch; the per-field errors say more than a guess about intent would.



61
62
63
64
65
66
# File 'lib/jade/interop/boundary.rb', line 61

def string_keyed!(label, v)
  return v if v.empty? || v.keys.any?(::String)

  v.keys.grep(::Symbol)
    .then { it.empty? ? v : raise(Jade::Interop::SymbolKeys.new(label, it)) }
end

#type_error!(label, v) ⇒ Object



68
69
70
71
72
73
# File 'lib/jade/interop/boundary.rb', line 68

def type_error!(label, v)
  raise Jade::Interop::DecodeError.new(
    Jade::Decode::WrongType[label, Jade::Decode.type_name(v)],
    v,
  )
end