literal 1.0.0 → 1.2.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 +4 -4
- data/lib/literal/array.rb +428 -0
- data/lib/literal/data_structure.rb +0 -10
- data/lib/literal/flags.rb +245 -0
- data/lib/literal/hash.rb +48 -0
- data/lib/literal/properties/schema.rb +5 -3
- data/lib/literal/properties.rb +5 -0
- data/lib/literal/rails/flags_type.rb +41 -0
- data/lib/literal/rails.rb +1 -0
- data/lib/literal/railtie.rb +8 -0
- data/lib/literal/set.rb +48 -0
- data/lib/literal/struct.rb +26 -0
- data/lib/literal/type.rb +7 -0
- data/lib/literal/types/any_type.rb +13 -3
- data/lib/literal/types/array_type.rb +18 -1
- data/lib/literal/types/boolean_type.rb +18 -3
- data/lib/literal/types/callable_type.rb +22 -3
- data/lib/literal/types/class_type.rb +20 -1
- data/lib/literal/types/constraint_type.rb +55 -1
- data/lib/literal/types/descendant_type.rb +18 -1
- data/lib/literal/types/enumerable_type.rb +18 -1
- data/lib/literal/types/falsy_type.rb +22 -3
- data/lib/literal/types/hash_type.rb +17 -0
- data/lib/literal/types/interface_type.rb +2 -0
- data/lib/literal/types/intersection_type.rb +10 -0
- data/lib/literal/types/json_data_type.rb +16 -0
- data/lib/literal/types/map_type.rb +9 -3
- data/lib/literal/types/nilable_type.rb +6 -0
- data/lib/literal/types/set_type.rb +10 -0
- data/lib/literal/types/tuple_type.rb +16 -0
- data/lib/literal/types/union_type.rb +7 -0
- data/lib/literal/types.rb +13 -13
- data/lib/literal/version.rb +1 -1
- data/lib/literal.rb +97 -0
- metadata +8 -2
@@ -17,4 +17,14 @@ class Literal::Types::SetType
|
|
17
17
|
|
18
18
|
true
|
19
19
|
end
|
20
|
+
|
21
|
+
def record_literal_type_errors(context)
|
22
|
+
return unless Set === context.actual
|
23
|
+
|
24
|
+
context.actual.each do |actual|
|
25
|
+
unless @type === actual
|
26
|
+
context.add_child(label: "[]", expected: @type, actual:)
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
20
30
|
end
|
@@ -23,4 +23,20 @@ class Literal::Types::TupleType
|
|
23
23
|
|
24
24
|
true
|
25
25
|
end
|
26
|
+
|
27
|
+
def record_literal_type_errors(context)
|
28
|
+
return unless Array === context.actual
|
29
|
+
|
30
|
+
len = [@types.size, context.actual.size].max
|
31
|
+
i = 0
|
32
|
+
while i < len
|
33
|
+
actual = context.actual[i]
|
34
|
+
if !(expected = @types[i])
|
35
|
+
context.add_child(label: "[#{i}]", expected: Literal::Types::NeverType, actual:)
|
36
|
+
elsif !(expected === actual)
|
37
|
+
context.add_child(label: "[#{i}]", expected:, actual:)
|
38
|
+
end
|
39
|
+
i += 1
|
40
|
+
end
|
41
|
+
end
|
26
42
|
end
|
@@ -39,6 +39,13 @@ class Literal::Types::UnionType
|
|
39
39
|
end
|
40
40
|
end
|
41
41
|
|
42
|
+
def record_literal_type_errors(ctx)
|
43
|
+
@types.each do |type|
|
44
|
+
ctx.add_child(label: type.inspect, expected: type, actual: ctx.actual)
|
45
|
+
end
|
46
|
+
ctx.children.clear if ctx.children.none? { |c| c.children.any? }
|
47
|
+
end
|
48
|
+
|
42
49
|
protected
|
43
50
|
|
44
51
|
attr_reader :types
|
data/lib/literal/types.rb
CHANGED
@@ -32,15 +32,15 @@ module Literal::Types
|
|
32
32
|
autoload :UnionType, "literal/types/union_type"
|
33
33
|
autoload :VoidType, "literal/types/void_type"
|
34
34
|
|
35
|
-
NilableBooleanType = NilableType.new(BooleanType)
|
36
|
-
NilableCallableType = NilableType.new(CallableType)
|
37
|
-
NilableJSONDataType = NilableType.new(JSONDataType)
|
38
|
-
NilableLambdaType = NilableType.new(LambdaType)
|
39
|
-
NilableProcableType = NilableType.new(ProcableType)
|
35
|
+
NilableBooleanType = NilableType.new(BooleanType::Instance).freeze
|
36
|
+
NilableCallableType = NilableType.new(CallableType::Instance).freeze
|
37
|
+
NilableJSONDataType = NilableType.new(JSONDataType).freeze
|
38
|
+
NilableLambdaType = NilableType.new(LambdaType).freeze
|
39
|
+
NilableProcableType = NilableType.new(ProcableType).freeze
|
40
40
|
|
41
|
-
# Matches any value except `nil`. Use `_Any?` or `
|
41
|
+
# Matches any value except `nil`. Use `_Any?` or `_Void` to match any value including `nil`.
|
42
42
|
def _Any
|
43
|
-
AnyType
|
43
|
+
AnyType::Instance
|
44
44
|
end
|
45
45
|
|
46
46
|
def _Any?
|
@@ -61,7 +61,7 @@ module Literal::Types
|
|
61
61
|
|
62
62
|
# Matches if the value is `true` or `false`.
|
63
63
|
def _Boolean
|
64
|
-
BooleanType
|
64
|
+
BooleanType::Instance
|
65
65
|
end
|
66
66
|
|
67
67
|
# Nilable version of `_Boolean`
|
@@ -71,7 +71,7 @@ module Literal::Types
|
|
71
71
|
|
72
72
|
# Matches if the value responds to `#call`.
|
73
73
|
def _Callable
|
74
|
-
CallableType
|
74
|
+
CallableType::Instance
|
75
75
|
end
|
76
76
|
|
77
77
|
# Nilabl version of `_Callable`
|
@@ -131,7 +131,7 @@ module Literal::Types
|
|
131
131
|
|
132
132
|
# Matches *"falsy"* values (`nil` and `false`).
|
133
133
|
def _Falsy
|
134
|
-
FalsyType
|
134
|
+
FalsyType::Instance
|
135
135
|
end
|
136
136
|
|
137
137
|
# Matches if the value is a `Float` and matches the given constraint.
|
@@ -166,9 +166,9 @@ module Literal::Types
|
|
166
166
|
end
|
167
167
|
|
168
168
|
# Nilable version of `_Hash`
|
169
|
-
def _Hash?
|
169
|
+
def _Hash?(...)
|
170
170
|
NilableType.new(
|
171
|
-
HashType.new,
|
171
|
+
HashType.new(...),
|
172
172
|
)
|
173
173
|
end
|
174
174
|
|
@@ -184,7 +184,7 @@ module Literal::Types
|
|
184
184
|
# Nilable version of `_Integer`
|
185
185
|
def _Integer?(...)
|
186
186
|
NilableType.new(
|
187
|
-
IntegerType(...),
|
187
|
+
IntegerType.new(...),
|
188
188
|
)
|
189
189
|
end
|
190
190
|
|
data/lib/literal/version.rb
CHANGED
data/lib/literal.rb
CHANGED
@@ -3,15 +3,24 @@
|
|
3
3
|
module Literal
|
4
4
|
TYPE_CHECKS_DISABLED = ENV["LITERAL_TYPE_CHECKS"] == "false"
|
5
5
|
|
6
|
+
autoload :Array, "literal/array"
|
6
7
|
autoload :Data, "literal/data"
|
7
8
|
autoload :DataProperty, "literal/data_property"
|
8
9
|
autoload :DataStructure, "literal/data_structure"
|
9
10
|
autoload :Enum, "literal/enum"
|
11
|
+
autoload :Flags, "literal/flags"
|
12
|
+
autoload :Flags16, "literal/flags"
|
13
|
+
autoload :Flags32, "literal/flags"
|
14
|
+
autoload :Flags64, "literal/flags"
|
15
|
+
autoload :Flags8, "literal/flags"
|
16
|
+
autoload :Hash, "literal/hash"
|
10
17
|
autoload :Null, "literal/null"
|
11
18
|
autoload :Object, "literal/object"
|
12
19
|
autoload :Properties, "literal/properties"
|
13
20
|
autoload :Property, "literal/property"
|
21
|
+
autoload :Set, "literal/set"
|
14
22
|
autoload :Struct, "literal/struct"
|
23
|
+
autoload :Type, "literal/type"
|
15
24
|
autoload :Types, "literal/types"
|
16
25
|
|
17
26
|
# Errors
|
@@ -19,12 +28,89 @@ module Literal
|
|
19
28
|
autoload :TypeError, "literal/errors/type_error"
|
20
29
|
autoload :ArgumentError, "literal/errors/argument_error"
|
21
30
|
|
31
|
+
TRANSFORMS = {
|
32
|
+
Integer => {
|
33
|
+
abs: Integer,
|
34
|
+
ceil: Integer,
|
35
|
+
chr: String,
|
36
|
+
denominator: Integer,
|
37
|
+
even?: Types::BooleanType::Instance,
|
38
|
+
floor: Integer,
|
39
|
+
hash: Integer,
|
40
|
+
inspect: String,
|
41
|
+
integer?: true,
|
42
|
+
magnitude: Integer,
|
43
|
+
negative?: Types::BooleanType::Instance,
|
44
|
+
next: Integer,
|
45
|
+
nonzero?: Types::BooleanType::Instance,
|
46
|
+
numerator: Integer,
|
47
|
+
odd?: Types::BooleanType::Instance,
|
48
|
+
ord: Integer,
|
49
|
+
positive?: Types::BooleanType::Instance,
|
50
|
+
pred: Integer,
|
51
|
+
round: Integer,
|
52
|
+
size: Integer,
|
53
|
+
succ: Integer,
|
54
|
+
to_f: Float,
|
55
|
+
to_i: Integer,
|
56
|
+
to_int: Integer,
|
57
|
+
to_r: Rational,
|
58
|
+
to_s: String,
|
59
|
+
truncate: Integer,
|
60
|
+
zero?: Types::BooleanType::Instance,
|
61
|
+
},
|
62
|
+
String => {
|
63
|
+
ascii_only?: Types::BooleanType::Instance,
|
64
|
+
bytesize: Integer,
|
65
|
+
capitalize: String,
|
66
|
+
chomp: String,
|
67
|
+
chop: String,
|
68
|
+
downcase: String,
|
69
|
+
dump: String,
|
70
|
+
empty?: Types::BooleanType::Instance,
|
71
|
+
hash: Integer,
|
72
|
+
inspect: String,
|
73
|
+
length: Integer,
|
74
|
+
lstrip: String,
|
75
|
+
ord: Integer,
|
76
|
+
reverse: String,
|
77
|
+
rstrip: String,
|
78
|
+
scrub: String,
|
79
|
+
size: Integer,
|
80
|
+
strip: String,
|
81
|
+
swapcase: String,
|
82
|
+
to_str: String,
|
83
|
+
upcase: String,
|
84
|
+
valid_encoding?: Types::BooleanType::Instance,
|
85
|
+
},
|
86
|
+
Array => {
|
87
|
+
size: Integer,
|
88
|
+
length: Integer,
|
89
|
+
empty?: Types::BooleanType::Instance,
|
90
|
+
sort: Array,
|
91
|
+
to_a: Array,
|
92
|
+
to_ary: Array,
|
93
|
+
},
|
94
|
+
}.transform_values! { |it| it.transform_keys(&:to_proc) }.freeze
|
95
|
+
|
22
96
|
def self.Enum(type)
|
23
97
|
Class.new(Literal::Enum) do
|
24
98
|
prop :value, type, :positional
|
25
99
|
end
|
26
100
|
end
|
27
101
|
|
102
|
+
def self.Array(type)
|
103
|
+
Literal::Array::Generic.new(type)
|
104
|
+
end
|
105
|
+
|
106
|
+
def self.Set(type)
|
107
|
+
Literal::Set::Generic.new(type)
|
108
|
+
end
|
109
|
+
|
110
|
+
def self.Hash(key_type, value_type)
|
111
|
+
Literal::Hash::Generic.new(key_type, value_type)
|
112
|
+
end
|
113
|
+
|
28
114
|
def self.check(actual:, expected:)
|
29
115
|
if expected === actual
|
30
116
|
true
|
@@ -35,6 +121,17 @@ module Literal
|
|
35
121
|
raise Literal::TypeError.new(context:)
|
36
122
|
end
|
37
123
|
end
|
124
|
+
|
125
|
+
def self.subtype?(type, of:)
|
126
|
+
(of == type) || case of
|
127
|
+
when Literal::Type, Module
|
128
|
+
of >= type
|
129
|
+
when Range
|
130
|
+
of.cover?(type)
|
131
|
+
else
|
132
|
+
false
|
133
|
+
end
|
134
|
+
end
|
38
135
|
end
|
39
136
|
|
40
137
|
require_relative "literal/rails" if defined?(Rails)
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: literal
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.
|
4
|
+
version: 1.2.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Joel Drapper
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2024-11-
|
11
|
+
date: 2024-11-22 00:00:00.000000000 Z
|
12
12
|
dependencies: []
|
13
13
|
description: A literal Ruby gem.
|
14
14
|
email:
|
@@ -20,6 +20,7 @@ files:
|
|
20
20
|
- LICENSE.txt
|
21
21
|
- README.md
|
22
22
|
- lib/literal.rb
|
23
|
+
- lib/literal/array.rb
|
23
24
|
- lib/literal/data.rb
|
24
25
|
- lib/literal/data_property.rb
|
25
26
|
- lib/literal/data_structure.rb
|
@@ -27,6 +28,8 @@ files:
|
|
27
28
|
- lib/literal/errors/argument_error.rb
|
28
29
|
- lib/literal/errors/error.rb
|
29
30
|
- lib/literal/errors/type_error.rb
|
31
|
+
- lib/literal/flags.rb
|
32
|
+
- lib/literal/hash.rb
|
30
33
|
- lib/literal/null.rb
|
31
34
|
- lib/literal/object.rb
|
32
35
|
- lib/literal/properties.rb
|
@@ -36,9 +39,12 @@ files:
|
|
36
39
|
- lib/literal/rails.rb
|
37
40
|
- lib/literal/rails/enum_serializer.rb
|
38
41
|
- lib/literal/rails/enum_type.rb
|
42
|
+
- lib/literal/rails/flags_type.rb
|
39
43
|
- lib/literal/rails/patches/active_record.rb
|
40
44
|
- lib/literal/railtie.rb
|
45
|
+
- lib/literal/set.rb
|
41
46
|
- lib/literal/struct.rb
|
47
|
+
- lib/literal/type.rb
|
42
48
|
- lib/literal/types.rb
|
43
49
|
- lib/literal/types/any_type.rb
|
44
50
|
- lib/literal/types/array_type.rb
|