# frozen_string_literal: true
module ESM
module Arma
class Request < Data.define(:id, :type, :content)
# These numbers MUST match the associated RequestType enum value
# in esm_arma/src/esm/src/request.rs
TYPES = {
0 => :noop,
1 => :error,
2 => :heartbeat,
3 => :identification,
4 => :initialize,
5 => :handshake,
6 => :message
}.freeze
def self.from_client(data)
new(id: data[:i], type: TYPES[data[:t]], content: data[:c]&.pack("C*"))
end
delegate :to_json, to: :to_h
def initialize(type:, id: nil, content: nil)
id ||= SecureRandom.uuid
id = id.delete("-")
raise ArgumentError, "ID must be 32 bytes" if id.size != 32 # The size of a UUID without the dashes
raise ArgumentError, "Invalid type #{type}" unless TYPES.value?(type.to_sym)
super(id: id, type: type, content: content)
end
def to_h
{
i: id,
t: TYPES.key(type),
c: case content
when NilClass
[]
when Array
content
when Symbol
content.to_s.bytes
when ->(c) { c.respond_to?(:bytes) }
content.bytes
else
raise ArgumentError, "Content must be nil, Symbol, Array, or must respond to #bytes"
end
}
end
end
end
end