class Strum::Json::Schema::Cast

Public Instance Methods

audit() click to toggle source
# File lib/strum/json/schema/cast.rb, line 15
def audit
  add_error(:schema, :not_found) unless args[:schema].is_a?(Hash)
end
call() click to toggle source
# File lib/strum/json/schema/cast.rb, line 11
def call
  output(casted(input, args[:schema]))
end

Protected Instance Methods

casted(input_data, schema, path = []) click to toggle source
# File lib/strum/json/schema/cast.rb, line 21
def casted(input_data, schema, path = [])
  item = custom_dig(input_data, path)

  return item if item.is_a?(NoValue)

  case schema[:type]
  when Array
    schema[:type].reduce(nil) do |type, x|
      new_schema = schema.clone
      new_schema[:type] = x
      type || casted(input_data, new_schema, path)
    end
  when "object"
    if item.is_a?(Hash) && schema[:properties].is_a?(Hash)
      item.map do |key, val|
        if (prop = schema[:properties][key])
          [key,
           casted(input_data, prop, path + [key])]
        else
          [key, val]
        end
      end.filter { |pair| !pair[1].is_a?(NoValue) }.to_h
    end
  when "array"
    if item.is_a?(Array) && schema[:items].is_a?(Hash)
      (0..(item.length - 1)).reduce([]) { |res, idx| res << casted(input_data, schema[:items], path + [idx]) }
    end
  when "string"
    item.to_s
  when "integer", "number"
    case item
    when Numeric
      item
    when String, Symbol
      (item.to_s.to_f % 1).positive? ? item.to_s.to_f : item.to_s.to_i
    end
  when "boolean"
    item.to_s.downcase == "true"
  when "jsonb"
    if Module.constants.include?(:Sequel) && Sequel.methods.include?(:pg_jsonb_wrap)
      Sequel.pg_jsonb_wrap(item)
    else
      add_error(:schema, "jsonb type is not supported")
    end
  when nil, ""
    item
  else
    add_error(:schema, :invalid_type)
  end
end
custom_dig(obj, path) click to toggle source
# File lib/strum/json/schema/cast.rb, line 72
def custom_dig(obj, path)
  path.reduce(obj) { |item, x| item.fetch(x) { |_it| return NoValue.new } }
end