transproc 0.2.0 → 0.2.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
 - data/.rubocop.yml +66 -0
 - data/.rubocop_todo.yml +11 -0
 - data/.travis.yml +2 -1
 - data/CHANGELOG.md +31 -2
 - data/Gemfile +5 -0
 - data/Guardfile +2 -2
 - data/README.md +5 -4
 - data/Rakefile +1 -1
 - data/lib/transproc.rb +13 -2
 - data/lib/transproc/all.rb +2 -0
 - data/lib/transproc/array.rb +78 -1
 - data/lib/transproc/class.rb +52 -0
 - data/lib/transproc/composite.rb +50 -0
 - data/lib/transproc/conditional.rb +0 -1
 - data/lib/transproc/error.rb +16 -0
 - data/lib/transproc/function.rb +8 -50
 - data/lib/transproc/hash.rb +52 -2
 - data/lib/transproc/object.rb +19 -0
 - data/lib/transproc/version.rb +1 -1
 - data/rakelib/mutant.rake +16 -0
 - data/rakelib/rubocop.rake +18 -0
 - data/spec/spec_helper.rb +4 -2
 - data/spec/unit/array_transformations_spec.rb +166 -0
 - data/spec/unit/class_transformations_spec.rb +47 -0
 - data/spec/{integration → unit}/coercions_spec.rb +10 -10
 - data/spec/{integration → unit}/composer_spec.rb +0 -0
 - data/spec/{integration → unit}/conditional_spec.rb +2 -2
 - data/spec/{integration → unit}/function_spec.rb +30 -7
 - data/spec/{integration/hash_spec.rb → unit/hash_transformations_spec.rb} +71 -23
 - data/spec/{integration → unit}/recursion_spec.rb +6 -9
 - data/spec/unit/transproc_spec.rb +64 -0
 - data/transproc.gemspec +10 -10
 - metadata +28 -19
 - data/spec/integration/array_spec.rb +0 -98
 - data/spec/integration/transproc_spec.rb +0 -37
 
    
        checksums.yaml
    CHANGED
    
    | 
         @@ -1,7 +1,7 @@ 
     | 
|
| 
       1 
1 
     | 
    
         
             
            ---
         
     | 
| 
       2 
2 
     | 
    
         
             
            SHA1:
         
     | 
| 
       3 
     | 
    
         
            -
              metadata.gz:  
     | 
| 
       4 
     | 
    
         
            -
              data.tar.gz:  
     | 
| 
      
 3 
     | 
    
         
            +
              metadata.gz: c88956f58489c894cec8a4dd8a8714e47b3b1af0
         
     | 
| 
      
 4 
     | 
    
         
            +
              data.tar.gz: 570b8a17eb185d2129fda432dce71160d13fdcc0
         
     | 
| 
       5 
5 
     | 
    
         
             
            SHA512:
         
     | 
| 
       6 
     | 
    
         
            -
              metadata.gz:  
     | 
| 
       7 
     | 
    
         
            -
              data.tar.gz:  
     | 
| 
      
 6 
     | 
    
         
            +
              metadata.gz: c81a55daec46a1cf7f46b0ce4aa99897f2efa598899f335891036fd9531b1e991fb969d4f17a31ef89743eea7cff21c8b72573bac9eb98e02fc45b4212a1a620
         
     | 
| 
      
 7 
     | 
    
         
            +
              data.tar.gz: b6f9740cab83acad2875220322f1a93814ce6e1a861893cceb08903730f2f2208b11f98b229b6a54cf6da63f3b8d1925d52b00e009fc0567c6a953796ffd8032
         
     | 
    
        data/.rubocop.yml
    ADDED
    
    | 
         @@ -0,0 +1,66 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            inherit_from: .rubocop_todo.yml
         
     | 
| 
      
 2 
     | 
    
         
            +
             
     | 
| 
      
 3 
     | 
    
         
            +
            # Exclude temporary files
         
     | 
| 
      
 4 
     | 
    
         
            +
            AllCops:
         
     | 
| 
      
 5 
     | 
    
         
            +
              Exclude:
         
     | 
| 
      
 6 
     | 
    
         
            +
                - tmp/**/*
         
     | 
| 
      
 7 
     | 
    
         
            +
             
     | 
| 
      
 8 
     | 
    
         
            +
            # Allow global Transproc method definition
         
     | 
| 
      
 9 
     | 
    
         
            +
            Style/MethodName:
         
     | 
| 
      
 10 
     | 
    
         
            +
              Exclude:
         
     | 
| 
      
 11 
     | 
    
         
            +
                - lib/transproc.rb
         
     | 
| 
      
 12 
     | 
    
         
            +
             
     | 
| 
      
 13 
     | 
    
         
            +
            # No need to handle LoadError in Rakefile
         
     | 
| 
      
 14 
     | 
    
         
            +
            Lint/HandleExceptions:
         
     | 
| 
      
 15 
     | 
    
         
            +
              Exclude:
         
     | 
