Easily transform keys from one format to another.
Add this line to your application's Gemfile:
gem 'key_mapable'
And then execute:
$ bundle
Or install it yourself as:
$ gem install key_mapable
class Espresso
extend KeyMapable
define_map(:to_h) do
key_map(:strength, 'Strength')
key_map(:temperature, 'Temperature, transform: ->(value) { value.to_i })
key_value('IsHot') { |espresso| espresso.temperature >= 80 }
array_key_map(:sips, 'Sips') do
key_map(:sipper, 'Sipper')
key_map(:temperature, 'Temperature')
end
end
end
To map keys from one format to another. You must first extend the KeyMapable
module. This will add the necessary methods to define a map.
class Espresso
extend KeyMapable
end
The .define_map
method lets you define a method that will return a hash from
the given map rules defined in the block. The following example will map
#strength
to the key 'Strength'
in the hash returned from #to_h
.
class Espresso
extend KeyMapable
attr_accessor :strength
define_map(:to_h) do
key_map(:strength, 'Strength')
end
end
You can then use the #to_h
method like so:
espresso = Espresso.new
espresso.strength = 10
espresso.to_h
#=> { 'Strength' => 10 }
The map definition can be arbitrarily nested as long as the returned objects respond to the described methods.
define_map(:to_h) do
key_map(:manufacturer, 'Manufacturer') do
key_map(:location, 'Location') do
key_map(:country, 'Country')
end
end
end
If you wish to transform the value you can provide a third argument which must be a lambda and return the transformed value.
define_map(:to_h) do
key_map(:temperature, 'Temperature', transform: ->(value) { value.to_i })
end
You can define a structure for a custom key by using the #key
method.
define_map(:to_h) do
key('Coffee') do
key_map(:brand, 'Brand')
end
end
Use #array_key_map
to define maps over arrays:
define_map(:to_h) do
array_key_map(:sips, 'Sips') do
key_map(:sipper, 'Sipper')
key_map(:temperature, 'Temperature')
end
end
Use #key_value
to define a key that will have a manufactured value. The block
is yielded the subject and must return the manufactured value.
define_map(:to_h) do
key_value('IsHot') { |espresso| espresso.temperature >= 80 }
end
By default the object the keys are read on is the object itself. If you want to
use another object you can set the :subject
keyword to a reader method on the
object.
define_map(:to_h, subject: :my_reader) do
# ...
end
Sometimes you do not want to return a hash. Provide the :resolve
keyword to
transform the resulting hash to your own format.
define_map(:to_h, resolve: ->(value) { OpenStruct.new(value)}) do
# ...
end
If the object itself is an hash you might want to use hash notation to access
the values. In that case pass :hash
as the :access
argument.
define_map(:to_h, access: :hash) do
# ...
end
You can also pass a custom accessor. The accessor must respond to #access
. It
will then be passed the subject and key.
After checking out the repo, run bin/setup
to install dependencies. Then, run rake spec
to run the tests. You can also run bin/console
for an interactive prompt that will allow you to experiment.
To install this gem onto your local machine, run bundle exec rake install
. To release a new version, update the version number in version.rb
, and then run bundle exec rake release
, which will create a git tag for the version, push git commits and tags, and push the .gem
file to rubygems.org.
Bug reports and pull requests are welcome on GitHub at https://github.com/[USERNAME]/key_mapable.
The gem is available as open source under the terms of the MIT License.