lazy_mapper 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/.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
|