strong_json 2.1.0 → 2.1.1
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/.ruby-version +1 -1
- data/CHANGELOG.md +4 -0
- data/Gemfile +2 -0
- data/README.md +1 -1
- data/Rakefile +2 -2
- data/Steepfile +7 -0
- data/example/Steepfile +8 -0
- data/example/{example.rb → lib/example.rb} +1 -1
- data/example/sig/example.rbs +11 -0
- data/lib/strong_json/error_reporter.rb +3 -3
- data/lib/strong_json/type.rb +2 -11
- data/lib/strong_json/types.rb +0 -4
- data/lib/strong_json/version.rb +1 -1
- data/pp.rb +27 -0
- data/sig/strong_json.rbs +67 -0
- data/sig/type.rbs +131 -0
- data/spec/enum_spec.rb +4 -4
- data/spec/object_spec.rb +5 -5
- data/strong_json.gemspec +1 -1
- metadata +12 -10
- data/example/example.rbi +0 -11
- data/sig/strong_json.rbi +0 -68
- data/sig/type.rbi +0 -135
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: d1118cf0a2239601909e8d3af33e2b7d2809c8baccae8a0a77b2f2c6fdc814a1
|
4
|
+
data.tar.gz: 39a6fe29b3383722be668af971c9a78b8719dee1bb8b7e2fe1eb06ce8fe1f5f4
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: bc54d705a3b26803caed812795525e64c2a08260be22c1d14e48f9e47e897b3b60acf4f256eb3ce846fb1c9afda0ed3f019d0a2932827bbfa2ec0fb65931eecb
|
7
|
+
data.tar.gz: 40bc0d295723533e3ed0e86f77af4b70f26e7fce0fd12498ef14cb906ea28b549b50825021a6421d702a3cd956ef1cec7d9353073124b7859380c1906793a830
|
data/.ruby-version
CHANGED
@@ -1 +1 @@
|
|
1
|
-
2.
|
1
|
+
2.6.3
|
data/CHANGELOG.md
CHANGED
data/Gemfile
CHANGED
data/README.md
CHANGED
@@ -47,7 +47,7 @@ If the input JSON data conforms to `order`'s structure, the `json` will be that
|
|
47
47
|
|
48
48
|
If the input JSON contains attributes which is not white-listed in the definition, it will raise an exception.
|
49
49
|
|
50
|
-
If an attribute has a value which does not match with given type, the `coerce` method call will raise an exception `StrongJSON::Type::
|
50
|
+
If an attribute has a value which does not match with given type, the `coerce` method call will raise an exception `StrongJSON::Type::TypeError`.
|
51
51
|
|
52
52
|
## Catalogue of Types
|
53
53
|
|
data/Rakefile
CHANGED
@@ -6,11 +6,11 @@ RSpec::Core::RakeTask.new(:spec)
|
|
6
6
|
task :default => [:spec, :typecheck, :"example:typecheck"]
|
7
7
|
|
8
8
|
task :typecheck do
|
9
|
-
sh "bundle exec steep check
|
9
|
+
sh "bundle exec steep check"
|
10
10
|
end
|
11
11
|
|
12
12
|
namespace :example do
|
13
13
|
task :typecheck do
|
14
|
-
sh "bundle exec steep check --
|
14
|
+
sh "bundle exec steep check --steepfile=example/Steepfile"
|
15
15
|
end
|
16
16
|
end
|
data/Steepfile
ADDED
data/example/Steepfile
ADDED
@@ -0,0 +1,11 @@
|
|
1
|
+
type address = { address: String, country: Symbol? }
|
2
|
+
type email = { email: String }
|
3
|
+
|
4
|
+
class AddressSchema < StrongJSON
|
5
|
+
def address: -> StrongJSON::Type::Object[address]
|
6
|
+
def email: -> StrongJSON::Type::Object[email]
|
7
|
+
def contact: -> StrongJSON::Type::Object[email | address]
|
8
|
+
def person: -> StrongJSON::Type::Object[{ name: String, contacts: Array[email | address] }]
|
9
|
+
end
|
10
|
+
|
11
|
+
Schema: AddressSchema
|
@@ -18,7 +18,7 @@ class StrongJSON
|
|
18
18
|
format_trace(path: path)
|
19
19
|
where = format_aliases(path: path, where: [])
|
20
20
|
|
21
|
-
# @type var ty: Type::Enum
|
21
|
+
# @type var ty: Type::Enum[untyped]
|
22
22
|
if (ty = _ = path.type).is_a?(Type::Enum)
|
23
23
|
ty.types.each do |t|
|
24
24
|
if (a = t.alias)
|
@@ -67,7 +67,7 @@ class StrongJSON
|
|
67
67
|
end
|
68
68
|
|
69
69
|
def format_single_alias(name, type)
|
70
|
-
# @type const PrettyPrint:
|
70
|
+
# @type const PrettyPrint: untyped
|
71
71
|
PrettyPrint.format do |pp|
|
72
72
|
pp.text(name.to_s)
|
73
73
|
pp.text(" = ")
|
@@ -78,7 +78,7 @@ class StrongJSON
|
|
78
78
|
end
|
79
79
|
|
80
80
|
def pretty_str(type, expand_alias: false)
|
81
|
-
# @type const PrettyPrint:
|
81
|
+
# @type const PrettyPrint: untyped
|
82
82
|
PrettyPrint.singleline_format do |pp|
|
83
83
|
pretty(type, pp, expand_alias: expand_alias)
|
84
84
|
end
|
data/lib/strong_json/type.rb
CHANGED
@@ -20,7 +20,7 @@ class StrongJSON
|
|
20
20
|
|
21
21
|
def with_alias(name)
|
22
22
|
_ = dup.tap do |copy|
|
23
|
-
copy.instance_eval do
|
23
|
+
copy.instance_eval do |x|
|
24
24
|
@alias = name
|
25
25
|
end
|
26
26
|
end
|
@@ -76,7 +76,6 @@ class StrongJSON
|
|
76
76
|
|
77
77
|
def ==(other)
|
78
78
|
if other.is_a?(Base)
|
79
|
-
# @type var other: Base<any>
|
80
79
|
other.type == type
|
81
80
|
end
|
82
81
|
end
|
@@ -111,7 +110,6 @@ class StrongJSON
|
|
111
110
|
|
112
111
|
def ==(other)
|
113
112
|
if other.is_a?(Optional)
|
114
|
-
# @type var other: Optional<any>
|
115
113
|
other.type == type
|
116
114
|
end
|
117
115
|
end
|
@@ -143,7 +141,6 @@ class StrongJSON
|
|
143
141
|
|
144
142
|
def ==(other)
|
145
143
|
if other.is_a?(Literal)
|
146
|
-
# @type var other: Literal<any>
|
147
144
|
other.value == value
|
148
145
|
end
|
149
146
|
end
|
@@ -180,7 +177,6 @@ class StrongJSON
|
|
180
177
|
|
181
178
|
def ==(other)
|
182
179
|
if other.is_a?(Array)
|
183
|
-
# @type var other: Array<any>
|
184
180
|
other.type == type
|
185
181
|
end
|
186
182
|
end
|
@@ -230,7 +226,7 @@ class StrongJSON
|
|
230
226
|
end
|
231
227
|
end
|
232
228
|
|
233
|
-
# @type var result: ::Hash
|
229
|
+
# @type var result: ::Hash[Symbol, untyped]
|
234
230
|
result = {}
|
235
231
|
|
236
232
|
fields.each do |key, type|
|
@@ -240,7 +236,6 @@ class StrongJSON
|
|
240
236
|
_ = result
|
241
237
|
end
|
242
238
|
|
243
|
-
# @type method ignore: (*Symbol, ?except: Set<Symbol>?) -> self
|
244
239
|
def ignore(*ignores, except: nil)
|
245
240
|
if ignores.empty? && !except
|
246
241
|
Object.new(fields, on_unknown: :ignore, exceptions: Set[])
|
@@ -253,7 +248,6 @@ class StrongJSON
|
|
253
248
|
end
|
254
249
|
end
|
255
250
|
|
256
|
-
# @type method reject: (*Symbol, ?except: Set<Symbol>?) -> self
|
257
251
|
def reject(*rejecteds, except: nil)
|
258
252
|
if rejecteds.empty? && !except
|
259
253
|
Object.new(fields, on_unknown: :reject, exceptions: Set[])
|
@@ -284,7 +278,6 @@ class StrongJSON
|
|
284
278
|
|
285
279
|
def ==(other)
|
286
280
|
if other.is_a?(Object)
|
287
|
-
# @type var other: Object<any>
|
288
281
|
other.fields == fields &&
|
289
282
|
other.on_unknown == on_unknown &&
|
290
283
|
other.exceptions == exceptions
|
@@ -333,7 +326,6 @@ class StrongJSON
|
|
333
326
|
|
334
327
|
def ==(other)
|
335
328
|
if other.is_a?(Enum)
|
336
|
-
# @type var other: Enum<any>
|
337
329
|
other.types == types &&
|
338
330
|
other.detector == detector
|
339
331
|
end
|
@@ -369,7 +361,6 @@ class StrongJSON
|
|
369
361
|
|
370
362
|
def ==(other)
|
371
363
|
if other.is_a?(Hash)
|
372
|
-
# @type var other: Hash<any>
|
373
364
|
other.type == type
|
374
365
|
end
|
375
366
|
end
|
data/lib/strong_json/types.rb
CHANGED
@@ -1,6 +1,5 @@
|
|
1
1
|
class StrongJSON
|
2
2
|
module Types
|
3
|
-
# @type method object: (?Hash<Symbol, ty>) -> Type::Object<any>
|
4
3
|
def object(fields = {})
|
5
4
|
if fields.empty?
|
6
5
|
Type::Object.new(fields, on_unknown: :ignore, exceptions: Set.new)
|
@@ -9,12 +8,10 @@ class StrongJSON
|
|
9
8
|
end
|
10
9
|
end
|
11
10
|
|
12
|
-
# @type method array: (?ty) -> Type::Array<any>
|
13
11
|
def array(type = any)
|
14
12
|
Type::Array.new(type)
|
15
13
|
end
|
16
14
|
|
17
|
-
# @type method optional: (?ty) -> Type::Optional<any>
|
18
15
|
def optional(type = any)
|
19
16
|
Type::Optional.new(type)
|
20
17
|
end
|
@@ -87,7 +84,6 @@ class StrongJSON
|
|
87
84
|
optional(array(ty))
|
88
85
|
end
|
89
86
|
|
90
|
-
# @type method object?: (?Hash<Symbol, ty>) -> Type::Optional<any>
|
91
87
|
def object?(fields={})
|
92
88
|
optional(object(fields))
|
93
89
|
end
|
data/lib/strong_json/version.rb
CHANGED
data/pp.rb
ADDED
@@ -0,0 +1,27 @@
|
|
1
|
+
require "prettyprint"
|
2
|
+
|
3
|
+
pp = PrettyPrint.new
|
4
|
+
|
5
|
+
pp.group 0 do
|
6
|
+
pp.text "hello = "
|
7
|
+
|
8
|
+
pp.group 0, "enum_____(", ")" do
|
9
|
+
pp.nest(2) do
|
10
|
+
pp.breakable ""
|
11
|
+
count = 7
|
12
|
+
count.times do |i|
|
13
|
+
pp.text "hello #{i}"
|
14
|
+
|
15
|
+
if i < count - 1
|
16
|
+
pp.text ","
|
17
|
+
pp.breakable " "
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
22
|
+
pp.breakable ""
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
pp.flush
|
27
|
+
puts pp.output
|
data/sig/strong_json.rbs
ADDED
@@ -0,0 +1,67 @@
|
|
1
|
+
class StrongJSON
|
2
|
+
def initialize: { (StrongJSON) -> void } -> untyped
|
3
|
+
def let: (Symbol, ty) -> void
|
4
|
+
include StrongJSON::Types
|
5
|
+
end
|
6
|
+
|
7
|
+
StrongJSON::VERSION: String
|
8
|
+
|
9
|
+
interface StrongJSON::_Schema[T]
|
10
|
+
def coerce: (untyped, ?path: Type::ErrorPath) -> T
|
11
|
+
def =~: (untyped) -> bool
|
12
|
+
def to_s: -> String
|
13
|
+
def is_a?: (untyped) -> bool
|
14
|
+
def `alias`: -> Symbol?
|
15
|
+
def with_alias: (Symbol) -> self
|
16
|
+
def ==: (untyped) -> bool
|
17
|
+
def yield_self: [X] () { (self) -> X } -> X
|
18
|
+
end
|
19
|
+
|
20
|
+
type StrongJSON::ty = _Schema[untyped]
|
21
|
+
|
22
|
+
module StrongJSON::Types
|
23
|
+
def object: [X] (Hash[Symbol, ty]) -> Type::Object[X]
|
24
|
+
| () -> Type::Object[bot]
|
25
|
+
def object?: [X] (Hash[Symbol, ty]) -> Type::Optional[X]
|
26
|
+
| () -> Type::Optional[bot]
|
27
|
+
def any: () -> Type::Base[untyped]
|
28
|
+
def any?: () -> Type::Optional[untyped]
|
29
|
+
def optional: [X] (_Schema[X]) -> Type::Optional[X]
|
30
|
+
| () -> Type::Optional[untyped]
|
31
|
+
def string: () -> Type::Base[String]
|
32
|
+
def string?: () -> Type::Optional[String]
|
33
|
+
def number: () -> Type::Base[Numeric]
|
34
|
+
def number?: () -> Type::Optional[Numeric]
|
35
|
+
def numeric: () -> Type::Base[Numeric]
|
36
|
+
def numeric?: () -> Type::Optional[Numeric]
|
37
|
+
def integer: () -> Type::Base[Integer]
|
38
|
+
def integer?: () -> Type::Optional[Integer]
|
39
|
+
def boolean: () -> Type::Base[bool]
|
40
|
+
def boolean?: () -> Type::Optional[bool]
|
41
|
+
def symbol: () -> Type::Base[Symbol]
|
42
|
+
def symbol?: () -> Type::Optional[Symbol]
|
43
|
+
def array: [X] (_Schema[X]) -> Type::Array[X]
|
44
|
+
| () -> Type::Array[untyped]
|
45
|
+
def array?: [X] (_Schema[X]) -> Type::Optional[::Array[X]]
|
46
|
+
def literal: [X] (X) -> Type::Literal[X]
|
47
|
+
def literal?: [X] (X) -> Type::Optional[X]
|
48
|
+
def enum: [X] (*_Schema[untyped], ?detector: Type::detector?) -> Type::Enum[X]
|
49
|
+
def enum?: [X] (*_Schema[untyped], ?detector: Type::detector?) -> Type::Optional[X]
|
50
|
+
incompatible def hash: [X] (_Schema[X]) -> Type::Hash[X]
|
51
|
+
def hash?: [X] (_Schema[X]) -> Type::Optional[Hash[Symbol, X]]
|
52
|
+
end
|
53
|
+
|
54
|
+
class StrongJSON::ErrorReporter
|
55
|
+
attr_reader path: Type::ErrorPath
|
56
|
+
@string: String
|
57
|
+
|
58
|
+
def initialize: (path: Type::ErrorPath) -> untyped
|
59
|
+
def format: -> void
|
60
|
+
def pretty_str: (ty, ?expand_alias: bool) -> ::String
|
61
|
+
|
62
|
+
private
|
63
|
+
def format_trace: (path: Type::ErrorPath, ?index: Integer) -> void
|
64
|
+
def format_aliases: (path: Type::ErrorPath, where: ::Array[String]) -> ::Array[String]
|
65
|
+
def format_single_alias: (Symbol, ty) -> String
|
66
|
+
def pretty: (ty, untyped, ?expand_alias: bool) -> void
|
67
|
+
end
|
data/sig/type.rbs
ADDED
@@ -0,0 +1,131 @@
|
|
1
|
+
module StrongJSON::Type
|
2
|
+
end
|
3
|
+
|
4
|
+
module StrongJSON::Type::Match : _Schema[untyped]
|
5
|
+
def =~: (untyped) -> bool
|
6
|
+
def ===: (untyped) -> bool
|
7
|
+
end
|
8
|
+
|
9
|
+
module StrongJSON::Type::WithAlias : ::Object
|
10
|
+
@alias: Symbol?
|
11
|
+
def `alias`: -> Symbol?
|
12
|
+
def with_alias: (Symbol) -> self
|
13
|
+
end
|
14
|
+
|
15
|
+
type StrongJSON::base_type_name = :any | :number | :string | :boolean | :numeric | :symbol | :integer
|
16
|
+
|
17
|
+
class StrongJSON::Type::Base[A]
|
18
|
+
include Match
|
19
|
+
include WithAlias
|
20
|
+
|
21
|
+
attr_reader type: base_type_name
|
22
|
+
|
23
|
+
def initialize: (base_type_name) -> untyped
|
24
|
+
def test: (untyped) -> bool
|
25
|
+
def coerce: (untyped, ?path: ErrorPath) -> A
|
26
|
+
end
|
27
|
+
|
28
|
+
class StrongJSON::Type::Optional[T]
|
29
|
+
include Match
|
30
|
+
include WithAlias
|
31
|
+
|
32
|
+
attr_reader type: _Schema[T]
|
33
|
+
|
34
|
+
def initialize: (_Schema[T]) -> untyped
|
35
|
+
def coerce: (untyped, ?path: ErrorPath) -> (T | nil)
|
36
|
+
end
|
37
|
+
|
38
|
+
class StrongJSON::Type::Literal[T]
|
39
|
+
include Match
|
40
|
+
include WithAlias
|
41
|
+
|
42
|
+
attr_reader value: T
|
43
|
+
|
44
|
+
def initialize: (T) -> untyped
|
45
|
+
def coerce: (untyped, ?path: ErrorPath) -> T
|
46
|
+
end
|
47
|
+
|
48
|
+
class StrongJSON::Type::Array[T]
|
49
|
+
include Match
|
50
|
+
include WithAlias
|
51
|
+
|
52
|
+
attr_reader type: _Schema[T]
|
53
|
+
|
54
|
+
def initialize: (_Schema[T]) -> untyped
|
55
|
+
def coerce: (untyped, ?path: ErrorPath) -> ::Array[T]
|
56
|
+
end
|
57
|
+
|
58
|
+
class StrongJSON::Type::Object[T]
|
59
|
+
include Match
|
60
|
+
include WithAlias
|
61
|
+
|
62
|
+
attr_reader fields: ::Hash[Symbol, _Schema[untyped]]
|
63
|
+
attr_reader on_unknown: :ignore | :reject
|
64
|
+
attr_reader exceptions: Set[Symbol]
|
65
|
+
|
66
|
+
def initialize: (::Hash[Symbol, _Schema[T]], on_unknown: :ignore | :reject, exceptions: Set[Symbol]) -> untyped
|
67
|
+
def coerce: (untyped, ?path: ErrorPath) -> T
|
68
|
+
|
69
|
+
# If no argument is given, it ignores all unknown attributes.
|
70
|
+
# If `Symbol`s are given, it ignores the listed attributes, but rejects if other unknown attributes are detected.
|
71
|
+
# If `except:` is specified, it rejects attributes listed in `except` are detected, but ignores other unknown attributes.
|
72
|
+
def ignore: (*Symbol ignores, ?except: Set[Symbol]?) -> Object[T]
|
73
|
+
|
74
|
+
# If no argument is given, it rejects on untyped unknown attribute.
|
75
|
+
# If `Symbol`s are given, it rejects the listed attributes are detected, but ignores other unknown attributes.
|
76
|
+
# If `except:` is specified, it ignores given attributes, but rejects if other unknown attributes are detected.
|
77
|
+
def reject: (*Symbol rejecteds, ?except: Set[Symbol]?) -> Object[T]
|
78
|
+
|
79
|
+
def update_fields: [X] { (::Hash[Symbol, _Schema[untyped]]) -> void } -> Object[X]
|
80
|
+
end
|
81
|
+
|
82
|
+
type StrongJSON::Type::detector = ^(untyped) -> _Schema[untyped]?
|
83
|
+
|
84
|
+
class StrongJSON::Type::Enum[T]
|
85
|
+
include Match
|
86
|
+
include WithAlias
|
87
|
+
|
88
|
+
attr_reader types: ::Array[_Schema[untyped]]
|
89
|
+
attr_reader detector: detector?
|
90
|
+
|
91
|
+
def initialize: (::Array[_Schema[untyped]], ?detector?) -> untyped
|
92
|
+
def coerce: (untyped, ?path: ErrorPath) -> T
|
93
|
+
end
|
94
|
+
|
95
|
+
class StrongJSON::Type::ErrorPath
|
96
|
+
attr_reader type: _Schema[untyped]
|
97
|
+
attr_reader parent: [Symbol | Integer | nil, ErrorPath]?
|
98
|
+
|
99
|
+
def initialize: (type: _Schema[untyped], parent: [Symbol | Integer | nil, ErrorPath]?) -> untyped
|
100
|
+
def dig: (key: Symbol | Integer, type: _Schema[untyped]) -> ErrorPath
|
101
|
+
def expand: (type: _Schema[untyped]) -> ErrorPath
|
102
|
+
|
103
|
+
def self.root: (_Schema[untyped]) -> ErrorPath
|
104
|
+
def root?: -> bool
|
105
|
+
end
|
106
|
+
|
107
|
+
class StrongJSON::Type::TypeError < StandardError
|
108
|
+
attr_reader path: ErrorPath
|
109
|
+
attr_reader value: untyped
|
110
|
+
|
111
|
+
def initialize: (path: ErrorPath, value: untyped) -> untyped
|
112
|
+
def type: -> _Schema[untyped]
|
113
|
+
end
|
114
|
+
|
115
|
+
class StrongJSON::Type::UnexpectedAttributeError < StandardError
|
116
|
+
attr_reader path: ErrorPath
|
117
|
+
attr_reader attribute: Symbol
|
118
|
+
|
119
|
+
def initialize: (path: ErrorPath, attribute: Symbol) -> untyped
|
120
|
+
def type: -> _Schema[untyped]
|
121
|
+
end
|
122
|
+
|
123
|
+
class StrongJSON::Type::Hash[T]
|
124
|
+
include Match
|
125
|
+
include WithAlias
|
126
|
+
|
127
|
+
attr_reader type: _Schema[T]
|
128
|
+
|
129
|
+
def initialize: (_Schema[T]) -> untyped
|
130
|
+
def coerce: (untyped, ?path: ErrorPath) -> ::Hash[Symbol, T]
|
131
|
+
end
|
data/spec/enum_spec.rb
CHANGED
@@ -29,7 +29,7 @@ describe StrongJSON::Type::Enum do
|
|
29
29
|
id: StrongJSON::Type::Literal.new("id1"),
|
30
30
|
value: StrongJSON::Type::Base.new(:string)
|
31
31
|
},
|
32
|
-
on_unknown: :
|
32
|
+
on_unknown: :reject,
|
33
33
|
exceptions: Set[]
|
34
34
|
),
|
35
35
|
StrongJSON::Type::Object.new(
|
@@ -37,7 +37,7 @@ describe StrongJSON::Type::Enum do
|
|
37
37
|
id: StrongJSON::Type::Base.new(:string),
|
38
38
|
value: StrongJSON::Type::Base.new(:symbol)
|
39
39
|
},
|
40
|
-
on_unknown: :
|
40
|
+
on_unknown: :reject,
|
41
41
|
exceptions: Set[]
|
42
42
|
),
|
43
43
|
StrongJSON::Type::Optional.new(StrongJSON::Type::Literal.new(3)),
|
@@ -73,7 +73,7 @@ describe StrongJSON::Type::Enum do
|
|
73
73
|
regexp: StrongJSON::Type::Base.new(:string),
|
74
74
|
option: StrongJSON::Type::Base.new(:string),
|
75
75
|
},
|
76
|
-
on_unknown: :
|
76
|
+
on_unknown: :reject,
|
77
77
|
exceptions: Set[]
|
78
78
|
)
|
79
79
|
}
|
@@ -83,7 +83,7 @@ describe StrongJSON::Type::Enum do
|
|
83
83
|
{
|
84
84
|
literal: StrongJSON::Type::Base.new(:string)
|
85
85
|
},
|
86
|
-
on_unknown: :
|
86
|
+
on_unknown: :reject,
|
87
87
|
exceptions: Set[]
|
88
88
|
)
|
89
89
|
}
|
data/spec/object_spec.rb
CHANGED
@@ -8,7 +8,7 @@ describe StrongJSON::Type::Object do
|
|
8
8
|
a: StrongJSON::Type::Base.new(:numeric),
|
9
9
|
b: StrongJSON::Type::Base.new(:string)
|
10
10
|
},
|
11
|
-
on_unknown: :
|
11
|
+
on_unknown: :reject,
|
12
12
|
exceptions: Set.new
|
13
13
|
)
|
14
14
|
|
@@ -85,7 +85,7 @@ describe StrongJSON::Type::Object do
|
|
85
85
|
{
|
86
86
|
a: StrongJSON::Type::Optional.new(StrongJSON::Type::Base.new(:numeric))
|
87
87
|
},
|
88
|
-
on_unknown: :
|
88
|
+
on_unknown: :reject,
|
89
89
|
exceptions: Set[]
|
90
90
|
)
|
91
91
|
}
|
@@ -110,7 +110,7 @@ describe StrongJSON::Type::Object do
|
|
110
110
|
a: StrongJSON::Type::Base.new(:numeric),
|
111
111
|
b: StrongJSON::Type::Base.new(:string)
|
112
112
|
},
|
113
|
-
on_unknown: :
|
113
|
+
on_unknown: :reject,
|
114
114
|
exceptions: Set[]
|
115
115
|
)
|
116
116
|
}
|
@@ -128,7 +128,7 @@ describe StrongJSON::Type::Object do
|
|
128
128
|
let (:type) {
|
129
129
|
StrongJSON::Type::Object.new(
|
130
130
|
{ a: StrongJSON::Type::Base.new(:numeric) },
|
131
|
-
on_unknown: :
|
131
|
+
on_unknown: :reject,
|
132
132
|
exceptions: Set[]
|
133
133
|
)
|
134
134
|
}
|
@@ -163,7 +163,7 @@ describe StrongJSON::Type::Object do
|
|
163
163
|
let (:type) {
|
164
164
|
StrongJSON::Type::Object.new(
|
165
165
|
{ a: StrongJSON::Type::Base.new(:numeric) },
|
166
|
-
on_unknown: :
|
166
|
+
on_unknown: :reject,
|
167
167
|
exceptions: Set[]
|
168
168
|
)
|
169
169
|
}
|
data/strong_json.gemspec
CHANGED
@@ -22,5 +22,5 @@ Gem::Specification.new do |spec|
|
|
22
22
|
spec.add_development_dependency "bundler", ">= 1.6"
|
23
23
|
spec.add_development_dependency "rake", "~> 10.0"
|
24
24
|
spec.add_development_dependency "rspec", "~> 3.0"
|
25
|
-
spec.add_development_dependency "steep", "~> 0.
|
25
|
+
spec.add_development_dependency "steep", "~> 0.15"
|
26
26
|
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: strong_json
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 2.1.
|
4
|
+
version: 2.1.1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Soutaro Matsumoto
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2020-05-16 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: bundler
|
@@ -58,14 +58,14 @@ dependencies:
|
|
58
58
|
requirements:
|
59
59
|
- - "~>"
|
60
60
|
- !ruby/object:Gem::Version
|
61
|
-
version: '0.
|
61
|
+
version: '0.15'
|
62
62
|
type: :development
|
63
63
|
prerelease: false
|
64
64
|
version_requirements: !ruby/object:Gem::Requirement
|
65
65
|
requirements:
|
66
66
|
- - "~>"
|
67
67
|
- !ruby/object:Gem::Version
|
68
|
-
version: '0.
|
68
|
+
version: '0.15'
|
69
69
|
description: Type check JSON objects
|
70
70
|
email:
|
71
71
|
- matsumoto@soutaro.com
|
@@ -81,15 +81,18 @@ files:
|
|
81
81
|
- LICENSE.txt
|
82
82
|
- README.md
|
83
83
|
- Rakefile
|
84
|
-
-
|
85
|
-
- example/
|
84
|
+
- Steepfile
|
85
|
+
- example/Steepfile
|
86
|
+
- example/lib/example.rb
|
87
|
+
- example/sig/example.rbs
|
86
88
|
- lib/strong_json.rb
|
87
89
|
- lib/strong_json/error_reporter.rb
|
88
90
|
- lib/strong_json/type.rb
|
89
91
|
- lib/strong_json/types.rb
|
90
92
|
- lib/strong_json/version.rb
|
91
|
-
-
|
92
|
-
- sig/
|
93
|
+
- pp.rb
|
94
|
+
- sig/strong_json.rbs
|
95
|
+
- sig/type.rbs
|
93
96
|
- spec/array_spec.rb
|
94
97
|
- spec/basetype_spec.rb
|
95
98
|
- spec/case_subsumption_operator_spec.rb
|
@@ -121,8 +124,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
121
124
|
- !ruby/object:Gem::Version
|
122
125
|
version: '0'
|
123
126
|
requirements: []
|
124
|
-
|
125
|
-
rubygems_version: 2.7.6
|
127
|
+
rubygems_version: 3.0.3
|
126
128
|
signing_key:
|
127
129
|
specification_version: 4
|
128
130
|
summary: Type check JSON objects
|
data/example/example.rbi
DELETED
@@ -1,11 +0,0 @@
|
|
1
|
-
type address = { address: String, country: Symbol? }
|
2
|
-
type email = { email: String }
|
3
|
-
|
4
|
-
class AddressSchema < StrongJSON
|
5
|
-
def address: -> StrongJSON::Type::Object<address>
|
6
|
-
def email: -> StrongJSON::Type::Object<email>
|
7
|
-
def contact: -> StrongJSON::Type::Object<email | address>
|
8
|
-
def person: -> StrongJSON::Type::Object<{ name: String, contacts: Array<email | address> }>
|
9
|
-
end
|
10
|
-
|
11
|
-
Schema: AddressSchema
|
data/sig/strong_json.rbi
DELETED
@@ -1,68 +0,0 @@
|
|
1
|
-
class StrongJSON
|
2
|
-
def initialize: { (self) -> void } -> any
|
3
|
-
def let: (Symbol, ty) -> void
|
4
|
-
include StrongJSON::Types
|
5
|
-
end
|
6
|
-
|
7
|
-
StrongJSON::VERSION: String
|
8
|
-
|
9
|
-
class StandardError
|
10
|
-
def initialize: (String) -> any
|
11
|
-
end
|
12
|
-
|
13
|
-
interface StrongJSON::_Schema<'type>
|
14
|
-
def coerce: (any, ?path: Type::ErrorPath) -> 'type
|
15
|
-
def =~: (any) -> bool
|
16
|
-
def to_s: -> String
|
17
|
-
def is_a?: (any) -> bool
|
18
|
-
def alias: -> Symbol?
|
19
|
-
def with_alias: (Symbol) -> self
|
20
|
-
def ==: (any) -> bool
|
21
|
-
def yield_self: <'a> () { (self) -> 'a } -> 'a
|
22
|
-
end
|
23
|
-
|
24
|
-
type StrongJSON::ty = _Schema<any>
|
25
|
-
|
26
|
-
module StrongJSON::Types
|
27
|
-
def object: <'x> (Hash<Symbol, ty>) -> Type::Object<'x>
|
28
|
-
| () -> Type::Object<{}>
|
29
|
-
def object?: <'x> (Hash<Symbol, ty>) -> Type::Optional<'x>
|
30
|
-
| () -> Type::Optional<{}>
|
31
|
-
def any: () -> Type::Base<any>
|
32
|
-
def any?: () -> Type::Optional<any>
|
33
|
-
def optional: <'x> (_Schema<'x>) -> Type::Optional<'x>
|
34
|
-
| () -> Type::Optional<any>
|
35
|
-
def string: () -> Type::Base<String>
|
36
|
-
def string?: () -> Type::Optional<String>
|
37
|
-
def number: () -> Type::Base<Numeric>
|
38
|
-
def number?: () -> Type::Optional<Numeric>
|
39
|
-
def numeric: () -> Type::Base<Numeric>
|
40
|
-
def numeric?: () -> Type::Optional<Numeric>
|
41
|
-
def integer: () -> Type::Base<Integer>
|
42
|
-
def integer?: () -> Type::Optional<Integer>
|
43
|
-
def boolean: () -> Type::Base<bool>
|
44
|
-
def boolean?: () -> Type::Optional<bool>
|
45
|
-
def symbol: () -> Type::Base<Symbol>
|
46
|
-
def symbol?: () -> Type::Optional<Symbol>
|
47
|
-
def array: <'x> (_Schema<'x>) -> Type::Array<'x>
|
48
|
-
| () -> Type::Array<any>
|
49
|
-
def array?: <'x> (_Schema<'x>) -> Type::Optional<::Array<'x>>
|
50
|
-
def literal: <'x> ('x) -> Type::Literal<'x>
|
51
|
-
def literal?: <'x> ('x) -> Type::Optional<'x>
|
52
|
-
def enum: <'x> (*_Schema<any>, ?detector: Type::detector?) -> Type::Enum<'x>
|
53
|
-
def enum?: <'x> (*_Schema<any>, ?detector: Type::detector?) -> Type::Optional<'x>
|
54
|
-
def (incompatible) hash: <'x> (_Schema<'x>) -> Type::Hash<'x>
|
55
|
-
def hash?: <'x> (_Schema<'x>) -> Type::Optional<Hash<Symbol, 'x>>
|
56
|
-
end
|
57
|
-
|
58
|
-
class StrongJSON::ErrorReporter
|
59
|
-
attr_reader path: Type::ErrorPath
|
60
|
-
@string: String
|
61
|
-
def initialize: (path: Type::ErrorPath) -> any
|
62
|
-
def format: -> void
|
63
|
-
def (private) format_trace: (path: Type::ErrorPath, ?index: Integer) -> void
|
64
|
-
def (private) format_aliases: (path: Type::ErrorPath, where: ::Array<String>) -> ::Array<String>
|
65
|
-
def (private) format_single_alias: (Symbol, ty) -> String
|
66
|
-
def (private) pretty: (ty, any, ?expand_alias: bool) -> void
|
67
|
-
def pretty_str: (ty, ?expand_alias: bool) -> ::String
|
68
|
-
end
|
data/sig/type.rbi
DELETED
@@ -1,135 +0,0 @@
|
|
1
|
-
module StrongJSON::Type
|
2
|
-
end
|
3
|
-
|
4
|
-
module StrongJSON::Type::Match: _Schema<any>
|
5
|
-
def =~: (any) -> bool
|
6
|
-
def ===: (any) -> bool
|
7
|
-
end
|
8
|
-
|
9
|
-
module StrongJSON::Type::WithAlias: ::Object
|
10
|
-
@alias: Symbol?
|
11
|
-
def alias: -> Symbol?
|
12
|
-
def with_alias: (Symbol) -> self
|
13
|
-
end
|
14
|
-
|
15
|
-
type StrongJSON::base_type_name = :any | :number | :string | :boolean | :numeric | :symbol | :integer
|
16
|
-
|
17
|
-
class StrongJSON::Type::Base<'a>
|
18
|
-
include Match
|
19
|
-
include WithAlias
|
20
|
-
|
21
|
-
attr_reader type: base_type_name
|
22
|
-
|
23
|
-
def initialize: (base_type_name) -> any
|
24
|
-
def test: (any) -> bool
|
25
|
-
def coerce: (any, ?path: ErrorPath) -> 'a
|
26
|
-
end
|
27
|
-
|
28
|
-
class StrongJSON::Type::Optional<'t>
|
29
|
-
include Match
|
30
|
-
include WithAlias
|
31
|
-
|
32
|
-
attr_reader type: _Schema<'t>
|
33
|
-
|
34
|
-
def initialize: (_Schema<'t>) -> any
|
35
|
-
def coerce: (any, ?path: ErrorPath) -> ('t | nil)
|
36
|
-
end
|
37
|
-
|
38
|
-
class StrongJSON::Type::Literal<'t>
|
39
|
-
include Match
|
40
|
-
include WithAlias
|
41
|
-
|
42
|
-
attr_reader value: 't
|
43
|
-
|
44
|
-
def initialize: ('t) -> any
|
45
|
-
def coerce: (any, ?path: ErrorPath) -> 't
|
46
|
-
end
|
47
|
-
|
48
|
-
class StrongJSON::Type::Array<'t>
|
49
|
-
include Match
|
50
|
-
include WithAlias
|
51
|
-
|
52
|
-
attr_reader type: _Schema<'t>
|
53
|
-
|
54
|
-
def initialize: (_Schema<'t>) -> any
|
55
|
-
def coerce: (any, ?path: ErrorPath) -> ::Array<'t>
|
56
|
-
end
|
57
|
-
|
58
|
-
class StrongJSON::Type::Object<'t>
|
59
|
-
include Match
|
60
|
-
include WithAlias
|
61
|
-
|
62
|
-
attr_reader fields: ::Hash<Symbol, _Schema<any>>
|
63
|
-
attr_reader on_unknown: :ignore | :reject
|
64
|
-
attr_reader exceptions: Set<Symbol>
|
65
|
-
|
66
|
-
def initialize: (::Hash<Symbol, _Schema<'t>>, on_unknown: :ignore | :reject, exceptions: Set<Symbol>) -> any
|
67
|
-
def coerce: (any, ?path: ErrorPath) -> 't
|
68
|
-
|
69
|
-
# If no argument is given, it ignores all unknown attributes.
|
70
|
-
# If `Symbol`s are given, it ignores the listed attributes, but rejects if other unknown attributes are detected.
|
71
|
-
# If `except:` is specified, it rejects attributes listed in `except` are detected, but ignores other unknown attributes.
|
72
|
-
def ignore: () -> self
|
73
|
-
| (*Symbol) -> self
|
74
|
-
| (?except: Set<Symbol>) -> self
|
75
|
-
|
76
|
-
# If no argument is given, it rejects on any unknown attribute.
|
77
|
-
# If `Symbol`s are given, it rejects the listed attributes are detected, but ignores other unknown attributes.
|
78
|
-
# If `except:` is specified, it ignores given attributes, but rejects if other unknown attributes are detected.
|
79
|
-
def reject: () -> self
|
80
|
-
| (*Symbol) -> self
|
81
|
-
| (?except: Set<Symbol>) -> self
|
82
|
-
|
83
|
-
def update_fields: <'x> { (::Hash<Symbol, _Schema<any>>) -> void } -> Object<'x>
|
84
|
-
end
|
85
|
-
|
86
|
-
type StrongJSON::Type::detector = ^(any) -> _Schema<any>?
|
87
|
-
|
88
|
-
class StrongJSON::Type::Enum<'t>
|
89
|
-
include Match
|
90
|
-
include WithAlias
|
91
|
-
|
92
|
-
attr_reader types: ::Array<_Schema<any>>
|
93
|
-
attr_reader detector: detector?
|
94
|
-
|
95
|
-
def initialize: (::Array<_Schema<any>>, ?detector?) -> any
|
96
|
-
def coerce: (any, ?path: ErrorPath) -> 't
|
97
|
-
end
|
98
|
-
|
99
|
-
class StrongJSON::Type::ErrorPath
|
100
|
-
attr_reader type: _Schema<any>
|
101
|
-
attr_reader parent: [Symbol | Integer | nil, instance]?
|
102
|
-
|
103
|
-
def initialize: (type: _Schema<any>, parent: [Symbol | Integer | nil, instance]?) -> any
|
104
|
-
def (constructor) dig: (key: Symbol | Integer, type: _Schema<any>) -> self
|
105
|
-
def (constructor) expand: (type: _Schema<any>) -> self
|
106
|
-
|
107
|
-
def self.root: (_Schema<any>) -> instance
|
108
|
-
def root?: -> bool
|
109
|
-
end
|
110
|
-
|
111
|
-
class StrongJSON::Type::TypeError < StandardError
|
112
|
-
attr_reader path: ErrorPath
|
113
|
-
attr_reader value: any
|
114
|
-
|
115
|
-
def initialize: (path: ErrorPath, value: any) -> any
|
116
|
-
def type: -> _Schema<any>
|
117
|
-
end
|
118
|
-
|
119
|
-
class StrongJSON::Type::UnexpectedAttributeError < StandardError
|
120
|
-
attr_reader path: ErrorPath
|
121
|
-
attr_reader attribute: Symbol
|
122
|
-
|
123
|
-
def initialize: (path: ErrorPath, attribute: Symbol) -> any
|
124
|
-
def type: -> _Schema<any>
|
125
|
-
end
|
126
|
-
|
127
|
-
class StrongJSON::Type::Hash<'t>
|
128
|
-
include Match
|
129
|
-
include WithAlias
|
130
|
-
|
131
|
-
attr_reader type: _Schema<'t>
|
132
|
-
|
133
|
-
def initialize: (_Schema<'t>) -> any
|
134
|
-
def coerce: (any, ?path: ErrorPath) -> ::Hash<Symbol, 't>
|
135
|
-
end
|