primalize 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 +4 -4
- data/Gemfile.lock +1 -1
- data/README.md +13 -0
- data/lib/primalize/many.rb +21 -0
- data/lib/primalize/single.rb +96 -13
- data/lib/primalize/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: 211551a4a7fc66702f544d35f053e4e9f65d1fe1
|
4
|
+
data.tar.gz: b6f715a19f9b32fae1b4c025ae195ed1643faf65
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 1557c13cf41e2924453083053dd5de8b08b258cbdca01a2f55cf9d72f2f1a6ab048bb94fe564467346daea9292f8a436fd932db6dca4fc989d4b1a8aebf601ab
|
7
|
+
data.tar.gz: 133145cfb6bca06af9fd920eca885aa16707ca2af8b49e7c4c059112d65052232af87ab6a7e6049d701497c143e15008a22ae8be8fe5a6b1e18e756518e63a2e
|
data/Gemfile.lock
CHANGED
data/README.md
CHANGED
@@ -112,6 +112,19 @@ class ShipmentSerializer < Primalize::Single
|
|
112
112
|
end
|
113
113
|
```
|
114
114
|
|
115
|
+
### Type Checking
|
116
|
+
|
117
|
+
By default, subclasses of `Primalize::Single` will raise an `ArgumentError` if there is a mismatch between the types declared in its `attributes` call and what is passed in to be primalized. In production, you might not want that to happen, so you can change that in your production config:
|
118
|
+
|
119
|
+
```ruby
|
120
|
+
Primalize::Single.type_mismatch_handler = proc do |attr, type, value|
|
121
|
+
msg = "Type mismatch: #{attr} is expected to be #{type.inspect}, but is a #{value.inspect} - " +
|
122
|
+
caller.grep(Regexp.new(Rails.root))
|
123
|
+
|
124
|
+
Slack.notify '#bugs', msg
|
125
|
+
end
|
126
|
+
```
|
127
|
+
|
115
128
|
## Development
|
116
129
|
|
117
130
|
After checking out the repo, run `bin/setup` to install dependencies. Then, run `rake spec` to run the tests. You can also run `bin/console` for an interactive prompt that will allow you to experiment.
|
data/lib/primalize/many.rb
CHANGED
@@ -28,6 +28,10 @@ module Primalize
|
|
28
28
|
define_singleton_method :inspect do
|
29
29
|
"enumerable(#{serializer_class.inspect})"
|
30
30
|
end
|
31
|
+
|
32
|
+
define_singleton_method :attributes do
|
33
|
+
serializer_class.attributes
|
34
|
+
end
|
31
35
|
end
|
32
36
|
end
|
33
37
|
|
@@ -86,5 +90,22 @@ module Primalize
|
|
86
90
|
def to_json
|
87
91
|
call.to_json
|
88
92
|
end
|
93
|
+
|
94
|
+
def to_csv attr
|
95
|
+
CSV.generate do |csv|
|
96
|
+
result = call[attr]
|
97
|
+
|
98
|
+
csv << self.class.attributes[attr].attributes.keys
|
99
|
+
|
100
|
+
case result
|
101
|
+
when Hash
|
102
|
+
csv << result.values
|
103
|
+
when Array
|
104
|
+
result.each do |hash|
|
105
|
+
csv << hash.values
|
106
|
+
end
|
107
|
+
end
|
108
|
+
end
|
109
|
+
end
|
89
110
|
end
|
90
111
|
end
|
data/lib/primalize/single.rb
CHANGED
@@ -1,10 +1,11 @@
|
|
1
1
|
require 'json'
|
2
2
|
require 'date'
|
3
|
+
require 'csv'
|
3
4
|
|
4
5
|
module Primalize
|
5
6
|
class Single
|
6
|
-
@type_mismatch_handler = proc do |attr, type, value|
|
7
|
-
raise TypeError, "#{
|
7
|
+
@type_mismatch_handler = proc do |klass, attr, type, value|
|
8
|
+
raise TypeError, "#{klass}##{attr} is specified as #{type.inspect}, but is #{value.inspect}"
|
8
9
|
end
|
9
10
|
|
10
11
|
class << self
|
@@ -24,12 +25,7 @@ module Primalize
|
|
24
25
|
|
25
26
|
attrs.each do |attr, type|
|
26
27
|
define_method attr do
|
27
|
-
|
28
|
-
if type === value
|
29
|
-
value
|
30
|
-
else
|
31
|
-
self.class.type_mismatch_handler.call attr, type, value
|
32
|
-
end
|
28
|
+
type.coerce(object.public_send(attr))
|
33
29
|
end
|
34
30
|
end
|
35
31
|
end
|
@@ -58,6 +54,10 @@ module Primalize
|
|
58
54
|
Float.new(&coerce)
|
59
55
|
end
|
60
56
|
|
57
|
+
def number &coerce
|
58
|
+
Number.new(&coerce)
|
59
|
+
end
|
60
|
+
|
61
61
|
def optional *types, &coerce
|
62
62
|
Optional.new(types, &coerce)
|
63
63
|
end
|
@@ -70,6 +70,14 @@ module Primalize
|
|
70
70
|
Timestamp.new(&coerce)
|
71
71
|
end
|
72
72
|
|
73
|
+
def any *types, &coerce
|
74
|
+
Any.new(types, &coerce)
|
75
|
+
end
|
76
|
+
|
77
|
+
def primalize primalizer, &coerce
|
78
|
+
Primalizer.new(primalizer, &coerce)
|
79
|
+
end
|
80
|
+
|
73
81
|
def type_mismatch_handler= handler
|
74
82
|
@type_mismatch_handler = handler
|
75
83
|
end
|
@@ -90,20 +98,42 @@ module Primalize
|
|
90
98
|
attr_reader :object
|
91
99
|
|
92
100
|
def initialize object
|
101
|
+
raise ArgumentError, "#{self.class.inspect} cannot serialize `nil'" if object.nil?
|
93
102
|
@object = object
|
94
103
|
end
|
95
104
|
|
96
105
|
def call
|
97
|
-
self.class.attributes.each_with_object({}) do |(attr,
|
98
|
-
|
106
|
+
self.class.attributes.each_with_object({}) do |(attr, type), hash|
|
107
|
+
value = public_send(attr)
|
108
|
+
|
109
|
+
if type === value
|
110
|
+
hash[attr] = value
|
111
|
+
else
|
112
|
+
self.class.type_mismatch_handler.call self.class, attr, type, value
|
113
|
+
end
|
99
114
|
end
|
100
115
|
end
|
101
116
|
|
102
|
-
#
|
117
|
+
# CONVERSION
|
103
118
|
|
104
|
-
|
119
|
+
def to_json
|
120
|
+
call.to_json
|
121
|
+
end
|
122
|
+
|
123
|
+
def csv_headers
|
124
|
+
self.class.attributes.keys.map(&:to_s)
|
125
|
+
end
|
126
|
+
|
127
|
+
def to_csv
|
128
|
+
hash = call
|
129
|
+
CSV.generate { |csv| csv << hash.values }
|
130
|
+
end
|
131
|
+
|
132
|
+
# TYPES
|
105
133
|
|
106
134
|
module Type
|
135
|
+
DEFAULT_COERCION = proc { |arg| arg } # Don't coerce by default
|
136
|
+
|
107
137
|
def coerce *args
|
108
138
|
(@coercion || DEFAULT_COERCION).call(*args)
|
109
139
|
end
|
@@ -141,6 +171,18 @@ module Primalize
|
|
141
171
|
end
|
142
172
|
end
|
143
173
|
|
174
|
+
class Number
|
175
|
+
include Type
|
176
|
+
|
177
|
+
def === value
|
178
|
+
::Numeric === value
|
179
|
+
end
|
180
|
+
|
181
|
+
def inspect
|
182
|
+
'number'
|
183
|
+
end
|
184
|
+
end
|
185
|
+
|
144
186
|
class String
|
145
187
|
include Type
|
146
188
|
|
@@ -203,7 +245,7 @@ module Primalize
|
|
203
245
|
|
204
246
|
def initialize types, &coercion
|
205
247
|
@types = types
|
206
|
-
@coercion = coercion
|
248
|
+
@coercion = coercion
|
207
249
|
end
|
208
250
|
|
209
251
|
def === value
|
@@ -233,6 +275,30 @@ module Primalize
|
|
233
275
|
end
|
234
276
|
end
|
235
277
|
|
278
|
+
class Primalizer
|
279
|
+
include Type
|
280
|
+
|
281
|
+
def initialize primalizer, &coercion
|
282
|
+
@primalizer = primalizer
|
283
|
+
@coercion = coercion || proc do |obj|
|
284
|
+
# FIXME: this is dumb
|
285
|
+
begin
|
286
|
+
primalizer.new(obj).call
|
287
|
+
rescue ArgumentError => e
|
288
|
+
raise TypeError.new(e)
|
289
|
+
end
|
290
|
+
end
|
291
|
+
end
|
292
|
+
|
293
|
+
def === value
|
294
|
+
true
|
295
|
+
end
|
296
|
+
|
297
|
+
def inspect
|
298
|
+
"primalize(#{@primalizer.inspect})"
|
299
|
+
end
|
300
|
+
end
|
301
|
+
|
236
302
|
class Optional
|
237
303
|
include Type
|
238
304
|
|
@@ -249,5 +315,22 @@ module Primalize
|
|
249
315
|
"optional(#{@types.map(&:inspect).join(', ')})"
|
250
316
|
end
|
251
317
|
end
|
318
|
+
|
319
|
+
class Any
|
320
|
+
include Type
|
321
|
+
|
322
|
+
def initialize types, &coercion
|
323
|
+
@types = types
|
324
|
+
end
|
325
|
+
|
326
|
+
def === value
|
327
|
+
@types.empty? || @types.any? { |type| type === value }
|
328
|
+
end
|
329
|
+
|
330
|
+
def inspect
|
331
|
+
params = "(#{@types.map(&:inspect).join(', ')})"
|
332
|
+
"any#{@types.empty? ? nil : params}"
|
333
|
+
end
|
334
|
+
end
|
252
335
|
end
|
253
336
|
end
|
data/lib/primalize/version.rb
CHANGED
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: primalize
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.2.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Jamie Gaskins
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date: 2017-09-
|
11
|
+
date: 2017-09-09 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: bundler
|