json_model_rb 0.1.13 → 0.1.14

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: e4f530abe8264be24ec3b62c627bbab78fe3d25ace6bbd03a9360d7bbac688f2
4
- data.tar.gz: e1997308062e1cd0b3af670b381bd461324f0c29e49457534cd1196048f57c47
3
+ metadata.gz: 55a34992353fa6800b488fba56a9516d78c0b1c256c987ea7f22cb61782477dc
4
+ data.tar.gz: c3d0b4289612c86e3e7ba805b26209534099503947df12885591decb2942a647
5
5
  SHA512:
6
- metadata.gz: aa7626727be77b8da34aa0775f2c8ba3f1f2e636dfca50b83224e51c92e7d78c70079a2732fb0ee17ded82f295d1d2f0654e274b94ceff224b55c36aa99bff88
7
- data.tar.gz: 8bcd5c1fee253effded868ff5466f00969eebd6e50ae6c5ace3dce2bb5befc6ea6be3730bfd3ca9806bf5380267591df23dc679d97bb2751f227a9ef819669bc
6
+ metadata.gz: 128cceae1c36a9b9f130013417d2e0131a8b3b673b6cedde600297bb1d1d327fa7cfb91ebecf974af72f05e6efe96849ee2477f3e734b2b5e90ee6b0f2655c09
7
+ data.tar.gz: bb21f9d7ff5ccedcd7448f148d69ce78502b7f7200d0e6cb90edf5b54d77afae0284a3729c9d4dcba9fbac82253b3a95d957bd1aef56bc8a641453f0971a5283
data/README.md CHANGED
@@ -623,7 +623,7 @@ class PaymentMethod
623
623
  title "Payment Method"
624
624
  description "Must specify exactly one payment method"
625
625
 
626
- property :payment, type: T::OneOf[CreditCardPayment, PayPalPayment, BankTransferPayment]
626
+ property :payment, type: T::OneOf[CreditCardPayment, PayPalPayment, BankTransferPayment], discriminator: :payment_type
627
627
  end
628
628
 
629
629
  # Generate the JSON Schema
@@ -30,6 +30,7 @@ module JsonModel
30
30
  def invert_alias(name)
31
31
  aliased_properties[name]&.name || superclass&.invert_alias(name)
32
32
  rescue NoMethodError
33
+ nil
33
34
  end
34
35
 
35
36
  # @param [Symbol] name
@@ -17,7 +17,7 @@ module JsonModel
17
17
  return nil
18
18
  end
19
19
 
20
- @types.map do |type|
20
+ types_for(json).map do |type|
21
21
  type.cast(json)
22
22
  rescue StandardError
23
23
  raise(Errors::TypeError, "Value #{json.inspect} cannot be cast to allOf type #{self}")
@@ -17,7 +17,7 @@ module JsonModel
17
17
  return nil
18
18
  end
19
19
 
20
- type = @types.detect do |type|
20
+ type = types_for(json).detect do |type|
21
21
  type.cast(json)
22
22
  rescue StandardError
23
23
  false
@@ -17,7 +17,7 @@ module JsonModel
17
17
  return nil
18
18
  end
19
19
 
20
- types = @types.select do |type|
20
+ types = types_for(json).select do |type|
21
21
  type.cast(json)
22
22
  rescue StandardError
23
23
  false
@@ -3,25 +3,28 @@
3
3
  module JsonModel
4
4
  class TypeSpec
5
5
  class Composition < TypeSpec
6
+ attr_reader(:types, :modifier, :discriminator)
7
+
6
8
  # @param [Symbol] modifier
7
- # @param [TypeSpec] types
8
- def initialize(modifier, *types)
9
+ # @param [::Array<TypeSpec>] types
10
+ def initialize(modifier, *types, discriminator: nil)
9
11
  super()
10
12
  @types = types
11
13
  @modifier = modifier
14
+ @discriminator = discriminator
12
15
  end
13
16
 
14
17
  # @param [Hash] options
15
18
  # @return [Hash]
16
19
  def as_schema(**options)
17
20
  {
18
- @modifier => @types.map { |type| type.as_schema(**options) },
21
+ modifier => types.map { |type| type.as_schema(**options) },
19
22
  }
20
23
  end
21
24
 
22
25
  # @return [Array<TypeSpec>]
23
26
  def referenced_schemas
24
- @types.flat_map(&:referenced_schemas)
27
+ types.flat_map(&:referenced_schemas)
25
28
  end
26
29
 
27
30
  # @param [::Object] json
