cloudsmith-api 2.0.38 → 2.0.40

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.
Files changed (43) hide show
  1. checksums.yaml +4 -4
  2. data/Gemfile.lock +1 -1
  3. data/README.md +14 -4
  4. data/build.json +1 -1
  5. data/docs/OrganizationApiKeyRule.md +1 -1
  6. data/docs/ReposApi.md +401 -0
  7. data/docs/Service.md +1 -1
  8. data/docs/SkillsUpstream.md +34 -0
  9. data/docs/SkillsUpstreamRequest.md +22 -0
  10. data/docs/SkillsUpstreamRequestPatch.md +22 -0
  11. data/docs/SkillsUpstreamSelection.md +10 -0
  12. data/lib/cloudsmith-api/api/repos_api.rb +395 -0
  13. data/lib/cloudsmith-api/models/huggingface_upstream.rb +2 -2
  14. data/lib/cloudsmith-api/models/huggingface_upstream_request.rb +2 -2
  15. data/lib/cloudsmith-api/models/huggingface_upstream_request_patch.rb +2 -2
  16. data/lib/cloudsmith-api/models/organization_api_key_rule.rb +1 -1
  17. data/lib/cloudsmith-api/models/service.rb +1 -1
  18. data/lib/cloudsmith-api/models/skills_upstream.rb +532 -0
  19. data/lib/cloudsmith-api/models/skills_upstream_request.rb +401 -0
  20. data/lib/cloudsmith-api/models/skills_upstream_request_patch.rb +391 -0
  21. data/lib/cloudsmith-api/models/skills_upstream_selection.rb +220 -0
  22. data/lib/cloudsmith-api/version.rb +1 -1
  23. data/lib/cloudsmith-api.rb +4 -0
  24. data/spec/api/repos_api_spec.rb +87 -0
  25. data/spec/models/huggingface_upstream_request_patch_spec.rb +1 -1
  26. data/spec/models/huggingface_upstream_request_spec.rb +1 -1
  27. data/spec/models/huggingface_upstream_spec.rb +1 -1
  28. data/spec/models/skills_upstream_request_patch_spec.rb +137 -0
  29. data/spec/models/skills_upstream_request_spec.rb +137 -0
  30. data/spec/models/skills_upstream_selection_spec.rb +53 -0
  31. data/spec/models/skills_upstream_spec.rb +213 -0
  32. data/vendor/bundle/ruby/2.6.0/extensions/x86_64-linux/2.6.0/autotest-fsevent-0.3.2/gem_make.out +1 -1
  33. data/vendor/bundle/ruby/2.6.0/extensions/x86_64-linux/2.6.0/bigdecimal-4.1.3/gem_make.out +2 -2
  34. data/vendor/bundle/ruby/2.6.0/extensions/x86_64-linux/2.6.0/bigdecimal-4.1.3/mkmf.log +4 -4
  35. data/vendor/bundle/ruby/2.6.0/extensions/x86_64-linux/2.6.0/ffi-1.17.4/gem_make.out +2 -2
  36. data/vendor/bundle/ruby/2.6.0/extensions/x86_64-linux/2.6.0/ffi-1.17.4/mkmf.log +1 -1
  37. data/vendor/bundle/ruby/2.6.0/extensions/x86_64-linux/2.6.0/json-2.7.6/gem_make.out +2 -2
  38. data/vendor/bundle/ruby/2.6.0/extensions/x86_64-linux/2.6.0/json-2.7.6/mkmf.log +1 -1
  39. data/vendor/bundle/ruby/2.6.0/gems/bigdecimal-4.1.3/ext/bigdecimal/Makefile +2 -2
  40. data/vendor/bundle/ruby/2.6.0/gems/ffi-1.17.4/ext/ffi_c/Makefile +2 -2
  41. data/vendor/bundle/ruby/2.6.0/gems/json-2.7.6/ext/json/ext/generator/Makefile +2 -2
  42. data/vendor/bundle/ruby/2.6.0/gems/json-2.7.6/ext/json/ext/parser/Makefile +2 -2
  43. metadata +18 -2