| 
      
 16 
     | 
    
         
            +
                - rakelib/*.rake
         
     | 
| 
      
 17 
     | 
    
         
            +
                - spec/spec_helper.rb
         
     | 
| 
      
 18 
     | 
    
         
            +
             
     | 
| 
      
 19 
     | 
    
         
            +
            # It’s quite readable when we know what we are doing
         
     | 
| 
      
 20 
     | 
    
         
            +
            Lint/AssignmentInCondition:
         
     | 
| 
      
 21 
     | 
    
         
            +
              Enabled: false
         
     | 
| 
      
 22 
     | 
    
         
            +
             
     | 
| 
      
 23 
     | 
    
         
            +
            # The enforced style doesn’t match Vim’s defaults
         
     | 
| 
      
 24 
     | 
    
         
            +
            Style/AlignParameters:
         
     | 
| 
      
 25 
     | 
    
         
            +
              Enabled: false
         
     | 
| 
      
 26 
     | 
    
         
            +
             
     | 
| 
      
 27 
     | 
    
         
            +
            # UTF-8 is perfectly fine in comments
         
     | 
| 
      
 28 
     | 
    
         
            +
            Style/AsciiComments:
         
     | 
| 
      
 29 
     | 
    
         
            +
              Enabled: false
         
     | 
| 
      
 30 
     | 
    
         
            +
             
     | 
| 
      
 31 
     | 
    
         
            +
            # Allow using braces for value-returning blocks
         
     | 
| 
      
 32 
     | 
    
         
            +
            Style/BlockDelimiters:
         
     | 
| 
      
 33 
     | 
    
         
            +
              Enabled: false
         
     | 
| 
      
 34 
     | 
    
         
            +
             
     | 
| 
      
 35 
     | 
    
         
            +
            # Documentation checked by Inch CI
         
     | 
| 
      
 36 
     | 
    
         
            +
            Style/Documentation:
         
     | 
| 
      
 37 
     | 
    
         
            +
              Enabled: false
         
     | 
| 
      
 38 
     | 
    
         
            +
             
     | 
| 
      
 39 
     | 
    
         
            +
            # Early returns have their vices
         
     | 
| 
      
 40 
     | 
    
         
            +
            Style/GuardClause:
         
     | 
| 
      
 41 
     | 
    
         
            +
              Enabled: false
         
     | 
| 
      
 42 
     | 
    
         
            +
             
     | 
| 
      
 43 
     | 
    
         
            +
            # Need to be skipped for >-> usage
         
     | 
| 
      
 44 
     | 
    
         
            +
            Style/Lambda:
         
     | 
| 
      
 45 
     | 
    
         
            +
              Enabled: false
         
     | 
| 
      
 46 
     | 
    
         
            +
             
     | 
| 
      
 47 
     | 
    
         
            +
            # Multiline block chains are ok
         
     | 
| 
      
 48 
     | 
    
         
            +
            Style/MultilineBlockChain:
         
     | 
| 
      
 49 
     | 
    
         
            +
              Enabled: false
         
     | 
| 
      
 50 
     | 
    
         
            +
             
     | 
| 
      
 51 
     | 
    
         
            +
            # Even a single escaped slash can be confusing
         
     | 
| 
      
 52 
     | 
    
         
            +
            Style/RegexpLiteral:
         
     | 
| 
      
 53 
     | 
    
         
            +
              MaxSlashes: 0
         
     | 
| 
      
 54 
     | 
    
         
            +
             
     | 
| 
      
 55 
     | 
    
         
            +
            # Don’t introduce semantic fail/raise distinction
         
     | 
| 
      
 56 
     | 
    
         
            +
            Style/SignalException:
         
     | 
| 
      
 57 
     | 
    
         
            +
              EnforcedStyle: only_raise
         
     | 
| 
      
 58 
     | 
    
         
            +
             
     | 
| 
      
 59 
     | 
    
         
            +
            # Allow compact style for specs
         
     | 
| 
      
 60 
     | 
    
         
            +
            Style/ClassAndModuleChildren:
         
     | 
| 
      
 61 
     | 
    
         
            +
              Exclude:
         
     | 
| 
      
 62 
     | 
    
         
            +
                - spec/**/*_spec.rb
         
     | 
| 
      
 63 
     | 
    
         
            +
             
     | 
| 
      
 64 
     | 
    
         
            +
            # Allow logical `or`/`and` in conditionals
         
     | 
| 
      
 65 
     | 
    
         
            +
            Style/AndOr:
         
     | 
| 
      
 66 
     | 
    
         
            +
              EnforcedStyle: conditionals
         
     | 
    
        data/.rubocop_todo.yml
    ADDED
    
    | 
         @@ -0,0 +1,11 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            # This configuration was generated by `rubocop --auto-gen-config`
         
     | 
| 
      
 2 
     | 
    
         
            +
            # on 2015-04-16 18:31:27 +0100 using RuboCop version 0.26.0.
         
     | 
| 
      
 3 
     | 
    
         
            +
            # The point is for the user to remove these configuration records
         
     | 
| 
      
 4 
     | 
    
         
            +
            # one by one as the offenses are removed from the code base.
         
     | 
| 
      
 5 
     | 
    
         
            +
            # Note that changes in the inspected code, or installation of new
         
     | 
| 
      
 6 
     | 
    
         
            +
            # versions of RuboCop, may require this file to be generated again.
         
     | 
| 
      
 7 
     | 
    
         
            +
             
     | 
| 
      
 8 
     | 
    
         
            +
            # Offense count: 11
         
     | 
| 
      
 9 
     | 
    
         
            +
            # Configuration parameters: AllowURI.
         
     | 
| 
      
 10 
     | 
    
         
            +
            Metrics/LineLength:
         
     | 