@@ -29,6 +32,44 @@ module JsonModel
29
32
  def cast(json)
30
33
  raise(NotImplementedError)
31
34
  end
35
+
36
+ protected
37
+
38
+ # @return [Hash, nil]
39
+ def type_map
40
+ if discriminator.nil?
41
+ return nil
42
+ end
43
+
44
+ @type_map ||= types.each_with_object({}) do |type, hash|
45
+ if !type.is_a?(Object)
46
+ raise('Discriminator property can only be used with Object types')
47
+ end
48
+
49
+ discriminator_property = type.type.properties[discriminator]
50
+ discriminator_values = if discriminator_property&.type.is_a?(Const)
51
+ [discriminator_property.type.value]
52
+ elsif discriminator_property&.type.is_a?(Enum)
53
+ discriminator_property.type.values
54
+ else
55
+ raise('Discriminator property must be of type Const or Enum')
56
+ end
57
+ discriminator_values.each do |value|
58
+ hash[value] ||= []
59
+ hash[value] << type
60
+ end
61
+ end
62
+ end
63
+
64
+ # @param [::Object] json
65
+ # @return [::Array<TypeSpec>]
66
+ def types_for(json)
67
+ if type_map.nil?
68
+ types
69
+ else
70
+ type_map[json[discriminator]]
71
+ end
72
+ end
32
73
  end
33
74
  end
34
75
  end
@@ -3,6 +3,8 @@
3
3
  module JsonModel
4
4
  class TypeSpec
5
5
  class Const < TypeSpec
6
+ attr_reader(:value)
7
+
6
8
  # @param [String] value
7
9
  def initialize(value)
8
10
  super()
@@ -17,7 +19,7 @@ module JsonModel
17
19
  # @return [Hash]
18
20
  def as_schema(**_options)
19
21
  {
20
- const: @value,
22
+ const: value,
21
23
  }.compact
22
24
  end
23
25
 
@@ -26,7 +28,7 @@ module JsonModel
26
28
  def register_validations(name, klass)
27
29
  super
28
30
 
29
- klass.validates(name, inclusion: { in: @value }, allow_nil: true)
31
+ klass.validates(name, inclusion: { in: value }, allow_nil: true)
30
32
  end
31
33
  end
32
34
  end
@@ -3,6 +3,8 @@
3
3
  module JsonModel
4
4
  class TypeSpec
5
5
  class Enum < TypeSpec
6
+ attr_reader(:values)
7
+
6
8
  # @param [Array<Object, nil>] values
7
9
  def initialize(*values)
8
10
  super()
@@ -17,7 +19,7 @@ module JsonModel
17
19
  # @return [Hash]
18
20
  def as_schema(**_options)
19
21
  {
20
- enum: @values,
22
+ enum: values,
21
23
  }.compact
22
24
  end
23
25
 
@@ -26,7 +28,7 @@ module JsonModel
26
28
  def register_validations(name, klass)
27
29
  super
28
30
 
29
- klass.validates(name, inclusion: { in: @values }, allow_nil: true)
31
+ klass.validates(name, inclusion: { in: values }, allow_nil: true)
30
32
  end
31
33
  end
32
34
  end
@@ -3,6 +3,8 @@
3
3
  module JsonModel
4
4
  class TypeSpec
5
5
  class Object < TypeSpec
6
+ attr_reader(:type)
7
+
6
8
  # @param [Schema] type
7
9
  def initialize(type)
8
10
  super()
@@ -12,18 +14,18 @@ module JsonModel
12
14
  # @param [Hash] options
13
15
  # @return [Hash]
14
16
  def as_schema(**options)
15
- @type.as_schema(**options)
17
+ type.as_schema(**options)
16
18
  end
17
19
 
18
20
  # @return [Array<TypeSpec>]
19
21
  def referenced_schemas
20
- [@type]
22
+ [type]
21
23
  end
22
24
 
23
25
  # @param [::Object] json
24
26
  # @return [::Object, nil]
25
27
  def cast(json)
26
- @type.from_json(**json)
28
+ type.from_json(**json)
27
29
  end
28
30
  end
29
31
  end
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module JsonModel
4
- VERSION = '0.1.13'
4
+ VERSION = '0.1.14'
5
5
  end
@@ -9,7 +9,7 @@ RSpec.describe('File system schema') do
9
9
  Class.new do
10
10
  include(JsonModel::Schema)
11
11
 
