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