| 
      
 11 
     | 
    
         
            +
              Max: 110
         
     | 
    
        data/.travis.yml
    CHANGED
    
    
    
        data/CHANGELOG.md
    CHANGED
    
    | 
         @@ -1,10 +1,39 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            ## v0.2.1 2015-05-17
         
     | 
| 
      
 2 
     | 
    
         
            +
             
     | 
| 
      
 3 
     | 
    
         
            +
            ### Added
         
     | 
| 
      
 4 
     | 
    
         
            +
             
     | 
| 
      
 5 
     | 
    
         
            +
            * `:constructor_inject` injects arguments into the constructor of a class (AMHOL)
         
     | 
| 
      
 6 
     | 
    
         
            +
            * `:set_ivars` which allocates an object and sets instance variables from a hash (key/value pairs) on an object (AMHOL)
         
     | 
| 
      
 7 
     | 
    
         
            +
            * `:combine` which merges multiple arrays into one using "join keys" (solnic)
         
     | 
| 
      
 8 
     | 
    
         
            +
            * `:reject_keys` which rejects specified keys in a hash (solnic)
         
     | 
| 
      
 9 
     | 
    
         
            +
            * `:accept_keys` which accepts specified keys in a hash (solnic)
         
     | 
| 
      
 10 
     | 
    
         
            +
            * `:extract_key` converts the array of hashes to array of values (nepalez)
         
     | 
| 
      
 11 
     | 
    
         
            +
             
     | 
| 
      
 12 
     | 
    
         
            +
            ### Changed
         
     | 
| 
      
 13 
     | 
    
         
            +
             
     | 
| 
      
 14 
     | 
    
         
            +
            * `:unwrap` can be called without keys (solnic)
         
     | 
| 
      
 15 
     | 
    
         
            +
            * `Transproc.register` raises a meaningful error when a given function is already registered (kwando)
         
     | 
| 
      
 16 
     | 
    
         
            +
            * `Transproc[]` raises a meaningful error when a given function doesn't exist (kwando)
         
     | 
| 
      
 17 
     | 
    
         
            +
            * `Transproc[]` raises a meaningful error when a transformation crashes (kwando)
         
     | 
| 
      
 18 
     | 
    
         
            +
             
     | 
| 
      
 19 
     | 
    
         
            +
            ### Fixed
         
     | 
| 
      
 20 
     | 
    
         
            +
             
     | 
| 
      
 21 
     | 
    
         
            +
            * `Transproc()` no longer creates a function if it's already a function (splattael)
         
     | 
| 
      
 22 
     | 
    
         
            +
            * A couple of mistakes in the API docs (AMHOL)
         
     | 
| 
      
 23 
     | 
    
         
            +
             
     | 
| 
      
 24 
     | 
    
         
            +
            ### Internal
         
     | 
| 
      
 25 
     | 
    
         
            +
             
     | 
| 
      
 26 
     | 
    
         
            +
            * Rubocop integration \o/ (AMHOL)
         
     | 
| 
      
 27 
     | 
    
         
            +
             
     | 