12
- property(:type, type: T::Enum['disk'])
12
+ property(:type, type: T::Const['disk'])
13
13
  property(:device, type: String, pattern: %r{\A/dev/[^/]+(/[^/]+)*\z})
14
14
  end,
15
15
  )
@@ -19,7 +19,7 @@ RSpec.describe('File system schema') do
19
19
  Class.new do
20
20
  include(JsonModel::Schema)
21
21
 
22
- property(:type, type: T::Enum['disk'])
22
+ property(:type, type: T::Enum['diskUUID', 'diskuuid'])
23
23
  property(
24
24
  :label,
25
25
  type: String,
@@ -33,7 +33,7 @@ RSpec.describe('File system schema') do
33
33
  Class.new do
34
34
  include(JsonModel::Schema)
35
35
 
36
- property(:type, type: T::Enum['nfs'])
36
+ property(:type, type: T::Const['nfs'])
37
37
  property(:remote_path, type: String, pattern: %r{\A(/[^/]+)+\z}, as: :remotePath)
38
38
  property(:server, type: String, format: :ipv4)
39
39
  end,
@@ -44,7 +44,7 @@ RSpec.describe('File system schema') do
44
44
  Class.new do
45
45
  include(JsonModel::Schema)
46
46
 
47
- property(:type, type: T::Enum['tmpfs'])
47
+ property(:type, type: T::Const['tmpfs'])
48
48
  property(:size_in_mb, type: Integer, minimum: 16, maximum: 512, as: :sizeInMB)
49
49
  end,
50
50
  )
@@ -55,7 +55,12 @@ RSpec.describe('File system schema') do
55
55
  include(JsonModel::Schema)
56
56
 
57
57
  description('JSON Schema for an fstab entry')
58
- property(:storage, type: T::OneOf[DiskDevice, DiskUuid, Nfs, Tmpfs], ref_mode: JsonModel::RefMode::LOCAL)
58
+ property(
59
+ :storage,
60
+ type: T::OneOf[DiskDevice, DiskUuid, Nfs, Tmpfs],
61
+ ref_mode: JsonModel::RefMode::LOCAL,
62
+ discriminator: :type,
63
+ )
59
64
  property(:fstype, type: T::Enum['ext3', 'ext4', 'btrfs'], optional: true)
60
65
  property(:options, type: T::Array[String], min_items: 1, unique_items: true, optional: true)
61
66
  property(:readonly, type: T::Boolean, optional: true)
@@ -100,7 +105,7 @@ RSpec.describe('File system schema') do
100
105
  DiskDevice: {
101
106
  properties: {
102
107
  type: {
103
- enum: ['disk'],
108
+ const: 'disk',
104
109
  },
105
110
  device: {
106
111
  type: 'string',
@@ -113,7 +118,7 @@ RSpec.describe('File system schema') do
113
118
  },
114
119
  DiskUuid: {
115
120
  properties: {
116
- type: { enum: ['disk'] },
121
+ type: { enum: %w(diskUUID diskuuid) },
117
122
  label: {
118
123
  type: 'string',
119
124
  pattern: '\\A[a-fA-F0-9]{8}-[a-fA-F0-9]{4}-[a-fA-F0-9]{4}-[a-fA-F0-9]{4}-[a-fA-F0-9]{12}\\z',
@@ -125,7 +130,7 @@ RSpec.describe('File system schema') do
125
130
  },
126
131
  Nfs: {
127
132
  properties: {
128
- type: { enum: ['nfs'] },
133
+ type: { const: 'nfs' },
129
134
  remotePath: {
130
135
  type: 'string',
131
136
  pattern: '\\A(/[^/]+)+\\z',
@@ -141,7 +146,7 @@ RSpec.describe('File system schema') do
141
146
  },
142
147
  Tmpfs: {
143
148
  properties: {
144
- type: { enum: ['tmpfs'] },
149
+ type: { const: 'tmpfs' },
145
150
  sizeInMB: { type: 'integer', minimum: 16, maximum: 512 },
146
151
  },
147
152
  required: %i(sizeInMB type),
data/spec/schema_spec.rb CHANGED
@@ -76,7 +76,7 @@ RSpec.describe(JsonModel::Schema) do
76
76
 
77
77
  stub_const(
78
78
  'Bar',
79
- Class.new(Foo) {},
79
+ Class.new(Foo),
80
80
  )
81
81
  end
82
82
 
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: json_model_rb
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.13
4
+ version: 0.1.14
5
5
  platform: ruby
6
6
  authors:
7
7
  - Paul Gillesberger