class Google::Ads::GoogleAds::FieldMaskUtil

Utility for constructing FieldMask objects.

Copied from C# implementation courtesy of jonskeet@google.com

Constants

WRAPPER_TYPES

Public Class Methods

all_set_fields_of(obj) click to toggle source

Construct a field mask containing any fields set on the given object.

Example:

obj = MyObject.new
obj.some_property = 1
obj.other_property = 2

mask = FieldMaskUtil.all_set_fields_of obj

# the mask will contain the present properties "some_property" and
# "other_property"
api_client.mutate obj, mask

@param obj [Object] the object to watch return [Google::Protobuf::FieldMask] the computed mask

# File lib/google/ads/google_ads/field_mask_util.rb, line 70
def self.all_set_fields_of(obj)
  new_instance = obj.class.new
  compare_obj(Google::Protobuf::FieldMask.new, '', new_instance, obj)
end
compare(original, modified) click to toggle source

Creates Google::Protobuf::FieldMask objects based on the difference between two objects.

@param original @param modified @return [Google::Protobuf::FieldMask] the computed mask

# File lib/google/ads/google_ads/field_mask_util.rb, line 81
def self.compare(original, modified)
  raise 'nil cannot be compared' if original.nil? || modified.nil?
  raise 'objects of different types cannot be compared' if original.class != modified.class
  compare_obj(Google::Protobuf::FieldMask.new, '', original, modified)
end
with(obj) { |obj| ... } click to toggle source

Construct a field mask containing any changes to the object made in the given block.

Example:

obj = MyObject.new
obj.some_property = 1

mask = FieldMaskUtil.with obj do
  obj.other_property = 2
end

# the mask will contain the changed property "other_property"
api_client.mutate obj, mask

@param obj [Object] the object to watch @yield block used for determining changes to the object @return [Google::Protobuf::FieldMask] the computed mask

# File lib/google/ads/google_ads/field_mask_util.rb, line 47
def self.with(obj)
  raise 'nil cannot be compared' if obj.nil?
  original = obj.class.decode(obj.class.encode(obj))
  yield obj
  compare original, obj
end

Private Class Methods

compare_obj(mask, current_field, original, modified) click to toggle source
# File lib/google/ads/google_ads/field_mask_util.rb, line 87
def self.compare_obj(mask, current_field, original, modified)
  descriptor = original.class.descriptor

  descriptor.entries.each do |field|
    field_path = get_path current_field, field.name

    # extract values
    original_value = original[field.name]
    modified_value = modified[field.name]

    if is_repeated?(field)
      # repeated fields - must match exactly or add the field
      mask.paths << field_path unless original_value == modified_value
    else
      case field.type
      when :message
        if original_value != modified_value
          # wrappers - do not include the .value part of the path
          if is_wrapper? [original_value, modified_value]
            mask.paths << field_path
          elsif original_value.nil?
            # new message, make a blank instance and then compare
            # against it
            original_value = modified[field.name].class.new
            compare_obj mask, field_path, original_value, modified_value
          elsif modified_value.nil?
            # just emit the deleted field name
            mask.paths << field_path
          else
            compare_obj mask, field_path, original_value, modified_value
          end
        end
      else # primitive types
        mask.paths << field_path unless original_value == modified_value
      end
    end
  end

  mask
end
get_path(path, field) click to toggle source

Construts path string

# File lib/google/ads/google_ads/field_mask_util.rb, line 129
def self.get_path(path, field)
  path.nil? || path == '' ? field : "#{path}.#{field}"
end
is_repeated?(field) click to toggle source

Checks if the object is a repeated field

# File lib/google/ads/google_ads/field_mask_util.rb, line 150
def self.is_repeated?(field)
  field.label == :repeated
end
is_wrapper?(obj) click to toggle source

Checks if the object is a wrapper type

# File lib/google/ads/google_ads/field_mask_util.rb, line 144
def self.is_wrapper?(obj)
  obj = [obj] unless obj.is_a?(Array)
  obj.any? { |x| WRAPPER_TYPES.count { |klass| klass == x.class } > 0 }
end