surrealist 1.0.0 → 1.1.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.rubocop.yml +8 -3
- data/.travis.yml +4 -9
- data/CHANGELOG.md +31 -14
- data/README.md +159 -114
- data/lib/surrealist/carrier.rb +12 -1
- data/lib/surrealist/exception_raiser.rb +2 -2
- data/lib/surrealist/helper.rb +12 -0
- data/lib/surrealist/serializer.rb +21 -2
- data/lib/surrealist/value_assigner.rb +1 -1
- data/lib/surrealist/version.rb +1 -1
- data/lib/surrealist.rb +33 -3
- data/surrealist.gemspec +2 -2
- metadata +11 -11
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 2b3537308a609571f4a82a0f35792244135fd0fe249b85b408d444dc46c4ecf4
|
4
|
+
data.tar.gz: 8c50d83dbbe452bb55f70eadccc69ad024a6055e2ee1e60aa29f768c3281bfbc
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 3b5a167801a3393667d0fae41727f3512be479bfcdfb26426615a422173ff417b186ea59d067550db2f2f44af49a789450c5056bad07de500849e8b21ae46e0e
|
7
|
+
data.tar.gz: 9c3923e37180abfaa4159dbc5f55b393f6ab88927803bf639ffa1825cbf5aa16e8a61199a7dc19e65f8586e26666b6208f4e995826d6a8ecaa03b9868ce01f57
|
data/.rubocop.yml
CHANGED
@@ -33,9 +33,6 @@ Layout/MultilineOperationIndentation:
|
|
33
33
|
Layout/SpaceInLambdaLiteral:
|
34
34
|
EnforcedStyle: require_space
|
35
35
|
|
36
|
-
Layout/SpaceInsideBrackets:
|
37
|
-
Enabled: false
|
38
|
-
|
39
36
|
# Lint
|
40
37
|
Lint/AmbiguousBlockAssociation:
|
41
38
|
Enabled: false
|
@@ -97,6 +94,10 @@ Performance/UnfreezeString:
|
|
97
94
|
|
98
95
|
# Style
|
99
96
|
|
97
|
+
# ¯\_(ツ)_/¯
|
98
|
+
Style/AsciiComments:
|
99
|
+
Enabled: false
|
100
|
+
|
100
101
|
Style/MixinUsage:
|
101
102
|
Exclude:
|
102
103
|
- spec/**/*rb
|
@@ -152,3 +153,7 @@ Style/TrailingCommaInLiteral:
|
|
152
153
|
|
153
154
|
Style/MethodMissing:
|
154
155
|
Enabled: false
|
156
|
+
|
157
|
+
Style/EvalWithLocation:
|
158
|
+
Exclude:
|
159
|
+
- spec/**/*.rb
|
data/.travis.yml
CHANGED
@@ -10,15 +10,10 @@ matrix:
|
|
10
10
|
gemfile: Gemfile
|
11
11
|
- rvm: 2.5.0
|
12
12
|
gemfile: Gemfile
|
13
|
-
- rvm: 2.4.
|
13
|
+
- rvm: 2.4.3
|
14
14
|
gemfile: Gemfile
|
15
|
-
- rvm: 2.
|
15
|
+
- rvm: 2.3.6
|
16
16
|
gemfile: Gemfile
|
17
|
-
- rvm: 2.
|
18
|
-
gemfile: Gemfile
|
19
|
-
- rvm: 2.3.1
|
20
|
-
gemfile: Gemfile
|
21
|
-
- rvm: 2.2.5
|
22
|
-
gemfile: gemfiles/activerecord42.gemfile
|
23
|
-
- rvm: 2.2.0
|
17
|
+
- rvm: 2.2.9
|
24
18
|
gemfile: gemfiles/activerecord42.gemfile
|
19
|
+
|
data/CHANGELOG.md
CHANGED
@@ -1,36 +1,48 @@
|
|
1
|
+
# 1.1.0
|
2
|
+
|
3
|
+
## Added
|
4
|
+
* Configuration of default serialization params ([@nesaulov][]) [#77](https://github.com/nesaulov/surrealist/pull/77)
|
5
|
+
* DSL for custom serializers context ([@nesaulov][]) [#80](https://github.com/nesaulov/surrealist/pull/80)
|
6
|
+
|
7
|
+
## Fixed
|
8
|
+
* Fix failing serialization with sequel & custom serializers ([@azhi][]) [#84](https://github.com/nesaulov/surrealist/pull/84)
|
9
|
+
|
10
|
+
## Miscellaneous
|
11
|
+
* Pin Oj version to 3.4.0 [#79](https://github.com/nesaulov/surrealist/pull/79)
|
12
|
+
|
1
13
|
# 1.0.0
|
2
14
|
|
3
15
|
## Added
|
4
|
-
* `#build_schema` for collections from `Surrealist::Serializer` (@nesaulov) #74
|
16
|
+
* `#build_schema` for collections from `Surrealist::Serializer` ([@nesaulov][]) [#74](https://github.com/nesaulov/surrealist/pull/74)
|
5
17
|
* Oj dependency
|
6
|
-
* Multiple serializers API (@nulldef) #66
|
18
|
+
* Multiple serializers API ([@nulldef][]) [#66](https://github.com/nesaulov/surrealist/pull/66)
|
7
19
|
|
8
20
|
## Miscellaneous
|
9
21
|
* Benchmarks for Surrealist vs AMS
|
10
|
-
* A lot of memory & performance optimizations (@nesaulov) #64
|
22
|
+
* A lot of memory & performance optimizations ([@nesaulov][]) [#64](https://github.com/nesaulov/surrealist/pull/64)
|
11
23
|
|
12
24
|
# 0.4.0
|
13
25
|
|
14
26
|
## Added
|
15
|
-
* Introduce an abstract serializer class (@nesaulov) #61
|
16
|
-
* Full integration for Sequel (@nesaulov) #47
|
17
|
-
* Integration for ROM 4.x (@nesaulov) #56
|
18
|
-
* Ruby 2.5 support (@nesaulov) #57
|
27
|
+
* Introduce an abstract serializer class ([@nesaulov][]) [#61](https://github.com/nesaulov/surrealist/pull/61)
|
28
|
+
* Full integration for Sequel ([@nesaulov][]) [#47](https://github.com/nesaulov/surrealist/pull/47)
|
29
|
+
* Integration for ROM 4.x ([@nesaulov][]) [#56](https://github.com/nesaulov/surrealist/pull/56)
|
30
|
+
* Ruby 2.5 support ([@nesaulov][]) [#57](https://github.com/nesaulov/surrealist/pull/57)
|
19
31
|
|
20
32
|
## Miscellaneous
|
21
|
-
* Memory & performance optimizations (@nesaulov) #51
|
22
|
-
* Refactorings (@nulldef) #55
|
33
|
+
* Memory & performance optimizations ([@nesaulov][]) [#51](https://github.com/nesaulov/surrealist/pull/51)
|
34
|
+
* Refactorings ([@nulldef][]) [#55](https://github.com/nesaulov/surrealist/pull/55)
|
23
35
|
|
24
36
|
# 0.3.0
|
25
37
|
|
26
38
|
## Added
|
27
|
-
* Full integration for ActiveRecord (@nesaulov, @AlessandroMinali) #37
|
28
|
-
* Full integration for ROM <= 3 (@nesaulov, @AlessandroMinali) #37
|
29
|
-
* `root` optional argument (@chrisatanasian) #32
|
30
|
-
* Nested records surrealization (@AlessandroMinali) #34
|
39
|
+
* Full integration for ActiveRecord ([@nesaulov][], [@AlessandroMinali][]) [#37](https://github.com/nesaulov/surrealist/pull/37)
|
40
|
+
* Full integration for ROM <= 3 ([@nesaulov][], [@AlessandroMinali][]) [#37](https://github.com/nesaulov/surrealist/pull/37)
|
41
|
+
* `root` optional argument ([@chrisatanasian][]) [#32](https://github.com/nesaulov/surrealist/pull/32)
|
42
|
+
* Nested records surrealization ([@AlessandroMinali][]) [#34](https://github.com/nesaulov/surrealist/pull/34)
|
31
43
|
|
32
44
|
## Fixed
|
33
|
-
* Dependencies update (@nesaulov) #48
|
45
|
+
* Dependencies update ([@nesaulov][]) [#48](https://github.com/nesaulov/surrealist/pull/48)
|
34
46
|
|
35
47
|
# 0.2.0
|
36
48
|
## Added
|
@@ -65,5 +77,10 @@
|
|
65
77
|
* Allow nil values by default.
|
66
78
|
* Allow nested objects.
|
67
79
|
|
80
|
+
[@nesaulov]: https://github.com/nesaulov
|
81
|
+
[@AlessandroMinali]: https://github.com/AlessandroMinali
|
82
|
+
[@nulldef]: https://github.com/nulldef
|
83
|
+
[@azhi]: https://github.com/azhi
|
84
|
+
[@chrisatanasian]: https://github.com/chrisatanasian
|
68
85
|
|
69
86
|
|
data/README.md
CHANGED
@@ -6,7 +6,7 @@
|
|
6
6
|
[![Open Source Helpers](https://www.codetriage.com/nesaulov/surrealist/badges/users.svg)](https://www.codetriage.com/nesaulov/surrealist)
|
7
7
|
|
8
8
|
![Surrealist](surrealist-icon.png)
|
9
|
-
|
9
|
+
|
10
10
|
A gem that provides DSL for serialization of plain old Ruby objects to JSON in a declarative style
|
11
11
|
by defining a `json_schema`. It also provides a trivial type checking in the runtime before serialization.
|
12
12
|
[Yard documentation](http://www.rubydoc.info/github/nesaulov/surrealist/master)
|
@@ -31,18 +31,19 @@ to serialize nested objects and structures. [Introductory blogpost.](https://med
|
|
31
31
|
* [ActiveRecord](#activerecord)
|
32
32
|
* [ROM](#rom)
|
33
33
|
* [Sequel](#sequel)
|
34
|
-
* [Usage with Dry::Types](#usage-with-drytypes)
|
34
|
+
* [Usage with Dry::Types](#usage-with-drytypes)
|
35
35
|
* [Delegating Surrealization](#delegating-surrealization)
|
36
36
|
* [Optional arguments](#optional-arguments)
|
37
37
|
* [Camelization](#camelization)
|
38
38
|
* [Include root](#include-root)
|
39
39
|
* [Root](#root)
|
40
40
|
* [Include namespaces](#include-namespaces)
|
41
|
+
* [Configuration](#configuration)
|
41
42
|
* [Bool and Any](#bool-and-any)
|
42
43
|
* [Type errors](#type-errors)
|
43
44
|
* [Undefined methods in schema](#undefined-methods-in-schema)
|
44
45
|
* [Other notes](#other-notes)
|
45
|
-
* [Roadmap](#roadmap)
|
46
|
+
* [Roadmap](#roadmap)
|
46
47
|
* [Contributing](#contributing)
|
47
48
|
* [Credits](#credits)
|
48
49
|
* [Authors](#authors)
|
@@ -79,15 +80,15 @@ that will be used for type-checks.
|
|
79
80
|
``` ruby
|
80
81
|
class Person
|
81
82
|
include Surrealist
|
82
|
-
|
83
|
+
|
83
84
|
json_schema do
|
84
85
|
{ name: String, age: Integer }
|
85
86
|
end
|
86
|
-
|
87
|
+
|
87
88
|
def name
|
88
89
|
'John Doe'
|
89
90
|
end
|
90
|
-
|
91
|
+
|
91
92
|
def age
|
92
93
|
42
|
93
94
|
end
|
@@ -106,7 +107,7 @@ Person.new.surrealize
|
|
106
107
|
``` ruby
|
107
108
|
class Person
|
108
109
|
include Surrealist
|
109
|
-
|
110
|
+
|
110
111
|
json_schema do
|
111
112
|
{
|
112
113
|
foo: String,
|
@@ -121,7 +122,7 @@ class Person
|
|
121
122
|
end
|
122
123
|
# ... method definitions
|
123
124
|
end
|
124
|
-
|
125
|
+
|
125
126
|
Person.find_by(email: 'example@email.com').surrealize
|
126
127
|
# => '{ "foo": "Some string", "name": "John Doe", "nested": { "at": { "any": 42, "level": true } } }'
|
127
128
|
```
|
@@ -133,7 +134,7 @@ define a method that calls nested object:
|
|
133
134
|
``` ruby
|
134
135
|
class User
|
135
136
|
include Surrealist
|
136
|
-
|
137
|
+
|
137
138
|
json_schema do
|
138
139
|
{
|
139
140
|
name: String,
|
@@ -143,11 +144,11 @@ class User
|
|
143
144
|
},
|
144
145
|
}
|
145
146
|
end
|
146
|
-
|
147
|
+
|
147
148
|
def name
|
148
149
|
'John Doe'
|
149
150
|
end
|
150
|
-
|
151
|
+
|
151
152
|
def credit_card
|
152
153
|
# Assuming that instance of a CreditCard has methods #number and #cvv defined
|
153
154
|
CreditCard.find_by(holder: name)
|
@@ -164,20 +165,20 @@ Since 0.2.0 Surrealist has API for collection serialization. Example for ActiveR
|
|
164
165
|
``` ruby
|
165
166
|
class User < ActiveRecord::Base
|
166
167
|
include Surrealist
|
167
|
-
|
168
|
+
|
168
169
|
json_schema do
|
169
170
|
{ name: String, age: Integer }
|
170
171
|
end
|
171
172
|
end
|
172
|
-
|
173
|
+
|
173
174
|
users = User.all
|
174
175
|
# => [#<User:0x007fa1485de878 id: 1, name: "Nikita", age: 23>, #<User:0x007fa1485de5f8 id: 2, name: "Alessandro", age: 24>]
|
175
|
-
|
176
|
+
|
176
177
|
Surrealist.surrealize_collection(users)
|
177
178
|
# => '[{ "name": "Nikita", "age": 23 }, { "name": "Alessandro", "age": 24 }]'
|
178
179
|
```
|
179
|
-
You can find motivation behind introducing new API versus monkey-patching [here](https://alessandrominali.github.io/monkey_patching_real_example).
|
180
|
-
`#surrealize_collection` works for all data structures that
|
180
|
+
You can find motivation behind introducing new API versus monkey-patching [here](https://alessandrominali.github.io/monkey_patching_real_example).
|
181
|
+
`#surrealize_collection` works for all data structures that behave like `Enumerable`. All ActiveRecord
|
181
182
|
features (like associations, inheritance etc) are supported and covered. Further reading: [working with ORMs](#working-with-orms).
|
182
183
|
All optional arguments (`camelize`, `include_root` etc) are also supported.
|
183
184
|
|
@@ -195,65 +196,84 @@ will inherit from `Surrealist::Serializer`. To point to that class from the mode
|
|
195
196
|
``` ruby
|
196
197
|
class CatSerializer < Surrealist::Serializer
|
197
198
|
json_schema { { age: Integer, age_group: String } }
|
198
|
-
|
199
|
+
|
199
200
|
def age_group
|
200
201
|
age <= 5 ? 'kitten' : 'cat'
|
201
202
|
end
|
202
203
|
end
|
203
|
-
|
204
|
+
|
204
205
|
class Cat
|
205
206
|
include Surrealist
|
206
207
|
attr_reader :age
|
207
|
-
|
208
|
+
|
208
209
|
surrealize_with CatSerializer
|
209
|
-
|
210
|
+
|
210
211
|
def initialize(age)
|
211
212
|
@age = age
|
212
213
|
end
|
213
214
|
end
|
214
|
-
|
215
|
+
|
215
216
|
Cat.new(12).surrealize # Implicit usage through .surrealize_with
|
216
217
|
# => '{ "age": 12, "age_group": "cat" }'
|
217
|
-
|
218
|
+
|
218
219
|
CatSerializer.new(Cat.new(3)).surrealize # explicit usage of CatSerializer
|
219
220
|
# => '{ "age": 3, "age_group": "kitten" }'
|
220
221
|
```
|
221
|
-
The constructor of `Surrealist::Serializer` takes two arguments: serializable model (or collection) and
|
222
|
+
The constructor of `Surrealist::Serializer` takes two arguments: serializable model (or collection) and
|
222
223
|
a context hash. So if there is an object that is not coupled to serializable model
|
223
|
-
but it is still necessary for constructing JSON, you can pass it to constructor as a hash. It will
|
224
|
-
be available in the serializer in the `context` hash.
|
224
|
+
but it is still necessary for constructing JSON, you can pass it to constructor as a hash. It will
|
225
|
+
be available in the serializer in the `context` hash.
|
225
226
|
``` ruby
|
226
227
|
class IncomeSerializer < Surrealist::Serializer
|
227
228
|
json_schema { { amount: Integer } }
|
228
|
-
|
229
|
+
|
229
230
|
def amount
|
230
231
|
current_user.guest? ? 100000000 : object.amount
|
231
232
|
end
|
232
|
-
|
233
|
+
|
233
234
|
def current_user
|
234
235
|
context[:current_user]
|
235
236
|
end
|
236
237
|
end
|
237
|
-
|
238
|
+
|
238
239
|
class Income
|
239
240
|
include Surrealist
|
240
241
|
surrealize_with IncomeSerializer
|
241
|
-
|
242
|
+
|
242
243
|
attr_reader :amount
|
243
|
-
|
244
|
+
|
244
245
|
def initialize(amount)
|
245
246
|
@amount = amount
|
246
|
-
end
|
247
|
+
end
|
247
248
|
end
|
248
|
-
|
249
|
+
|
249
250
|
income = Income.new(200)
|
250
251
|
IncomeSerializer.new(income, current_user: GuestUser.new).surrealize
|
251
252
|
# => '{ "amount": 100000000 }'
|
252
|
-
|
253
|
+
|
253
254
|
IncomeSerializer.new(income, current_user: User.find(3)).surrealize
|
254
255
|
# => '{ "amount": 200 }'
|
255
256
|
```
|
256
|
-
|
257
|
+
If you happen to pass a context to a serializer, there is a handy DSL to reduce the number of methods
|
258
|
+
you have to define yourself. DSL looks as follows
|
259
|
+
``` ruby
|
260
|
+
class IncomeSerializer < Surrealist::Serializer
|
261
|
+
serializer_context :current_user
|
262
|
+
json_schema { { amount: Integer } }
|
263
|
+
|
264
|
+
def amount
|
265
|
+
current_user.guest? ? 100000000 : object.amount
|
266
|
+
end
|
267
|
+
end
|
268
|
+
```
|
269
|
+
`.serializer_context` takes an array of symbols and dynamically defines instance methods
|
270
|
+
that read values from the context hash. So `.serializer_context :current_user` will become
|
271
|
+
``` ruby
|
272
|
+
def current_user
|
273
|
+
context[:current_user]
|
274
|
+
end
|
275
|
+
```
|
276
|
+
There is also an alias in the plural form: `.serializer_contexts`.
|
257
277
|
### Multiple serializers
|
258
278
|
|
259
279
|
You can define several custom serializers for one object and use it in different cases. Just mark it with a tag:
|
@@ -269,10 +289,10 @@ end
|
|
269
289
|
|
270
290
|
class Post
|
271
291
|
include Surrealist
|
272
|
-
|
292
|
+
|
273
293
|
surrealize_with PostSerializer
|
274
294
|
surrealize_with PreviewSerializer, tag: :preview
|
275
|
-
|
295
|
+
|
276
296
|
attr_reader :id, :title, :author
|
277
297
|
end
|
278
298
|
```
|
@@ -282,7 +302,7 @@ And then specify serializer's tag with `for` argument:
|
|
282
302
|
author = Struct.new(:name).new("John")
|
283
303
|
post = Post.new(1, "Ruby is awesome", author)
|
284
304
|
post.surrealize # => '{ "id": 1, "title": "Ruby is awesome", author: { name: "John" } }'
|
285
|
-
|
305
|
+
|
286
306
|
post.surrealize(for: :preview) # => '{ "id": 1, "title": "Ruby is awesome" }'
|
287
307
|
```
|
288
308
|
Or specify serializer explicitly with `serializer` argument:
|
@@ -318,45 +338,45 @@ Methods that return instances:
|
|
318
338
|
.find_by
|
319
339
|
.find_by!
|
320
340
|
.take!
|
321
|
-
.first
|
341
|
+
.first
|
322
342
|
.first!
|
323
|
-
.second
|
343
|
+
.second
|
324
344
|
.second!
|
325
|
-
.third
|
345
|
+
.third
|
326
346
|
.third!
|
327
|
-
.fourth
|
347
|
+
.fourth
|
328
348
|
.fourth!
|
329
|
-
.fifth
|
349
|
+
.fifth
|
330
350
|
.fifth!
|
331
|
-
.forty_two
|
351
|
+
.forty_two
|
332
352
|
.forty_two!
|
333
|
-
.last
|
353
|
+
.last
|
334
354
|
.last!
|
335
|
-
.third_to_last
|
355
|
+
.third_to_last
|
336
356
|
.third_to_last!
|
337
|
-
.second_to_last
|
357
|
+
.second_to_last
|
338
358
|
.second_to_last!
|
339
359
|
```
|
340
360
|
Methods that return collections:
|
341
361
|
``` ruby
|
342
362
|
.all
|
343
|
-
.where
|
344
|
-
.where_not
|
345
|
-
.order
|
346
|
-
.take
|
347
|
-
.limit
|
348
|
-
.offset
|
349
|
-
.lock
|
350
|
-
.readonly
|
351
|
-
.reorder
|
352
|
-
.distinct
|
353
|
-
.find_each
|
354
|
-
.select
|
355
|
-
.group
|
356
|
-
.order
|
357
|
-
.except
|
358
|
-
.extending
|
359
|
-
.having
|
363
|
+
.where
|
364
|
+
.where_not
|
365
|
+
.order
|
366
|
+
.take
|
367
|
+
.limit
|
368
|
+
.offset
|
369
|
+
.lock
|
370
|
+
.readonly
|
371
|
+
.reorder
|
372
|
+
.distinct
|
373
|
+
.find_each
|
374
|
+
.select
|
375
|
+
.group
|
376
|
+
.order
|
377
|
+
.except
|
378
|
+
.extending
|
379
|
+
.having
|
360
380
|
.references
|
361
381
|
.includes
|
362
382
|
.joins
|
@@ -376,7 +396,7 @@ container = ROM.container(:sql, ['sqlite::memory']) do |conf|
|
|
376
396
|
end
|
377
397
|
# ...
|
378
398
|
end
|
379
|
-
|
399
|
+
|
380
400
|
users = UserRepo.new(container).users
|
381
401
|
# => #<ROM::Relation[Users] name=ROM::Relation::Name(users) dataset=#<Sequel::SQLite::Dataset: "SELECT `users`.`id`, `users`.`name`, `users`.`email` FROM `users` ORDER BY `users`.`id`">>
|
382
402
|
```
|
@@ -385,67 +405,67 @@ Basically, there are several ways to fetch/represent data in ROM:
|
|
385
405
|
# With json_schema defined in ROM::Struct::User
|
386
406
|
class ROM::Struct::User < ROM::Struct
|
387
407
|
include Surrealist
|
388
|
-
|
408
|
+
|
389
409
|
json_schema { { name: String } }
|
390
|
-
end
|
391
|
-
|
410
|
+
end
|
411
|
+
|
392
412
|
users.to_a.first # => #<ROM::Struct::User id=1 name="Jane Struct" email="jane@struct.rom">
|
393
413
|
users.to_a.first.surrealize # => "{\"name\":\"Jane Struct\"}"
|
394
|
-
|
414
|
+
|
395
415
|
users.where(id: 1).first # => #<ROM::Struct::User id=1 name="Jane Struct" email="jane@struct.rom">
|
396
416
|
users.where(id: 1).first.surrealize # => "{\"name\":\"Jane Struct\"}"
|
397
|
-
|
417
|
+
|
398
418
|
Surrealist.surrealize_collection(users.to_a) # => "[{\"name\":\"Jane Struct\"},{\"name\":\"Dane As\"},{\"name\":\"Jack Mapper\"}]"
|
399
|
-
|
419
|
+
|
400
420
|
# using ROM::Struct::Model#as(Representative) with json_schema defined in representative
|
401
421
|
class RomUser < Dry::Struct
|
402
422
|
include Surrealist
|
403
|
-
|
423
|
+
|
404
424
|
attribute :name, String
|
405
425
|
attribute :email, String
|
406
|
-
|
426
|
+
|
407
427
|
json_schema { { email: String } }
|
408
428
|
end
|
409
|
-
|
429
|
+
|
410
430
|
# ROM 3.x
|
411
431
|
rom_users = users.as(RomUser).to_a
|
412
|
-
|
432
|
+
|
413
433
|
# ROM 4.x
|
414
434
|
rom_users = users.map_to(RomUser).to_a
|
415
|
-
|
435
|
+
|
416
436
|
rom_users[1].surrealize # => "{\"email\":\"dane@as.rom\"}"
|
417
437
|
Surrealist.surrealize_collection(rom_users) # => "[{\"email\":\"jane@struct.rom\"},{\"email\":\"dane@as.rom\"},{\"email\":\"jack@mapper.rom\"}]"
|
418
|
-
|
438
|
+
|
419
439
|
# using Mappers
|
420
440
|
class UserModel
|
421
441
|
include Surrealist
|
422
|
-
|
442
|
+
|
423
443
|
json_schema { { id: Integer, email: String } }
|
424
|
-
|
444
|
+
|
425
445
|
attr_reader :id, :name, :email
|
426
|
-
|
446
|
+
|
427
447
|
def initialize(attributes)
|
428
448
|
@id, @name, @email = attributes.values_at(:id, :name, :email)
|
429
449
|
end
|
430
450
|
end
|
431
|
-
|
451
|
+
|
432
452
|
class UsersMapper < ROM::Mapper
|
433
453
|
register_as :user_obj
|
434
454
|
relation :users
|
435
455
|
model UserModel
|
436
456
|
end
|
437
|
-
|
457
|
+
|
438
458
|
# ROM 3.x
|
439
459
|
mapped = users.as(:user_obj)
|
440
460
|
# ROM 4.x
|
441
461
|
mapped = users.map_with(:user_obj)
|
442
|
-
|
462
|
+
|
443
463
|
mapped.to_a[2] # => #<UserModel:0x00007f8ec19fb3c8 @email="jack@mapper.rom", @id=3, @name="Jack Mapper">
|
444
464
|
mapped.where(id: 3).first # => #<UserModel:0x00007f8ec19fb3c8 @email="jack@mapper.rom", @id=3, @name="Jack Mapper">
|
445
465
|
mapped.to_a[2].surrealize # => "{\"id\":3,\"email\":\"jack@mapper.rom\"}"
|
446
|
-
Surrealist.surrealize_collection(mapped.to_a) # => "[{\"email\":\"jane@struct.rom\"},{\"email\":\"dane@as.rom\"},{\"email\":\"jack@mapper.rom\"}]"
|
447
|
-
Surrealist.surrealize_collection(mapped.where { id < 4 }.to_a) # => "[{\"email\":\"jane@struct.rom\"},{\"email\":\"dane@as.rom\"},{\"email\":\"jack@mapper.rom\"}]"
|
448
|
-
```
|
466
|
+
Surrealist.surrealize_collection(mapped.to_a) # => "[{\"email\":\"jane@struct.rom\"},{\"email\":\"dane@as.rom\"},{\"email\":\"jack@mapper.rom\"}]"
|
467
|
+
Surrealist.surrealize_collection(mapped.where { id < 4 }.to_a) # => "[{\"email\":\"jane@struct.rom\"},{\"email\":\"dane@as.rom\"},{\"email\":\"jack@mapper.rom\"}]"
|
468
|
+
```
|
449
469
|
|
450
470
|
#### Sequel
|
451
471
|
Basically, Sequel returns instances only on `.first`, `.last`, `.[]` and `.with_pk!`. Collections are returned for all other methods.
|
@@ -464,7 +484,7 @@ require 'dry-types'
|
|
464
484
|
|
465
485
|
class Car
|
466
486
|
include Surrealist
|
467
|
-
|
487
|
+
|
468
488
|
json_schema do
|
469
489
|
{
|
470
490
|
age: Types::Coercible::Int,
|
@@ -475,25 +495,25 @@ class Car
|
|
475
495
|
previous_owner: Types::String,
|
476
496
|
}
|
477
497
|
end
|
478
|
-
|
498
|
+
|
479
499
|
def age;
|
480
500
|
'7'
|
481
501
|
end
|
482
|
-
|
502
|
+
|
483
503
|
def previous_owner;
|
484
504
|
'John Doe'
|
485
505
|
end
|
486
|
-
|
506
|
+
|
487
507
|
def horsepower;
|
488
508
|
140
|
489
509
|
end
|
490
|
-
|
510
|
+
|
491
511
|
def brand;
|
492
512
|
'Toyota'
|
493
513
|
end
|
494
|
-
|
514
|
+
|
495
515
|
def doors; end
|
496
|
-
|
516
|
+
|
497
517
|
def fuel_system;
|
498
518
|
'Direct injection'
|
499
519
|
end
|
@@ -508,11 +528,11 @@ You can share the `json_schema` between classes:
|
|
508
528
|
``` ruby
|
509
529
|
class Host
|
510
530
|
include Surrealist
|
511
|
-
|
531
|
+
|
512
532
|
json_schema do
|
513
533
|
{ name: String }
|
514
534
|
end
|
515
|
-
|
535
|
+
|
516
536
|
def name
|
517
537
|
'Host'
|
518
538
|
end
|
@@ -520,7 +540,7 @@ end
|
|
520
540
|
|
521
541
|
class Guest
|
522
542
|
delegate_surrealization_to Host
|
523
|
-
|
543
|
+
|
524
544
|
def name
|
525
545
|
'Guest'
|
526
546
|
end
|
@@ -538,7 +558,7 @@ in this case you have to `include Surrealist` in class that delegates schema as
|
|
538
558
|
class Potato
|
539
559
|
include Surrealist
|
540
560
|
delegate_surrealization_to Host
|
541
|
-
|
561
|
+
|
542
562
|
def name
|
543
563
|
'Potato'
|
544
564
|
end
|
@@ -566,16 +586,16 @@ surrealizable object.
|
|
566
586
|
``` ruby
|
567
587
|
class Cat
|
568
588
|
include Surrealist
|
569
|
-
|
589
|
+
|
570
590
|
json_schema do
|
571
591
|
{ weight: String }
|
572
592
|
end
|
573
|
-
|
593
|
+
|
574
594
|
def weight
|
575
595
|
'3 kilos'
|
576
596
|
end
|
577
597
|
end
|
578
|
-
|
598
|
+
|
579
599
|
Cat.new.surrealize(include_root: true)
|
580
600
|
# => '{ "cat": { "weight": "3 kilos" } }'
|
581
601
|
```
|
@@ -584,11 +604,11 @@ With nested classes the last namespace will be taken as root key:
|
|
584
604
|
class Animal
|
585
605
|
class Dog
|
586
606
|
include Surrealist
|
587
|
-
|
607
|
+
|
588
608
|
json_schema do
|
589
609
|
{ breed: String }
|
590
610
|
end
|
591
|
-
|
611
|
+
|
592
612
|
def breed
|
593
613
|
'Collie'
|
594
614
|
end
|
@@ -605,11 +625,11 @@ to `#surrealize` or `#build_schema`. The `root` argument will be stripped of whi
|
|
605
625
|
``` ruby
|
606
626
|
class Cat
|
607
627
|
include Surrealist
|
608
|
-
|
628
|
+
|
609
629
|
json_schema do
|
610
630
|
{ weight: String }
|
611
631
|
end
|
612
|
-
|
632
|
+
|
613
633
|
def weight
|
614
634
|
'3 kilos'
|
615
635
|
end
|
@@ -633,20 +653,20 @@ You can build wrap schema into a nested hash from namespaces of the object's cla
|
|
633
653
|
``` ruby
|
634
654
|
class BusinessSystem::Cashout::ReportSystem::Withdraws
|
635
655
|
include Surrealist
|
636
|
-
|
656
|
+
|
637
657
|
json_schema do
|
638
658
|
{ withdraws_amount: Integer }
|
639
659
|
end
|
640
|
-
|
660
|
+
|
641
661
|
def withdraws_amount
|
642
662
|
34
|
643
663
|
end
|
644
664
|
end
|
645
|
-
|
665
|
+
|
646
666
|
withdraws = BusinessSystem::Cashout::ReportSystem::Withdraws.new
|
647
|
-
|
667
|
+
|
648
668
|
withdraws.surrealize(include_namespaces: true)
|
649
|
-
# => '{ "business_system": { "cashout": { "report_system": { "withdraws": { "withdraws_amount": 34 } } } } }'
|
669
|
+
# => '{ "business_system": { "cashout": { "report_system": { "withdraws": { "withdraws_amount": 34 } } } } }'
|
650
670
|
```
|
651
671
|
By default all namespaces will be taken. If you want you can explicitly specify the level of nesting:
|
652
672
|
``` ruby
|
@@ -654,6 +674,31 @@ withdraws.surrealize(include_namespaces: true, namespaces_nesting_level: 2)
|
|
654
674
|
# => '{ "report_system": { "withdraws": { "withdraws_amount": 34 } } }'
|
655
675
|
```
|
656
676
|
|
677
|
+
### Configuration
|
678
|
+
|
679
|
+
There are two ways of setting default arguments for serialization,
|
680
|
+
by passing a block to `Surrealist.configure`:
|
681
|
+
```ruby
|
682
|
+
Surrealist.configure do |config|
|
683
|
+
config.camelize = true
|
684
|
+
config.namespaces_nesting_level = 2
|
685
|
+
end
|
686
|
+
```
|
687
|
+
And by passing a hash:
|
688
|
+
|
689
|
+
`Surrealist.configure(camelize: true, include_root: true)`
|
690
|
+
|
691
|
+
These arguments will be applied to all calls of `#build_schema` and `#surrealize`.
|
692
|
+
If these methods will be called with arguments, they will be merged with respect to explicitly passed ones:
|
693
|
+
|
694
|
+
```ruby
|
695
|
+
Surrealist.configure(camelize: true, include_root: true)
|
696
|
+
|
697
|
+
Something.new.surrealize(camelize: false)
|
698
|
+
# will result in Something.new.surrealize(camelize: false, include_root: true)
|
699
|
+
```
|
700
|
+
|
701
|
+
|
657
702
|
### Bool and Any
|
658
703
|
If you have a parameter that is of boolean type, or if you don't care about the type, you
|
659
704
|
can use `Bool` and `Any` respectively.
|
@@ -661,7 +706,7 @@ can use `Bool` and `Any` respectively.
|
|
661
706
|
``` ruby
|
662
707
|
class User
|
663
708
|
include Surrealist
|
664
|
-
|
709
|
+
|
665
710
|
json_schema do
|
666
711
|
{
|
667
712
|
age: Any,
|
@@ -677,13 +722,13 @@ end
|
|
677
722
|
``` ruby
|
678
723
|
class CreditCard
|
679
724
|
include Surrealist
|
680
|
-
|
725
|
+
|
681
726
|
json_schema do
|
682
727
|
{ number: Integer }
|
683
728
|
end
|
684
|
-
|
729
|
+
|
685
730
|
def number
|
686
|
-
'string'
|
731
|
+
'string'
|
687
732
|
end
|
688
733
|
end
|
689
734
|
|
@@ -698,7 +743,7 @@ a corresponding method defined in the object.
|
|
698
743
|
``` ruby
|
699
744
|
class Car
|
700
745
|
include Surrealist
|
701
|
-
|
746
|
+
|
702
747
|
json_schema do
|
703
748
|
{ weight: Integer }
|
704
749
|
end
|
@@ -716,7 +761,7 @@ type check will be passed. If you want to be strict about `nil`s consider using
|
|
716
761
|
## Roadmap
|
717
762
|
Here is a list of features that are not implemented yet (contributions are welcome):
|
718
763
|
* [Having a config that would keep serialization parameters](https://github.com/nesaulov/surrealist/issues/76)
|
719
|
-
* [DSL for serializer contexts](https://github.com/nesaulov/surrealist/issues/67)
|
764
|
+
* [DSL for serializer contexts](https://github.com/nesaulov/surrealist/issues/67)
|
720
765
|
* Memoization/caching
|
721
766
|
|
722
767
|
## Contributing
|
data/lib/surrealist/carrier.rb
CHANGED
@@ -2,10 +2,11 @@
|
|
2
2
|
|
3
3
|
module Surrealist
|
4
4
|
# A data structure to carry arguments across methods.
|
5
|
+
# @api private
|
5
6
|
class Carrier
|
6
7
|
BOOLEANS = [true, false].freeze
|
7
8
|
|
8
|
-
|
9
|
+
attr_accessor :camelize, :include_root, :include_namespaces, :root, :namespaces_nesting_level
|
9
10
|
|
10
11
|
# Public wrapper for Carrier.
|
11
12
|
#
|
@@ -43,10 +44,19 @@ module Surrealist
|
|
43
44
|
self
|
44
45
|
end
|
45
46
|
|
47
|
+
# Checks if all arguments are set to default
|
46
48
|
def no_args_provided?
|
47
49
|
@no_args ||= no_args
|
48
50
|
end
|
49
51
|
|
52
|
+
# Returns all arguments
|
53
|
+
#
|
54
|
+
# @return [Hash]
|
55
|
+
def parameters
|
56
|
+
{ camelize: camelize, include_root: include_root, include_namespaces: include_namespaces,
|
57
|
+
root: root, namespaces_nesting_level: namespaces_nesting_level }
|
58
|
+
end
|
59
|
+
|
50
60
|
private
|
51
61
|
|
52
62
|
# Checks all boolean arguments
|
@@ -85,6 +95,7 @@ module Surrealist
|
|
85
95
|
root.is_a?(String) && @root = root.strip
|
86
96
|
end
|
87
97
|
|
98
|
+
# Checks if all arguments are set to default
|
88
99
|
def no_args
|
89
100
|
!camelize && !include_root && !include_namespaces && root.nil? &&
|
90
101
|
namespaces_nesting_level == DEFAULT_NESTING_LEVEL
|
@@ -31,7 +31,7 @@ module Surrealist
|
|
31
31
|
# A class that raises all Surrealist exceptions
|
32
32
|
module ExceptionRaiser
|
33
33
|
CLASS_NAME_NOT_PASSED = "Can't wrap schema in root key - class name was not passed".freeze
|
34
|
-
|
34
|
+
MUST_BEHAVE_LIKE_ENUMERABLE = "Can't serialize collection - must behave like enumerable".freeze
|
35
35
|
CLASS_DOESNT_INCLUDE_SURREALIST = 'Class does not include Surrealist'.freeze
|
36
36
|
|
37
37
|
class << self
|
@@ -64,7 +64,7 @@ module Surrealist
|
|
64
64
|
#
|
65
65
|
# @raise Surrealist::InvalidCollectionError
|
66
66
|
def raise_invalid_collection!
|
67
|
-
raise Surrealist::InvalidCollectionError,
|
67
|
+
raise Surrealist::InvalidCollectionError, MUST_BEHAVE_LIKE_ENUMERABLE
|
68
68
|
end
|
69
69
|
|
70
70
|
# Raises ArgumentError if namespaces_nesting_level is not an integer.
|
data/lib/surrealist/helper.rb
CHANGED
@@ -11,5 +11,17 @@ module Surrealist
|
|
11
11
|
def self.surrealist?(klass)
|
12
12
|
klass < Surrealist || klass < Surrealist::Serializer
|
13
13
|
end
|
14
|
+
|
15
|
+
def self.collection?(object)
|
16
|
+
# 4.2 AR relation object did not include Enumerable (it defined
|
17
|
+
# all necessary method through ActiveRecord::Delegation module),
|
18
|
+
# so we need to explicitly check for this
|
19
|
+
object.is_a?(Enumerable) || ar_relation?(object)
|
20
|
+
end
|
21
|
+
|
22
|
+
def self.ar_relation?(object)
|
23
|
+
defined?(ActiveRecord) && object.is_a?(ActiveRecord::Relation)
|
24
|
+
end
|
25
|
+
private_class_method :ar_relation?
|
14
26
|
end
|
15
27
|
end
|
@@ -31,6 +31,25 @@ module Surrealist
|
|
31
31
|
class Serializer
|
32
32
|
extend Surrealist::ClassMethods
|
33
33
|
|
34
|
+
class << self
|
35
|
+
# Defines instance methods that read values from the context hash.
|
36
|
+
#
|
37
|
+
# @param [Array<Symbol>] array
|
38
|
+
# an array of symbols which represent method names
|
39
|
+
#
|
40
|
+
# @raise ArgumentError if type of argument is not an array of symbols
|
41
|
+
def serializer_context(*array)
|
42
|
+
unless array.all? { |i| i.is_a? Symbol }
|
43
|
+
raise ArgumentError, 'Please provide an array of symbols to `.serializer_context`'
|
44
|
+
end
|
45
|
+
|
46
|
+
array.each { |method| define_method(method) { context[method] } }
|
47
|
+
end
|
48
|
+
|
49
|
+
# Plural form ¯\_(ツ)_/¯
|
50
|
+
alias serializer_contexts serializer_context
|
51
|
+
end
|
52
|
+
|
34
53
|
# NOTE: #context will work only when using serializer explicitly,
|
35
54
|
# e.g `CatSerializer.new(Cat.new(3), food: CatFood.new)`
|
36
55
|
# And then food will be available inside serializer via `context[:food]`
|
@@ -41,7 +60,7 @@ module Surrealist
|
|
41
60
|
|
42
61
|
# Checks whether object is a collection or an instance and serializes it
|
43
62
|
def surrealize(**args)
|
44
|
-
if
|
63
|
+
if Helper.collection?(object)
|
45
64
|
Surrealist.surrealize_collection(object, args.merge(context: context))
|
46
65
|
else
|
47
66
|
Surrealist.surrealize(instance: self, **args)
|
@@ -50,7 +69,7 @@ module Surrealist
|
|
50
69
|
|
51
70
|
# Passes build_schema to Surrealist
|
52
71
|
def build_schema(**args)
|
53
|
-
if
|
72
|
+
if Helper.collection?(object)
|
54
73
|
build_collection_schema(args)
|
55
74
|
else
|
56
75
|
Surrealist.build_schema(instance: self, **args)
|
@@ -18,7 +18,7 @@ module Surrealist
|
|
18
18
|
|
19
19
|
if value.respond_to?(:build_schema)
|
20
20
|
yield assign_nested_record(instance, value)
|
21
|
-
elsif
|
21
|
+
elsif Helper.collection?(value) && !value.empty? && value.all? { |v| Helper.surrealist?(v.class) }
|
22
22
|
yield assign_nested_collection(instance, value)
|
23
23
|
else
|
24
24
|
yield value
|
data/lib/surrealist/version.rb
CHANGED
data/lib/surrealist.rb
CHANGED
@@ -54,7 +54,7 @@ module Surrealist
|
|
54
54
|
# # => "[{\"name\":\"Nikita\",\"age\":23}, {\"name\":\"Alessandro\",\"age\":24}]"
|
55
55
|
# # For more examples see README
|
56
56
|
def surrealize_collection(collection, **args)
|
57
|
-
Surrealist::ExceptionRaiser.raise_invalid_collection! unless collection
|
57
|
+
Surrealist::ExceptionRaiser.raise_invalid_collection! unless Helper.collection?(collection)
|
58
58
|
|
59
59
|
result = collection.map do |object|
|
60
60
|
Helper.surrealist?(object.class) ? __build_schema(object, args) : object
|
@@ -81,6 +81,8 @@ module Surrealist
|
|
81
81
|
Oj.dump(build_schema(instance: instance, **args), mode: :compat)
|
82
82
|
end
|
83
83
|
|
84
|
+
# rubocop:disable Metrics/AbcSize
|
85
|
+
|
84
86
|
# Builds hash from schema provided in the object's class and type-checks the values.
|
85
87
|
#
|
86
88
|
# @param [Object] instance of a class that has +Surrealist+ included.
|
@@ -121,15 +123,43 @@ module Surrealist
|
|
121
123
|
# # => { name: 'Nikita', age: 23 }
|
122
124
|
# # For more examples see README
|
123
125
|
def build_schema(instance:, **args)
|
124
|
-
carrier = Surrealist::Carrier.call(args)
|
125
126
|
schema = Surrealist::VarsHelper.find_schema(instance.class)
|
126
|
-
|
127
127
|
Surrealist::ExceptionRaiser.raise_unknown_schema!(instance) if schema.nil?
|
128
128
|
|
129
|
+
parameters = config ? config.merge(args) : args
|
130
|
+
carrier = Surrealist::Carrier.call(parameters)
|
129
131
|
normalized_schema = Surrealist::Copier.deep_copy(schema, carrier, instance.class.name)
|
130
132
|
hash = Builder.new(carrier, normalized_schema, instance).call
|
131
133
|
carrier.camelize ? Surrealist::HashUtils.camelize_hash(hash) : hash
|
132
134
|
end
|
135
|
+
# rubocop:enable Metrics/AbcSize
|
136
|
+
|
137
|
+
# Reads current default serialization arguments.
|
138
|
+
#
|
139
|
+
# @return [Hash] default arguments (@see Surrealist::Carrier)
|
140
|
+
def config
|
141
|
+
@default_args || Surrealist::Copier::EMPTY_HASH
|
142
|
+
end
|
143
|
+
|
144
|
+
# Sets default serialization arguments with a block
|
145
|
+
#
|
146
|
+
# @param [Hash] hash arguments to be set (@see Surrealist::Carrier)
|
147
|
+
# @param [Proc] _block a block which will be yielded to Surrealist::Carrier instance
|
148
|
+
#
|
149
|
+
# @example set config
|
150
|
+
# Surrealist.configure do |config|
|
151
|
+
# config.camelize = true
|
152
|
+
# config.include_root = true
|
153
|
+
# end
|
154
|
+
def configure(hash = nil, &_block)
|
155
|
+
if block_given?
|
156
|
+
carrier = Surrealist::Carrier.new
|
157
|
+
yield(carrier)
|
158
|
+
@default_args = carrier.parameters
|
159
|
+
else
|
160
|
+
@default_args = hash.nil? ? Surrealist::Copier::EMPTY_HASH : hash
|
161
|
+
end
|
162
|
+
end
|
133
163
|
|
134
164
|
private
|
135
165
|
|
data/surrealist.gemspec
CHANGED
@@ -24,11 +24,11 @@ Gem::Specification.new do |spec|
|
|
24
24
|
spec.require_paths = ['lib']
|
25
25
|
spec.required_ruby_version = '>= 2.2.0'
|
26
26
|
|
27
|
-
spec.add_runtime_dependency 'oj', '
|
27
|
+
spec.add_runtime_dependency 'oj', '3.4.0'
|
28
28
|
|
29
29
|
spec.add_development_dependency 'bundler', '~> 1.16'
|
30
30
|
spec.add_development_dependency 'pry', '~> 0.11'
|
31
31
|
spec.add_development_dependency 'rake', '~> 12.3'
|
32
32
|
spec.add_development_dependency 'rspec', '~> 3.7'
|
33
|
-
spec.add_development_dependency 'rubocop', '0.
|
33
|
+
spec.add_development_dependency 'rubocop', '~> 0.52'
|
34
34
|
end
|
metadata
CHANGED
@@ -1,29 +1,29 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: surrealist
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.
|
4
|
+
version: 1.1.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Nikita Esaulov
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date: 2018-02-
|
11
|
+
date: 2018-02-28 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: oj
|
15
15
|
requirement: !ruby/object:Gem::Requirement
|
16
16
|
requirements:
|
17
|
-
- -
|
17
|
+
- - '='
|
18
18
|
- !ruby/object:Gem::Version
|
19
|
-
version:
|
19
|
+
version: 3.4.0
|
20
20
|
type: :runtime
|
21
21
|
prerelease: false
|
22
22
|
version_requirements: !ruby/object:Gem::Requirement
|
23
23
|
requirements:
|
24
|
-
- -
|
24
|
+
- - '='
|
25
25
|
- !ruby/object:Gem::Version
|
26
|
-
version:
|
26
|
+
version: 3.4.0
|
27
27
|
- !ruby/object:Gem::Dependency
|
28
28
|
name: bundler
|
29
29
|
requirement: !ruby/object:Gem::Requirement
|
@@ -84,16 +84,16 @@ dependencies:
|
|
84
84
|
name: rubocop
|
85
85
|
requirement: !ruby/object:Gem::Requirement
|
86
86
|
requirements:
|
87
|
-
- -
|
87
|
+
- - "~>"
|
88
88
|
- !ruby/object:Gem::Version
|
89
|
-
version: 0.
|
89
|
+
version: '0.52'
|
90
90
|
type: :development
|
91
91
|
prerelease: false
|
92
92
|
version_requirements: !ruby/object:Gem::Requirement
|
93
93
|
requirements:
|
94
|
-
- -
|
94
|
+
- - "~>"
|
95
95
|
- !ruby/object:Gem::Version
|
96
|
-
version: 0.
|
96
|
+
version: '0.52'
|
97
97
|
description: A gem that provides DSL for serialization of plain old Ruby objects to
|
98
98
|
JSON in a declarative style by defining a `schema`. It also provides a trivial type
|
99
99
|
checking in the runtime before serialization.
|
@@ -157,7 +157,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
157
157
|
version: '0'
|
158
158
|
requirements: []
|
159
159
|
rubyforge_project:
|
160
|
-
rubygems_version: 2.7.
|
160
|
+
rubygems_version: 2.7.6
|
161
161
|
signing_key:
|
162
162
|
specification_version: 4
|
163
163
|
summary: A gem that provides DSL for serialization of plain old Ruby objects to JSON
|