Module: Kobako::Wire::Envelope
- Defined in:
- lib/kobako/wire/envelope.rb,
lib/kobako/wire/envelope/payloads.rb
Overview
Outcome-path envelopes (SPEC.md Outcome Envelope): Result and Panic value objects plus the tagged Outcome wrapper that frames them on the wire. The RPC-path counterparts (Request / Response) live in the parent envelope.rb file.
Defined Under Namespace
Classes: Outcome, Panic, Request, Response, Result
Constant Summary collapse
- OUTCOME_TAG_RESULT =
First byte of the OUTCOME_BUFFER for a Result envelope.
0x01- OUTCOME_TAG_PANIC =
First byte of the OUTCOME_BUFFER for a Panic envelope.
0x02- STATUS_OK =
Response variant marker for the success branch.
0- STATUS_ERROR =
Response variant marker for the error branch.
1
Class Method Summary collapse
- .decode_outcome(bytes) ⇒ Object
- .decode_panic(bytes) ⇒ Object
- .decode_request(bytes) ⇒ Object
- .decode_response(bytes) ⇒ Object
- .decode_result(bytes) ⇒ Object
- .encode_outcome(outcome) ⇒ Object
- .encode_panic(panic) ⇒ Object
-
.encode_request(request) ⇒ Object
Encode a Request to bytes.
- .encode_response(response) ⇒ Object
- .encode_result(value) ⇒ Object
Class Method Details
.decode_outcome(bytes) ⇒ Object
126 127 128 129 130 131 132 133 |
# File 'lib/kobako/wire/envelope/payloads.rb', line 126 def self.decode_outcome(bytes) bytes = bytes.b raise Codec::InvalidType, "Outcome bytes must not be empty" if bytes.empty? tag = bytes.getbyte(0) body = bytes.byteslice(1, bytes.bytesize - 1) Outcome.new(decode_outcome_payload(tag, body)) end |
.decode_panic(bytes) ⇒ Object
76 77 78 79 80 81 82 83 84 85 86 |
# File 'lib/kobako/wire/envelope/payloads.rb', line 76 def self.decode_panic(bytes) map = Codec::Decoder.decode(bytes) raise Codec::InvalidType, "Panic envelope must be a map, got #{map.class}" unless map.is_a?(Hash) Codec.translate_value_object_error do Panic.new( origin: map["origin"], klass: map["class"], message: map["message"], backtrace: map["backtrace"] || [], details: map["details"] ) end end |
.decode_request(bytes) ⇒ Object
83 84 85 86 87 88 89 90 91 92 93 |
# File 'lib/kobako/wire/envelope.rb', line 83 def self.decode_request(bytes) arr = Codec::Decoder.decode(bytes) unless arr.is_a?(Array) && arr.length == 4 raise Codec::InvalidType, "Request must be a 4-element array, got #{arr.inspect}" end target, method_name, args, kwargs = arr Codec.translate_value_object_error do Request.new(target: target, method: method_name, args: args, kwargs: kwargs) end end |
.decode_response(bytes) ⇒ Object
134 135 136 137 138 139 140 141 142 |
# File 'lib/kobako/wire/envelope.rb', line 134 def self.decode_response(bytes) arr = Codec::Decoder.decode(bytes) unless arr.is_a?(Array) && arr.length == 2 raise Codec::InvalidType, "Response must be a 2-element array, got #{arr.inspect}" end status, payload = arr Codec.translate_value_object_error { Response.new(status: status, payload: payload) } end |
.decode_result(bytes) ⇒ Object
26 27 28 29 30 31 32 33 |
# File 'lib/kobako/wire/envelope/payloads.rb', line 26 def self.decode_result(bytes) arr = Codec::Decoder.decode(bytes) unless arr.is_a?(Array) && arr.length == 1 raise Codec::InvalidType, "Result envelope must be a 1-element array, got #{arr.inspect}" end Result.new(arr[0]) end |
.encode_outcome(outcome) ⇒ Object
110 111 112 113 114 115 116 |
# File 'lib/kobako/wire/envelope/payloads.rb', line 110 def self.encode_outcome(outcome) tag, body = encode_outcome_payload(outcome.payload) out = String.new(encoding: Encoding::ASCII_8BIT) out << [tag].pack("C") out << body out end |
.encode_panic(panic) ⇒ Object
59 60 61 |
# File 'lib/kobako/wire/envelope/payloads.rb', line 59 def self.encode_panic(panic) Codec::Encoder.encode(panic_map(panic)) end |
.encode_request(request) ⇒ Object
Encode a Request to bytes. The Value Object’s own invariants are the contract; this method does not re-check the shape.
79 80 81 |
# File 'lib/kobako/wire/envelope.rb', line 79 def self.encode_request(request) Codec::Encoder.encode([request.target, request.method_name, request.args, request.kwargs]) end |