hash_map 0.2.0 → 0.3.0
Sign up to get free protection for your applications and to get access to all the features.
- 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
|