Class: Protobug::Field::MapField

Inherits:
MessageField show all
Defined in:
lib/protobug/field.rb

Constant Summary collapse

SUPER_INITIALIZE =
instance_method(:initialize).super_method

Instance Attribute Summary

Attributes inherited from MessageField

#message_type

Attributes inherited from Protobug::Field

#adder, #cardinality, #clearer, #haser, #ivar, #json_name, #name, #number, #oneof, #setter

Instance Method Summary collapse

Methods inherited from MessageField

#binary_decode_one, #binary_encode_one, #json_decode_one, #json_encode_one, #wire_type

Methods inherited from Protobug::Field

#binary_decode, #json_key_encode, #optional?, #packed?, #pretty_print, #proto3_optional?, #to_text, #validate!

Constructor Details

#initialize(number, name, key_type:, value_type:, json_name: name, oneof: nil, enum_type: nil, message_type: nil) ⇒ MapField

rubocop:disable Lint/MissingSuper,



234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
# File 'lib/protobug/field.rb', line 234

def initialize(number, name, key_type:, value_type:, json_name: name, oneof: nil, # rubocop:disable Lint/MissingSuper,
               enum_type: nil, message_type: nil)
  SUPER_INITIALIZE.bind_call(
    self, number, name,
    cardinality: :repeated,
    json_name: json_name,
    oneof: oneof
  )

  @map_class = Class.new do
    extend Protobug::Message

    optional(1, "key", type: key_type, proto3_optional: false)
    value_type_kwargs = { enum_type: enum_type, message_type: message_type }
    value_type_kwargs.compact!
    optional(2, "value", type: value_type, **value_type_kwargs, proto3_optional: false)
  end
end

Instance Method Details

#binary_encode(value, outbuf) ⇒ Object



257
258
259
260
261
262
263
264
# File 'lib/protobug/field.rb', line 257

def binary_encode(value, outbuf)
  value.each_with_object(@map_class.new) do |(k, v), entry|
    entry.key = k
    entry.value = v
    BinaryEncoding.encode_varint (number << 3) | wire_type, outbuf
    BinaryEncoding.encode_length @map_class.encode(entry), outbuf
  end
end

#defaultObject



254
# File 'lib/protobug/field.rb', line 254

def default = {}

#define_adder(message) ⇒ Object



300
301
302
303
304
305
306
307
308
309
310
311
# File 'lib/protobug/field.rb', line 300

def define_adder(message)
  field = self
  message.define_method(adder) do |msg|
    existing = instance_variable_get(field.ivar)
    if UNSET == existing
      existing = field.default
      instance_variable_set(field.ivar, existing)
    end

    existing[msg.key] = msg.value
  end
end

#json_decode(value, message, ignore_unknown_fields, registry) ⇒ Object



273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
# File 'lib/protobug/field.rb', line 273

def json_decode(value, message, ignore_unknown_fields, registry)
  return if value.nil?

  unless value.is_a?(Hash)
    raise DecodeError,
          "expected Hash for #{inspect}, got #{value.inspect}"
  end

  value.each do |k, v|
    entry = @map_class.decode_json_hash(
      { "key" => k, "value" => v },
      registry: registry,
      ignore_unknown_fields: ignore_unknown_fields
    )
    # can't use haser because default values should also be counted...
    if UNSET == entry.instance_variable_get(:@value)
      next if ignore_unknown_fields && @map_class.fields_by_name.fetch("value").is_a?(EnumField)

      raise DecodeError, "nil values are not allowed in map #{name} in #{message.class}"
    end

    message.send(adder, entry)
  end
end

#json_encode(value, print_unknown_fields:) ⇒ Object



266
267
268
269
270
271
# File 'lib/protobug/field.rb', line 266

def json_encode(value, print_unknown_fields:)
  value.to_h do |k, v|
    value = @map_class.fields_by_name["value"].json_encode(v, print_unknown_fields: print_unknown_fields)
    [json_key_encode(k), value]
  end
end

#repeatedObject



253
# File 'lib/protobug/field.rb', line 253

def repeated = true

#repeated?Boolean

Returns:

  • (Boolean)


255
# File 'lib/protobug/field.rb', line 255

def repeated? = true

#type_lookup(_registry) ⇒ Object



298
# File 'lib/protobug/field.rb', line 298

def type_lookup(_registry) = @map_class