json-schema-serializer 1.4.0 → 1.5.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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 4b4c5d9d360e8b71d59ffaf2dbaef3a19cb782acdbb4c97548188f4c3339d654
4
- data.tar.gz: 180e413608d626170441274fa43c82a20cf62d78a5509cc1cee6b8ade65dbeae
3
+ metadata.gz: 0efb6d3beb44452ee9a2aa14ac89bd465e8c23ecbaf7cb650ff39faeaf22f19d
4
+ data.tar.gz: f9d35967622b23c02a1a09cfad3c33c3af0f1bf38de295d365732231d0926011
5
5
  SHA512:
6
- metadata.gz: 6b5e545a90241344d73da7d4a015ba83e0d96ec71df27f98652f755018c2c241b612cdbbcbdcf0b3fc5b10a447e493047a035cdf93c770f42214a41e90935b7b
7
- data.tar.gz: 8c875c4c2681df2ef05ae8bde119c6cd1a9cc6621e667616e8df935acfe34c2a4c459cf648730aa9e9439240d805382ff9d8033f2edecd804e8a697def9877e5
6
+ metadata.gz: c1905cf229d6fd7c484fb3703eb507a4fb7641c28b840ee2e045b250fd688502b8c09dcb36bb28d191b1d36a7c5772040c0bd10297f6ba533e4d676d191c02a1
7
+ data.tar.gz: c24cd2d21e573339dd9b861b4f6936753f78ed63d6f7988316608d9315d1322689c3bac080873ee4e54a0327073d89545c77d51576ebd4bc6ebe842ce6fb2b19
File without changes
data/.gitignore CHANGED
File without changes
data/.prettierrc CHANGED
File without changes
data/.rspec CHANGED
File without changes
data/.rubocop.yml CHANGED
File without changes
data/.rubocop_airbnb.yml CHANGED
File without changes
data/CHANGELOG.md CHANGED
@@ -1,5 +1,9 @@
1
1
  # CHANGELOG
2
2
 
3
+ ## 1.5.0
4
+
5
+ - add: many options
6
+
3
7
  ## 1.4.0
4
8
 
5
9
  - add: "additionalProperties" support
data/Gemfile CHANGED
File without changes
data/LICENSE CHANGED
File without changes
data/README.md CHANGED
@@ -1,4 +1,4 @@
1
- # Json::Schema::Serializer
1
+ # JSON::Schema::Serializer
2
2
 
