class Kanade::Engine

Public Class Methods

converter(sym) click to toggle source
# File lib/kanade/engine.rb, line 145
def self.converter(sym)
  @@converters[sym]
end
new(configuration=nil) click to toggle source
# File lib/kanade/engine.rb, line 8
def initialize(configuration=nil)
  @config = configuration || Kanade::Config.default
end
register_converter!(klass) click to toggle source
# File lib/kanade/engine.rb, line 113
def self.register_converter!(klass)
  key = klass.name.split('::').last.underscore.to_sym

  return if key === :base

  # We don't support multiple converter for now
  raise NotSupportedError.new("#{key} registered twice") if not @@converters[key].nil?

  @@converters[key] = klass.new
end
register_name_resolver!(klass) click to toggle source
# File lib/kanade/engine.rb, line 124
def self.register_name_resolver!(klass)
  key = klass.name.split('::').last.underscore.to_sym

  return if key === :base

  # We don't support multiple converter for now
  raise NotSupportedError.new("#{key} registered twice") if not @@name_resolvers[key].nil?

  @@name_resolvers[key] = klass.new
end

Public Instance Methods

configure() { |config| ... } click to toggle source
# File lib/kanade/engine.rb, line 12
def configure
  yield @config
end
deserialize(definition, json) click to toggle source
# File lib/kanade/engine.rb, line 59
def deserialize(definition, json)
  raise NotSupportedError.new("Can not process non-class!") unless definition.is_a?(Class)
  raise NotSupportedError.new("Can not process other than DTO!") unless definition < Dto

  hash = JSON.parse(json)
  deserialize_object(definition, hash)
end
deserialize_list(value, field_info) click to toggle source
# File lib/kanade/engine.rb, line 91
def deserialize_list(value, field_info)
  return nil if value.nil?

  # Catatan pribadi: Jadi "of" itu harusnya mengandung field definition?
  # bukan of: Product, tapi of: {as: :dto, of: Product}
  # dengan field definition ini, kita bisa membuat hal yang lebih konfleks, misal:
  # of: {as: :symbol, mapping: {success: 'RES_SUCCESS'}}
  value.map do |v|
    if field_info.options[:of].is_a?(Class) and field_info.options[:of] < Dto
      deserialize_object(field_info.options[:of], v)
    else
      conversion_method = field_info.options[:of]
      # TODO how to refer to static field?
      converter = Engine.converter(conversion_method)

      raise NotSupportedError.new("Can not process unknown converter! #{conversion_method}") if converter.nil?

      converter.deserialize(v, field_info)
    end
  end
end
deserialize_object(definition, hash) click to toggle source

IF engine contains deserialization logic, we can no more unit test the converters. Seems like, the conversion logic must be outsourced to its respective converter

# File lib/kanade/engine.rb, line 70
def deserialize_object(definition, hash)
  return nil if hash.nil?
  result = definition.new
  result.__fields.each do |field|
    name = field.key_json || name_to_json(field.sym)

    if field.options[:as] == :list
      value = deserialize_list(hash[name], field)
    elsif field.options[:as] == :dto
      value = deserialize_object(field.options[:of], hash[name])
    else
      value = hash[name]
    end

    next if value.nil?

    result.send("#{field.key_ruby}=", value)
  end
  result
end
name_to_json(sym) click to toggle source
# File lib/kanade/engine.rb, line 140
def name_to_json(sym)
  strategy = @config.contract
  @@name_resolvers[strategy].serialize(sym)
end
name_to_ruby(string) click to toggle source
# File lib/kanade/engine.rb, line 135
def name_to_ruby(string)
  strategy = @config.contract
  @@name_resolvers[strategy].deserialize(string)
end
serialize(object) click to toggle source
# File lib/kanade/engine.rb, line 16
def serialize(object)
  traverse_field(object).to_json
end
serialize_list(list, field_info) click to toggle source
# File lib/kanade/engine.rb, line 42
def serialize_list(list, field_info)
  return nil if list.nil?
  list.map do |entry|
    if field_info.options[:of].is_a?(Class) and field_info.options[:of] < Dto
      traverse_field(entry)
    else
      conversion_method = field_info.options[:of]
      # TODO how to refer to static field?
      converter = Engine.converter(conversion_method)

      raise NotSupportedError.new("Can not process unknown converter! #{conversion_method}") if converter.nil?

      converter.serialize(entry, field_info)
    end
  end
end
traverse_field(object) click to toggle source
# File lib/kanade/engine.rb, line 20
def traverse_field(object)
  return nil if object.nil?
  raise NotSupportedError.new("Serializer only works for Kanade::Dto, and #{object.class.name} does not extend Kanade::Dto") unless object.class < Kanade::Dto

  result = {}

  object.__fields.each do |field|
    name = field.key_json || name_to_json(field.sym)

    if field.options[:as] == :list
      value = serialize_list(object.send(field.sym), field)
    elsif field.options[:as] == :dto
      value = traverse_field(object.send(field.sym))
    else
      value = field.converter.serialize(object.send(field.sym), field)
    end
    result[name] = value
  end

  result
end