lib/google/ads/google_ads/autoboxing_fields.rb in google-ads-googleads-2.4.1 vs lib/google/ads/google_ads/autoboxing_fields.rb in google-ads-googleads-3.0.0
- old
+ new
@@ -1,90 +1,96 @@
-require 'google/protobuf/message_exts'
-require 'google/protobuf/wrappers_pb'
+require 'google/ads/google_ads/autoboxing_mappings'
+
module Google
module Ads
module GoogleAds
module AutoboxingFields
- MAPPINGS = {
- Google::Protobuf::Int32Value => lambda { |x| Integer(x) },
- Google::Protobuf::Int64Value => lambda { |x| Integer(x) },
- Google::Protobuf::StringValue => lambda { |x| String(x) },
- Google::Protobuf::BoolValue => lambda { |x|
- case x
- when TrueClass, true, "true", "TRUE", "True", "1", 1
- true
- when FalseClass, false, "false", "FALSE", "False", "0", 0
- false
- else
- raise ArgumentError.new("Value #{x} is not boolish")
- end
- },
- Google::Protobuf::DoubleValue => lambda { |x| Float(x) },
- Google::Protobuf::BytesValue => lambda { |x| x.force_encoding("ASCII-8BIT") },
- }
-
def self.patch_class(klass)
return if klass.instance_variable_get(:@_patched_for_autoboxing_fields)
klass.instance_variable_set(:@_patched_for_autoboxing_fields, true)
klass.instance_eval do
fields = []
+ repeated_fields = []
+
descriptor.each do |field|
if field.type == :message && AutoboxingFields.is_value_field?(field.subtype.msgclass)
- fields << field
- AutoboxingFields.patch_field_for_autoboxing(field, self)
+ repeated = field.label == :repeated
+ if repeated
+ repeated_fields << field
+ else
+ fields << field
+ end
+
+ AutoboxingFields.patch_field_for_autoboxing(field, repeated, self)
end
end
- AutoboxingFields.patch_constructor_for_autoboxing(fields, self)
+ AutoboxingFields.patch_constructor_for_autoboxing(fields, repeated_fields, self)
end
end
def self.is_value_field?(class_name)
- MAPPINGS.keys.include?(class_name)
+ AutoboxingMappings.has_type?(class_name)
end
- def self.patch_constructor_for_autoboxing(fields, klass_to_patch)
+ def self.patch_constructor_for_autoboxing(fields, repeated_fields, klass_to_patch)
orig_initialize = klass_to_patch.instance_method(:initialize)
klass_to_patch.instance_eval do
define_method(:initialize) do |**kwargs|
- new_kwargs = Hash[kwargs.map { |name, value|
- field = fields.select { |x| x.name == name.to_s }.first
- actual_value = if field
- if field.subtype.msgclass === value
- value
- else
- field.subtype.msgclass.new(value: MAPPINGS.fetch(field.subtype.msgclass).call(value))
- end
- else
- value
- end
- [name, actual_value]
- }]
+ new_kwargs = kwargs.dup
+ fields.select { |x| new_kwargs.include?(x.name.to_sym) }.each do |field|
+ value = new_kwargs.fetch(field.name.to_sym)
+ new_kwargs[field.name.to_sym] = AutoboxingMappings.wrapped_mapping(field.subtype.msgclass).call(value)
+ end
+
+ repeated_fields.select { |x| new_kwargs.include?(x.name.to_sym) }.each do |field|
+ value = new_kwargs.fetch(field.name.to_sym)
+ mapping = AutoboxingMappings.wrapped_mapping(field.subtype.msgclass)
+ new_kwargs[field.name.to_sym] = value.map { |x| mapping.call(x) }
+ end
+
orig_initialize.bind(self).call(**new_kwargs)
end
end
end
- def self.patch_field_for_autoboxing(field, klass_to_patch)
+ def self.patch_field_for_autoboxing(field, repeated, klass_to_patch)
name = field.name
- field_klass = field.subtype.msgclass
- mapping = MAPPINGS.fetch(field_klass)
+ mapping = AutoboxingMappings.wrapped_mapping(field.subtype.msgclass)
- klass_to_patch.instance_eval do
- define_method("#{name}=".to_sym) do |value|
- if value.nil?
- send(:method_missing, :"#{name}=", value)
- elsif field_klass === value
- send(:method_missing, :"#{name}=", value)
- else
- send(:method_missing, :"#{name}=", field_klass.new(value: mapping.call(value)))
+ if repeated
+ klass_to_patch.instance_eval do
+ define_method(name.to_sym) do
+ @patched_repeated_fields ||= {}
+ @patched_repeated_fields[name] ||= RepeatedFieldProxy.new(
+ send(:method_missing, name.to_sym),
+ mapping,
+ )
+ @patched_repeated_fields[name]
end
end
+ else
+ klass_to_patch.instance_eval do
+ define_method("#{name}=".to_sym) do |value|
+ send(:method_missing, :"#{name}=", mapping.call(value))
+ end
+ end
end
end
end
end
+ end
+end
+
+class RepeatedFieldProxy < SimpleDelegator
+ def initialize(collection, mapping)
+ super(collection)
+ @mapping = mapping
+ end
+
+ def <<(value)
+ super(@mapping.call(value))
end
end
module Google::Protobuf
module MessageExts