Created
September 14, 2020 06:05
-
-
Save ayamomiji/9783e6294f188e0c714698aeb1591dbc to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
class HashSchema | |
def initialize(schema) | |
@schema = schema.map { |key, type| | |
[key, HashSchema.lookup(type)] | |
}.to_h | |
end | |
def cast(params) | |
params.map { |key, value| | |
[key, @schema[key] ? @schema[key].cast(value) : value] | |
}.to_h | |
end | |
class << self | |
def lookup(type) | |
case type | |
when Array then ArraySchema.new(type[0]) | |
when Hash then HashSchema.new(type) | |
when Symbol then ActiveModel::Type.lookup(type) | |
else type | |
end | |
end | |
end | |
class ArraySchema | |
def initialize(type) | |
@type = HashSchema.lookup(type) | |
end | |
def cast(values) | |
values.map { |value| @type.cast(value) } | |
end | |
end | |
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
require 'rails_helper' | |
RSpec.describe HashSchema do | |
it 'casts correctly' do | |
schema = HashSchema.new(str: :string, int: :integer, bool: :boolean) | |
expect(schema.cast(str: 100, int: '200', bool: 't', undef: 'wat')).to eq( | |
str: '100', int: 200, bool: true, undef: 'wat' | |
) | |
end | |
it 'casts recursively' do | |
schema = HashSchema.new(obj: { str: :string, int: :integer, bool: :boolean }) | |
expect(schema.cast(obj: { str: 100, int: '200', bool: 't', undef: 'wat' })).to eq( | |
obj: { str: '100', int: 200, bool: true, undef: 'wat' } | |
) | |
end | |
it 'casts for an array' do | |
schema = HashSchema.new(ints: [:integer]) | |
expect(schema.cast(ints: ['1', '2', 3.1416])).to eq( | |
ints: [1, 2, 3] | |
) | |
end | |
end |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment