json_model_rb 0.1.19 → 0.1.22
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/README.md +156 -572
- data/lib/json_model/builder/alias_builder.rb +10 -0
- data/lib/json_model/builder/array_builder.rb +24 -0
- data/lib/json_model/builder/base_builder.rb +24 -0
- data/lib/json_model/builder/composition/any_of_builder.rb +16 -0
- data/lib/json_model/builder/composition/builder.rb +47 -0
- data/lib/json_model/builder/composition/intersection_builder.rb +16 -0
- data/lib/json_model/builder/composition/one_of_builder.rb +16 -0
- data/lib/json_model/builder/composition/sum_builder.rb +16 -0
- data/lib/json_model/builder/composition.rb +6 -0
- data/lib/json_model/builder/constrained_builder.rb +83 -0
- data/lib/json_model/builder/default_builder.rb +14 -0
- data/lib/json_model/builder/enum_builder.rb +16 -0
- data/lib/json_model/builder/format_builder.rb +47 -0
- data/lib/json_model/builder/key_builder.rb +30 -0
- data/lib/json_model/builder/nested_builder.rb +31 -0
- data/lib/json_model/builder/primitive/boolean_builder.rb +16 -0
- data/lib/json_model/builder/primitive/builder.rb +25 -0
- data/lib/json_model/builder/primitive/integer_builder.rb +16 -0
- data/lib/json_model/builder/primitive/null_builder.rb +16 -0
- data/lib/json_model/builder/primitive/number_builder.rb +16 -0
- data/lib/json_model/builder/primitive/string_builder.rb +16 -0
- data/lib/json_model/builder/primitive.rb +7 -0
- data/lib/json_model/builder/ref_builder.rb +35 -0
- data/lib/json_model/builder/schema_builder.rb +14 -0
- data/lib/json_model/builder.rb +65 -0
- data/lib/json_model/config/options.rb +5 -2
- data/lib/json_model/config.rb +0 -2
- data/lib/json_model/errors.rb +0 -3
- data/lib/json_model/logic/predicates/methods.rb +17 -0
- data/lib/json_model/predicates.rb +3 -0
- data/lib/json_model/schema.rb +41 -77
- data/lib/json_model/schema_meta.rb +7 -28
- data/lib/json_model/types/alias.rb +33 -0
- data/lib/json_model/types/any_of.rb +51 -20
- data/lib/json_model/types/one_of.rb +51 -20
- data/lib/json_model/types/ref.rb +32 -0
- data/lib/json_model/types.rb +47 -9
- data/lib/json_model/version.rb +1 -1
- data/lib/json_model.rb +3 -6
- data/spec/config_spec.rb +0 -14
- data/spec/examples/file_system_spec.rb +71 -31
- data/spec/examples/user_spec.rb +67 -26
- data/spec/schema_meta_spec.rb +0 -40
- data/spec/schema_spec.rb +43 -59
- metadata +84 -57
- data/lib/json_model/errors/invalid_ref_mode_error.rb +0 -12
- data/lib/json_model/errors/type_error.rb +0 -8
- data/lib/json_model/errors/unknown_attribute_error.rb +0 -13
- data/lib/json_model/properties.rb +0 -86
- data/lib/json_model/property.rb +0 -54
- data/lib/json_model/ref_mode.rb +0 -9
- data/lib/json_model/type_spec/array.rb +0 -72
- data/lib/json_model/type_spec/castable.rb +0 -34
- data/lib/json_model/type_spec/composition/all_of.rb +0 -29
- data/lib/json_model/type_spec/composition/any_of.rb +0 -34
- data/lib/json_model/type_spec/composition/one_of.rb +0 -38
- data/lib/json_model/type_spec/composition.rb +0 -79
- data/lib/json_model/type_spec/const.rb +0 -35
- data/lib/json_model/type_spec/enum.rb +0 -35
- data/lib/json_model/type_spec/object.rb +0 -32
- data/lib/json_model/type_spec/primitive/boolean.rb +0 -13
- data/lib/json_model/type_spec/primitive/integer.rb +0 -21
- data/lib/json_model/type_spec/primitive/null.rb +0 -13
- data/lib/json_model/type_spec/primitive/number.rb +0 -14
- data/lib/json_model/type_spec/primitive/numeric.rb +0 -85
- data/lib/json_model/type_spec/primitive/string.rb +0 -150
- data/lib/json_model/type_spec/primitive.rb +0 -40
- data/lib/json_model/type_spec.rb +0 -82
- data/lib/json_model/types/all_of.rb +0 -29
- data/lib/json_model/types/array.rb +0 -29
- data/lib/json_model/types/boolean.rb +0 -7
- data/lib/json_model/types/const.rb +0 -23
- data/lib/json_model/types/enum.rb +0 -23
- data/lib/json_model/types/integer.rb +0 -23
- data/lib/json_model/types/null.rb +0 -7
- data/lib/json_model/types/number.rb +0 -23
- data/lib/json_model/types/string.rb +0 -23
- data/spec/properties_spec.rb +0 -76
- data/spec/property_spec.rb +0 -86
- data/spec/type_spec/array_spec.rb +0 -206
- data/spec/type_spec/castable_spec.rb +0 -19
- data/spec/type_spec/composition/all_of_spec.rb +0 -57
- data/spec/type_spec/composition/any_of_spec.rb +0 -54
- data/spec/type_spec/composition/one_of_spec.rb +0 -59
- data/spec/type_spec/composition_spec.rb +0 -90
- data/spec/type_spec/const_spec.rb +0 -18
- data/spec/type_spec/enum_spec.rb +0 -84
- data/spec/type_spec/primitive/boolean_spec.rb +0 -12
- data/spec/type_spec/primitive/integer_spec.rb +0 -57
- data/spec/type_spec/primitive/null_spec.rb +0 -12
- data/spec/type_spec/primitive/number_spec.rb +0 -12
- data/spec/type_spec/primitive/numeric_spec.rb +0 -176
- data/spec/type_spec/primitive/string_spec.rb +0 -119
- data/spec/type_spec_spec.rb +0 -32
|
@@ -1,35 +0,0 @@
|
|
|
1
|
-
# frozen_string_literal: true
|
|
2
|
-
|
|
3
|
-
module JsonModel
|
|
4
|
-
class TypeSpec
|
|
5
|
-
class Const < TypeSpec
|
|
6
|
-
attr_reader(:value)
|
|
7
|
-
|
|
8
|
-
# @param [String] value
|
|
9
|
-
def initialize(value)
|
|
10
|
-
super()
|
|
11
|
-
@value = value
|
|
12
|
-
|
|
13
|
-
if value.blank?
|
|
14
|
-
raise(ArgumentError, 'Const type spec requires a non-empty value')
|
|
15
|
-
end
|
|
16
|
-
end
|
|
17
|
-
|
|
18
|
-
# @param [Hash] _options
|
|
19
|
-
# @return [Hash]
|
|
20
|
-
def as_schema(**_options)
|
|
21
|
-
{
|
|
22
|
-
const: value,
|
|
23
|
-
}.compact
|
|
24
|
-
end
|
|
25
|
-
|
|
26
|
-
# @param [Symbol] name
|
|
27
|
-
# @param [ActiveModel::Validations] klass
|
|
28
|
-
def register_validations(name, klass)
|
|
29
|
-
super
|
|
30
|
-
|
|
31
|
-
klass.validates(name, inclusion: { in: value }, allow_nil: true)
|
|
32
|
-
end
|
|
33
|
-
end
|
|
34
|
-
end
|
|
35
|
-
end
|
|
@@ -1,35 +0,0 @@
|
|
|
1
|
-
# frozen_string_literal: true
|
|
2
|
-
|
|
3
|
-
module JsonModel
|
|
4
|
-
class TypeSpec
|
|
5
|
-
class Enum < TypeSpec
|
|
6
|
-
attr_reader(:values)
|
|
7
|
-
|
|
8
|
-
# @param [Array<Object, nil>] values
|
|
9
|
-
def initialize(*values)
|
|
10
|
-
super()
|
|
11
|
-
@values = values
|
|
12
|
-
|
|
13
|
-
if @values.blank?
|
|
14
|
-
raise(ArgumentError, 'Enum type spec requires a non-empty enum array')
|
|
15
|
-
end
|
|
16
|
-
end
|
|
17
|
-
|
|
18
|
-
# @param [Hash] _options
|
|
19
|
-
# @return [Hash]
|
|
20
|
-
def as_schema(**_options)
|
|
21
|
-
{
|
|
22
|
-
enum: values,
|
|
23
|
-
}.compact
|
|
24
|
-
end
|
|
25
|
-
|
|
26
|
-
# @param [Symbol] name
|
|
27
|
-
# @param [ActiveModel::Validations] klass
|
|
28
|
-
def register_validations(name, klass)
|
|
29
|
-
super
|
|
30
|
-
|
|
31
|
-
klass.validates(name, inclusion: { in: values }, allow_nil: true)
|
|
32
|
-
end
|
|
33
|
-
end
|
|
34
|
-
end
|
|
35
|
-
end
|
|
@@ -1,32 +0,0 @@
|
|
|
1
|
-
# frozen_string_literal: true
|
|
2
|
-
|
|
3
|
-
module JsonModel
|
|
4
|
-
class TypeSpec
|
|
5
|
-
class Object < TypeSpec
|
|
6
|
-
attr_reader(:type)
|
|
7
|
-
|
|
8
|
-
# @param [Schema] type
|
|
9
|
-
def initialize(type)
|
|
10
|
-
super()
|
|
11
|
-
@type = type
|
|
12
|
-
end
|
|
13
|
-
|
|
14
|
-
# @param [Hash] options
|
|
15
|
-
# @return [Hash]
|
|
16
|
-
def as_schema(**options)
|
|
17
|
-
type.as_schema(**options)
|
|
18
|
-
end
|
|
19
|
-
|
|
20
|
-
# @return [Array<TypeSpec>]
|
|
21
|
-
def referenced_schemas
|
|
22
|
-
[type]
|
|
23
|
-
end
|
|
24
|
-
|
|
25
|
-
# @param [::Object] json
|
|
26
|
-
# @return [::Object, nil]
|
|
27
|
-
def cast(json)
|
|
28
|
-
type.from_json(**json)
|
|
29
|
-
end
|
|
30
|
-
end
|
|
31
|
-
end
|
|
32
|
-
end
|
|
@@ -1,21 +0,0 @@
|
|
|
1
|
-
# frozen_string_literal: true
|
|
2
|
-
|
|
3
|
-
module JsonModel
|
|
4
|
-
class TypeSpec
|
|
5
|
-
class Primitive
|
|
6
|
-
class Integer < Numeric
|
|
7
|
-
# @param [Hash] options
|
|
8
|
-
def initialize(**options)
|
|
9
|
-
super(types: [::Integer], schema_type: 'integer', **options)
|
|
10
|
-
end
|
|
11
|
-
|
|
12
|
-
# @param [Symbol] name
|
|
13
|
-
# @param [ActiveModel::Validations] klass
|
|
14
|
-
def register_validations(name, klass)
|
|
15
|
-
super
|
|
16
|
-
klass.validates(name, numericality: { only_integer: true }, allow_nil: true)
|
|
17
|
-
end
|
|
18
|
-
end
|
|
19
|
-
end
|
|
20
|
-
end
|
|
21
|
-
end
|
|
@@ -1,14 +0,0 @@
|
|
|
1
|
-
# frozen_string_literal: true
|
|
2
|
-
|
|
3
|
-
module JsonModel
|
|
4
|
-
class TypeSpec
|
|
5
|
-
class Primitive
|
|
6
|
-
class Number < Numeric
|
|
7
|
-
# @param [Hash] options
|
|
8
|
-
def initialize(**options)
|
|
9
|
-
super(types: [Float], schema_type: 'number', **options)
|
|
10
|
-
end
|
|
11
|
-
end
|
|
12
|
-
end
|
|
13
|
-
end
|
|
14
|
-
end
|
|
@@ -1,85 +0,0 @@
|
|
|
1
|
-
# frozen_string_literal: true
|
|
2
|
-
|
|
3
|
-
module JsonModel
|
|
4
|
-
class TypeSpec
|
|
5
|
-
class Primitive
|
|
6
|
-
class Numeric < Primitive
|
|
7
|
-
# @param [::Array<Class>] types
|
|
8
|
-
# @param [String] schema_type
|
|
9
|
-
# @param [Integer, nil] multiple_of
|
|
10
|
-
# @param [Integer, nil] minimum
|
|
11
|
-
# @param [Integer, nil] maximum
|
|
12
|
-
# @param [Integer, nil] exclusive_minimum
|
|
13
|
-
# @param [Integer, nil] exclusive_maximum
|
|
14
|
-
def initialize(
|
|
15
|
-
types:,
|
|
16
|
-
schema_type:,
|
|
17
|
-
multiple_of: nil,
|
|
18
|
-
minimum: nil,
|
|
19
|
-
maximum: nil,
|
|
20
|
-
exclusive_minimum: nil,
|
|
21
|
-
exclusive_maximum: nil
|
|
22
|
-
)
|
|
23
|
-
super(types: types, schema_type: schema_type)
|
|
24
|
-
@multiple_of = multiple_of
|
|
25
|
-
@minimum = minimum
|
|
26
|
-
@maximum = maximum
|
|
27
|
-
@exclusive_minimum = exclusive_minimum
|
|
28
|
-
@exclusive_maximum = exclusive_maximum
|
|
29
|
-
end
|
|
30
|
-
|
|
31
|
-
# @param [Hash] options
|
|
32
|
-
# @return [Hash]
|
|
33
|
-
def as_schema(**options)
|
|
34
|
-
super
|
|
35
|
-
.merge(
|
|
36
|
-
{
|
|
37
|
-
multipleOf: @multiple_of,
|
|
38
|
-
minimum: @minimum,
|
|
39
|
-
maximum: @maximum,
|
|
40
|
-
exclusiveMinimum: @exclusive_minimum,
|
|
41
|
-
exclusiveMaximum: @exclusive_maximum,
|
|
42
|
-
}.compact,
|
|
43
|
-
)
|
|
44
|
-
end
|
|
45
|
-
|
|
46
|
-
# @param [Symbol] name
|
|
47
|
-
# @param [ActiveModel::Validations] klass
|
|
48
|
-
def register_validations(name, klass)
|
|
49
|
-
super
|
|
50
|
-
register_multiple_of_validation(name, klass, @multiple_of)
|
|
51
|
-
if @minimum || @maximum || @exclusive_minimum || @exclusive_maximum
|
|
52
|
-
klass.validates_numericality_of(
|
|
53
|
-
name,
|
|
54
|
-
**{
|
|
55
|
-
greater_than: @exclusive_minimum,
|
|
56
|
-
less_than: @exclusive_maximum,
|
|
57
|
-
greater_than_or_equal_to: @minimum,
|
|
58
|
-
less_than_or_equal_to: @maximum,
|
|
59
|
-
}.compact,
|
|
60
|
-
allow_nil: true,
|
|
61
|
-
)
|
|
62
|
-
end
|
|
63
|
-
end
|
|
64
|
-
|
|
65
|
-
private
|
|
66
|
-
|
|
67
|
-
# @param [Symbol] name
|
|
68
|
-
# @param [ActiveModel::Validations] klass
|
|
69
|
-
# @param [Integer, nil] multiple_of
|
|
70
|
-
def register_multiple_of_validation(name, klass, multiple_of)
|
|
71
|
-
if multiple_of.nil?
|
|
72
|
-
return
|
|
73
|
-
end
|
|
74
|
-
|
|
75
|
-
klass.validate do |record|
|
|
76
|
-
value = record.send(name)
|
|
77
|
-
if value.present? && value % multiple_of != 0
|
|
78
|
-
record.errors.add(name, :multiple_of, message: "must be a multiple of #{multiple_of}")
|
|
79
|
-
end
|
|
80
|
-
end
|
|
81
|
-
end
|
|
82
|
-
end
|
|
83
|
-
end
|
|
84
|
-
end
|
|
85
|
-
end
|
|
@@ -1,150 +0,0 @@
|
|
|
1
|
-
# frozen_string_literal: true
|
|
2
|
-
|
|
3
|
-
module JsonModel
|
|
4
|
-
class TypeSpec
|
|
5
|
-
class Primitive
|
|
6
|
-
class String < Primitive
|
|
7
|
-
JSON_SCHEMA_FORMATS = {
|
|
8
|
-
date_time: lambda { |v|
|
|
9
|
-
begin
|
|
10
|
-
DateTime.iso8601(v)
|
|
11
|
-
true
|
|
12
|
-
rescue StandardError
|
|
13
|
-
false
|
|
14
|
-
end
|
|
15
|
-
},
|
|
16
|
-
date: lambda { |v|
|
|
17
|
-
begin
|
|
18
|
-
Date.iso8601(v)
|
|
19
|
-
true
|
|
20
|
-
rescue StandardError
|
|
21
|
-
false
|
|
22
|
-
end
|
|
23
|
-
},
|
|
24
|
-
time: lambda { |v|
|
|
25
|
-
begin
|
|
26
|
-
Time.iso8601(v)
|
|
27
|
-
true
|
|
28
|
-
rescue StandardError
|
|
29
|
-
false
|
|
30
|
-
end
|
|
31
|
-
},
|
|
32
|
-
email: ->(v) { v.match?(URI::MailTo::EMAIL_REGEXP) },
|
|
33
|
-
hostname: ->(v) { v.match?(/\A[a-zA-Z0-9\-.]{1,253}\z/) },
|
|
34
|
-
ipv4: lambda { |v|
|
|
35
|
-
begin
|
|
36
|
-
IPAddr.new(v).ipv4?
|
|
37
|
-
rescue StandardError
|
|
38
|
-
false
|
|
39
|
-
end
|
|
40
|
-
},
|
|
41
|
-
ipv6: lambda { |v|
|
|
42
|
-
begin
|
|
43
|
-
IPAddr.new(v).ipv6?
|
|
44
|
-
rescue StandardError
|
|
45
|
-
false
|
|
46
|
-
end
|
|
47
|
-
},
|
|
48
|
-
uri: lambda { |v|
|
|
49
|
-
begin
|
|
50
|
-
URI.parse(v)
|
|
51
|
-
true
|
|
52
|
-
rescue StandardError
|
|
53
|
-
false
|
|
54
|
-
end
|
|
55
|
-
},
|
|
56
|
-
uri_reference: lambda { |v|
|
|
57
|
-
begin
|
|
58
|
-
URI.parse(v)
|
|
59
|
-
true
|
|
60
|
-
rescue StandardError
|
|
61
|
-
false
|
|
62
|
-
end
|
|
63
|
-
},
|
|
64
|
-
uuid: lambda { |v|
|
|
65
|
-
v.match?(/\A[0-9a-f]{8}-[0-9a-f]{4}-[1-5][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}\z/i)
|
|
66
|
-
},
|
|
67
|
-
regex: lambda { |v|
|
|
68
|
-
begin
|
|
69
|
-
Regexp.new(v)
|
|
70
|
-
true
|
|
71
|
-
rescue StandardError
|
|
72
|
-
false
|
|
73
|
-
end
|
|
74
|
-
},
|
|
75
|
-
json_pointer: ->(v) { v.match?(%r{\A(?:/(?:[^~]|~[01])*)*\z}) },
|
|
76
|
-
relative_json_pointer: ->(v) { v.match?(%r{\A(?:0|[1-9][0-9]*)(?:#|(?:/(?:[^~]|~[01])*))*\z}) },
|
|
77
|
-
}.freeze
|
|
78
|
-
|
|
79
|
-
# @param [Integer, nil] min_length
|
|
80
|
-
# @param [Integer, nil] max_length
|
|
81
|
-
# @param [Regexp, nil] pattern
|
|
82
|
-
# @param [Symbol, nil] format
|
|
83
|
-
def initialize(min_length: nil, max_length: nil, pattern: nil, format: nil)
|
|
84
|
-
super(types: [::String], schema_type: 'string')
|
|
85
|
-
|
|
86
|
-
@min_length = min_length
|
|
87
|
-
@max_length = max_length
|
|
88
|
-
@pattern = pattern
|
|
89
|
-
@format = format
|
|
90
|
-
end
|
|
91
|
-
|
|
92
|
-
# @param [Hash] options
|
|
93
|
-
# @return [Hash]
|
|
94
|
-
def as_schema(**options)
|
|
95
|
-
super.merge(
|
|
96
|
-
{
|
|
97
|
-
minLength: @min_length,
|
|
98
|
-
maxLength: @max_length,
|
|
99
|
-
pattern: @pattern&.source,
|
|
100
|
-
format: @format&.to_s&.tr('_', '-'),
|
|
101
|
-
}.compact,
|
|
102
|
-
)
|
|
103
|
-
end
|
|
104
|
-
|
|
105
|
-
# @param [Symbol] name
|
|
106
|
-
# @param [ActiveModel::Validations]
|
|
107
|
-
def register_validations(name, klass)
|
|
108
|
-
super
|
|
109
|
-
|
|
110
|
-
if !@min_length.nil? || !@max_length.nil?
|
|
111
|
-
klass.validates(name, length: { minimum: @min_length, maximum: @max_length }.compact, allow_nil: true)
|
|
112
|
-
end
|
|
113
|
-
if @pattern
|
|
114
|
-
klass.validates(name, format: { with: @pattern }, allow_nil: true)
|
|
115
|
-
end
|
|
116
|
-
if @format
|
|
117
|
-
if JSON_SCHEMA_FORMATS.key?(@format)
|
|
118
|
-
register_format_validation(klass, name)
|
|
119
|
-
else
|
|
120
|
-
raise(ArgumentError, "Invalid format: #{@format}")
|
|
121
|
-
end
|
|
122
|
-
end
|
|
123
|
-
end
|
|
124
|
-
|
|
125
|
-
private
|
|
126
|
-
|
|
127
|
-
# @param [Class] klass
|
|
128
|
-
# @param [Symbol] name
|
|
129
|
-
def register_format_validation(klass, name)
|
|
130
|
-
if @format.nil?
|
|
131
|
-
return
|
|
132
|
-
end
|
|
133
|
-
|
|
134
|
-
format_validator = JSON_SCHEMA_FORMATS[@format]
|
|
135
|
-
if format_validator.nil?
|
|
136
|
-
return
|
|
137
|
-
end
|
|
138
|
-
|
|
139
|
-
klass.validate do |record|
|
|
140
|
-
value = record.send(name)
|
|
141
|
-
|
|
142
|
-
if !value.nil? && !format_validator.call(value)
|
|
143
|
-
record.errors.add(name, :invalid_format, message: "must be a valid #{@format}")
|
|
144
|
-
end
|
|
145
|
-
end
|
|
146
|
-
end
|
|
147
|
-
end
|
|
148
|
-
end
|
|
149
|
-
end
|
|
150
|
-
end
|
|
@@ -1,40 +0,0 @@
|
|
|
1
|
-
# frozen_string_literal: true
|
|
2
|
-
|
|
3
|
-
module JsonModel
|
|
4
|
-
class TypeSpec
|
|
5
|
-
class Primitive < TypeSpec
|
|
6
|
-
# @param [::Array<Class>] types
|
|
7
|
-
# @param [String] schema_type
|
|
8
|
-
def initialize(types:, schema_type:)
|
|
9
|
-
super()
|
|
10
|
-
@types = types
|
|
11
|
-
@schema_type = schema_type
|
|
12
|
-
end
|
|
13
|
-
|
|
14
|
-
# @param [Hash] _options
|
|
15
|
-
# @return [Hash]
|
|
16
|
-
def as_schema(**_options)
|
|
17
|
-
{ type: @schema_type }
|
|
18
|
-
end
|
|
19
|
-
|
|
20
|
-
# @param [::Object] json
|
|
21
|
-
# @return [::Object, nil]
|
|
22
|
-
def cast(json)
|
|
23
|
-
if json.nil?
|
|
24
|
-
nil
|
|
25
|
-
elsif @types.any? { |type| json.is_a?(type) }
|
|
26
|
-
json
|
|
27
|
-
else
|
|
28
|
-
raise(Errors::TypeError, "Expected one of #{@types.join('/')}, got #{json.class} (#{json.inspect})")
|
|
29
|
-
end
|
|
30
|
-
end
|
|
31
|
-
end
|
|
32
|
-
end
|
|
33
|
-
end
|
|
34
|
-
|
|
35
|
-
require_relative('primitive/boolean')
|
|
36
|
-
require_relative('primitive/numeric')
|
|
37
|
-
require_relative('primitive/integer')
|
|
38
|
-
require_relative('primitive/null')
|
|
39
|
-
require_relative('primitive/number')
|
|
40
|
-
require_relative('primitive/string')
|
data/lib/json_model/type_spec.rb
DELETED
|
@@ -1,82 +0,0 @@
|
|
|
1
|
-
# frozen_string_literal: true
|
|
2
|
-
|
|
3
|
-
require_relative('type_spec/array')
|
|
4
|
-
require_relative('type_spec/castable')
|
|
5
|
-
require_relative('type_spec/composition')
|
|
6
|
-
require_relative('type_spec/const')
|
|
7
|
-
require_relative('type_spec/enum')
|
|
8
|
-
require_relative('type_spec/object')
|
|
9
|
-
require_relative('type_spec/primitive')
|
|
10
|
-
|
|
11
|
-
module JsonModel
|
|
12
|
-
class TypeSpec
|
|
13
|
-
TYPE_MAP = {
|
|
14
|
-
Date => Castable.new(format: 'date') { |v| ::DateTime.iso8601(v) },
|
|
15
|
-
DateTime => Castable.new(format: 'date-time') { |v| ::DateTime.iso8601(v) },
|
|
16
|
-
FalseClass => Primitive::Boolean.new,
|
|
17
|
-
Float => Primitive::Number.new,
|
|
18
|
-
Integer => Primitive::Integer.new,
|
|
19
|
-
NilClass => Primitive::Null.new,
|
|
20
|
-
Regexp => Castable.new(format: 'regex') { |v| Regexp.new(v) },
|
|
21
|
-
String => Primitive::String.new,
|
|
22
|
-
Time => Castable.new(format: 'time') { |v| ::Time.iso8601(v) },
|
|
23
|
-
TrueClass => Primitive::Boolean.new,
|
|
24
|
-
URI => Castable.new(format: 'uri') { |v| URI.parse(v) },
|
|
25
|
-
}.freeze
|
|
26
|
-
|
|
27
|
-
# @param [Hash] options
|
|
28
|
-
# @return [Hash]
|
|
29
|
-
def as_schema(**options)
|
|
30
|
-
raise(NotImplementedError)
|
|
31
|
-
end
|
|
32
|
-
|
|
33
|
-
# @param [Symbol] name
|
|
34
|
-
# @param [ActiveModel::Validations] klass
|
|
35
|
-
def register_validations(name, klass) end
|
|
36
|
-
|
|
37
|
-
# @return [Array<TypeSpec>]
|
|
38
|
-
def referenced_schemas
|
|
39
|
-
[]
|
|
40
|
-
end
|
|
41
|
-
|
|
42
|
-
# @param [::Object] json
|
|
43
|
-
# @return [::Object, nil]
|
|
44
|
-
def cast(json)
|
|
45
|
-
json
|
|
46
|
-
end
|
|
47
|
-
|
|
48
|
-
class << self
|
|
49
|
-
# @param [Object, Class] type
|
|
50
|
-
# @return [TypeSpec]
|
|
51
|
-
def resolve(type)
|
|
52
|
-
if type.is_a?(TypeSpec)
|
|
53
|
-
return type
|
|
54
|
-
end
|
|
55
|
-
|
|
56
|
-
if TYPE_MAP.key?(type)
|
|
57
|
-
TYPE_MAP[type]
|
|
58
|
-
elsif type.respond_to?(:to_type_spec)
|
|
59
|
-
type.to_type_spec
|
|
60
|
-
elsif type.is_a?(Class) && type < Schema
|
|
61
|
-
TypeSpec::Object.new(type)
|
|
62
|
-
else
|
|
63
|
-
raise(ArgumentError, "Unsupported type: #{type}")
|
|
64
|
-
end
|
|
65
|
-
end
|
|
66
|
-
|
|
67
|
-
private
|
|
68
|
-
|
|
69
|
-
# @param [Object, Class] type
|
|
70
|
-
# @return [TypeSpec]
|
|
71
|
-
def resolve_type_from_class(type)
|
|
72
|
-
if TYPE_MAP.key?(type)
|
|
73
|
-
TYPE_MAP[type]
|
|
74
|
-
elsif type < Schema
|
|
75
|
-
TypeSpec::Object.new(type)
|
|
76
|
-
else
|
|
77
|
-
raise(ArgumentError, "Unsupported type: #{type}")
|
|
78
|
-
end
|
|
79
|
-
end
|
|
80
|
-
end
|
|
81
|
-
end
|
|
82
|
-
end
|
|
@@ -1,29 +0,0 @@
|
|
|
1
|
-
# frozen_string_literal: true
|
|
2
|
-
|
|
3
|
-
module T
|
|
4
|
-
class AllOf
|
|
5
|
-
# @param [Array<Class>] types
|
|
6
|
-
# @param [Hash] options
|
|
7
|
-
def initialize(*types, **options)
|
|
8
|
-
@types = types
|
|
9
|
-
@options = options
|
|
10
|
-
end
|
|
11
|
-
|
|
12
|
-
# @return [JsonModel::TypeSpec::Composition::AllOf]
|
|
13
|
-
def to_type_spec
|
|
14
|
-
JsonModel::TypeSpec::Composition::AllOf.new(
|
|
15
|
-
*@types.map { |type| JsonModel::TypeSpec.resolve(type) },
|
|
16
|
-
**@options,
|
|
17
|
-
)
|
|
18
|
-
end
|
|
19
|
-
|
|
20
|
-
class << self
|
|
21
|
-
# @param [Array] types
|
|
22
|
-
# @param [Hash] options
|
|
23
|
-
# @return [AllOf]
|
|
24
|
-
def [](*types, **options)
|
|
25
|
-
AllOf.new(*types, **options)
|
|
26
|
-
end
|
|
27
|
-
end
|
|
28
|
-
end
|
|
29
|
-
end
|
|
@@ -1,29 +0,0 @@
|
|
|
1
|
-
# frozen_string_literal: true
|
|
2
|
-
|
|
3
|
-
module T
|
|
4
|
-
class Array
|
|
5
|
-
# @param [Class] type
|
|
6
|
-
# @param [Hash] options
|
|
7
|
-
def initialize(type, **options)
|
|
8
|
-
@type = type
|
|
9
|
-
@options = options
|
|
10
|
-
end
|
|
11
|
-
|
|
12
|
-
# @return [JsonModel::TypeSpec::Array]
|
|
13
|
-
def to_type_spec
|
|
14
|
-
JsonModel::TypeSpec::Array.new(
|
|
15
|
-
JsonModel::TypeSpec.resolve(@type),
|
|
16
|
-
**@options,
|
|
17
|
-
)
|
|
18
|
-
end
|
|
19
|
-
|
|
20
|
-
class << self
|
|
21
|
-
# @param [Class] type
|
|
22
|
-
# @param [Hash] options
|
|
23
|
-
# @return [Array]
|
|
24
|
-
def [](type, **options)
|
|
25
|
-
Array.new(type, **options)
|
|
26
|
-
end
|
|
27
|
-
end
|
|
28
|
-
end
|
|
29
|
-
end
|
|
@@ -1,23 +0,0 @@
|
|
|
1
|
-
# frozen_string_literal: true
|
|
2
|
-
|
|
3
|
-
module T
|
|
4
|
-
class Const
|
|
5
|
-
# @param [String] value
|
|
6
|
-
def initialize(value)
|
|
7
|
-
@value = value
|
|
8
|
-
end
|
|
9
|
-
|
|
10
|
-
# @return [JsonModel::TypeSpec::Const]
|
|
11
|
-
def to_type_spec
|
|
12
|
-
JsonModel::TypeSpec::Const.new(*@value)
|
|
13
|
-
end
|
|
14
|
-
|
|
15
|
-
class << self
|
|
16
|
-
# @param [Array] args
|
|
17
|
-
# @return [Const]
|
|
18
|
-
def [](*args)
|
|
19
|
-
Const.new(*args)
|
|
20
|
-
end
|
|
21
|
-
end
|
|
22
|
-
end
|
|
23
|
-
end
|
|
@@ -1,23 +0,0 @@
|
|
|
1
|
-
# frozen_string_literal: true
|
|
2
|
-
|
|
3
|
-
module T
|
|
4
|
-
class Enum
|
|
5
|
-
# @param [Array<Object>] values
|
|
6
|
-
def initialize(*values)
|
|
7
|
-
@values = values
|
|
8
|
-
end
|
|
9
|
-
|
|
10
|
-
# @return [JsonModel::TypeSpec::Enum]
|
|
11
|
-
def to_type_spec
|
|
12
|
-
JsonModel::TypeSpec::Enum.new(*@values)
|
|
13
|
-
end
|
|
14
|
-
|
|
15
|
-
class << self
|
|
16
|
-
# @param [Array] args
|
|
17
|
-
# @return [Enum]
|
|
18
|
-
def [](*args)
|
|
19
|
-
Enum.new(*args)
|
|
20
|
-
end
|
|
21
|
-
end
|
|
22
|
-
end
|
|
23
|
-
end
|
|
@@ -1,23 +0,0 @@
|
|
|
1
|
-
# frozen_string_literal: true
|
|
2
|
-
|
|
3
|
-
module T
|
|
4
|
-
class Integer
|
|
5
|
-
# @param [Hash] options
|
|
6
|
-
def initialize(**options)
|
|
7
|
-
@options = options
|
|
8
|
-
end
|
|
9
|
-
|
|
10
|
-
# @return [JsonModel::TypeSpec::Composition::Primitive::Integer]
|
|
11
|
-
def to_type_spec
|
|
12
|
-
JsonModel::TypeSpec::Primitive::Integer.new(**@options)
|
|
13
|
-
end
|
|
14
|
-
|
|
15
|
-
class << self
|
|
16
|
-
# @param [Hash] options
|
|
17
|
-
# @return [T::Integer]
|
|
18
|
-
def [](**options)
|
|
19
|
-
Integer.new(**options)
|
|
20
|
-
end
|
|
21
|
-
end
|
|
22
|
-
end
|
|
23
|
-
end
|