| 
      
 28 
     | 
    
         
            +
            [Compare v0.2.0...v0.2.1](https://github.com/solnic/transproc/compare/v0.2.0...v0.2.1)
         
     | 
| 
      
 29 
     | 
    
         
            +
             
     | 
| 
       1 
30 
     | 
    
         
             
            ## v0.2.0 2015-04-14
         
     | 
| 
       2 
31 
     | 
    
         | 
| 
       3 
32 
     | 
    
         
             
            ### Added
         
     | 
| 
       4 
33 
     | 
    
         | 
| 
      
 34 
     | 
    
         
            +
            * `:map_keys` hash transformation (AMHOL)
         
     | 
| 
      
 35 
     | 
    
         
            +
            * `:stringify_keys` hash transformation (AMHOL)
         
     | 
| 
       5 
36 
     | 
    
         
             
            * `:map_values` hash transformation (AMHOL)
         
     | 
| 
       6 
     | 
    
         
            -
            * `:map_value` hash transformation (AMHOL)
         
     | 
| 
       7 
     | 
    
         
            -
            * `:map_value` hash transformation (AMHOL)
         
     | 
| 
       8 
37 
     | 
    
         
             
            * `:guard` function (AMHOL)
         
     | 
| 
       9 
38 
     | 
    
         
             
            * `:is` type-check function (solnic)
         
     | 
| 
       10 
39 
     | 
    
         
             
            * `Function#to_ast` for easy inspection (solnic)
         
     | 
    
        data/Gemfile
    CHANGED
    
    | 
         @@ -3,13 +3,18 @@ source 'https://rubygems.org' 
     | 
|
| 
       3 
3 
     | 
    
         
             
            gemspec
         
     | 
| 
       4 
4 
     | 
    
         | 
| 
       5 
5 
     | 
    
         
             
            group :test do
         
     | 
| 
      
 6 
     | 
    
         
            +
              gem 'equalizer'
         
     | 
| 
      
 7 
     | 
    
         
            +
              gem 'anima'
         
     | 
| 
       6 
8 
     | 
    
         
             
              gem 'mutant'
         
     | 
| 
       7 
9 
     | 
    
         
             
              gem 'mutant-rspec'
         
     | 
| 
       8 
10 
     | 
    
         
             
              gem 'codeclimate-test-reporter', require: nil
         
     | 
| 
       9 
11 
     | 
    
         
             
            end
         
     | 
| 
       10 
12 
     | 
    
         | 
| 
       11 
13 
     | 
    
         
             
            group :tools do
         
     | 
| 
      
 14 
     | 
    
         
            +
              gem 'rubocop', '~> 0.30.0'
         
     | 
| 
       12 
15 
     | 
    
         
             
              gem 'byebug', platform: :mri
         
     | 
| 
       13 
16 
     | 
    
         
             
              gem 'benchmark-ips'
         
     | 
| 
      
 17 
     | 
    
         
            +
              gem 'guard'
         
     | 
| 
       14 
18 
     | 
    
         
             
              gem 'guard-rspec'
         
     | 
| 
      
 19 
     | 
    
         
            +
              gem 'guard-rubocop'
         
     | 
| 
       15 
20 
     | 
    
         
             
            end
         
     | 
    
        data/Guardfile
    CHANGED
    
    | 
         @@ -1,4 +1,4 @@ 
     | 
|
| 
       1 
     | 
    
         
            -
            guard :rspec, cmd:  
     | 
| 
      
 1 
     | 
    
         
            +
            guard :rspec, cmd: 'rspec' do
         
     | 
| 
       2 
2 
     | 
    
         
             
              # run all specs if configuration is modified
         
     | 
| 
       3 
3 
     | 
    
         
             
              watch('Guardfile')           { 'spec' }
         
     | 
| 
       4 
4 
     | 
    
         
             
              watch('Gemfile.lock')        { 'spec' }
         
     | 
| 
         @@ -12,5 +12,5 @@ guard :rspec, cmd: "rspec" do 
     | 
|
| 
       12 
12 
     | 
    
         
             
              # run a spec if it is modified
         
     | 
| 
       13 
13 
     | 
    
         
             
              watch(%r{\Aspec/(?:unit|integration)/.+_spec\.rb\z})
         
     | 
| 
       14 
14 
     | 
    
         | 
| 
       15 
     | 
    
         
            -
              notification :tmux, display_message: true
         
     | 
| 
      
 15 
     | 
    
         
            +
              notification :tmux, display_message: true if ENV.key?('TMUX')
         
     | 
| 
       16 
16 
     | 
    
         
             
            end
         
     | 
    
        data/README.md
    CHANGED
    
    | 
         @@ -5,11 +5,11 @@ 
     | 
|
| 
       5 
5 
     | 
    
         
             
            [coveralls]: https://coveralls.io/r/solnic/transproc
         
     | 
| 
       6 
6 
     | 
    
         
             
            [inchpages]: http://inch-ci.org/github/solnic/transproc
         
     | 
| 
       7 
7 
     | 
    
         | 
| 
       8 
     | 
    
         
            -
            # Transproc [](https://gitter.im/solnic/transproc 
     | 
| 
      
 8 
     | 
    
         
            +
            # Transproc [](https://gitter.im/solnic/transproc)
         
     | 
| 
       9 
9 
     | 
    
         | 
| 
       10 
10 
     | 
    
         
             
            [][gem]
         
     | 
| 
       11 
11 
     | 
    
         
             
            [][travis]
         
     | 
| 
       12 
     | 
    
         
            -
            [][gemnasium]
         
     | 
| 
       13 
13 
     | 
    
         
             
            [][codeclimate]
         
     | 
| 
       14 
14 
     | 
    
         
             
            [][codeclimate]
         
     | 
| 
       15 
15 
     | 
    
         
             
            [][inchpages]
         
     | 
| 
         @@ -36,6 +36,7 @@ Or install it yourself as: 
     | 
|
| 
       36 
36 
     | 
    
         
             
            ## Usage
         
     | 
| 
       37 
37 
     | 
    
         | 
| 
       38 
38 
     | 
    
         
             
            ``` ruby
         
     | 
| 
      
 39 
     | 
    
         
            +
            require 'json'
         
     | 
| 
       39 
40 
     | 
    
         
             
            require 'transproc/all'
         
     | 
| 
       40 
41 
     | 
    
         | 
| 
       41 
42 
     | 
    
         
             
            # compose transformation functions
         
     | 
| 
         @@ -56,7 +57,7 @@ transformation.call( 
     | 
|
| 
       56 
57 
     | 
    
         
             
            # => [{:user=>"Jane", :address=>{:city=>"NYC", :street=>"Street 1", :zipcode=>"123"}}]
         
     | 
| 
       57 
58 
     | 
    
         | 
| 
       58 
59 
     | 
    
         
             
            # Define your own transformations easily
         
     | 
| 
       59 
     | 
    
         
            -
            Transproc(:to_json, -> v { JSON.dump(v) })
         
     | 
| 
      
 60 
     | 
    
         
            +
            Transproc.register(:to_json, -> v { JSON.dump(v) })
         
     | 
| 
       60 
61 
     | 
    
         | 
| 
       61 
62 
     | 
    
         
             
            Transproc(:to_json).call([{ name: 'Jane' }])
         
     | 
| 
       62 
63 
     | 
    
         
             
            # => "[{\"name\":\"Jane\"}]"
         
     | 
| 
         @@ -70,7 +71,7 @@ module MyTransformations 
     | 
|
| 
       70 
71 
     | 
    
         
             
              end
         
     | 
| 
       71 
72 
     | 
    
         
             
            end
         
     | 
| 
       72 
73 
     | 
    
         | 
| 
       73 
     | 
    
         
            -
            (Transproc(:load_json) >> Transproc(:symbolize_keys)).call('[{"name":"Jane"}]')
         
     | 
| 
      
 74 
     | 
    
         
            +
            (Transproc(:load_json) >> Transproc(:map_array, Transproc(:symbolize_keys))).call('[{"name":"Jane"}]')
         
     | 
| 
       74 
75 
     | 
    
         
             
            # => [{ :name => "Jane" }]
         
     | 
| 
       75 
76 
     | 
    
         
             
            ```
         
     | 
| 
       76 
77 
     | 
    
         | 
    
        data/Rakefile
    CHANGED
    
    
    
        data/lib/transproc.rb
    CHANGED
    
    | 
         @@ -1,6 +1,7 @@ 
     | 
|
| 
       1 
1 
     | 
    
         
             
            require 'transproc/version'
         
     | 
| 
       2 
2 
     | 
    
         
             
            require 'transproc/function'
         
     | 
| 
       3 
3 
     | 
    
         
             
            require 'transproc/composer'
         
     | 
| 
      
 4 
     | 
    
         
            +
            require 'transproc/error'
         
     | 
| 
       4 
5 
     | 
    
         | 
| 
       5 
6 
     | 
    
         
             
            module Transproc
         
     | 
| 
       6 
7 
     | 
    
         
             
              module_function
         
     | 
| 
         @@ -18,6 +19,9 @@ module Transproc 
     | 
|
| 
       18 
19 
     | 
    
         
             
              # @api public
         
     | 
| 
       19 
20 
     | 
    
         
             
              def register(*args, &block)
         
     | 
| 
       20 
21 
     | 
    
         
             
                name, fn = *args
         
     | 
| 
      
 22 
     | 
    
         
            +
                if functions.include?(name)
         
     | 
| 
      
 23 
     | 
    
         
            +
                  raise FunctionAlreadyRegisteredError, "function #{name} is already defined"
         
     | 
| 
      
 24 
     | 
    
         
            +
                end
         
     | 
| 
       21 
25 
     | 
    
         
             
                functions[name] = fn || block
         
     | 
| 
       22 
26 
     | 
    
         
             
              end
         
     | 
| 
       23 
27 
     | 
    
         | 
| 
         @@ -27,7 +31,9 @@ module Transproc 
     | 
|
| 
       27 
31 
     | 
    
         
             
              #
         
     | 
| 
       28 
32 
     | 
    
         
             
              # @api private
         
     | 
| 
       29 
33 
     | 
    
         
             
              def [](name)
         
     | 
| 
       30 
     | 
    
         
            -
                functions.fetch(name)
         
     | 
| 
      
 34 
     | 
    
         
            +
                functions.fetch(name) {
         
     | 
| 
      
 35 
     | 
    
         
            +
                  raise FunctionNotFoundError, "no registered function for #{name}"
         
     | 
| 
      
 36 
     | 
    
         
            +
                }
         
     | 
| 
       31 
37 
     | 
    
         
             
              end
         
     | 
| 
       32 
38 
     | 
    
         | 
| 
       33 
39 
     | 
    
         
             
              # Function registry
         
     | 
| 
         @@ -75,6 +81,11 @@ end 
     | 
|
| 
       75 
81 
     | 
    
         
             
            def Transproc(fn, *args)
         
     | 
| 
       76 
82 
     | 
    
         
             
              case fn
         
     | 
| 
       77 
83 
     | 
    
         
             
              when Proc then Transproc::Function.new(fn, args: args)
         
     | 
| 
       78 
     | 
    
         
            -
              when Symbol 
     | 
| 
      
 84 
     | 
    
         
            +
              when Symbol
         
     | 
| 
      
 85 
     | 
    
         
            +
                fun = Transproc[fn]
         
     | 
| 
      
 86 
     | 
    
         
            +
                case fun
         
     | 
| 
      
 87 
     | 
    
         
            +
                when Transproc::Function, Transproc::Composite then fun
         
     | 
| 
      
 88 
     | 
    
         
            +
                else Transproc::Function.new(fun, args: args)
         
     | 
| 
      
 89 
     | 
    
         
            +
                end
         
     | 
| 
       79 
90 
     | 
    
         
             
              end
         
     | 
| 
       80 
91 
     | 
    
         
             
            end
         
     | 
    
        data/lib/transproc/all.rb
    CHANGED
    
    
    
        data/lib/transproc/array.rb
    CHANGED
    
    | 
         @@ -16,7 +16,7 @@ module Transproc 
     | 
|
| 
       16 
16 
     | 
    
         
             
              #       { 'city' => 'NYC', 'zipcode' => '312' }
         
     | 
| 
       17 
17 
     | 
    
         
             
              #     ]
         
     | 
| 
       18 
18 
     | 
    
         
             
              #   )
         
     | 
| 
       19 
     | 
    
         
            -
              #   # => [{ 
     | 
| 
      
 19 
     | 
    
         
            +
              #   # => [{:address=>{:city=>"Boston", :zipcode=>"123"}}, {:address=>{:city=>"NYC", :zipcode=>"312"}}]
         
     | 
| 
       20 
20 
     | 
    
         
             
              #
         
     | 
| 
       21 
21 
     | 
    
         
             
              # @api public
         
     | 
| 
       22 
22 
     | 
    
         
             
              module ArrayTransformations
         
     | 
| 
         @@ -98,5 +98,82 @@ module Transproc 
     | 
|
| 
       98 
98 
     | 
    
         
             
                    root.merge(key => children)
         
     | 
| 
       99 
99 
     | 
    
         
             
                  end
         
     | 
| 
       100 
100 
     | 
    
         
             
                end
         
     | 
| 
      
 101 
     | 
    
         
            +
             
     | 
| 
      
 102 
     | 
    
         
            +
                # Combines two arrays by merging child items from right array using join keys
         
     | 
| 
      
 103 
     | 
    
         
            +
                #
         
     | 
| 
      
 104 
     | 
    
         
            +
                # @example
         
     | 
| 
      
 105 
     | 
    
         
            +
                #   fn = t(:combine, [[:tasks, name: :user]])
         
     | 
| 
      
 106 
     | 
    
         
            +
                #
         
     | 
| 
      
 107 
     | 
    
         
            +
                #   fn.call([[{ name: 'Jane' }], [{ user: 'Jane', title: 'One' }]])
         
     | 
| 
      
 108 
     | 
    
         
            +
                #   # => [{:name=>"Jane", :tasks=>[{:user=>"Jane", :title=>"One"}]}]
         
     | 
| 
      
 109 
     | 
    
         
            +
                #
         
     | 
| 
      
 110 
     | 
    
         
            +
                # @param [Array<Array>] array The input array
         
     | 
| 
      
 111 
     | 
    
         
            +
                # @param [Array<Hash>] mappings The mapping definitions array
         
     | 
| 
      
 112 
     | 
    
         
            +
                #
         
     | 
| 
      
 113 
     | 
    
         
            +
                # @return [Array<Hash>]
         
     | 
| 
      
 114 
     | 
    
         
            +
                #
         
     | 
| 
      
 115 
     | 
    
         
            +
                # @api public
         
     | 
| 
      
 116 
     | 
    
         
            +
                def combine(array, mappings)
         
     | 
| 
      
 117 
     | 
    
         
            +
                  root, groups = array
         
     | 
| 
      
 118 
     | 
    
         
            +
             
     | 
| 
      
 119 
     | 
    
         
            +
                  cache = Hash.new { |h, k| h[k] = Hash.new }
         
     | 
| 
      
 120 
     | 
    
         
            +
             
     | 
| 
      
 121 
     | 
    
         
            +
                  root.map { |parent|
         
     | 
| 
      
 122 
     | 
    
         
            +
                    child_hash = {}
         
     | 
| 
      
 123 
     | 
    
         
            +
             
     | 
| 
      
 124 
     | 
    
         
            +
                    groups.each_with_index do |candidates, index|
         
     | 
| 
      
 125 
     | 
    
         
            +
                      key, keys, group_mappings = mappings[index]
         
     | 
| 
      
 126 
     | 
    
         
            +
             
     | 
| 
      
 127 
     | 
    
         
            +
                      children =
         
     | 
| 
      
 128 
     | 
    
         
            +
                        if group_mappings
         
     | 
| 
      
 129 
     | 
    
         
            +
                          combine(candidates, group_mappings)
         
     | 
| 
      
 130 
     | 
    
         
            +
                        else
         
     | 
| 
      
 131 
     | 
    
         
            +
                          candidates
         
     | 
| 
      
 132 
     | 
    
         
            +
                        end
         
     | 
| 
      
 133 
     | 
    
         
            +
             
     | 
| 
      
 134 
     | 
    
         
            +
                      child_keys = keys.values
         
     | 
| 
      
 135 
     | 
    
         
            +
                      pkey_value = parent.values_at(*keys.keys) # ugh
         
     | 
| 
      
 136 
     | 
    
         
            +
             
     | 
| 
      
 137 
     | 
    
         
            +
                      cache[key][child_keys] ||= children.group_by { |child|
         
     | 
| 
      
 138 
     | 
    
         
            +
                        child.values_at(*child_keys)
         
     | 
| 
      
 139 
     | 
    
         
            +
                      }
         
     | 
| 
      
 140 
     | 
    
         
            +
                      child_arr = cache[key][child_keys][pkey_value] || []
         
     | 
| 
      
 141 
     | 
    
         
            +
             
     | 
| 
      
 142 
     | 
    
         
            +
                      child_hash.update(key => child_arr)
         
     | 
| 
      
 143 
     | 
    
         
            +
                    end
         
     | 
| 
      
 144 
     | 
    
         
            +
             
     | 
| 
      
 145 
     | 
    
         
            +
                    parent.merge(child_hash)
         
     | 
| 
      
 146 
     | 
    
         
            +
                  }
         
     | 
| 
      
 147 
     | 
    
         
            +
                end
         
     | 
| 
      
 148 
     | 
    
         
            +
             
     | 
| 
      
 149 
     | 
    
         
            +
                # Converts the array of hashes to array of values, extracted by given key
         
     | 
| 
      
 150 
     | 
    
         
            +
                #
         
     | 
| 
      
 151 
     | 
    
         
            +
                # @example
         
     | 
| 
      
 152 
     | 
    
         
            +
                #   fn = t(:extract_key, :name)
         
     | 
| 
      
 153 
     | 
    
         
            +
                #   fn.call [
         
     | 
| 
      
 154 
     | 
    
         
            +
                #     { name: 'Alice', role: 'sender' },
         
     | 
| 
      
 155 
     | 
    
         
            +
                #     { name: 'Bob', role: 'receiver' },
         
     | 
| 
      
 156 
     | 
    
         
            +
                #     { role: 'listener' }
         
     | 
| 
      
 157 
     | 
    
         
            +
                #   ]
         
     | 
| 
      
 158 
     | 
    
         
            +
                #   # => ['Alice', 'Bob', nil]
         
     | 
| 
      
 159 
     | 
    
         
            +
                #
         
     | 
| 
      
 160 
     | 
    
         
            +
                # @param [Array<Hash>] array The input array of hashes
         
     | 
| 
      
 161 
     | 
    
         
            +
                # @param [Object] key The key to extract values by
         
     | 
| 
      
 162 
     | 
    
         
            +
                #
         
     | 
| 
      
 163 
     | 
    
         
            +
                # @return [Array]
         
     | 
| 
      
 164 
     | 
    
         
            +
                #
         
     | 
| 
      
 165 
     | 
    
         
            +
                # @api public
         
     | 
| 
      
 166 
     | 
    
         
            +
                def extract_key(array, key)
         
     | 
| 
      
 167 
     | 
    
         
            +
                  extract_key!(Array[*array], key)
         
     | 
| 
      
 168 
     | 
    
         
            +
                end
         
     | 
| 
      
 169 
     | 
    
         
            +
             
     | 
| 
      
 170 
     | 
    
         
            +
                # Same as `extract_key` but mutates the array
         
     | 
| 
      
 171 
     | 
    
         
            +
                #
         
     | 
| 
      
 172 
     | 
    
         
            +
                # @see ArrayTransformations.extract_key
         
     | 
| 
      
 173 
     | 
    
         
            +
                #
         
     | 
| 
      
 174 
     | 
    
         
            +
                # @api public
         
     | 
| 
      
 175 
     | 
    
         
            +
                def extract_key!(array, key)
         
     | 
| 
      
 176 
     | 
    
         
            +
                  map_array!(array, -> v { v[key] })
         
     | 
| 
      
 177 
     | 
    
         
            +
                end
         
     | 
| 
       101 
178 
     | 
    
         
             
              end
         
     | 
| 
       102 
179 
     | 
    
         
             
            end
         
     | 
| 
         @@ -0,0 +1,52 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            module Transproc
         
     | 
| 
      
 2 
     | 
    
         
            +
              # Transformation functions for Classes
         
     | 
| 
      
 3 
     | 
    
         
            +
              #
         
     | 
| 
      
 4 
     | 
    
         
            +
              # @example
         
     | 
| 
      
 5 
     | 
    
         
            +
              #   require 'transproc/class'
         
     | 
| 
      
 6 
     | 
    
         
            +
              #
         
     | 
| 
      
 7 
     | 
    
         
            +
              #   include Transproc::Helper
         
     | 
| 
      
 8 
     | 
    
         
            +
              #
         
     | 
| 
      
 9 
     | 
    
         
            +
              #   fn = t(:constructor_inject, 'User', :name, :age)
         
     | 
| 
      
 10 
     | 
    
         
            +
              #
         
     | 
| 
      
 11 
     | 
    
         
            +
              #   fn[Struct]
         
     | 
| 
      
 12 
     | 
    
         
            +
              #   # => Struct::User
         
     | 
| 
      
 13 
     | 
    
         
            +
              #
         
     | 
| 
      
 14 
     | 
    
         
            +
              # @api public
         
     | 
| 
      
 15 
     | 
    
         
            +
              module ClassTransformations
         
     | 
| 
      
 16 
     | 
    
         
            +
                extend Functions
         
     | 
| 
      
 17 
     | 
    
         
            +
             
     | 
| 
      
 18 
     | 
    
         
            +
                # Inject given arguments into the constructor of the class
         
     | 
| 
      
 19 
     | 
    
         
            +
                #
         
     | 
| 
      
 20 
     | 
    
         
            +
                # @example
         
     | 
| 
      
 21 
     | 
    
         
            +
                #   Transproct(:constructor_inject, 'User', :name, :age)[Struct]
         
     | 
| 
      
 22 
     | 
    
         
            +
                #   # => Struct::User
         
     | 
| 
      
 23 
     | 
    
         
            +
                #
         
     | 
| 
      
 24 
     | 
    
         
            +
                # @param [Class]
         
     | 
| 
      
 25 
     | 
    
         
            +
                #
         
     | 
| 
      
 26 
     | 
    
         
            +
                # @return [Mixed]
         
     | 
| 
      
 27 
     | 
    
         
            +
                #
         
     | 
| 
      
 28 
     | 
    
         
            +
                # @api public
         
     | 
| 
      
 29 
     | 
    
         
            +
                def constructor_inject(*args, klass)
         
     | 
| 
      
 30 
     | 
    
         
            +
                  klass.new(*args)
         
     | 
| 
      
 31 
     | 
    
         
            +
                end
         
     | 
| 
      
 32 
     | 
    
         
            +
             
     | 
| 
      
 33 
     | 
    
         
            +
                # Set instance variables from the hash argument (key/value pairs) on the object
         
     | 
| 
      
 34 
     | 
    
         
            +
                #
         
     | 
| 
      
 35 
     | 
    
         
            +
                # @example
         
     | 
| 
      
 36 
     | 
    
         
            +
                #   Transproc(:set_ivars, Object)[name: 'Jane', age: 25]
         
     | 
| 
      
 37 
     | 
    
         
            +
                #   # => #<Object:0x007f411d06a210 @name="Jane", @age=25>
         
     | 
| 
      
 38 
     | 
    
         
            +
                #
         
     | 
| 
      
 39 
     | 
    
         
            +
                # @param [Object]
         
     | 
| 
      
 40 
     | 
    
         
            +
                #
         
     | 
| 
      
 41 
     | 
    
         
            +
                # @return [Object]
         
     | 
| 
      
 42 
     | 
    
         
            +
                #
         
     | 
| 
      
 43 
     | 
    
         
            +
                # @api public
         
     | 
| 
      
 44 
     | 
    
         
            +
                def set_ivars(ivar_hash, klass)
         
     | 
| 
      
 45 
     | 
    
         
            +
                  object = klass.allocate
         
     | 
| 
      
 46 
     | 
    
         
            +
                  ivar_hash.each do |ivar_name, ivar_value|
         
     | 
| 
      
 47 
     | 
    
         
            +
                    object.instance_variable_set("@#{ivar_name}", ivar_value)
         
     | 
| 
      
 48 
     | 
    
         
            +
                  end
         
     | 
| 
      
 49 
     | 
    
         
            +
                  object
         
     | 
| 
      
 50 
     | 
    
         
            +
                end
         
     | 
| 
      
 51 
     | 
    
         
            +
              end
         
     | 
| 
      
 52 
     | 
    
         
            +
            end
         
     | 
| 
         @@ -0,0 +1,50 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            module Transproc
         
     | 
| 
      
 2 
     | 
    
         
            +
              # Composition of two functions
         
     | 
| 
      
 3 
     | 
    
         
            +
              #
         
     | 
| 
      
 4 
     | 
    
         
            +
              # @api private
         
     | 
| 
      
 5 
     | 
    
         
            +
              class Composite
         
     | 
| 
      
 6 
     | 
    
         
            +
                # @return [Proc]
         
     | 
| 
      
 7 
     | 
    
         
            +
                #
         
     | 
| 
      
 8 
     | 
    
         
            +
                # @api private
         
     | 
| 
      
 9 
     | 
    
         
            +
                attr_reader :left
         
     | 
| 
      
 10 
     | 
    
         
            +
             
     | 
| 
      
 11 
     | 
    
         
            +
                # @return [Proc]
         
     | 
| 
      
 12 
     | 
    
         
            +
                #
         
     | 
| 
      
 13 
     | 
    
         
            +
                # @api private
         
     | 
| 
      
 14 
     | 
    
         
            +
                attr_reader :right
         
     | 
| 
      
 15 
     | 
    
         
            +
             
     | 
| 
      
 16 
     | 
    
         
            +
                # @api private
         
     | 
| 
      
 17 
     | 
    
         
            +
                def initialize(left, right)
         
     | 
| 
      
 18 
     | 
    
         
            +
                  @left = left
         
     | 
| 
      
 19 
     | 
    
         
            +
                  @right = right
         
     | 
| 
      
 20 
     | 
    
         
            +
                end
         
     | 
| 
      
 21 
     | 
    
         
            +
             
     | 
| 
      
 22 
     | 
    
         
            +
                # Call right side with the result from the left side
         
     | 
| 
      
 23 
     | 
    
         
            +
                #
         
     | 
| 
      
 24 
     | 
    
         
            +
                # @param [Object] value The input value
         
     | 
| 
      
 25 
     | 
    
         
            +
                #
         
     | 
| 
      
 26 
     | 
    
         
            +
                # @return [Object]
         
     | 
| 
      
 27 
     | 
    
         
            +
                #
         
     | 
| 
      
 28 
     | 
    
         
            +
                # @api public
         
     | 
| 
      
 29 
     | 
    
         
            +
                def call(value)
         
     | 
| 
      
 30 
     | 
    
         
            +
                  right[left[value]]
         
     | 
| 
      
 31 
     | 
    
         
            +
                end
         
     | 
| 
      
 32 
     | 
    
         
            +
                alias_method :[], :call
         
     | 
| 
      
 33 
     | 
    
         
            +
             
     | 
| 
      
 34 
     | 
    
         
            +
                # @see Function#compose
         
     | 
| 
      
 35 
     | 
    
         
            +
                #
         
     | 
| 
      
 36 
     | 
    
         
            +
                # @api public
         
     | 
| 
      
 37 
     | 
    
         
            +
                def compose(other)
         
     | 
| 
      
 38 
     | 
    
         
            +
                  self.class.new(self, other)
         
     | 
| 
      
 39 
     | 
    
         
            +
                end
         
     | 
| 
      
 40 
     | 
    
         
            +
                alias_method :+, :compose
         
     | 
| 
      
 41 
     | 
    
         
            +
                alias_method :>>, :compose
         
     | 
| 
      
 42 
     | 
    
         
            +
             
     | 
| 
      
 43 
     | 
    
         
            +
                # @see Function#to_ast
         
     | 
| 
      
 44 
     | 
    
         
            +
                #
         
     | 
| 
      
 45 
     | 
    
         
            +
                # @api public
         
     | 
| 
      
 46 
     | 
    
         
            +
                def to_ast
         
     | 
| 
      
 47 
     | 
    
         
            +
                  left.to_ast << right.to_ast
         
     | 
| 
      
 48 
     | 
    
         
            +
                end
         
     | 
| 
      
 49 
     | 
    
         
            +
              end
         
     | 
| 
      
 50 
     | 
    
         
            +
            end
         
     |