README.md in key_mapable-0.5.0 vs README.md in key_mapable-0.6.0
- old
+ new
@@ -16,37 +16,141 @@
Or install it yourself as:
$ gem install key_mapable
+## A quick example
+
+```ruby
+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
+```
+
## Usage
+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.
+
```ruby
-class MyClass
+class Espresso
extend KeyMapable
+end
+```
- # Define a method called `#to_h` that use the provided map. The keys
- # will be accessed on the provided subject. Transform the resulting hash
- # with the provided lambda.
- define_map(:to_h, resolve: ->(val) { val }, subject: :my_reader) do
- # Map the value of `#name` to the key 'Name'.
- key_map(:name, 'Name')
+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`.
- # Map the value of `#maybe_value` to the key 'GuaranteedValue'.
- # Transform the value by calling `#to_s` first.
- key_map(:maybe_value, 'GuaranteedValue', transform: ->(val) { val.to_s })
+```ruby
+class Espresso
+ extend KeyMapable
- # Map the key 'Name' to the value provided by the block.
- key_value('AConstant') { 'Foo' }
+ attr_accessor :strength
- # Map every item returned from `#rows`.
- array_key_map(:rows, 'Rows') do
- # Map the value of `#id` to the key 'Id'.
- key_map(:id, 'Id')
+ define_map(:to_h) do
+ key_map(:strength, 'Strength')
+ end
+end
+```
+
+You can then use the `#to_h` method like so:
+```ruby
+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.
+```ruby
+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.
+
+```ruby
+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.
+
+```ruby
+define_map(:to_h) do
+ key('Coffee') do
+ key_map(:brand, 'Brand')
+ end
+end
+```
+
+Use `#array_key_map` to define maps over arrays:
+```ruby
+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.
+
+```ruby
+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.
+
+```ruby
+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.
+```ruby
+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.
+
+```ruby
+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.
## Development
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.