hash_map 0.1.0 → 0.2.0

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 51d76821ef02787e48a5db5f176e275211908853
4
- data.tar.gz: 41f2c3dbcaf07d40e1960620e2b0844d477ae482
3
+ metadata.gz: 09a2c86f0de008f859fd4002f7cd84531714d62b
4
+ data.tar.gz: 5efd346e6d557652d39622bfe7283d6a0ffcf52d
5
5
  SHA512:
6
- metadata.gz: 855212df63008725acd35ac52329b295e6891905a1b940f96db5158a011d4ab5b1dd568f74d55e2b0aa794a10f741a0737071e7235005ee39a5f224e66444df8
7
- data.tar.gz: 517de2379d1e5634afa259f491297a1c3760d55e38dcc0b371a575669fe7becff08ffba308143838a57f7ba53c764c05f0e1f7d1f60b7e9d890d5a580f44084d
6
+ metadata.gz: b041e1a7e7da905df2a8ceff08bcf5de7de7e6d2ec5f8aa5e6c2fbfc2e1af4dd9c924c75ddf211b1dbf6fc7daf84009851a10354bc39aca2259b4df99cf9fd91
7
+ data.tar.gz: 56b443c5b44598d5e442e00f831928873a26ce77534aea20a9a1f3adf74ca335d4693840aa3f5eac9f85a626bf89aa9695408d93e4aab666bd4d04ef12bdc3ce
data/Gemfile CHANGED
@@ -2,3 +2,4 @@ source 'https://rubygems.org'
2
2
 
3
3
  # Specify your gem's dependencies in hash_map.gemspec
4
4
  gemspec
5
+ gem 'pry'
data/README.md CHANGED
@@ -1,8 +1,8 @@
1
1
  # HashMap
2
2
 
3
- Welcome to your new gem! In this directory, you'll find the files you need to be able to package up your Ruby library into a gem. Put your Ruby code in the file `lib/hash_map`. To experiment with that code, run `bin/console` for an interactive prompt.
4
-
5
- TODO: Delete this and the text above, and describe your gem
3
+ HashMap is a small library that allow you to map hashes with style :).
4
+ It will remove from your code many of the ugly navigation inside hashes to
5
+ get your needed hash structure.
6
6
 
7
7
  ## Installation
8
8
 
@@ -22,7 +22,68 @@ Or install it yourself as:
22
22
 
23
23
  ## Usage
24
24
 
25
- TODO: Write usage instructions here
25
+ Your hash:
26
+
27
+ ```ruby
28
+ {
29
+ name: 'Artur',
30
+ first_surname: 'hello',
31
+ second_surname: 'world',
32
+ address: {
33
+ postal_code: 12345,
34
+ country: {
35
+ name: 'Spain',
36
+ language: 'ES'
37
+ }
38
+ },
39
+ email: 'asdf@sdfs.com',
40
+ phone: nil
41
+ }
42
+ ```
43
+
44
+ Your beautiful Mapper:
45
+
46
+ ```ruby
47
+ class ProfileMapper < HashMap::Base
48
+ property :first_name, from: :name
49
+ property(:last_name) { |input| "#{input[:first_surname]} #{input[:second_surname]}" }
50
+ property :language, from: [:address, :country, :language]
51
+
52
+ from_children :address do
53
+ property :code, from: :postal_code
54
+ from_children :country do
55
+ property :country_name
56
+ end
57
+ end
58
+
59
+ to_children :email do
60
+ property :address, from: :email
61
+ property :type, default: :work
62
+ end
63
+
64
+ property :telephone, from: :phone
65
+ end
66
+ ```
67
+
68
+ Your wanted hash:
69
+
70
+ ```ruby
71
+ ProfileMapper.new(original).to_h
72
+ => {
73
+ first_name: "Artur",
74
+ last_name: "hello world",
75
+ language: "ES",
76
+ code: 12345,
77
+ country_name: nil,
78
+ email: {
79
+ address: "asdf@sdfs.com",
80
+ type: :work
81
+ },
82
+ telephone: nil
83
+ }
84
+ ```
85
+
86
+ Enjoy!
26
87
 
27
88
  ## Development
28
89
 
@@ -38,4 +99,3 @@ Bug reports and pull requests are welcome on GitHub at https://github.com/[USERN
38
99
  ## License
39
100
 