@@ -0,0 +1,532 @@
1
+ =begin
2
+ #Cloudsmith API (v1)
3
+
4
+ #The API to the Cloudsmith Service
5
+
6
+ OpenAPI spec version: v1
7
+ Contact: support@cloudsmith.io
8
+ Generated by: https://github.com/swagger-api/swagger-codegen.git
9
+ Swagger Codegen version: 2.4.52
10
+
11
+ =end
12
+
13
+ require 'date'
14
+
15
+ module CloudsmithApi
16
+ class SkillsUpstream
17
+ # The authentication mode to use when accessing this upstream.
18
+ attr_accessor :auth_mode
19
+
20
+ # Secret to provide with requests to upstream.
21
+ attr_accessor :auth_secret
22
+
23
+ # Username to provide with requests to upstream.
24
+ attr_accessor :auth_username
25
+
26
+ # Whether the upstream is available for use.
27
+ attr_accessor :available
28
+
29
+ # Whether the upstream can be reindexed.
30
+ attr_accessor :can_reindex
31
+
32
+ # The package types to serve from the upstream: skills, plugins, or both.
33
+ attr_accessor :contents
34
+
35
+ # The datetime the upstream source was created.
36
+ attr_accessor :created_at
37
+
38
+ attr_accessor :disable_reason
39
+
40
+ # Human-readable explanation of why this upstream is disabled
41
+ attr_accessor :disable_reason_text
42
+
43
+ # The key for extra header #1 to send to upstream.
44
+ attr_accessor :extra_header_1
45
+
46
+ # The key for extra header #2 to send to upstream.
47
+ attr_accessor :extra_header_2
48
+
49
+ # The value for extra header #1 to send to upstream. This is stored as plaintext, and is NOT encrypted.
50
+ attr_accessor :extra_value_1
51
+
52
+ # The value for extra header #2 to send to upstream. This is stored as plaintext, and is NOT encrypted.
53
+ attr_accessor :extra_value_2
54
+
55
+ # Whether the upstream has failed signature verification.
56
+ attr_accessor :has_failed_signature_verification
57
+
58
+ # The number of packages available in this upstream source
59
+ attr_accessor :index_package_count
60
+
61
+ # The current indexing status of this upstream source
62
+ attr_accessor :index_status
63
+
64
+ # Whether or not this upstream is active and ready for requests.
65
+ attr_accessor :is_active
66
+
67
+ # The last time this upstream source was indexed
68
+ attr_accessor :last_indexed
69
+
70
+ # The mode that this upstream should operate in. Upstream sources can be used to proxy resolved packages, as well as operate in a proxy/cache or cache only mode.
71
+ attr_accessor :mode
72
+
73
+ # A descriptive name for this upstream source. A shortened version of this name will be used for tagging cached packages retrieved from this upstream.
74
+ attr_accessor :name
75
+
76
+ # When true, this upstream source is pending validation.
77
+ attr_accessor :pending_validation
78
+
79
+ # Upstream sources are selected for resolving requests by sequential order (1..n), followed by creation date.
80
+ attr_accessor :priority
81
+
82
+ # Exact ClawHub releases to cache.
83
+ attr_accessor :selections
84
+
85
+ attr_accessor :slug_perm
86
+
87
+ attr_accessor :updated_at
88
+
89
+ # The URL for this upstream source. This must be a fully qualified URL including any path elements required to reach the root of the repository.
90
+ attr_accessor :upstream_url
91
+
92
+ # If enabled, SSL certificates are verified when requests are made to this upstream. It's recommended to leave this enabled for all public sources to help mitigate Man-In-The-Middle (MITM) attacks. Please note this only applies to HTTPS upstreams.
93
+ attr_accessor :verify_ssl
94
+
95
+ class EnumAttributeValidator
96
+ attr_reader :datatype
97
+ attr_reader :allowable_values
98
+
99
+ def initialize(datatype, allowable_values)
100
+ @allowable_values = allowable_values.map do |value|
101
+ case datatype.to_s
102
+ when /Integer/i
103
+ value.to_i
104
+ when /Float/i
105
+ value.to_f
106
+ else
107
+ value
108
+ end
109
+ end
110
+ end
111
+
112
+ def valid?(value)
113
+ !value || allowable_values.include?(value)
114
+ end
115
+ end
116
+
117
+ # Attribute mapping from ruby-style variable name to JSON key.
118
+ def self.attribute_map
119
+ {
120
+ :'auth_mode' => :'auth_mode',
121
+ :'auth_secret' => :'auth_secret',
122
+ :'auth_username' => :'auth_username',
123
+ :'available' => :'available',
124
+ :'can_reindex' => :'can_reindex',
125
+ :'contents' => :'contents',
126
+ :'created_at' => :'created_at',
127
+ :'disable_reason' => :'disable_reason',
128
+ :'disable_reason_text' => :'disable_reason_text',
129
+ :'extra_header_1' => :'extra_header_1',
130
+ :'extra_header_2' => :'extra_header_2',
131
+ :'extra_value_1' => :'extra_value_1',
132
+ :'extra_value_2' => :'extra_value_2',
133
+ :'has_failed_signature_verification' => :'has_failed_signature_verification',
134
+ :'index_package_count' => :'index_package_count',
135
+ :'index_status' => :'index_status',
136
+ :'is_active' => :'is_active',
137
+ :'last_indexed' => :'last_indexed',
138
+ :'mode' => :'mode',
139
+ :'name' => :'name',
140
+ :'pending_validation' => :'pending_validation',
141
+ :'priority' => :'priority',
142
+ :'selections' => :'selections',
143
+ :'slug_perm' => :'slug_perm',
144
+ :'updated_at' => :'updated_at',
145
+ :'upstream_url' => :'upstream_url',
146
+ :'verify_ssl' => :'verify_ssl'
147
+ }
148
+ end
149
+
150
+ # Attribute type mapping.
151
+ def self.swagger_types
152
+ {
153
+ :'auth_mode' => :'String',
154
+ :'auth_secret' => :'String',
155
+ :'auth_username' => :'String',
156
+ :'available' => :'BOOLEAN',
157
+ :'can_reindex' => :'BOOLEAN',
158
+ :'contents' => :'String',
159
+ :'created_at' => :'DateTime',
160
+ :'disable_reason' => :'String',
161
+ :'disable_reason_text' => :'String',
162
+ :'extra_header_1' => :'String',
163
+ :'extra_header_2' => :'String',
164
+ :'extra_value_1' => :'String',
165
+ :'extra_value_2' => :'String',
166
+ :'has_failed_signature_verification' => :'BOOLEAN',
167
+ :'index_package_count' => :'Integer',
168
+ :'index_status' => :'String',
169
+ :'is_active' => :'BOOLEAN',
170
+ :'last_indexed' => :'String',
171
+ :'mode' => :'String',
172
+ :'name' => :'String',
173
+ :'pending_validation' => :'BOOLEAN',
174
+ :'priority' => :'Integer',
175
+ :'selections' => :'Array<SkillsUpstreamSelection>',
176
+ :'slug_perm' => :'String',
177
+ :'updated_at' => :'DateTime',
178
+ :'upstream_url' => :'String',
179
+ :'verify_ssl' => :'BOOLEAN'
180
+ }
181
+ end
182
+
183
+ # Initializes the object
184
+ # @param [Hash] attributes Model attributes in the form of hash
185
+ def initialize(attributes = {})
186
+ return unless attributes.is_a?(Hash)
187
+
188
+ # convert string to symbol for hash key
189
+ attributes = attributes.each_with_object({}) { |(k, v), h| h[k.to_sym] = v }
190
+
191
+ if attributes.has_key?(:'auth_mode')
192
+ self.auth_mode = attributes[:'auth_mode']
193
+ else
194
+ self.auth_mode = 'None'
195
+ end
196
+
197
+ if attributes.has_key?(:'auth_secret')
198
+ self.auth_secret = attributes[:'auth_secret']
199
+ end
200
+
201
+ if attributes.has_key?(:'auth_username')
202
+ self.auth_username = attributes[:'auth_username']
203
+ end
204
+
205
+ if attributes.has_key?(:'available')
206
+ self.available = attributes[:'available']
207
+ end
208
+
209
+ if attributes.has_key?(:'can_reindex')
210
+ self.can_reindex = attributes[:'can_reindex']
211
+ end
212
+
213
+ if attributes.has_key?(:'contents')
214
+ self.contents = attributes[:'contents']
215
+ else
216
+ self.contents = 'Skills'
217
+ end
218
+
219
+ if attributes.has_key?(:'created_at')
220
+ self.created_at = attributes[:'created_at']
221
+ end
222
+
223
+ if attributes.has_key?(:'disable_reason')
224
+ self.disable_reason = attributes[:'disable_reason']
225
+ else
226
+ self.disable_reason = 'N/A'
227
+ end
228
+
229
+ if attributes.has_key?(:'disable_reason_text')
230
+ self.disable_reason_text = attributes[:'disable_reason_text']
231
+ end
232
+
233
+ if attributes.has_key?(:'extra_header_1')
234
+ self.extra_header_1 = attributes[:'extra_header_1']
235
+ end
236
+
237
+ if attributes.has_key?(:'extra_header_2')
238
+ self.extra_header_2 = attributes[:'extra_header_2']
239
+ end
240
+
241
+ if attributes.has_key?(:'extra_value_1')
242
+ self.extra_value_1 = attributes[:'extra_value_1']
243
+ end
244
+
245
+ if attributes.has_key?(:'extra_value_2')
246
+ self.extra_value_2 = attributes[:'extra_value_2']
247
+ end
248
+
249
+ if attributes.has_key?(:'has_failed_signature_verification')
250
+ self.has_failed_signature_verification = attributes[:'has_failed_signature_verification']
251
+ end
252
+
253
+ if attributes.has_key?(:'index_package_count')
254
+ self.index_package_count = attributes[:'index_package_count']
255
+ end
256
+
257
+ if attributes.has_key?(:'index_status')
258
+ self.index_status = attributes[:'index_status']
259
+ end
260
+
261
+ if attributes.has_key?(:'is_active')
262
+ self.is_active = attributes[:'is_active']
263
+ end
264
+
265
+ if attributes.has_key?(:'last_indexed')
266
+ self.last_indexed = attributes[:'last_indexed']
267
+ end
268
+
269
+ if attributes.has_key?(:'mode')
270
+ self.mode = attributes[:'mode']
271
+ else
272
+ self.mode = 'Proxy Only'
273
+ end
274
+
275
+ if attributes.has_key?(:'name')
276
+ self.name = attributes[:'name']
277
+ end
278
+
279
+ if attributes.has_key?(:'pending_validation')
280
+ self.pending_validation = attributes[:'pending_validation']
281
+ end
282
+
283
+ if attributes.has_key?(:'priority')
284
+ self.priority = attributes[:'priority']
285
+ end
286
+
287
+ if attributes.has_key?(:'selections')
288
+ if (value = attributes[:'selections']).is_a?(Array)
289
+ self.selections = value
290
+ end
291
+ end
292
+
293
+ if attributes.has_key?(:'slug_perm')
294
+ self.slug_perm = attributes[:'slug_perm']
295
+ end
296
+
297
+ if attributes.has_key?(:'updated_at')
298
+ self.updated_at = attributes[:'updated_at']
299
+ end
300
+
301
+ if attributes.has_key?(:'upstream_url')
302
+ self.upstream_url = attributes[:'upstream_url']
303
+ end
304
+
305
+ if attributes.has_key?(:'verify_ssl')
306
+ self.verify_ssl = attributes[:'verify_ssl']
307
+ end
308
+ end
309
+
310
+ # Show invalid properties with the reasons. Usually used together with valid?
311
+ # @return Array for valid properties with the reasons
312
+ def list_invalid_properties
313
+ invalid_properties = Array.new
314
+ if @name.nil?
315
+ invalid_properties.push('invalid value for "name", name cannot be nil.')
316
+ end
317
+
318
+ if @upstream_url.nil?
319
+ invalid_properties.push('invalid value for "upstream_url", upstream_url cannot be nil.')
320
+ end
321
+
322
+ invalid_properties
323
+ end
324
+
325
+ # Check to see if the all the properties in the model are valid
326
+ # @return true if the model is valid
327
+ def valid?
328
+ auth_mode_validator = EnumAttributeValidator.new('String', ['None', 'Token'])
329
+ return false unless auth_mode_validator.valid?(@auth_mode)
330
+ contents_validator = EnumAttributeValidator.new('String', ['Skills', 'Plugins', 'Skills and plugins'])
331
+ return false unless contents_validator.valid?(@contents)
332
+ disable_reason_validator = EnumAttributeValidator.new('String', ['N/A', 'Upstream points to its own repository', 'Missing upstream source', 'RSA key did not verify the upstream\'s APKINDEX signature', 'Upstream was disabled by request of user'])
333
+ return false unless disable_reason_validator.valid?(@disable_reason)
334
+ mode_validator = EnumAttributeValidator.new('String', ['Proxy Only', 'Cache and Proxy', 'Cache Only'])
335
+ return false unless mode_validator.valid?(@mode)
336
+ return false if @name.nil?
337
+ return false if @upstream_url.nil?
338
+ true
339
+ end
340
+
341
+ # Custom attribute writer method checking allowed values (enum).
342
+ # @param [Object] auth_mode Object to be assigned
343
+ def auth_mode=(auth_mode)
344
+ validator = EnumAttributeValidator.new('String', ['None', 'Token'])
345
+ unless validator.valid?(auth_mode)
346
+ fail ArgumentError, 'invalid value for "auth_mode", must be one of #{validator.allowable_values}.'
347
+ end
348
+ @auth_mode = auth_mode
349
+ end
350
+
351
+ # Custom attribute writer method checking allowed values (enum).
352
+ # @param [Object] contents Object to be assigned
353
+ def contents=(contents)
354
+ validator = EnumAttributeValidator.new('String', ['Skills', 'Plugins', 'Skills and plugins'])
355
+ unless validator.valid?(contents)
356
+ fail ArgumentError, 'invalid value for "contents", must be one of #{validator.allowable_values}.'
357
+ end
358
+ @contents = contents
359
+ end
360
+
361
+ # Custom attribute writer method checking allowed values (enum).
362
+ # @param [Object] disable_reason Object to be assigned
363
+ def disable_reason=(disable_reason)
364
+ validator = EnumAttributeValidator.new('String', ['N/A', 'Upstream points to its own repository', 'Missing upstream source', 'RSA key did not verify the upstream\'s APKINDEX signature', 'Upstream was disabled by request of user'])
365
+ unless validator.valid?(disable_reason)
366
+ fail ArgumentError, 'invalid value for "disable_reason", must be one of #{validator.allowable_values}.'
367
+ end
368
+ @disable_reason = disable_reason
369
+ end
370
+
371
+ # Custom attribute writer method checking allowed values (enum).
372
+ # @param [Object] mode Object to be assigned
373
+ def mode=(mode)
374
+ validator = EnumAttributeValidator.new('String', ['Proxy Only', 'Cache and Proxy', 'Cache Only'])
375
+ unless validator.valid?(mode)
376
+ fail ArgumentError, 'invalid value for "mode", must be one of #{validator.allowable_values}.'
377
+ end
378
+ @mode = mode
379
+ end
380
+
381
+ # Checks equality by comparing each attribute.
382
+ # @param [Object] Object to be compared
383
+ def ==(o)
384
+ return true if self.equal?(o)
385
+ self.class == o.class &&
386
+ auth_mode == o.auth_mode &&
387
+ auth_secret == o.auth_secret &&
388
+ auth_username == o.auth_username &&
389
+ available == o.available &&
390
+ can_reindex == o.can_reindex &&
391
+ contents == o.contents &&
392
+ created_at == o.created_at &&
393
+ disable_reason == o.disable_reason &&
394
+ disable_reason_text == o.disable_reason_text &&
395
+ extra_header_1 == o.extra_header_1 &&
396
+ extra_header_2 == o.extra_header_2 &&
397
+ extra_value_1 == o.extra_value_1 &&
398
+ extra_value_2 == o.extra_value_2 &&
399
+ has_failed_signature_verification == o.has_failed_signature_verification &&
400
+ index_package_count == o.index_package_count &&
401
+ index_status == o.index_status &&
402
+ is_active == o.is_active &&
403
+ last_indexed == o.last_indexed &&
404
+ mode == o.mode &&
405
+ name == o.name &&
406
+ pending_validation == o.pending_validation &&
407
+ priority == o.priority &&
408
+ selections == o.selections &&
409
+ slug_perm == o.slug_perm &&
410
+ updated_at == o.updated_at &&
411
+ upstream_url == o.upstream_url &&
412
+ verify_ssl == o.verify_ssl
413
+ end
414
+
415
+ # @see the `==` method
416
+ # @param [Object] Object to be compared
417
+ def eql?(o)
418
+ self == o
419
+ end
420
+
421
+ # Calculates hash code according to all attributes.
422
+ # @return [Fixnum] Hash code
423
+ def hash
424
+ [auth_mode, auth_secret, auth_username, available, can_reindex, contents, created_at, disable_reason, disable_reason_text, extra_header_1, extra_header_2, extra_value_1, extra_value_2, has_failed_signature_verification, index_package_count, index_status, is_active, last_indexed, mode, name, pending_validation, priority, selections, slug_perm, updated_at, upstream_url, verify_ssl].hash
425
+ end
426
+
427
+ # Builds the object from hash
428
+ # @param [Hash] attributes Model attributes in the form of hash
429
+ # @return [Object] Returns the model itself
430
+ def build_from_hash(attributes)
431
+ return nil unless attributes.is_a?(Hash)
432
+ self.class.swagger_types.each_pair do |key, type|
433
+ if type =~ /\AArray<(.*)>/i
434
+ # check to ensure the input is an array given that the attribute
435
+ # is documented as an array but the input is not
436
+ if attributes[self.class.attribute_map[key]].is_a?(Array)
437
+ self.send("#{key}=", attributes[self.class.attribute_map[key]].map { |v| _deserialize($1, v) })
438
+ end
439
+ elsif !attributes[self.class.attribute_map[key]].nil?
440
+ self.send("#{key}=", _deserialize(type, attributes[self.class.attribute_map[key]]))
441
+ end # or else data not found in attributes(hash), not an issue as the data can be optional
442
+ end
443
+
444
+ self
445
+ end
446
+
447
+ # Deserializes the data based on type
448
+ # @param string type Data type
449
+ # @param string value Value to be deserialized
450
+ # @return [Object] Deserialized data
451
+ def _deserialize(type, value)
452
+ case type.to_sym
453
+ when :DateTime
454
+ DateTime.parse(value)
455
+ when :Date
456
+ Date.parse(value)
457
+ when :String
458
+ value.to_s
459
+ when :Integer
460
+ value.to_i
461
+ when :Float
462
+ value.to_f
463
+ when :BOOLEAN
464
+ if value.to_s =~ /\A(true|t|yes|y|1)\z/i
465
+ true
466
+ else
467
+ false
468
+ end
469
+ when :Object
470
+ # generic object (usually a Hash), return directly
471
+ value
472
+ when /\AArray<(?<inner_type>.+)>\z/
473
+ inner_type = Regexp.last_match[:inner_type]
474
+ value.map { |v| _deserialize(inner_type, v) }
475
+ when /\AHash<(?<k_type>.+?), (?<v_type>.+)>\z/
476
+ k_type = Regexp.last_match[:k_type]
477
+ v_type = Regexp.last_match[:v_type]
478
+ {}.tap do |hash|
479
+ value.each do |k, v|
480
+ hash[_deserialize(k_type, k)] = _deserialize(v_type, v)
481
+ end
482
+ end
483
+ else # model
484
+ temp_model = CloudsmithApi.const_get(type).new
485
+ temp_model.build_from_hash(value)
486
+ end
487
+ end
488
+
489
+ # Returns the string representation of the object
490
+ # @return [String] String presentation of the object
491
+ def to_s
492
+ to_hash.to_s
493
+ end
494
+
495
+ # to_body is an alias to to_hash (backward compatibility)
496
+ # @return [Hash] Returns the object in the form of hash
497
+ def to_body
498
+ to_hash
499
+ end
500
+
501
+ # Returns the object in the form of hash
502
+ # @return [Hash] Returns the object in the form of hash
503
+ def to_hash
504
+ hash = {}
505
+ self.class.attribute_map.each_pair do |attr, param|
506
+ value = self.send(attr)
507
+ next if value.nil?
508
+ hash[param] = _to_hash(value)
509
+ end
510
+ hash
511
+ end
512
+
513
+ # Outputs non-array value in the form of hash
514
+ # For object, use to_hash. Otherwise, just return the value
515
+ # @param [Object] value Any valid value
516
+ # @return [Hash] Returns the value in the form of hash
517
+ def _to_hash(value)
518
+ if value.is_a?(Array)
519
+ value.compact.map { |v| _to_hash(v) }
520
+ elsif value.is_a?(Hash)
521
+ {}.tap do |hash|
522
+ value.each { |k, v| hash[k] = _to_hash(v) }
523
+ end
524
+ elsif value.respond_to? :to_hash
525
+ value.to_hash
526
+ else
527
+ value
528
+ end
529
+ end
530
+
531
+ end
532
+ end