hash_map 0.2.0 → 0.3.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 +4 -4
- data/README.md +102 -7
- data/lib/hash_map/base.rb +6 -1
- data/lib/hash_map/dsl.rb +26 -8
- data/lib/hash_map/mapper.rb +14 -4
- data/lib/hash_map/version.rb +1 -1
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 94701f9bddaba8235a48d0340f4c900c0d73cf1a
|
4
|
+
data.tar.gz: 827a696b1b3194e1b83857795772cc4e78c4d7b0
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 6507b7366edc76cb9f072c6eecab282a8abaf8e18759dbb77d54766f4546946eafee13491ba7b6137a74f54c289900ce7f1bb36ed38123b905a94a282926b216
|
7
|
+
data.tar.gz: 8897e48ef5d0272feb79db75fee7390bda74ed9287139c226022a802b3b81757d33178349669e05b2b009db333bb77985a4eecb4af396be1f258d23fd02ebad4
|
data/README.md
CHANGED
@@ -46,17 +46,21 @@ Your beautiful Mapper:
|
|
46
46
|
```ruby
|
47
47
|
class ProfileMapper < HashMap::Base
|
48
48
|
property :first_name, from: :name
|
49
|
-
|
49
|
+
|
50
|
+
property :last_name do |input|
|
51
|
+
"#{input[:first_surname]} #{input[:second_surname]}"
|
52
|
+
end
|
53
|
+
|
50
54
|
property :language, from: [:address, :country, :language]
|
51
55
|
|
52
|
-
|
56
|
+
from_child :address do
|
53
57
|
property :code, from: :postal_code
|
54
|
-
|
55
|
-
property :country_name
|
58
|
+
from_child :country do
|
59
|
+
property :country_name, from: :name
|
56
60
|
end
|
57
61
|
end
|
58
62
|
|
59
|
-
|
63
|
+
to_child :email do
|
60
64
|
property :address, from: :email
|
61
65
|
property :type, default: :work
|
62
66
|
end
|
@@ -68,13 +72,13 @@ end
|
|
68
72
|
Your wanted hash:
|
69
73
|
|
70
74
|
```ruby
|
71
|
-
ProfileMapper.
|
75
|
+
ProfileMapper.map(original)
|
72
76
|
=> {
|
73
77
|
first_name: "Artur",
|
74
78
|
last_name: "hello world",
|
75
79
|
language: "ES",
|
76
80
|
code: 12345,
|
77
|
-
country_name:
|
81
|
+
country_name: "Spain",
|
78
82
|
email: {
|
79
83
|
address: "asdf@sdfs.com",
|
80
84
|
type: :work
|
@@ -82,9 +86,100 @@ ProfileMapper.new(original).to_h
|
|
82
86
|
telephone: nil
|
83
87
|
}
|
84
88
|
```
|
89
|
+
**IMPORTANT:**
|
90
|
+
- The **output** is a **HashWithIndifferentAccess** you can access the values with strings or symbols.
|
91
|
+
- The input is transformed as well, that's why you do not need to use strings.
|
85
92
|
|
86
93
|
Enjoy!
|
87
94
|
|
95
|
+
### Examples:
|
96
|
+
**no from needed**
|
97
|
+
```ruby
|
98
|
+
class Clever < HashMap::Base
|
99
|
+
property :name # will get value from the key 'name'
|
100
|
+
property :address
|
101
|
+
end
|
102
|
+
```
|
103
|
+
|
104
|
+
**properties**
|
105
|
+
```ruby
|
106
|
+
class Properties < HashMap::Base
|
107
|
+
properties :name, :address, :house
|
108
|
+
end
|
109
|
+
```
|
110
|
+
|
111
|
+
**blocks:**
|
112
|
+
|
113
|
+
If in **fron_child** block when you want to get the value with a block
|
114
|
+
the value of the child and original will be yielded in this order: child, original
|
115
|
+
|
116
|
+
```ruby
|
117
|
+
class Blocks < HashMap::Base
|
118
|
+
from_child :address do
|
119
|
+
property :street do |address|
|
120
|
+
address[:street].upcase
|
121
|
+
end
|
122
|
+
property :owner do |address, original|
|
123
|
+
original[:name]
|
124
|
+
end
|
125
|
+
from_child :country do
|
126
|
+
property :country do |country|
|
127
|
+
country[:code].upcase
|
128
|
+
end
|
129
|
+
end
|
130
|
+
end
|
131
|
+
property :name do |original|
|
132
|
+
original[:name]
|
133
|
+
end
|
134
|
+
end
|
135
|
+
|
136
|
+
hash = {
|
137
|
+
name: 'name',
|
138
|
+
address:{
|
139
|
+
street: 'street',
|
140
|
+
country:{
|
141
|
+
code: 'es'
|
142
|
+
}
|
143
|
+
}
|
144
|
+
}
|
145
|
+
|
146
|
+
Blocks.map(hash)
|
147
|
+
# => {"street"=>"STREET", "owner"=>"name", "country"=>"ES", "name"=>"name"}
|
148
|
+
|
149
|
+
```
|
150
|
+
|
151
|
+
### Motivation
|
152
|
+
I got bored of doing this:
|
153
|
+
```ruby
|
154
|
+
# this is a hash from an API
|
155
|
+
hash = JSON.parse(response, :symbolize_names => true)
|
156
|
+
# hash = {
|
157
|
+
# user: {
|
158
|
+
# name: 'John',
|
159
|
+
# last_name: 'Doe',
|
160
|
+
# telephone: '989898',
|
161
|
+
# country: {
|
162
|
+
# code: 'es'
|
163
|
+
# }
|
164
|
+
# }
|
165
|
+
# }
|
166
|
+
|
167
|
+
user_hash = hash[:user]
|
168
|
+
user = User.new
|
169
|
+
user.name = user_hash[:name]
|
170
|
+
user.lastname = user_hash[:last_name]
|
171
|
+
user.phone = Phone.parse(user_hash[:telephone])
|
172
|
+
user.country = Country.find_by(code: user_hash[:country][:code])
|
173
|
+
|
174
|
+
# boring!!!
|
175
|
+
# and that's a tiny response
|
176
|
+
```
|
177
|
+
|
178
|
+
solution:
|
179
|
+
```ruby
|
180
|
+
user = User.new(MyMapper.map(hash)) # done
|
181
|
+
```
|
182
|
+
|
88
183
|
## Development
|
89
184
|
|
90
185
|
After checking out the repo, run `bin/setup` to install dependencies. Then, run `rake rspec` to run the tests. You can also run `bin/console` for an interactive prompt that will allow you to experiment.
|
data/lib/hash_map/base.rb
CHANGED
@@ -3,13 +3,18 @@ module HashMap
|
|
3
3
|
include ToDSL
|
4
4
|
delegate :[], to: :output
|
5
5
|
|
6
|
+
def self.map(input)
|
7
|
+
new(input).output
|
8
|
+
end
|
9
|
+
|
6
10
|
def mapper
|
7
11
|
@mapper ||= Mapper.new(original, self.class.attributes)
|
8
12
|
end
|
9
13
|
|
10
14
|
def output
|
11
|
-
mapper.output
|
15
|
+
@output ||= mapper.output
|
12
16
|
end
|
13
17
|
alias_method :to_h, :output
|
18
|
+
alias_method :to_hash, :output
|
14
19
|
end
|
15
20
|
end
|
data/lib/hash_map/dsl.rb
CHANGED
@@ -32,20 +32,39 @@ module HashMap
|
|
32
32
|
end
|
33
33
|
|
34
34
|
def property(key, opts = {}, &block)
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
attributes <<
|
39
|
-
|
35
|
+
new_hash = {}.tap{ |h| h[:key] = single_to_ary(key) }
|
36
|
+
new_hash[:proc] = block if block
|
37
|
+
new_hash[:from] = generate_from(new_hash, opts)
|
38
|
+
attributes << new_hash.merge!(opts.except(:from))
|
39
|
+
new_hash
|
40
|
+
end
|
41
|
+
|
42
|
+
def properties(*args)
|
43
|
+
args.each do |arg|
|
44
|
+
property(*arg)
|
45
|
+
end
|
40
46
|
end
|
41
47
|
|
42
48
|
def from_children(key, opts = {}, &block)
|
49
|
+
puts "[Depercation Warning] using: #{__callee__} use from_child instead"
|
50
|
+
from_child(key, opts, &block)
|
51
|
+
end
|
52
|
+
|
53
|
+
def from_child(key, opts = {}, &block)
|
43
54
|
flat = _nested(key, opts, &block)
|
44
|
-
flat.each
|
55
|
+
flat.each do |attr|
|
56
|
+
attr[:from].unshift(key)
|
57
|
+
attr[:from_child] ? attr[:from_child].unshift(key) : attr[:from_child] = [key]
|
58
|
+
end
|
45
59
|
@attributes += flat
|
46
60
|
end
|
47
61
|
|
48
62
|
def to_children(key, opts = {}, &block)
|
63
|
+
puts "[Depercation Warning] using: #{__callee__} use to_child instead"
|
64
|
+
to_child(key, opts, &block)
|
65
|
+
end
|
66
|
+
|
67
|
+
def to_child(key, opts = {}, &block)
|
49
68
|
flat = _nested(key, opts, &block)
|
50
69
|
flat.each { |attr| attr[:key].unshift(key) }
|
51
70
|
@attributes += flat
|
@@ -65,8 +84,7 @@ module HashMap
|
|
65
84
|
end
|
66
85
|
|
67
86
|
def single_to_ary(elem)
|
68
|
-
|
69
|
-
elem.is_a?(Array) ? elem : [elem]
|
87
|
+
Array.wrap(elem)
|
70
88
|
end
|
71
89
|
end
|
72
90
|
end
|
data/lib/hash_map/mapper.rb
CHANGED
@@ -18,21 +18,31 @@ module HashMap
|
|
18
18
|
private
|
19
19
|
|
20
20
|
def get_value(struct)
|
21
|
-
value = if
|
22
|
-
|
21
|
+
value = if struct[:proc]
|
22
|
+
execute_block(struct)
|
23
23
|
elsif struct[:from]
|
24
24
|
get_value_from_key(struct)
|
25
25
|
end
|
26
26
|
nil_to_default(value, struct)
|
27
27
|
end
|
28
28
|
|
29
|
-
def get_value_from_key(struct)
|
30
|
-
struct[
|
29
|
+
def get_value_from_key(struct, from = :from)
|
30
|
+
struct[from].inject(original) do |output, k|
|
31
31
|
break unless output.respond_to?(:[])
|
32
32
|
output.send(:[], k)
|
33
33
|
end
|
34
34
|
end
|
35
35
|
|
36
|
+
def execute_block(struct)
|
37
|
+
block = struct[:proc]
|
38
|
+
if struct[:from_child]
|
39
|
+
nested = get_value_from_key(struct, :from_child)
|
40
|
+
block.call(nested, original)
|
41
|
+
else
|
42
|
+
block.call(original, original)
|
43
|
+
end
|
44
|
+
end
|
45
|
+
|
36
46
|
def build_keys(ary, value)
|
37
47
|
ary.reverse.inject(value) do |a, n|
|
38
48
|
HashWithIndifferentAccess.new({ n => a })
|
data/lib/hash_map/version.rb
CHANGED
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: hash_map
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.3.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Artur Pañach
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date: 2015-
|
11
|
+
date: 2015-11-19 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: bundler
|