40
101
  The gem is available as open source under the terms of the [MIT License](http://opensource.org/licenses/MIT).
41
-
@@ -7,8 +7,8 @@ require "hash_map"
7
7
  # with your gem easier. You can also use a different console, if you like.
8
8
 
9
9
  # (If you use this, don't forget to add pry to your Gemfile!)
10
- # require "pry"
11
- # Pry.start
10
+ require "pry"
11
+ Pry.start
12
12
 
13
- require "irb"
14
- IRB.start
13
+ # require "irb"
14
+ # IRB.start
@@ -22,4 +22,5 @@ Gem::Specification.new do |spec|
22
22
  spec.add_development_dependency "bundler", "~> 1.10"
23
23
  spec.add_development_dependency "rake", "~> 10.0"
24
24
  spec.add_development_dependency "rspec"
25
+ spec.add_dependency 'activesupport', '~> 4.2'
25
26
  end
@@ -1,5 +1,10 @@
1
1
  require "hash_map/version"
2
-
2
+ require 'active_support/all'
3
3
  module HashMap
4
- # Your code goes here...
4
+ def self.root
5
+ File.expand_path '../..', __FILE__
6
+ end
5
7
  end
8
+ require 'hash_map/dsl'
9
+ require 'hash_map/mapper'
10
+ require 'hash_map/base'
@@ -0,0 +1,15 @@
1
+ module HashMap
2
+ class Base < Struct.new(:original)
3
+ include ToDSL
4
+ delegate :[], to: :output
5
+
6
+ def mapper
7
+ @mapper ||= Mapper.new(original, self.class.attributes)
8
+ end
9
+
10
+ def output
11
+ mapper.output
12
+ end
13
+ alias_method :to_h, :output
14
+ end
15
+ end
@@ -0,0 +1,72 @@
1
+ module HashMap
2
+ module ToDSL
3
+ extend ActiveSupport::Concern
4
+ class_methods do
5
+ def method_missing(method, *args, &block)
6
+ if dsl.respond_to?(method)
7
+ dsl.send(method, *args, &block)
8
+ else
9
+ super
10
+ end
11
+ end
12
+
13
+ def dsl
14
+ @dsl ||= DSL.new
15
+ end
16
+
17
+ def attributes
18
+ dsl.attributes
19
+ end
20
+ end
21
+ end
22
+
23
+ class DSL
24
+ attr_reader :attributes
25
+
26
+ def initialize
27
+ @attributes = []
28
+ end
29
+
30
+ def attributes
31
+ @attributes
32
+ end
33
+
34
+ def property(key, opts = {}, &block)
35
+ new = {}.tap{ |h| h[:key] = single_to_ary(key) }
36
+ new[:proc] = block if block
37
+ new[:from] = generate_from(new, opts)
38
+ attributes << new.merge!(opts.except(:from))
39
+ new
40
+ end
41
+
42
+ def from_children(key, opts = {}, &block)
43
+ flat = _nested(key, opts, &block)
44
+ flat.each { |attr| attr[:from].unshift(key) }
45
+ @attributes += flat
46
+ end
47
+
48
+ def to_children(key, opts = {}, &block)
49
+ flat = _nested(key, opts, &block)
50
+ flat.each { |attr| attr[:key].unshift(key) }
51
+ @attributes += flat
52
+ end
53
+
54
+ private
55
+
56
+ def generate_from(hash, opts)
57
+ from = opts[:from]
58
+ from ? single_to_ary(from) : hash[:key].dup
59
+ end
60
+
61
+ def _nested(key, opts = {}, &block)
62
+ klass = self.class.new
63
+ klass.instance_exec(&block)
64
+ klass.attributes.flatten
65
+ end
66
+
67
+ def single_to_ary(elem)
68
+ return if elem.nil?
69
+ elem.is_a?(Array) ? elem : [elem]
70
+ end
71
+ end
72
+ end
@@ -0,0 +1,46 @@
1
+ module HashMap
2
+ class Mapper
3
+ attr_reader :original, :data_structure
4
+ def initialize(original, data_structure)
5
+ @original = HashWithIndifferentAccess.new(original)
6
+ @data_structure = data_structure
7
+ end
8
+
9
+ def output
10
+ new_hash = HashWithIndifferentAccess.new
11
+ data_structure.each do |struc|
12
+ value = get_value(struc)
13
+ new_hash.deep_merge! build_keys(struc[:key], value)
14
+ end
15
+ new_hash
16
+ end
17
+
18
+ private
19
+
20
+ def get_value(struct)
21
+ value = if block = struct[:proc]
22
+ block.call(original)
23
+ elsif struct[:from]
24
+ get_value_from_key(struct)
25
+ end
26
+ nil_to_default(value, struct)
27
+ end
28
+
29
+ def get_value_from_key(struct)
30
+ struct[:from].inject(original) do |output, k|
31
+ break unless output.respond_to?(:[])
32
+ output.send(:[], k)
33
+ end
34
+ end
35
+
36
+ def build_keys(ary, value)
37
+ ary.reverse.inject(value) do |a, n|
38
+ HashWithIndifferentAccess.new({ n => a })
39
+ end
40
+ end
41
+
42
+ def nil_to_default(value, struct)
43
+ value || struct[:default]
44
+ end
45
+ end
46
+ end
@@ -1,3 +1,3 @@
1
1
  module HashMap
2
- VERSION = "0.1.0"
2
+ VERSION = "0.2.0"
3
3
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: hash_map
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.0
4
+ version: 0.2.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Artur Pañach
@@ -52,6 +52,20 @@ dependencies:
52
52
  - - ">="
53
53
  - !ruby/object:Gem::Version
54
54
  version: '0'
55
+ - !ruby/object:Gem::Dependency
56
+ name: activesupport
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - "~>"
60
+ - !ruby/object:Gem::Version
61
+ version: '4.2'
62
+ type: :runtime
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - "~>"
67
+ - !ruby/object:Gem::Version
68
+ version: '4.2'
55
69
  description: Nice DSL to convert hash structure to different one.
56
70
  email:
57
71
  - arturictus@gmail.com
@@ -71,6 +85,9 @@ files:
71
85
  - bin/setup
72
86
  - hash_map.gemspec
73
87
  - lib/hash_map.rb
88
+ - lib/hash_map/base.rb
89
+ - lib/hash_map/dsl.rb
90
+ - lib/hash_map/mapper.rb
74
91
  - lib/hash_map/version.rb
75
92
  homepage: https://github.com/arturictus/hash_map
76
93
  licenses: