class Selenium::WebDriver::BiDi::Serialization::Record

@api private
Cookie = Record.define(name: ‘name’, value: {wire_key: ‘value’, ref: ‘Network::BytesValue’})
bakes each field’s wire facts and returns a ::Data subclass with serialization.
Immutable value type for the generated protocol classes. +Record.define(spec)+

def self.define(**spec)

def self.define(**spec)
  extensible = spec.delete(:extensible) || false
  fields = spec.map { |name, meta| field(name, meta) }
  names = fields.map(&:name)
  names << :extensions if extensible
  klass = super(*names)
  fields.freeze
  # Singleton methods are inherited by `X = Record.define(…)`; ivars would not.
  klass.define_singleton_method(:fields) { fields }
  klass.define_singleton_method(:extensible?) { extensible }
  klass.include(Serializable)
  # Capture ::Data's generated +new+, then prepend (not include) Deserializer so
  # its +new+ overrides it — outbound +new+ adds validation, while inbound
  # +from_json+ builds directly via the captured constructor. Bound to +self+ so a
  # subclass builds itself, not the base.
  data_new = klass.singleton_class.instance_method(:new)
  klass.singleton_class.prepend(Deserializer)
  klass.define_singleton_method(:construct) { |**attributes| data_new.bind_call(self, **attributes) }
  klass.singleton_class.send(:private, :construct)
  klass
end

def self.field(name, meta)

def self.field(name, meta)
  meta = {wire_key: meta} if meta.is_a?(::String)
  Field.new(name: name.to_sym, wire_key: meta.fetch(:wire_key, name.to_s),
            nullable: meta[:nullable] || false, ref: meta[:ref],
            list: meta[:list] || false, fixed: meta.fetch(:fixed, UNSET), enum: meta[:enum],
            required: meta.fetch(:required, true), primitive: meta[:primitive])
end