module ServiceContract module Avro class RecordType < AbstractType def name definition.name end def fields definition.fields.map do |field| Parameter.new(field) end end def valid_ruby_types [Hash] end end class MapType < AbstractType def name "Map(#{subtype.name})" end def subtype MapValue.new(Type.build(definition.values)) end def valid_ruby_types [Hash] end end class MapValue < AbstractType def name definition.name end def valid_type?(value) value.is_a?(Array) && value.length == 2 && definition.valid_type?(value[1]) end def valid_ruby_types definition.valid_ruby_types end end class ArrayType < AbstractType def name "Array(#{subtype.name})" end def subtype Type.build(definition.items) end def valid_ruby_types [Array] end end class UnionType < AbstractType def name "Union(#{union_types.map(&:name).join(", ")})" end def valid_ruby_types union_types.map(&:valid_ruby_types).flatten end protected def union_types definition.schemas.map{|schema| Type.build(schema)} end end class EnumType < AbstractType def name "Enum(#{definition.name})" end def valid_ruby_types [String] end def valid_values definition.symbols.map{|str| str.to_s.downcase} end end class StringType < AbstractType def name "string" end def valid_ruby_types [String] end end class IntegerType < AbstractType def name "int" end def valid_ruby_types [Fixnum] end end class FloatType < AbstractType def name "float" end def valid_ruby_types [Float] end end class BooleanType < AbstractType def name "boolean" end def valid_ruby_types [TrueClass, FalseClass] end end class NullType < AbstractType def name "null" end alias :to_s :name def valid_ruby_types [NilClass] end end class Type class << self def build(definition) type = type_string(definition) case type when "array" ArrayType.new(definition) when "record" RecordType.new(definition) when "union" UnionType.new(definition) when "enum" EnumType.new(definition) when "string" StringType.new when "int" IntegerType.new when "float" FloatType.new when "boolean" BooleanType.new when "null" NullType.new when "map" MapType.new(definition) else raise "unknown type: #{type}" end end def type_string(definition) type_string = definition.type type_string = type_string.type_sym.to_s if type_string.respond_to?(:type_sym) type_string end end end end end