123456789_123456789_123456789_123456789_123456789_

Class: Selenium::WebDriver::BiDi::Serialization::Union Private

Overview

Resolves a wire payload to the right Data variant: a shared discriminator gives table dispatch; presence rules and a no-tag fallback cover unions without one. Subclassed (never instantiated) — each union holds its own dispatch table.

class Locator < Serialization::Union
discriminator 'type'
variants('css' => 'BrowsingContext::CssLocator')
end

Class Method Summary

  • .build(**kwargs) Internal use only

    Outbound mirror of from_json: build the variant the command's kwargs describe so its typed as_json drives null-vs-absent per field (a flat hash through ::Selenium::WebDriver::BiDi::Transport cannot).

  • .discriminator(wire_key, values = {}) Internal use only

    values maps each variant's discriminator symbol to its wire token, so an inbound payload tag (a wire string) can be matched to the symbol-keyed table.

  • .fallback(path) Internal use only
  • .from_json(json_payload) Internal use only

    A non-Hash payload is a bare scalar arm (e.g.

  • .object_only Internal use only

    Declared (via the schema's objectOnly signal) on a union whose every arm is an object, so a non-Hash payload is a schema violation rather than a scalar arm.

  • .presence(rules) Internal use only
  • .variants(table) Internal use only
  • .outbound_variant(kwargs) private Internal use only

    An explicit nil kwarg still counts as supplied; a non-nullable field set to nil is rejected at construction (Data.new), not here.

  • .payload_tag(json_payload) private Internal use only

    The wire tag mapped back to its variant symbol (the table's key); an unrecognized tag falls through as-is so select misses and from_json raises.

  • .select(json_payload) private Internal use only

    The discriminator value may legitimately be null (e.g.

  • .variant_for(tag, &supplied) private Internal use only

    The matching variant's ref, or nil when none matches (the fallback if declared).

Class Method Details

.build(**kwargs)

Outbound mirror of from_json: build the variant the command's kwargs describe so its typed as_json drives null-vs-absent per field (a flat hash through ::Selenium::WebDriver::BiDi::Transport cannot). Dispatch keys are wire names equal to their ruby kwarg (asserted at generation), so they match the kwargs by symbol. A mismatch here is a caller error (unlike an unknown inbound value), so it fails loudly.

Raises:

  • (::ArgumentError)
[ GitHub ]

  
# File 'rb/lib/selenium/webdriver/bidi/serialization/union.rb', line 74

def build(**kwargs)
  variant = outbound_variant(kwargs) ||
            raise(::ArgumentError, "no #{name} variant matches #{kwargs.inspect}")
  klass = Protocol.const_get(variant)
  # An omitted optional arrives as UNSET; forward only what was provided. A provided
  # key that isn't a field of the chosen variant is an invalid combination for this union.
  provided = kwargs.reject { |_, value| UNSET.equal?(value) }
  invalid = provided.keys - klass.fields.map(&:name)
  return klass.new(**provided) if invalid.empty?

  raise ::ArgumentError, "invalid combination for #{name}: #{invalid.join(', ')}"
end

.discriminator(wire_key, values = {})

values maps each variant's discriminator symbol to its wire token, so an inbound payload tag (a wire string) can be matched to the symbol-keyed table.

[ GitHub ]

  
# File 'rb/lib/selenium/webdriver/bidi/serialization/union.rb', line 38

def discriminator(wire_key, values = {})
  @discriminator = wire_key
  @discriminator_values = values
end

.fallback(path)

[ GitHub ]

  
# File 'rb/lib/selenium/webdriver/bidi/serialization/union.rb', line 45

def fallback(path) = @fallback = path

.from_json(json_payload)

A non-Hash payload is a bare scalar arm (e.g. input.Origin's "viewport") with no object to dispatch on, so it is returned unchanged — unless every arm is an object (object_only), where a non-Hash cannot match any variant and is a wire error.

[ GitHub ]

  
# File 'rb/lib/selenium/webdriver/bidi/serialization/union.rb', line 54

def from_json(json_payload)
  unless json_payload.is_a?(::Hash)
    return json_payload unless @object_only

    raise Error::WebDriverError, "#{name} expected an object on the wire, got #{json_payload.inspect}"
  end

  variant = select(json_payload)
  unless variant
    raise Error::WebDriverError,
          "#{name} received a variant not in this Selenium's BiDi schema: #{json_payload.inspect}"
  end
  Protocol.const_get(variant).from_json(json_payload)
end

.object_only

Declared (via the schema's objectOnly signal) on a union whose every arm is an object, so a non-Hash payload is a schema violation rather than a scalar arm.

[ GitHub ]

  
# File 'rb/lib/selenium/webdriver/bidi/serialization/union.rb', line 49

def object_only = @object_only = true

.outbound_variant(kwargs) (private)

An explicit nil kwarg still counts as supplied; a non-nullable field set to nil is rejected at construction (Data.new), not here.

[ GitHub ]

  
# File 'rb/lib/selenium/webdriver/bidi/serialization/union.rb', line 97

def outbound_variant(kwargs)
  tag = @discriminator ? kwargs.fetch(@discriminator.to_sym, UNSET) : UNSET
  variant_for(tag) { |k| kwargs.key?(k.to_sym) && !UNSET.equal?(kwargs[k.to_sym]) }
end

.payload_tag(json_payload) (private)

The wire tag mapped back to its variant symbol (the table's key); an unrecognized tag falls through as-is so select misses and from_json raises.

[ GitHub ]

  
# File 'rb/lib/selenium/webdriver/bidi/serialization/union.rb', line 112

def payload_tag(json_payload)
  return UNSET unless @discriminator && json_payload.key?(@discriminator)

  wire = json_payload[@discriminator]
  @discriminator_values.key(wire) || wire
end

.presence(rules)

[ GitHub ]

  
# File 'rb/lib/selenium/webdriver/bidi/serialization/union.rb', line 44

def presence(rules) = @presence = rules

.select(json_payload) (private)

The discriminator value may legitimately be null (e.g. script.NullValue's "null" tag), so it is matched by key presence.

[ GitHub ]

  
# File 'rb/lib/selenium/webdriver/bidi/serialization/union.rb', line 91

def select(json_payload)
  variant_for(payload_tag(json_payload)) { |k| json_payload.key?(k) }
end

.variant_for(tag, &supplied) (private)

The matching variant's ref, or nil when none matches (the fallback if declared).

[ GitHub ]

  
# File 'rb/lib/selenium/webdriver/bidi/serialization/union.rb', line 103

def variant_for(tag, &supplied)
  return @variants[tag] if !UNSET.equal?(tag) && @variants&.key?(tag)

  @presence&.each { |path, keys| return path if keys.all?(&supplied) }
  @fallback
end

.variants(table)

[ GitHub ]

  
# File 'rb/lib/selenium/webdriver/bidi/serialization/union.rb', line 43

def variants(table) = @variants = table