3
3
  [![Actions Status](https://github.com/Narazaka/json-schema-serializer/workflows/Ruby/badge.svg)](https://github.com/Narazaka/json-schema-serializer/actions)
4
4
  [![Gem Version](https://badge.fury.io/rb/json-schema-serializer.svg)](https://badge.fury.io/rb/json-schema-serializer)
@@ -116,7 +116,7 @@ serializer_injected.serialize([1, 2, 3])
116
116
 
117
117
  ### "additionalProperties"
118
118
 
119
- "additionalProperties" is allowed but must be a schema object. (not boolean)
119
+ "additionalProperties" is allowed but must be a schema object or `false`. (not `true`)
120
120
 
121
121
  If "additionalProperties" does not exists, this serializer works as `{ additionalProperties": false }`.
122
122
 
@@ -167,6 +167,121 @@ serializer2 = JSON::Schema::Serializer.new(schema["properties"]["bar"], {
167
167
  })
168
168
  ```
169
169
 
170
+ ## JSON::Schema::Serializer API
171
+
172
+ ### .new(schema, options = nil)
173
+
174
+ The initializer.
175
+
176
+ # @param schema [any] JSON schema object. The serializer tries schema["type"], schema[:type] and schema.type!
177
+ # @param options [Hash] options
178
+ # @option options [Proc] :resolver schema object resolver
179
+ # @option options [Hashlike<String, Class>] :injectors If schema has inject key, the serializer treats injectors[inject_key].new(data).
180
+ # @option options [String, Symbol] :inject_key inject key
181
+ # @option
182
+
183
+ #### schema [any]
184
+
185
+ JSON schema object. The serializer tries schema["type"], schema[:type] and schema.type!
186
+
187
+ #### options [Hash]
188
+
189
+ options
190
+
191
+ #### options[:resolver] [Proc]
192
+
193
+ schema object `$ref` resolver
194
+
195
+ #### options[:input_key_transform] [Proc]
196
+
197
+ input key transform
198
+
199
+ ```ruby
200
+ new({
201
+ type: :object,
202
+ properties: {
203
+ userCount: { type: :integer },
204
+ },
205
+ }, { input_key_transform: ->(name) { name.underscore } }).serialize({ user_count: 1 }) == { "userCount" => 1 }
206
+ ```
207
+
208
+ #### options[:output_key_transform] [Proc]
209
+
210
+ output key transform
211
+
212
+ ```ruby
213
+ new({
214
+ type: :object,
215
+ properties: {
216
+ userCount: { type: :integer },
217
+ },
218
+ }, { output_key_transform: ->(name) { name.underscore } }).serialize({ userCount: 1 }) == { "user_count" => 1 }
219
+ ```
220
+
221
+ #### options[:injectors] [Hashlike<String, Class>, Class], options[:inject_key] [String, Symbol]
222
+
223
+ If schema has inject key, the serializer treats data by `injectors[inject_key].new(data)` (or `injectors.send(inject_key).new(data)`).
224
+
225
+ See examples in [Usage](#usage).
226
+
227
+ #### options[:null_through] [Boolean]
228
+
229
+ If data is null, always serialize null.
230
+
231
+ ```ruby
232
+ new({ type: :string }, { null_through: true }).serialize(nil) == nil
233
+ ```
234
+
235
+ #### options[:empty_string_number_coerce_null] [Boolean]
236
+
237
+ If data == "" in integer or number schema, returns nil.
238
+
239
+ ```ruby
240
+ new({ type: :integer }, { empty_string_number_coerce_null: true }).serialize("") == nil
241
+ ```
242
+
243
+ #### options[:empty_string_boolean_coerce_null] [Boolean]
244
+
245
+ If data == "" in boolean schema, returns nil.
246
+
247
+ ```ruby
248
+ new({ type: :boolean }, { empty_string_boolean_coerce_null: true }).serialize("") == nil
249
+ ```
250
+
251
+ #### options[:false_values] [Enumerable]
252
+
253
+ If specified, boolean schema treats `!false_values.include?(data)`.
254
+
255
+ ```ruby
256
+ new({ type: :boolean }, { false_values: Set.new([false]) }).serialize(nil) == true
257
+ ```
258
+
259
+ #### options[:no_boolean_coerce] [Boolean]
260
+
261
+ If true, boolean schema treats only `true` to be `true`.
262
+
263
+ ```ruby
264
+ new({ type: :boolean }, { no_boolean_coerce: true }).serialize(1) == false
265
+ ```
266
+
267
+ #### options[:guard_primitive_in_structure] [Boolean]
268
+
269
+ If true, array or object schema does not accept primitive data and returns empty value.
270
+
271
+
272
+ ```ruby
273
+ new({ type: :object }, { guard_primitive_in_structure: true }).serialize(1) == {}
274
+ new({ type: :object }, { guard_primitive_in_structure: true, null_through: true }).serialize(1) == nil
275
+ ```
276
+
277
+ ### #serialize(data)
278
+
279
+ Serialize the object data by the schema.
280
+
281
+ #### data [any]
282
+
283
+ Serialize target object. The serializer tries data["foo"], data[:foo] and data.foo!
284
+
170
285
  ## License
171
286
 
172
287
  Zlib License
data/Rakefile CHANGED
File without changes
data/bin/console CHANGED
File without changes
data/bin/fmt CHANGED
File without changes
data/bin/setup CHANGED
File without changes
@@ -4,7 +4,7 @@ require "json/schema/serializer/version"
4
4
 
5
5
  Gem::Specification.new do |spec|
6
6
  spec.name = "json-schema-serializer"
7
- spec.version = Json::Schema::Serializer::VERSION
7
+ spec.version = JSON::Schema::Serializer::VERSION
8
8
  spec.authors = %w[Narazaka]
9
9
  spec.email = %w[info@narazaka.net]
10
10
  spec.licenses = %w[Zlib]
@@ -5,13 +5,13 @@ require "set"
5
5
  module JSON
6
6
  class Schema
7
7
  class Serializer
8
- def initialize(obj, options = {})
9
- @schema = options && options[:resolver] ? options[:resolver].call(obj) : obj
10
- @options = options
8
+ def initialize(schema, options = nil)
9
+ @schema = options && options[:resolver] ? options[:resolver].call(schema) : schema
10
+ @options = options || {}
11
11
  end
12
12
 
13
- def serialize(obj)
14
- Walker.walk(@schema, obj, true, @options)
13
+ def serialize(data)
14
+ Walker.walk(@schema, data, true, @options)
15
15
  end
16
16
 
17
17
  class Walker
@@ -121,7 +121,7 @@ module JSON
121
121
  when "string"
122
122
  case obj
123
123
  when nil
124
- ""
124
+ options[:null_through] ? nil : ""
125
125
  when DateTime, Date, Time, TimeWithZone
126
126
  case format.to_s
127
127
  when "date-time"
@@ -134,7 +134,7 @@ module JSON
134
134
  obj.to_s
135
135
  end
136
136
  when Regexp
137
- obj.inspect.gsub(%r`^/|/[a-z]*$`, '')
137
+ obj.inspect.gsub(%r{^/|/[a-z]*$}, "")
138
138
  else
139
139
  obj.to_s
140
140
  end
@@ -144,6 +144,10 @@ module JSON
144
144
  1
145
145
  when false
146
146
  0
147
+ when nil
148
+ options[:null_through] ? nil : 0
149
+ when ""
150
+ options[:empty_string_number_coerce_null] ? nil : 0
147
151
  else
148
152
  obj.to_i
149
153
  end
@@ -153,28 +157,55 @@ module JSON
153
157
  1.0
154
158
  when false
155
159
  0.0
160
+ when nil
161
+ options[:null_through] ? nil : 0.0
162
+ when ""
163
+ options[:empty_string_number_coerce_null] ? nil : 0.0
156
164
  else
157
165
  obj.to_f
158
166
  end
159
167
  when "boolean"
160
- obj == true
168
+ if obj.nil? && options[:null_through]
169
+ nil
170
+ elsif options[:empty_string_boolean_coerce_null] && obj == ""
171
+ nil
172
+ elsif options[:false_values]
173
+ !options[:false_values].include?(obj)
174
+ elsif options[:no_boolean_coerce]
175
+ obj == true
176
+ else
177
+ obj ? true : false
178
+ end
161
179
  when "array"
162
180
  items_schema = try_hash(schema, :items)
163
- obj.nil? ? [] : obj.map { |item| walk(items_schema, item, true, options) }
181
+ return options[:null_through] ? nil : [] if obj.nil? || !obj.respond_to?(:map)
182
+ return options[:null_through] ? nil : [] if options[:guard_primitive_in_structure] && is_primitive?(obj)
183
+
184
+ obj.map { |item| walk(items_schema, item, true, options) }
164
185
  when "object"
186
+ return nil if obj.nil? && options[:null_through]
187
+ return options[:null_through] ? nil : {} if options[:guard_primitive_in_structure] && is_primitive?(obj)
188
+
165
189
  properties_schema = try_hash(schema, :properties)
166
190
  additional_properties_schema = try_hash(schema, :additionalProperties)
167
191
  required_schema = Set.new(try_hash(schema, :required)&.map(&:to_s))
168
- ret = properties_schema.map do |name, property_schema|
169
- [name.to_s, walk(property_schema, try_hash(obj, name), required_schema.include?(name.to_s), options)]
170
- end.to_h
192
+ input_key_transform = options[:input_key_transform] # schema key -> input obj key
193
+ output_key_transform = options[:output_key_transform] # schema key -> out
194
+ ret =
195
+ properties_schema.map do |name, property_schema|
196
+ input_key = input_key_transform ? input_key_transform.call(name.to_s) : name
197
+ output_key = output_key_transform ? output_key_transform.call(name.to_s) : name.to_s
198
+ [output_key, walk(property_schema, try_hash(obj, input_key), required_schema.include?(name.to_s), options)]
199
+ end.to_h
171
200
  if additional_properties_schema
172
- not_additional_keys = Set.new(properties_schema.keys.map(&:to_s))
201
+ not_additional_keys_array = properties_schema.keys.map(&:to_s)
202
+ not_additional_keys = Set.new(input_key_transform ? not_additional_keys_array.map { |k| input_key_transform.call(k) } : not_additional_keys_array)
173
203
  additional_keys = obj.keys.reject { |key| not_additional_keys.include?(key.to_s) }
174
204
  ret.merge(
175
205
  additional_keys.map do |name|
176
- [name.to_s, walk(additional_properties_schema, try_hash(obj, name), false, options)]
177
- end.to_h
206
+ output_key = output_key_transform ? output_key_transform.call(name.to_s) : name.to_s
207
+ [output_key, walk(additional_properties_schema, try_hash(obj, name), false, options)]
208
+ end.to_h,
178
209
  )
179
210
  else
180
211
  ret
@@ -186,11 +217,20 @@ module JSON
186
217
 
187
218
  def try_hash(obj, name)
188
219
  if obj.respond_to?(:"[]")
189
- obj[name] || obj[name.is_a?(Symbol) ? name.to_s : name.to_sym]
220
+ obj[name] || obj[name.is_a?(String) ? name.to_sym : name.to_s]
190
221
  elsif obj.respond_to?(name)
191
222
  obj.send(name)
192
223
  end
193
224
  end
225
+
226
+ def is_primitive?(obj)
227
+ case obj
228
+ when String, Integer, Float, true, false, nil
229
+ true
230
+ else
231
+ false
232
+ end
233
+ end
194
234
  end
195
235
  end
196
236
  end
@@ -1,7 +1,7 @@
1
- module Json
2
- module Schema
3
- module Serializer
4
- VERSION = "1.4.0".freeze
1
+ module JSON
2
+ class Schema
3
+ class Serializer
4
+ VERSION = "1.5.0".freeze
5
5
  end
6
6
  end
7
7
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: json-schema-serializer
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.4.0
4
+ version: 1.5.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Narazaka
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2019-12-01 00:00:00.000000000 Z
11
+ date: 2019-12-03 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler
@@ -181,7 +181,7 @@ metadata:
181
181
  homepage_uri: https://github.com/Narazaka/json-schema-serializer
182
182
  source_code_uri: https://github.com/Narazaka/json-schema-serializer.git
183
183
  changelog_uri: https://github.com/Narazaka/json-schema-serializer/blob/master/CHANGELOG.md
184
- documentation_uri: https://www.rubydoc.info/gems/json-schema-serializer/1.4.0
184
+ documentation_uri: https://www.rubydoc.info/gems/json-schema-serializer/1.5.0
185
185
  post_install_message:
186
186
  rdoc_options: []
187
187
  require_paths:
@@ -197,7 +197,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
197
197
  - !ruby/object:Gem::Version
198
198
  version: '0'
199
199
  requirements: []
200
- rubygems_version: 3.0.3
200
+ rubyforge_project:
201
+ rubygems_version: 2.7.6
201
202
  signing_key:
202
203
  specification_version: 4
203
204
  summary: JSON Schema based serializer