class MightyJSON::Type::Object

Public Class Methods

new(fields) click to toggle source
# File lib/mighty_json/type.rb, line 140
def initialize(fields)
  @fields = fields
end

Public Instance Methods

compile(var:, path:) click to toggle source
# File lib/mighty_json/type.rb, line 144
      def compile(var:, path:)
        v = var.cur
        keys = @fields.keys.map(&:inspect)

        result = var.next
        is_fixed = @fields.values.none?{|type| type.is_a?(Optional) || (type.is_a?(Base) && type.type == :ignored)}

        <<~END
          begin
            raise Error.new(path: #{path}, type: #{self.to_s.inspect}, value: object) unless #{v}.is_a?(Hash)

            if #{!is_fixed} || #{@fields.size} != #{v}.size
              #{v}.each do |key, value|
                next if #{keys.map{|key| "#{key} == key"}.join('||')}
                raise UnexpectedFieldError.new(path: #{path.inspect} + [key], value: #{v}) # TOOD: optimize path
              end
            end

            {}.tap do |#{result}|
              #{
                @fields.map do |key, type|
                  new_var = var.next
                  <<~END2
                    #{new_var} = #{v}.fetch(#{key.inspect}, none)
                    v = #{type.compile(var: var, path: path + [key])}
                    if !none.equal?(v) &&
                       #{!NONE.equal?(type)} &&
                       !(#{type.is_a?(Optional)} && none.equal?(#{new_var}))
                      #{result}[#{key.inspect}] = v
                    end
                  END2
                end.join("\n")
              }
            end
          end
        END
      end
to_s() click to toggle source
# File lib/mighty_json/type.rb, line 182
def to_s
  fields = []

  @fields.each do |name, type|
    fields << "#{name}: #{type}"
  end

  "object(#{fields.join(', ')})"
end