Module: Codecs::TaggedUnionCodec

Defined in:
lib/emery/codecs.rb

Class Method Summary collapse

Class Method Details

.applicable?(type) ⇒ Boolean

Returns:



213
214
215
# File 'lib/emery/codecs.rb', line 213

def self.applicable?(type)
  type.respond_to? :ancestors and type.ancestors.include? TaggedUnion
end

.deserialize(type, json_value) ⇒ Object



216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
# File 'lib/emery/codecs.rb', line 216

def self.deserialize(type, json_value)
  if !json_value.is_a?(Hash)
    raise JsonerError.new("JSON value type #{json_value.class} is not Hash but it has to be Hash to represent a union")
  end
  if type.discriminator == nil
    if json_value.keys.length != 1
      raise JsonerError.new("JSON value #{json_value} should have only one key to represent union type wrapper object, found #{json_value.keys.length}")
    end
    tag_key = json_value.keys[0]
    if not type.typed_tags.key? tag_key.to_sym
      raise JsonerError.new("JSON key '#{tag_key}' does not match any tag in union type #{self}")
    end
    tag_type = type.typed_tags[tag_key.to_sym]
    tag_json_value = json_value[tag_key]
    tag_value = Jsoner.deserialize(tag_type, tag_json_value)
    return type.new({tag_key.to_sym => tag_value})
  else
    if not json_value.key? type.discriminator
      raise JsonerError.new("JSON value #{json_value} does not have discriminator field #{type.discriminator}")
    end
    tag_key = json_value[type.discriminator]
    tag_type = type.typed_tags[tag_key.to_sym]
    tag_value = Jsoner.deserialize(tag_type, json_value)
    return type.new({tag_key.to_sym => tag_value})
  end
end

.serialize(type, value) ⇒ Object



242
243
244
245
246
247
248
249
250
251
252
253
# File 'lib/emery/codecs.rb', line 242

def self.serialize(type, value)
  T.check(type, value)
  tag_key = value.current_tag
  tag_type = type.typed_tags[tag_key]
  tag_json_value = Jsoner.serialize(tag_type, value.send(tag_key))
  if type.discriminator == nil
    return { tag_key => tag_json_value }
  else
    tag_json_value[type.discriminator] = tag_key
    return tag_json_value
  end
end