class Tros::Schema

Constants

INT_MAX_VALUE
INT_MIN_VALUE
LONG_MAX_VALUE
LONG_MIN_VALUE
NAMED_TYPES
NAMED_TYPES_SYM
PRIMITIVE_TYPES

Sets of strings, for backwards compatibility. See below for sets of symbols, for better performance.

PRIMITIVE_TYPES_SYM
VALID_TYPES
VALID_TYPES_SYM

Attributes

type_sym[R]

Public Class Methods

new(type) click to toggle source
    # File lib/tros/schema.rb
140 def initialize(type)
141   @type_sym = type.is_a?(Symbol) ? type : type.to_sym
142 end
parse(json_string) click to toggle source
   # File lib/tros/schema.rb
35 def self.parse(json_string)
36   real_parse(JSON.load("[#{json_string}]").first, {})
37 end
real_parse(json_obj, names=nil, default_namespace=nil) click to toggle source

Build Tros Schema from data parsed out of JSON string.

   # File lib/tros/schema.rb
40 def self.real_parse(json_obj, names=nil, default_namespace=nil)
41   if json_obj.is_a? Hash
42     type = json_obj['type']
43     raise SchemaParseError, %Q(No "type" property: #{json_obj}) if type.nil?
44 
45     # Check that the type is valid before calling #to_sym, since symbols are never garbage
46     # collected (important to avoid DoS if we're accepting schemas from untrusted clients)
47     unless VALID_TYPES.include?(type)
48       raise SchemaParseError, "Unknown type: #{type}"
49     end
50 
51     type_sym = type.to_sym
52     if PRIMITIVE_TYPES_SYM.include?(type_sym)
53       return PrimitiveSchema.new(type_sym)
54 
55     elsif NAMED_TYPES_SYM.include? type_sym
56       name = json_obj['name']
57       namespace = json_obj.include?('namespace') ? json_obj['namespace'] : default_namespace
58       case type_sym
59       when :fixed
60         size = json_obj['size']
61         return FixedSchema.new(name, namespace, size, names)
62       when :enum
63         symbols = json_obj['symbols']
64         return EnumSchema.new(name, namespace, symbols, names)
65       when :record, :error
66         fields = json_obj['fields']
67         return RecordSchema.new(name, namespace, fields, names, type_sym)
68       else
69         raise SchemaParseError.new("Unknown named type: #{type}")
70       end
71 
72     else
73       case type_sym
74       when :array
75         return ArraySchema.new(json_obj['items'], names, default_namespace)
76       when :map
77         return MapSchema.new(json_obj['values'], names, default_namespace)
78       else
79         raise SchemaParseError.new("Unknown Valid Type: #{type}")
80       end
81     end
82 
83   elsif json_obj.is_a? Array
84     # JSON array (union)
85     return UnionSchema.new(json_obj, names, default_namespace)
86   elsif PRIMITIVE_TYPES.include? json_obj
87     return PrimitiveSchema.new(json_obj)
88   else
89     msg = "#{json_obj.inspect} is not a schema we know about."
90     raise SchemaParseError.new(msg)
91   end
92 end
validate(expected_schema, datum, validator_method = :validate) click to toggle source

Determine if a ruby datum is an instance of a schema

    # File lib/tros/schema.rb
 95 def self.validate(expected_schema, datum, validator_method = :validate)
 96   return true if validate_strictly(expected_schema, datum, validator_method)
 97   case expected_schema.type_sym
 98   when :float, :double
 99     datum.is_a?(Numeric)
100   else
101     return false
102   end
103 end
validate_strictly(expected_schema, datum, validator_method = :validate_strictly) click to toggle source

Determine if a ruby datum is an instance of a schema

    # File lib/tros/schema.rb
106 def self.validate_strictly(expected_schema, datum, validator_method = :validate_strictly)
107   case expected_schema.type_sym
108   when :null
109     datum.nil?
110   when :boolean
111     datum == true || datum == false
112   when :string, :bytes
113     datum.is_a? String
114   when :int
115     datum.is_a?(Integer) && (INT_MIN_VALUE <= datum) && (datum <= INT_MAX_VALUE)
116   when :long
117     datum.is_a?(Integer) && (LONG_MIN_VALUE <= datum) && (datum <= LONG_MAX_VALUE)
118   when :float, :double
119     datum.is_a?(Float) || datum.is_a?(BigDecimal)
120   when :fixed
121     datum.is_a?(String) && datum.size == expected_schema.size
122   when :enum
123     expected_schema.symbols.include? datum
124   when :array
125     datum.is_a?(Array) &&
126       datum.all?{|d| send(validator_method, expected_schema.items, d) }
127   when :map
128       datum.keys.all?{|k| k.is_a? String } &&
129       datum.values.all?{|v| send(validator_method, expected_schema.values, v) }
130   when :union
131     expected_schema.schemas.any? { |s| send(validator_method, s, datum) }
132   when :record, :error, :request
133     datum.is_a?(Hash) &&
134       expected_schema.fields.all? { |f| send(validator_method, f.type, datum[f.name]) }
135   else
136     raise TypeError, "#{expected_schema.inspect} is not recognized as type."
137   end
138 end

Public Instance Methods

==(other, seen=nil) click to toggle source
    # File lib/tros/schema.rb
150 def ==(other, seen=nil)
151   other.is_a?(Schema) && type_sym == other.type_sym
152 end
hash(seen=nil) click to toggle source
    # File lib/tros/schema.rb
154 def hash(seen=nil)
155   type_sym.hash
156 end
subparse(json_obj, names=nil, namespace=nil) click to toggle source
    # File lib/tros/schema.rb
158 def subparse(json_obj, names=nil, namespace=nil)
159   if json_obj.is_a?(String) && names
160     fullname = Name.make_fullname(json_obj, namespace)
161     return names[fullname] if names.include?(fullname)
162   end
163 
164   begin
165     Schema.real_parse(json_obj, names, namespace)
166   rescue => e
167     raise e if e.is_a? SchemaParseError
168     raise SchemaParseError, "Sub-schema for #{self.class.name} not a valid Tros schema. Bad schema: #{json_obj}"
169   end
170 end
to_avro(names=nil) click to toggle source
    # File lib/tros/schema.rb
172 def to_avro(names=nil)
173   {'type' => type}
174 end
to_s() click to toggle source
    # File lib/tros/schema.rb
176 def to_s
177   to_avro.to_json
178 end
type() click to toggle source

Returns the type as a string (rather than a symbol), for backwards compatibility. Deprecated in favor of {#type_sym}.

    # File lib/tros/schema.rb
148 def type; @type_sym.to_s; end