lazy_mapper 0.2.0 → 0.2.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.gitignore +1 -0
- data/README.md +5 -1
- data/lazy_mapper.gemspec +1 -1
- data/lib/lazy_mapper.rb +65 -50
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 9fc03c578aa1fc21f450802874c88cacfd78512e963d8dd840c59a3258bb18cf
|
4
|
+
data.tar.gz: 6566aec14a6fd1c00eac05f3e5c973c5a48628e086c2631641c426426240bd97
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 8ef3c23e999803cae1da99eeb44cc6185be584507e32f1cf2ba827fe218d09ee9ff3d7d891b3647fa8bb71500d8208d0fbc868af7d72c1c3fc4b748ac6a01d2a
|
7
|
+
data.tar.gz: abd2639ae80601c08b13a861e9d76ae7271e3da5d93f1027e81f4623f681614b6c8fadaed0bb22ef54ffb4806eb81b7e09e54a5e494f78ca43af5ea53bb58ef1
|
data/.gitignore
CHANGED
data/README.md
CHANGED
data/lazy_mapper.gemspec
CHANGED
data/lib/lazy_mapper.rb
CHANGED
@@ -2,7 +2,7 @@ require 'bigdecimal'
|
|
2
2
|
require 'bigdecimal/util'
|
3
3
|
require 'time'
|
4
4
|
|
5
|
-
|
5
|
+
#
|
6
6
|
# Wraps a JSON object and lazily maps its attributes to domain objects
|
7
7
|
# using either a set of default mappers (for Ruby's built-in types), or
|
8
8
|
# custom mappers specified by the client.
|
@@ -20,20 +20,25 @@ require 'time'
|
|
20
20
|
|
21
21
|
class LazyMapper
|
22
22
|
|
23
|
+
#
|
23
24
|
# Default mappings for built-in types
|
25
|
+
#
|
24
26
|
DEFAULT_MAPPINGS = {
|
25
|
-
Object =>
|
26
|
-
String =>
|
27
|
-
Integer =>
|
28
|
-
BigDecimal =>
|
29
|
-
Float =>
|
30
|
-
Symbol =>
|
31
|
-
Hash =>
|
27
|
+
Object => :itself.to_proc,
|
28
|
+
String => :to_s.to_proc,
|
29
|
+
Integer => :to_i.to_proc,
|
30
|
+
BigDecimal => :to_d.to_proc,
|
31
|
+
Float => :to_f.to_proc,
|
32
|
+
Symbol => :to_sym.to_proc,
|
33
|
+
Hash => :to_h.to_proc,
|
32
34
|
Time => Time.method(:iso8601),
|
33
35
|
Date => Date.method(:parse),
|
34
36
|
URI => URI.method(:parse)
|
35
37
|
}.freeze
|
36
38
|
|
39
|
+
#
|
40
|
+
# Adds (or overrides) a default type for a given type
|
41
|
+
#
|
37
42
|
def self.default_value_for type, value
|
38
43
|
default_values[type] = value
|
39
44
|
end
|
@@ -42,8 +47,9 @@ class LazyMapper
|
|
42
47
|
@default_values ||= DEFAULT_VALUES
|
43
48
|
end
|
44
49
|
|
45
|
-
|
46
|
-
# Default values for
|
50
|
+
#
|
51
|
+
# Default values for built-in value types
|
52
|
+
#
|
47
53
|
DEFAULT_VALUES = {
|
48
54
|
String => '',
|
49
55
|
Integer => 0,
|
@@ -53,6 +59,9 @@ class LazyMapper
|
|
53
59
|
Array => []
|
54
60
|
}.freeze
|
55
61
|
|
62
|
+
#
|
63
|
+
# Adds a mapper for a give type
|
64
|
+
#
|
56
65
|
def self.mapper_for(type, mapper)
|
57
66
|
mappers[type] = mapper
|
58
67
|
end
|
@@ -82,9 +91,11 @@ class LazyMapper
|
|
82
91
|
|
83
92
|
WRITER = -> name { (name.to_s.gsub('?', '') + '=').to_sym }
|
84
93
|
|
85
|
-
# = ::new
|
86
94
|
#
|
87
|
-
#
|
95
|
+
# Creates a new instance by giving a Hash of attribues.
|
96
|
+
#
|
97
|
+
# Attribute values are type checked according to how they were defined.
|
98
|
+
# If a value has the wrong type, a `TypeError` is raised.
|
88
99
|
#
|
89
100
|
# == Example
|
90
101
|
#
|
@@ -106,23 +117,34 @@ class LazyMapper
|
|
106
117
|
end
|
107
118
|
end
|
108
119
|
|
109
|
-
# = ::from_json
|
110
120
|
#
|
111
121
|
# Create a new instance by giving a Hash of unmapped attributes.
|
112
122
|
#
|
113
123
|
# The keys in the Hash are assumed to be camelCased strings.
|
114
124
|
#
|
125
|
+
# == Arguments
|
126
|
+
#
|
127
|
+
# +json+ - The unmapped data as a Hash(-like object). Must respond to #to_h.
|
128
|
+
# Keys are assumed to be camelCased string
|
129
|
+
#
|
130
|
+
# +mappers:+ - Optional instance-level mappers.
|
131
|
+
# Keys can either be classes or symbols corresponding to named attributes.
|
132
|
+
#
|
133
|
+
#
|
115
134
|
# == Example
|
116
135
|
#
|
117
|
-
# Foo.from_json
|
136
|
+
# Foo.from_json({
|
137
|
+
# "xmlId" => 42,
|
118
138
|
# "createdAt" => "2015-07-29 14:07:35 +0200",
|
119
139
|
# "amount" => "$2.00",
|
120
140
|
# "users" => [
|
121
141
|
# { "id" => 23, "name" => "Adam" },
|
122
142
|
# { "id" => 45, "name" => "Ole" },
|
123
143
|
# { "id" => 66, "name" => "Anders" },
|
124
|
-
# { "id" => 91, "name" => "Kristoffer" }
|
125
|
-
#
|
144
|
+
# { "id" => 91, "name" => "Kristoffer" } ]},
|
145
|
+
# mappers: {
|
146
|
+
# :amount => -> x { Money.new(x) },
|
147
|
+
# User => User.method(:new) })
|
126
148
|
#
|
127
149
|
def self.from_json json, mappers: {}
|
128
150
|
return nil if json.nil?
|
@@ -137,29 +159,24 @@ class LazyMapper
|
|
137
159
|
@attributes ||= {}
|
138
160
|
end
|
139
161
|
|
140
|
-
# = ::one
|
141
162
|
#
|
142
163
|
# Defines an attribute and creates a reader and a writer for it.
|
143
164
|
# The writer verifies the type of it's supplied value.
|
144
165
|
#
|
145
166
|
# == Arguments
|
146
167
|
#
|
147
|
-
# +name+
|
168
|
+
# +name+ - The name of the attribue
|
148
169
|
#
|
149
|
-
# +type+
|
150
|
-
#
|
151
|
-
# If the type is allowed be one of several, use an Array to
|
152
|
-
# to specify which ones
|
170
|
+
# +type+ - The type of the attribute. If the wrapped value is already of that type, the mapper is bypassed.
|
171
|
+
# If the type is allowed be one of several, use an Array to to specify which ones
|
153
172
|
#
|
154
|
-
# +from:+
|
155
|
-
# Defaults to camelCased version of +name+.
|
173
|
+
# +from:+ - Specifies the name of the wrapped value in the JSON object. Defaults to camelCased version of +name+.
|
156
174
|
#
|
157
|
-
# +map:+
|
158
|
-
#
|
159
|
-
#
|
175
|
+
# +map:+ - Specifies a custom mapper to apply to the wrapped value.
|
176
|
+
# If unspecified, it defaults to the default mapper for the specified +type+ or simply the identity mapper
|
177
|
+
# if no default mapper exists.
|
160
178
|
#
|
161
|
-
# +default:+
|
162
|
-
# in the wrapped JSON object.
|
179
|
+
# +default:+ - The default value to use, if the wrapped value is not present in the wrapped JSON object.
|
163
180
|
#
|
164
181
|
# +allow_nil:+ - If true, allows the mapped value to be nil. Defaults to true.
|
165
182
|
#
|
@@ -192,11 +209,11 @@ class LazyMapper
|
|
192
209
|
attributes[name] = type
|
193
210
|
end
|
194
211
|
|
195
|
-
|
212
|
+
#
|
196
213
|
# Converts a value to true or false according to its truthyness
|
214
|
+
#
|
197
215
|
TO_BOOL = -> b { !!b }
|
198
216
|
|
199
|
-
# = ::is
|
200
217
|
#
|
201
218
|
# Defines an boolean attribute
|
202
219
|
#
|
@@ -205,13 +222,12 @@ class LazyMapper
|
|
205
222
|
# +name+ - The name of the attribue
|
206
223
|
#
|
207
224
|
# +from:+ - Specifies the name of the wrapped value in the JSON object.
|
208
|
-
#
|
225
|
+
# Defaults to camelCased version of +name+.
|
209
226
|
#
|
210
|
-
# +map:+
|
211
|
-
#
|
212
|
-
# Defaults to TO_BOOL if unspecified.
|
227
|
+
# +map:+ - Specifies a custom mapper to apply to the wrapped value. Must be a Callable.
|
228
|
+
# Defaults to TO_BOOL if unspecified.
|
213
229
|
#
|
214
|
-
# +default:+
|
230
|
+
# +default:+ The default value to use if the value is missing. False, if unspecified
|
215
231
|
#
|
216
232
|
# == Example
|
217
233
|
#
|
@@ -226,28 +242,24 @@ class LazyMapper
|
|
226
242
|
|
227
243
|
singleton_class.send(:alias_method, :has, :is)
|
228
244
|
|
229
|
-
|
230
|
-
# = ::many
|
231
245
|
#
|
232
|
-
#
|
246
|
+
# Defines a collection attribute
|
233
247
|
#
|
234
248
|
# == Arguments
|
235
249
|
#
|
236
|
-
# +name+ - The name of the
|
250
|
+
# +name+ - The name of the attribute
|
237
251
|
#
|
238
|
-
# +type+ - The type of the
|
239
|
-
# already of that type, the mapper is bypassed for that element.
|
252
|
+
# +type+ - The type of the elements in the collection.
|
240
253
|
#
|
241
254
|
# +from:+ - Specifies the name of the wrapped array in the JSON object.
|
242
|
-
#
|
255
|
+
# Defaults to camelCased version of +name+.
|
243
256
|
#
|
244
|
-
# +map:+ - Specifies a custom mapper to apply to
|
245
|
-
#
|
246
|
-
#
|
247
|
-
# mapper exists.
|
257
|
+
# +map:+ - Specifies a custom mapper to apply to each elements in the wrapped collection.
|
258
|
+
# If unspecified, it defaults to the default mapper for the specified +type+ or simply the identity mapper
|
259
|
+
# if no default mapper exists.
|
248
260
|
#
|
249
261
|
# +default:+ - The default value to use, if the wrapped value is not present
|
250
|
-
#
|
262
|
+
# in the wrapped JSON object.
|
251
263
|
#
|
252
264
|
# == Example
|
253
265
|
#
|
@@ -277,6 +289,9 @@ class LazyMapper
|
|
277
289
|
}
|
278
290
|
end
|
279
291
|
|
292
|
+
#
|
293
|
+
# Adds an instance-level type mapper
|
294
|
+
#
|
280
295
|
def add_mapper_for(type, &block)
|
281
296
|
mappers[type] = block
|
282
297
|
end
|
@@ -305,7 +320,7 @@ class LazyMapper
|
|
305
320
|
@json ||= {}
|
306
321
|
end
|
307
322
|
|
308
|
-
|
323
|
+
#
|
309
324
|
# Defines how to map an attribute name
|
310
325
|
# to the corresponding name in the unmapped
|
311
326
|
# JSON object.
|
@@ -360,6 +375,6 @@ class LazyMapper
|
|
360
375
|
instance_variable_get(ivar)
|
361
376
|
end
|
362
377
|
|
363
|
-
SNAKE_CASE_PATTERN = /(_[a-z])/
|
378
|
+
SNAKE_CASE_PATTERN = /(_[a-z])/ # :nodoc:
|
364
379
|
CAMELIZE = -> name { name.to_s.gsub(SNAKE_CASE_PATTERN) { |x| x[1].upcase }.gsub('?', '') }
|
365
380
|
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: lazy_mapper
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.2.
|
4
|
+
version: 0.2.1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Adam Lett
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2018-10-
|
11
|
+
date: 2018-10-15 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: bundler
|