module Pb::Serializable

Public Class Methods

included(base) click to toggle source
# File lib/pb/serializable.rb, line 6
def self.included(base)
  base.include Pb::Serializer::ComputedModelSupport
  base.extend Pb::Serializer::Dsl
end

Public Instance Methods

to_pb(with: nil) click to toggle source

@param with [

Google::Protobuf::FieldMask,
Array<(Symbol, Hash)>,
Hash{Symbol=>(Array,Symbol,Hash)},

]

# File lib/pb/serializable.rb, line 16
def to_pb(with: nil)
  with ||= ::Pb::Serializer.build_default_mask(self.class.message_class.descriptor)
  with = ::Pb::Serializer.normalize_mask(with)

  oneof_set = []

  o = self.class.message_class.new
  self.class.message_class.descriptor.each do |fd|
    attr = self.class.find_attribute_by_field_descriptor(fd)

    unless attr
      msg = "#{self.class.message_class.name}.#{fd.name} is missed in #{self.class.name}"

      case Pb::Serializer.configuration.missing_field_behavior
      when :raise then raise ::Pb::Serializer::MissingFieldError, msg
      when :warn  then Pb::Serializer.logger.warn msg
      end

      next
    end

    next unless with.key?(attr.name)
    next unless attr.serializable?(self)

    raise "#{self.name}.#{attr.name} is not defined" unless respond_to?(attr.name)

    v = public_send(attr.name)
    v = attr.convert_to_pb(v, with: with[attr.name])

    if attr.oneof?
      if !v.nil?
        if oneof_set.include?(attr.oneof)
          raise ::Pb::Serializer::ConflictOneofError, "#{primary_object.class.name}##{attr.name} is oneof attribute"
        end
        oneof_set << attr.oneof
      end
    elsif !attr.allow_nil? && v.nil?
      raise ::Pb::Serializer::ValidationError, "#{primary_object.class.name}##{attr.name} is required"
    end

    next if v.nil?

    if attr.repeated?
      o.public_send(attr.name).push(*v)
    else
      o.public_send("#{attr.name}=", v)
    end
  end

  self.class.oneofs.each do |oneof|
    next if oneof_set.include?(oneof.name)
    next if oneof.allow_nil?
    raise ::Pb::Serializer::ValidationError, "#{primary_object.class.name}##{oneof.name} is required"
  end

  o
end