Skip to content

neezer/key_bridge

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

22 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

KeyBridge

Translates one hash to another, given a map. Inspired to make a generic solution to the problem outlined here.

Named after the Key Bridge in Washington DC, because why not!

key bridge

Usage

Basic

Make a translator with the map you want to use:

translator = KeyBridge.new_translator({ 'name.firstName' => 'first_name' })

Both keys and values can use keypath syntax. By default, the delimiter is a ., but you can pass in a custom delimieter if you want to use something else (see Options).

Once you have a translator object, give it a hash that matches the left side of the map:

translator.translate({ name: { firstName: 'Milton' } })
#=> { 'first_name' => 'Milton' }

Note that you can use either symbols or strings for the hash keys in the given hash: KeyBridge uses ActiveSupport#hash_with_indifferent_access so it shouldn't matter. The keypaths provided in the map must always be strings.

Arrays

Keypaths support array queries too! Just provide the array index as part of the keypath:

translator = KeyBridge.new_translator({ 'organizations[0].title' => 'title' })

Then it'll pull out the value at that array in the translated hash:

translator.translate({ organizations: [{ title: 'Collator' }] })
#=> { 'title' => 'Collator' }

You can also write to arrays, either by index or by pushing an empty array. For example:

translator = KeyBridge.new_translator({ 'title' => 'organizations[].title' })
translator.translate({ title: 'Collator' })
#=> { 'organizations' => [{ 'title' => 'Collator' }] }

translator = KeyBridge.new_translator({ 'title' => 'organizations[2].title' })
translator.translate({ title: 'Collator' })
#=> { 'organizations' => [nil, nil, { 'title' => 'Collator' }] }

Reverse

If you want to do a reverse translation on an already instantiated translator object, just call reverse! on it to flip the map:

translator = KeyBridge.new_translator({ 'panda.bears' => 'grizzly.cubs' })
translator.reverse!
translator.translate({ grizzly: { cubs: 'are cuddly' } })
#=> { 'panda' => { 'bears' => 'are cuddly' } }

Options

translator = KeyBridge.new_translator(map, transforms: %i(), delimiter: '.')
  • transforms

    This is where you can specify any value transformations you want to apply during the translation. This is an array of symbols corresponding to transformation strategies in KeyBridge::ValueTransforms

    Default: []

    Available transforms:

    • :invert_booleans — Flips all boolean values.
    translator = KeyBridge.new_translator({ 'a.b' => 'x.y' }, transforms: %i(invert_booleans))
    translator.translate({ a: { b: false } })
    #=> { 'x' => { 'y' => true } }
  • delimiter

    Specify a custom delimiter. Default is .

    translator = KeyBridge.new_translator({ 'a@b' => 'x@y' }, delimiter: '@')
    translator.translate({ a: { b: 'c' } })
    #=> { 'x' => { 'y' => 'c' } }

Testing

Run the tests with

bundle exec rake

Notes

  • Makes use of recursion, so don't use it with hashes with keys nested thousands of levels deep, or enable TCO
  • Credit for the first, *rest goes to the inimitable Avdi Grimm

About

Ruby hash translator

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published

Languages