literal 1.6.0 → 1.7.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/lib/literal/array.rb +15 -15
- data/lib/literal/data_structure.rb +4 -3
- data/lib/literal/delegator.rb +25 -0
- data/lib/literal/enum.rb +2 -2
- data/lib/literal/flags/flags_16.rb +7 -0
- data/lib/literal/flags/flags_32.rb +7 -0
- data/lib/literal/flags/flags_64.rb +7 -0
- data/lib/literal/flags/flags_8.rb +7 -0
- data/lib/literal/flags.rb +0 -24
- data/lib/literal/hash.rb +1 -1
- data/lib/literal/properties/schema.rb +2 -2
- data/lib/literal/properties.rb +3 -4
- data/lib/literal/property.rb +3 -3
- data/lib/literal/rails/active_record_relation_patch.rb +9 -0
- data/lib/literal/rails/relation_type.rb +28 -0
- data/lib/literal/railtie.rb +31 -4
- data/lib/literal/set.rb +1 -1
- data/lib/literal/transforms.rb +2 -2
- data/lib/literal/tuple.rb +2 -2
- data/lib/literal/types/class_type.rb +2 -2
- data/lib/literal/types/constraint_type.rb +4 -4
- data/lib/literal/{deferred_type.rb → types/deferred_type.rb} +1 -1
- data/lib/literal/types/descendant_type.rb +1 -1
- data/lib/literal/types/enumerable_type.rb +1 -1
- data/lib/literal/types/frozen_type.rb +2 -2
- data/lib/literal/types/hash_type.rb +2 -2
- data/lib/literal/types/interface_type.rb +19 -14
- data/lib/literal/types/intersection_type.rb +3 -3
- data/lib/literal/types/map_type.rb +1 -1
- data/lib/literal/types/nilable_type.rb +2 -2
- data/lib/literal/types/not_type.rb +3 -3
- data/lib/literal/types/predicate_type.rb +22 -0
- data/lib/literal/types/range_type.rb +1 -1
- data/lib/literal/types/set_type.rb +1 -1
- data/lib/literal/types/union_type.rb +7 -12
- data/lib/literal/types.rb +4 -25
- data/lib/literal/value.rb +65 -0
- data/lib/literal/version.rb +1 -1
- data/lib/literal.rb +62 -34
- metadata +28 -7
- data/lib/literal/rails/patches/active_record.rb +0 -32
- data/lib/literal/rails.rb +0 -10
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: bfccfa4acf4ec640c3a47a2bab9d34aec7295a29abc387a20e81f6fb3beb085b
|
4
|
+
data.tar.gz: a5a029b15bfc36d930338fc5c2dd6b52abdab0ad1315d54725d2ad90e681bb97
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 9207d8ba24e146a2d9400c640b6d4c5d6fa97694d95097cf86ac09ebedf16613daa7b1cd4b7946b447809d71aef2e3dca8cd805c59902e3744d00d5b10da37a1
|
7
|
+
data.tar.gz: f02700e76bd9a65ef3d3885f3c79984cec164ac47af50f153bb034026d71576926245bc7a481f728c46ea6410a984d45d97d217d16ed1b34b6bf72233179033b
|
data/lib/literal/array.rb
CHANGED
@@ -17,13 +17,13 @@ class Literal::Array
|
|
17
17
|
alias_method :[], :new
|
18
18
|
|
19
19
|
def ===(value)
|
20
|
-
Literal::Array === value && Literal.subtype?(value.__type__,
|
20
|
+
Literal::Array === value && Literal.subtype?(value.__type__, @type)
|
21
21
|
end
|
22
22
|
|
23
23
|
def >=(other)
|
24
24
|
case other
|
25
25
|
when Literal::Array::Generic
|
26
|
-
Literal.subtype?(other.type,
|
26
|
+
Literal.subtype?(other.type, @type)
|
27
27
|
else
|
28
28
|
false
|
29
29
|
end
|
@@ -51,7 +51,7 @@ class Literal::Array
|
|
51
51
|
include Literal::Types
|
52
52
|
|
53
53
|
def initialize(value, type:)
|
54
|
-
Literal.check(
|
54
|
+
Literal.check(value, _Array(type)) do |c|
|
55
55
|
c.fill_receiver(receiver: self, method: "#initialize")
|
56
56
|
end
|
57
57
|
|
@@ -98,7 +98,7 @@ class Literal::Array
|
|
98
98
|
def +(other)
|
99
99
|
case other
|
100
100
|
when ::Array
|
101
|
-
Literal.check(
|
101
|
+
Literal.check(other, _Array(@__type__)) do |c|
|
102
102
|
c.fill_receiver(receiver: self, method: "#+")
|
103
103
|
end
|
104
104
|
|
@@ -129,7 +129,7 @@ class Literal::Array
|
|
129
129
|
end
|
130
130
|
|
131
131
|
def <<(value)
|
132
|
-
Literal.check(
|
132
|
+
Literal.check(value, @__type__) do |c|
|
133
133
|
c.fill_receiver(receiver: self, method: "#<<")
|
134
134
|
end
|
135
135
|
|
@@ -157,7 +157,7 @@ class Literal::Array
|
|
157
157
|
end
|
158
158
|
|
159
159
|
def []=(index, value)
|
160
|
-
Literal.check(
|
160
|
+
Literal.check(value, @__type__) do |c|
|
161
161
|
c.fill_receiver(receiver: self, method: "#[]=")
|
162
162
|
end
|
163
163
|
|
@@ -284,7 +284,7 @@ class Literal::Array
|
|
284
284
|
alias_method :index, :find_index
|
285
285
|
|
286
286
|
def insert(index, *value)
|
287
|
-
Literal.check(
|
287
|
+
Literal.check(value, _Array(@__type__)) do |c|
|
288
288
|
c.fill_receiver(receiver: self, method: "#insert")
|
289
289
|
end
|
290
290
|
|
@@ -344,9 +344,9 @@ class Literal::Array
|
|
344
344
|
|
345
345
|
def map(type, &block)
|
346
346
|
my_type = @__type__
|
347
|
-
transform_type = Literal::
|
347
|
+
transform_type = Literal::Transforms.dig(my_type, block)
|
348
348
|
|
349
|
-
if transform_type && Literal.subtype?(transform_type,
|
349
|
+
if transform_type && Literal.subtype?(transform_type, my_type)
|
350
350
|
Literal::Array.allocate.__initialize_without_check__(
|
351
351
|
@__value__.map(&block),
|
352
352
|
type:,
|
@@ -392,13 +392,13 @@ class Literal::Array
|
|
392
392
|
end
|
393
393
|
|
394
394
|
def narrow(type)
|
395
|
-
unless Literal.subtype?(type,
|
395
|
+
unless Literal.subtype?(type, @__type__)
|
396
396
|
raise ArgumentError.new("Cannot narrow #{@__type__} to #{type}")
|
397
397
|
end
|
398
398
|
|
399
399
|
if __type__ != type
|
400
400
|
@__value__.each do |item|
|
401
|
-
Literal.check(
|
401
|
+
Literal.check(item, type) do |c|
|
402
402
|
c.fill_receiver(receiver: self, method: "#narrow")
|
403
403
|
end
|
404
404
|
end
|
@@ -453,7 +453,7 @@ class Literal::Array
|
|
453
453
|
end
|
454
454
|
|
455
455
|
def push(*value)
|
456
|
-
Literal.check(
|
456
|
+
Literal.check(value, _Array(@__type__)) do |c|
|
457
457
|
c.fill_receiver(receiver: self, method: "#push")
|
458
458
|
end
|
459
459
|
|
@@ -475,7 +475,7 @@ class Literal::Array
|
|
475
475
|
def replace(value)
|
476
476
|
case value
|
477
477
|
when Array
|
478
|
-
Literal.check(
|
478
|
+
Literal.check(value, _Array(@__type__)) do |c|
|
479
479
|
c.fill_receiver(receiver: self, method: "#replace")
|
480
480
|
end
|
481
481
|
|
@@ -597,7 +597,7 @@ class Literal::Array
|
|
597
597
|
end
|
598
598
|
|
599
599
|
def unshift(value)
|
600
|
-
Literal.check(
|
600
|
+
Literal.check(value, @__type__) do |c|
|
601
601
|
c.fill_receiver(receiver: self, method: "#unshift")
|
602
602
|
end
|
603
603
|
|
@@ -636,7 +636,7 @@ class Literal::Array
|
|
636
636
|
def |(other)
|
637
637
|
case other
|
638
638
|
when ::Array
|
639
|
-
Literal.check(
|
639
|
+
Literal.check(other, _Array(@__type__)) do |c|
|
640
640
|
c.fill_receiver(receiver: self, method: "#|")
|
641
641
|
end
|
642
642
|
|
@@ -38,7 +38,7 @@ class Literal::DataStructure
|
|
38
38
|
end
|
39
39
|
|
40
40
|
def marshal_dump
|
41
|
-
[1, to_h, frozen?]
|
41
|
+
[1, to_h, frozen?].freeze
|
42
42
|
end
|
43
43
|
|
44
44
|
def hash
|
@@ -46,9 +46,10 @@ class Literal::DataStructure
|
|
46
46
|
end
|
47
47
|
|
48
48
|
def ==(other)
|
49
|
-
|
49
|
+
self.class === other && other.class.literal_properties.empty?
|
50
50
|
end
|
51
|
-
|
51
|
+
|
52
|
+
alias_method :eql?, :==
|
52
53
|
|
53
54
|
def self.__generate_literal_methods__(new_property, buffer = +"")
|
54
55
|
super
|
@@ -0,0 +1,25 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
class Literal::Delegator < SimpleDelegator
|
4
|
+
def self.to_proc
|
5
|
+
-> (value) { new(value) }
|
6
|
+
end
|
7
|
+
|
8
|
+
def self.[](value)
|
9
|
+
new(value)
|
10
|
+
end
|
11
|
+
|
12
|
+
def initialize(value)
|
13
|
+
Literal.check(value, __type__)
|
14
|
+
super
|
15
|
+
freeze
|
16
|
+
end
|
17
|
+
|
18
|
+
def ===(other)
|
19
|
+
self.class === other && __getobj__ == other.__getobj__
|
20
|
+
end
|
21
|
+
|
22
|
+
alias_method :==, :===
|
23
|
+
|
24
|
+
freeze
|
25
|
+
end
|
data/lib/literal/enum.rb
CHANGED
@@ -55,7 +55,7 @@ class Literal::Enum
|
|
55
55
|
|
56
56
|
types = @indexes_definitions.fetch(key)
|
57
57
|
type = types.first
|
58
|
-
Literal.check(
|
58
|
+
Literal.check(value, type) { |c| raise NotImplementedError }
|
59
59
|
|
60
60
|
@indexes.fetch(key)[value]
|
61
61
|
end
|
@@ -72,7 +72,7 @@ class Literal::Enum
|
|
72
72
|
end
|
73
73
|
|
74
74
|
type = @indexes_definitions.fetch(key)[0]
|
75
|
-
Literal.check(
|
75
|
+
Literal.check(value, type)
|
76
76
|
|
77
77
|
@indexes.fetch(key)[value]&.first
|
78
78
|
end
|
data/lib/literal/flags.rb
CHANGED
@@ -219,27 +219,3 @@ class Literal::Flags
|
|
219
219
|
2 ** self.class::FLAGS.fetch(key)
|
220
220
|
end
|
221
221
|
end
|
222
|
-
|
223
|
-
class Literal::Flags8 < Literal::Flags
|
224
|
-
BYTES = 1
|
225
|
-
BITS = BYTES * 8
|
226
|
-
PACKER = "C"
|
227
|
-
end
|
228
|
-
|
229
|
-
class Literal::Flags16 < Literal::Flags
|
230
|
-
BYTES = 2
|
231
|
-
BITS = BYTES * 8
|
232
|
-
PACKER = "S"
|
233
|
-
end
|
234
|
-
|
235
|
-
class Literal::Flags32 < Literal::Flags
|
236
|
-
BYTES = 4
|
237
|
-
BITS = BYTES * 8
|
238
|
-
PACKER = "L"
|
239
|
-
end
|
240
|
-
|
241
|
-
class Literal::Flags64 < Literal::Flags
|
242
|
-
BYTES = 8
|
243
|
-
BITS = BYTES * 8
|
244
|
-
PACKER = "Q"
|
245
|
-
end
|
data/lib/literal/hash.rb
CHANGED
@@ -25,7 +25,7 @@ class Literal::Hash
|
|
25
25
|
def initialize(value, key_type:, value_type:)
|
26
26
|
collection_type = Literal::Types::HashType.new(key_type, value_type)
|
27
27
|
|
28
|
-
Literal.check(
|
28
|
+
Literal.check(value, collection_type) do |c|
|
29
29
|
c.fill_receiver(receiver: self, method: "#initialize")
|
30
30
|
end
|
31
31
|
|
@@ -62,7 +62,7 @@ class Literal::Properties::Schema
|
|
62
62
|
end
|
63
63
|
|
64
64
|
def generate_after_initializer(buffer = +"")
|
65
|
-
buffer << " after_initialize if respond_to?(:after_initialize)\n"
|
65
|
+
buffer << " after_initialize if respond_to?(:after_initialize, true)\n"
|
66
66
|
end
|
67
67
|
|
68
68
|
def generate_to_h(buffer = +"")
|
@@ -96,7 +96,7 @@ class Literal::Properties::Schema
|
|
96
96
|
|
97
97
|
def generate_eq(buffer = +"")
|
98
98
|
buffer << "def ==(other)\n"
|
99
|
-
buffer << " return false unless
|
99
|
+
buffer << " return false unless self.class === other && other.class.literal_properties.size == self.class.literal_properties.size\n"
|
100
100
|
|
101
101
|
sorted_properties = @sorted_properties
|
102
102
|
i, n = 0, sorted_properties.size
|
data/lib/literal/properties.rb
CHANGED
@@ -1,9 +1,6 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
3
|
module Literal::Properties
|
4
|
-
autoload :Schema, "literal/properties/schema"
|
5
|
-
autoload :DataSchema, "literal/properties/data_schema"
|
6
|
-
|
7
4
|
include Literal::Types
|
8
5
|
|
9
6
|
module DocString
|
@@ -57,12 +54,14 @@ module Literal::Properties
|
|
57
54
|
literal_properties << property
|
58
55
|
__define_literal_methods__(property)
|
59
56
|
include(__literal_extension__)
|
57
|
+
|
58
|
+
name
|
60
59
|
end
|
61
60
|
|
62
61
|
def literal_properties
|
63
62
|
return @literal_properties if defined?(@literal_properties)
|
64
63
|
|
65
|
-
if
|
64
|
+
if Literal::Properties === superclass
|
66
65
|
@literal_properties = superclass.literal_properties.dup
|
67
66
|
else
|
68
67
|
@literal_properties = Literal::Properties::Schema.new
|
data/lib/literal/property.rb
CHANGED
@@ -97,15 +97,15 @@ class Literal::Property
|
|
97
97
|
def check(value, &)
|
98
98
|
raise ArgumentError.new("Cannot check type without a block") unless block_given?
|
99
99
|
|
100
|
-
Literal.check(
|
100
|
+
Literal.check(value, @type, &)
|
101
101
|
end
|
102
102
|
|
103
103
|
def check_writer(receiver, value)
|
104
|
-
Literal.check(
|
104
|
+
Literal.check(value, @type) { |c| c.fill_receiver(receiver:, method: "##{@name.name}=(value)") }
|
105
105
|
end
|
106
106
|
|
107
107
|
def check_initializer(receiver, value)
|
108
|
-
Literal.check(
|
108
|
+
Literal.check(value, @type) { |c| c.fill_receiver(receiver:, method: "#initialize", label: param) }
|
109
109
|
end
|
110
110
|
|
111
111
|
def generate_reader_method(buffer = +"")
|
@@ -0,0 +1,28 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Literal::Rails
|
4
|
+
class RelationType
|
5
|
+
def initialize(model_class)
|
6
|
+
unless Class === model_class && model_class < ActiveRecord::Base
|
7
|
+
raise Literal::TypeError.new(
|
8
|
+
context: Literal::TypeError::Context.new(
|
9
|
+
expected: ActiveRecord::Base, actual: model_class
|
10
|
+
)
|
11
|
+
)
|
12
|
+
end
|
13
|
+
|
14
|
+
@model_class = model_class
|
15
|
+
end
|
16
|
+
|
17
|
+
def inspect = "ActiveRecord::Relation(#{@model_class.name})"
|
18
|
+
|
19
|
+
def ===(value)
|
20
|
+
case value
|
21
|
+
when ActiveRecord::Relation, ActiveRecord::Associations::CollectionProxy, ActiveRecord::AssociationRelation
|
22
|
+
@model_class == value.model || value.model < @model_class
|
23
|
+
else
|
24
|
+
false
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
data/lib/literal/railtie.rb
CHANGED
@@ -1,15 +1,42 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
+
module Literal::Rails
|
4
|
+
if defined?(::ActiveJob)
|
5
|
+
require_relative "rails/enum_serializer"
|
6
|
+
end
|
7
|
+
|
8
|
+
if defined?(::ActiveRecord::Relation)
|
9
|
+
require_relative "rails/relation_type"
|
10
|
+
require_relative "rails/active_record_relation_patch"
|
11
|
+
::ActiveRecord.extend(ActiveRecordRelationPatch)
|
12
|
+
end
|
13
|
+
end
|
14
|
+
|
3
15
|
class Literal::Railtie < Rails::Railtie
|
4
|
-
|
5
|
-
|
6
|
-
|
16
|
+
if defined?(::ActiveModel::Type)
|
17
|
+
require_relative "rails/enum_type"
|
18
|
+
require_relative "rails/flags_type"
|
19
|
+
|
20
|
+
initializer "literal.register_active_model_types" do
|
21
|
+
ActiveModel::Type.register(:literal_enum) do |name, type:|
|
7
22
|
Literal::Rails::EnumType.new(type)
|
8
23
|
end
|
9
24
|
|
10
|
-
|
25
|
+
ActiveModel::Type.register(:literal_flags) do |name, type:|
|
11
26
|
Literal::Rails::FlagsType.new(type)
|
12
27
|
end
|
13
28
|
end
|
29
|
+
|
30
|
+
if defined?(::ActiveRecord::Type)
|
31
|
+
initializer "literal.register_active_record_types" do
|
32
|
+
ActiveRecord::Type.register(:literal_enum) do |name, type:|
|
33
|
+
Literal::Rails::EnumType.new(type)
|
34
|
+
end
|
35
|
+
|
36
|
+
ActiveRecord::Type.register(:literal_flags) do |name, type:|
|
37
|
+
Literal::Rails::FlagsType.new(type)
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
14
41
|
end
|
15
42
|
end
|
data/lib/literal/set.rb
CHANGED
@@ -26,7 +26,7 @@ class Literal::Set
|
|
26
26
|
def initialize(value, type:)
|
27
27
|
collection_type = Literal::Types::SetType.new(type)
|
28
28
|
|
29
|
-
Literal.check(
|
29
|
+
Literal.check(value, collection_type) do |c|
|
30
30
|
c.fill_receiver(receiver: self, method: "#initialize")
|
31
31
|
end
|
32
32
|
|
data/lib/literal/transforms.rb
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
3
|
# A map of core types to transform Procs mapping to the new type.
|
4
|
-
Literal::
|
4
|
+
Literal::Transforms = {
|
5
5
|
Integer => {
|
6
6
|
abs: Integer,
|
7
7
|
ceil: Integer,
|
@@ -140,4 +140,4 @@ Literal::TRANSFORMS = {
|
|
140
140
|
to_s: String,
|
141
141
|
year: Integer,
|
142
142
|
},
|
143
|
-
}.transform_values! { |it| it.transform_keys(&:to_proc) }.freeze
|
143
|
+
}.transform_values! { |it| it.transform_keys(&:to_proc).freeze }.freeze
|
data/lib/literal/tuple.rb
CHANGED
@@ -19,7 +19,7 @@ class Literal::Tuple
|
|
19
19
|
|
20
20
|
i, len = 0, types.size
|
21
21
|
while i < len
|
22
|
-
return false unless Literal.subtype?(other_types[i],
|
22
|
+
return false unless Literal.subtype?(other_types[i], types[i])
|
23
23
|
i += 1
|
24
24
|
end
|
25
25
|
|
@@ -36,7 +36,7 @@ class Literal::Tuple
|
|
36
36
|
|
37
37
|
i, len = 0, types.size
|
38
38
|
while i < len
|
39
|
-
return false unless Literal.subtype?(other_types[i],
|
39
|
+
return false unless Literal.subtype?(other_types[i], types[i])
|
40
40
|
i += 1
|
41
41
|
end
|
42
42
|
|
@@ -22,9 +22,9 @@ class Literal::Types::ClassType
|
|
22
22
|
def >=(other)
|
23
23
|
case other
|
24
24
|
when Literal::Types::ClassType
|
25
|
-
Literal.subtype?(other.type,
|
25
|
+
Literal.subtype?(other.type, @type)
|
26
26
|
when Literal::Types::DescendantType
|
27
|
-
(Class === other.type) && Literal.subtype?(other.type,
|
27
|
+
(Class === other.type) && Literal.subtype?(other.type, @type)
|
28
28
|
else
|
29
29
|
false
|
30
30
|
end
|
@@ -46,24 +46,24 @@ class Literal::Types::ConstraintType
|
|
46
46
|
when Literal::Types::ConstraintType
|
47
47
|
other_object_constraints = other.object_constraints
|
48
48
|
return false unless @object_constraints.all? do |constraint|
|
49
|
-
other_object_constraints.any? { |c| Literal.subtype?(c,
|
49
|
+
other_object_constraints.any? { |c| Literal.subtype?(c, constraint) }
|
50
50
|
end
|
51
51
|
|
52
52
|
other_property_constraints = other.property_constraints
|
53
53
|
return false unless @property_constraints.all? do |k, v|
|
54
|
-
Literal.subtype?(other_property_constraints[k],
|
54
|
+
Literal.subtype?(other_property_constraints[k], v)
|
55
55
|
end
|
56
56
|
|
57
57
|
true
|
58
58
|
when Literal::Types::IntersectionType
|
59
59
|
other_object_constraints = other.types
|
60
60
|
return false unless @object_constraints.all? do |constraint|
|
61
|
-
other_object_constraints.any? { |c| Literal.subtype?(c,
|
61
|
+
other_object_constraints.any? { |c| Literal.subtype?(c, constraint) }
|
62
62
|
end
|
63
63
|
|
64
64
|
true
|
65
65
|
when Literal::Types::FrozenType
|
66
|
-
@object_constraints.all? { |constraint| Literal.subtype?(other.type,
|
66
|
+
@object_constraints.all? { |constraint| Literal.subtype?(other.type, constraint) }
|
67
67
|
else
|
68
68
|
false
|
69
69
|
end
|
@@ -31,11 +31,11 @@ class Literal::Types::FrozenType
|
|
31
31
|
@type >= other.type
|
32
32
|
when Literal::Types::ConstraintType
|
33
33
|
type_match = false
|
34
|
-
frozen_match = Literal.subtype?(other.property_constraints[:frozen?],
|
34
|
+
frozen_match = Literal.subtype?(other.property_constraints[:frozen?], true)
|
35
35
|
|
36
36
|
other.object_constraints.each do |constraint|
|
37
37
|
frozen_match ||= ALWAYS_FROZEN.include?(constraint)
|
38
|
-
type_match ||= Literal.subtype?(constraint,
|
38
|
+
type_match ||= Literal.subtype?(constraint, @type)
|
39
39
|
return true if frozen_match && type_match
|
40
40
|
end
|
41
41
|
|
@@ -30,9 +30,9 @@ class Literal::Types::HashType
|
|
30
30
|
case other
|
31
31
|
when Literal::Types::HashType
|
32
32
|
(
|
33
|
-
Literal.subtype?(other.key_type,
|
33
|
+
Literal.subtype?(other.key_type, @key_type)
|
34
34
|
) && (
|
35
|
-
Literal.subtype?(other.value_type,
|
35
|
+
Literal.subtype?(other.value_type, @value_type)
|
36
36
|
)
|
37
37
|
else
|
38
38
|
false
|
@@ -2,18 +2,14 @@
|
|
2
2
|
|
3
3
|
# @api private
|
4
4
|
class Literal::Types::InterfaceType
|
5
|
-
# TODO: We can generate this and make it much more extensive.
|
6
|
-
METHOD_TYPE_MAPPINGS = {
|
7
|
-
:call => Set[Proc, Method],
|
8
|
-
:to_proc => Set[Proc, Method],
|
9
|
-
:to_s => Set[String],
|
10
|
-
}.freeze
|
11
|
-
|
12
5
|
include Literal::Type
|
13
6
|
|
7
|
+
# List of `===` method owners where the comparison will only match for objects with the same class
|
8
|
+
OwnClassTypeMethodOwners = Set[String, Integer, Kernel, Float, NilClass, TrueClass, FalseClass].freeze
|
9
|
+
|
14
10
|
def initialize(*methods)
|
15
11
|
raise Literal::ArgumentError.new("_Interface type must have at least one method.") if methods.size < 1
|
16
|
-
@methods = methods
|
12
|
+
@methods = methods.to_set.freeze
|
17
13
|
freeze
|
18
14
|
end
|
19
15
|
|
@@ -24,21 +20,30 @@ class Literal::Types::InterfaceType
|
|
24
20
|
end
|
25
21
|
|
26
22
|
def ===(value)
|
27
|
-
@methods.
|
23
|
+
@methods.each do |method|
|
24
|
+
return false unless value.respond_to?(method)
|
25
|
+
end
|
26
|
+
|
27
|
+
true
|
28
28
|
end
|
29
29
|
|
30
30
|
def >=(other)
|
31
31
|
case other
|
32
32
|
when Literal::Types::InterfaceType
|
33
|
-
@methods.
|
33
|
+
@methods.subset?(other.methods)
|
34
34
|
when Module
|
35
|
-
|
35
|
+
public_methods = other.public_instance_methods.to_set
|
36
|
+
@methods.subset?(public_methods)
|
36
37
|
when Literal::Types::IntersectionType
|
37
|
-
other.types.any? { |type| Literal.subtype?(type,
|
38
|
+
other.types.any? { |type| Literal.subtype?(type, self) }
|
38
39
|
when Literal::Types::ConstraintType
|
39
|
-
other.object_constraints.any? { |type| Literal.subtype?(type,
|
40
|
+
other.object_constraints.any? { |type| Literal.subtype?(type, self) }
|
40
41
|
else
|
41
|
-
|
42
|
+
if OwnClassTypeMethodOwners.include?(other.method(:===).owner)
|
43
|
+
self === other
|
44
|
+
else
|
45
|
+
false
|
46
|
+
end
|
42
47
|
end
|
43
48
|
end
|
44
49
|
|
@@ -36,17 +36,17 @@ class Literal::Types::IntersectionType
|
|
36
36
|
when Literal::Types::IntersectionType
|
37
37
|
@types.all? do |type|
|
38
38
|
other.types.any? do |other_type|
|
39
|
-
Literal.subtype?(other_type,
|
39
|
+
Literal.subtype?(other_type, type)
|
40
40
|
end
|
41
41
|
end
|
42
42
|
when Literal::Types::ConstraintType
|
43
43
|
@types.all? do |type|
|
44
44
|
other.object_constraints.any? do |object_constraint|
|
45
|
-
Literal.subtype?(object_constraint,
|
45
|
+
Literal.subtype?(object_constraint, type)
|
46
46
|
end
|
47
47
|
end
|
48
48
|
when Literal::Types::FrozenType
|
49
|
-
@types.all? { |type| Literal.subtype?(other.type,
|
49
|
+
@types.all? { |type| Literal.subtype?(other.type, type) }
|
50
50
|
else
|
51
51
|
false
|
52
52
|
end
|
@@ -26,11 +26,11 @@ class Literal::Types::NilableType
|
|
26
26
|
def >=(other)
|
27
27
|
case other
|
28
28
|
when Literal::Types::NilableType
|
29
|
-
Literal.subtype?(other.type,
|
29
|
+
Literal.subtype?(other.type, @type)
|
30
30
|
when nil
|
31
31
|
true
|
32
32
|
else
|
33
|
-
Literal.subtype?(other,
|
33
|
+
Literal.subtype?(other, @type)
|
34
34
|
end
|
35
35
|
end
|
36
36
|
|
@@ -22,11 +22,11 @@ class Literal::Types::NotType
|
|
22
22
|
def >=(other)
|
23
23
|
case other
|
24
24
|
when Literal::Types::NotType
|
25
|
-
Literal.subtype?(other.type,
|
25
|
+
Literal.subtype?(other.type, @type)
|
26
26
|
when Literal::Types::ConstraintType
|
27
|
-
other.object_constraints.any? { |constraint| Literal.subtype?(constraint,
|
27
|
+
other.object_constraints.any? { |constraint| Literal.subtype?(constraint, self) }
|
28
28
|
when Literal::Types::IntersectionType
|
29
|
-
other.types.any? { |type| Literal.subtype?(type,
|
29
|
+
other.types.any? { |type| Literal.subtype?(type, self) }
|
30
30
|
else
|
31
31
|
false
|
32
32
|
end
|
@@ -0,0 +1,22 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
class Literal::Types::PredicateType
|
4
|
+
include Literal::Type
|
5
|
+
|
6
|
+
def initialize(message:, block:)
|
7
|
+
@message = message
|
8
|
+
@block = block
|
9
|
+
|
10
|
+
freeze
|
11
|
+
end
|
12
|
+
|
13
|
+
def inspect
|
14
|
+
%(_Predicate("#{@message}"))
|
15
|
+
end
|
16
|
+
|
17
|
+
def ===(other)
|
18
|
+
@block === other
|
19
|
+
end
|
20
|
+
|
21
|
+
freeze
|
22
|
+
end
|
@@ -2,6 +2,7 @@
|
|
2
2
|
|
3
3
|
class Literal::Types::UnionType
|
4
4
|
include Enumerable
|
5
|
+
include Literal::Type
|
5
6
|
|
6
7
|
def initialize(*queue)
|
7
8
|
raise Literal::ArgumentError.new("_Union type must have at least one type.") if queue.size < 1
|
@@ -32,7 +33,7 @@ class Literal::Types::UnionType
|
|
32
33
|
attr_reader :types, :primitives
|
33
34
|
|
34
35
|
def inspect
|
35
|
-
"_Union(#{
|
36
|
+
"_Union(#{to_a.map(&:inspect).join(', ')})"
|
36
37
|
end
|
37
38
|
|
38
39
|
def ===(value)
|
@@ -45,6 +46,8 @@ class Literal::Types::UnionType
|
|
45
46
|
return true if types[i] === value
|
46
47
|
i += 1
|
47
48
|
end
|
49
|
+
|
50
|
+
false
|
48
51
|
end
|
49
52
|
|
50
53
|
def each(&)
|
@@ -66,14 +69,6 @@ class Literal::Types::UnionType
|
|
66
69
|
self[key] or raise KeyError.new("Key not found: #{key.inspect}")
|
67
70
|
end
|
68
71
|
|
69
|
-
def record_literal_type_errors(ctx)
|
70
|
-
each do |type|
|
71
|
-
ctx.add_child(label: type.inspect, expected: type, actual: ctx.actual)
|
72
|
-
end
|
73
|
-
|
74
|
-
ctx.children.clear if ctx.children.none? { |c| c.children.any? }
|
75
|
-
end
|
76
|
-
|
77
72
|
def >=(other)
|
78
73
|
types = @types
|
79
74
|
primitives = @primitives
|
@@ -81,16 +76,16 @@ class Literal::Types::UnionType
|
|
81
76
|
case other
|
82
77
|
when Literal::Types::UnionType
|
83
78
|
types_have_at_least_one_subtype = other.types.all? do |other_type|
|
84
|
-
primitives.any? { |p| Literal.subtype?(
|
79
|
+
primitives.any? { |p| Literal.subtype?(other_type, p) } || types.any? { |t| Literal.subtype?(other_type, t) }
|
85
80
|
end
|
86
81
|
|
87
82
|
primitives_have_at_least_one_subtype = other.primitives.all? do |other_primitive|
|
88
|
-
primitives.any? { |p| Literal.subtype?(
|
83
|
+
primitives.any? { |p| Literal.subtype?(other_primitive, p) } || types.any? { |t| Literal.subtype?(other_primitive, t) }
|
89
84
|
end
|
90
85
|
|
91
86
|
types_have_at_least_one_subtype && primitives_have_at_least_one_subtype
|
92
87
|
else
|
93
|
-
types.any? { |t| Literal.subtype?(other,
|
88
|
+
types.any? { |t| Literal.subtype?(other, t) } || primitives.any? { |p| Literal.subtype?(other, p) }
|
94
89
|
end
|
95
90
|
end
|
96
91
|
|
data/lib/literal/types.rb
CHANGED
@@ -3,31 +3,6 @@
|
|
3
3
|
module Literal::Types
|
4
4
|
extend self
|
5
5
|
|
6
|
-
autoload :AnyType, "literal/types/any_type"
|
7
|
-
autoload :ArrayType, "literal/types/array_type"
|
8
|
-
autoload :BooleanType, "literal/types/boolean_type"
|
9
|
-
autoload :ClassType, "literal/types/class_type"
|
10
|
-
autoload :ConstraintType, "literal/types/constraint_type"
|
11
|
-
autoload :DeferredType, "literal/deferred_type"
|
12
|
-
autoload :DescendantType, "literal/types/descendant_type"
|
13
|
-
autoload :EnumerableType, "literal/types/enumerable_type"
|
14
|
-
autoload :FalsyType, "literal/types/falsy_type"
|
15
|
-
autoload :FrozenType, "literal/types/frozen_type"
|
16
|
-
autoload :HashType, "literal/types/hash_type"
|
17
|
-
autoload :InterfaceType, "literal/types/interface_type"
|
18
|
-
autoload :IntersectionType, "literal/types/intersection_type"
|
19
|
-
autoload :JSONDataType, "literal/types/json_data_type"
|
20
|
-
autoload :MapType, "literal/types/map_type"
|
21
|
-
autoload :NeverType, "literal/types/never_type"
|
22
|
-
autoload :NilableType, "literal/types/nilable_type"
|
23
|
-
autoload :NotType, "literal/types/not_type"
|
24
|
-
autoload :RangeType, "literal/types/range_type"
|
25
|
-
autoload :SetType, "literal/types/set_type"
|
26
|
-
autoload :TruthyType, "literal/types/truthy_type"
|
27
|
-
autoload :TupleType, "literal/types/tuple_type"
|
28
|
-
autoload :UnionType, "literal/types/union_type"
|
29
|
-
autoload :VoidType, "literal/types/void_type"
|
30
|
-
|
31
6
|
# Matches any value except `nil`. Use `_Any?` or `_Void` to match any value including `nil`.
|
32
7
|
# ```ruby
|
33
8
|
# _Any
|
@@ -339,6 +314,10 @@ module Literal::Types
|
|
339
314
|
end
|
340
315
|
end
|
341
316
|
|
317
|
+
def _Predicate(message, &block)
|
318
|
+
PredicateType.new(message:, block:)
|
319
|
+
end
|
320
|
+
|
342
321
|
# Matches if the value is a `Proc` or responds to `#to_proc`.
|
343
322
|
def _Procable
|
344
323
|
ProcableType
|
@@ -0,0 +1,65 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
class Literal::Value
|
4
|
+
def self.to_proc
|
5
|
+
-> (value) { new(value) }
|
6
|
+
end
|
7
|
+
|
8
|
+
def self.[](value)
|
9
|
+
new(value)
|
10
|
+
end
|
11
|
+
|
12
|
+
def self.from_pack(payload)
|
13
|
+
object = allocate
|
14
|
+
object.marshal_load(payload)
|
15
|
+
object
|
16
|
+
end
|
17
|
+
|
18
|
+
# Takes a list of method names and delegates them to the underlying value.
|
19
|
+
def self.delegate(*methods)
|
20
|
+
methods.each do |method_name|
|
21
|
+
class_eval(<<~RUBY, __FILE__, __LINE__ + 1)
|
22
|
+
# frozen_string_literal: true
|
23
|
+
|
24
|
+
def #{method_name}(...)
|
25
|
+
@value.#{method_name}(...)
|
26
|
+
end
|
27
|
+
RUBY
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
def initialize(value)
|
32
|
+
Literal.check(value, __type__)
|
33
|
+
@value = value
|
34
|
+
freeze
|
35
|
+
end
|
36
|
+
|
37
|
+
attr_reader :value
|
38
|
+
|
39
|
+
def inspect
|
40
|
+
"#{self.class.name}(#{value.inspect})"
|
41
|
+
end
|
42
|
+
|
43
|
+
def ===(other)
|
44
|
+
self.class === other && @value == other.value
|
45
|
+
end
|
46
|
+
|
47
|
+
alias_method :==, :===
|
48
|
+
|
49
|
+
def as_pack
|
50
|
+
marshal_dump
|
51
|
+
end
|
52
|
+
|
53
|
+
def marshal_load(payload)
|
54
|
+
_version, value, was_frozen = payload
|
55
|
+
|
56
|
+
@value = value
|
57
|
+
freeze if was_frozen
|
58
|
+
end
|
59
|
+
|
60
|
+
def marshal_dump
|
61
|
+
[1, @value, frozen?].freeze
|
62
|
+
end
|
63
|
+
|
64
|
+
freeze
|
65
|
+
end
|
data/lib/literal/version.rb
CHANGED
data/lib/literal.rb
CHANGED
@@ -1,33 +1,58 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
+
require "zeitwerk"
|
4
|
+
require_relative "literal/version"
|
5
|
+
|
3
6
|
module Literal
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
7
|
+
Loader = Zeitwerk::Loader.for_gem.tap do |loader|
|
8
|
+
loader.ignore("#{__dir__}/literal/rails")
|
9
|
+
loader.ignore("#{__dir__}/literal/railtie.rb")
|
10
|
+
|
11
|
+
loader.inflector.inflect(
|
12
|
+
"json_data_type" => "JSONDataType"
|
13
|
+
)
|
14
|
+
|
15
|
+
loader.collapse("#{__dir__}/literal/flags")
|
16
|
+
loader.collapse("#{__dir__}/literal/errors")
|
17
|
+
|
18
|
+
loader.setup
|
19
|
+
end
|
20
|
+
|
21
|
+
def self.Value(*args, **kwargs, &block)
|
22
|
+
value_class = Class.new(Literal::Value)
|
23
|
+
|
24
|
+
type = Literal::Types._Constraint(*args, **kwargs)
|
25
|
+
value_class.define_method(:__type__) { type }
|
26
|
+
|
27
|
+
if subtype?(type, Integer)
|
28
|
+
value_class.alias_method :to_i, :value
|
29
|
+
elsif subtype?(type, String)
|
30
|
+
value_class.alias_method :to_s, :value
|
31
|
+
value_class.alias_method :to_str, :value
|
32
|
+
elsif subtype?(type, Array)
|
33
|
+
value_class.alias_method :to_a, :value
|
34
|
+
value_class.alias_method :to_ary, :value
|
35
|
+
elsif subtype?(type, Hash)
|
36
|
+
value_class.alias_method :to_h, :value
|
37
|
+
elsif subtype?(type, Float)
|
38
|
+
value_class.alias_method :to_f, :value
|
39
|
+
elsif subtype?(type, Set)
|
40
|
+
value_class.alias_method :to_set, :value
|
41
|
+
end
|
42
|
+
|
43
|
+
value_class.class_eval(&block) if block
|
44
|
+
value_class.freeze
|
45
|
+
end
|
46
|
+
|
47
|
+
def self.Delegator(*args, **kwargs, &block)
|
48
|
+
delegator_class = Class.new(Literal::Delegator)
|
49
|
+
|
50
|
+
type = Literal::Types._Constraint(*args, **kwargs)
|
51
|
+
delegator_class.define_method(:__type__) { type }
|
52
|
+
|
53
|
+
delegator_class.class_eval(&block) if block
|
54
|
+
delegator_class.freeze
|
55
|
+
end
|
31
56
|
|
32
57
|
def self.Enum(type)
|
33
58
|
Class.new(Literal::Enum) do
|
@@ -51,19 +76,22 @@ module Literal
|
|
51
76
|
Literal::Tuple::Generic.new(*types)
|
52
77
|
end
|
53
78
|
|
54
|
-
def self.
|
55
|
-
|
79
|
+
def self.Brand(...)
|
80
|
+
Literal::Brand.new(...)
|
81
|
+
end
|
82
|
+
|
83
|
+
def self.check(value, type)
|
84
|
+
if type === value
|
56
85
|
true
|
57
86
|
else
|
58
|
-
context = Literal::TypeError::Context.new(expected
|
59
|
-
|
87
|
+
context = Literal::TypeError::Context.new(expected: type, actual: value)
|
88
|
+
type.record_literal_type_errors(context) if type.respond_to?(:record_literal_type_errors)
|
60
89
|
yield context if block_given?
|
61
90
|
raise Literal::TypeError.new(context:)
|
62
91
|
end
|
63
92
|
end
|
64
93
|
|
65
|
-
def self.subtype?(type,
|
66
|
-
supertype = of
|
94
|
+
def self.subtype?(type, supertype)
|
67
95
|
subtype = type
|
68
96
|
|
69
97
|
subtype = subtype.block.call if Types::DeferredType === subtype
|
@@ -98,4 +126,4 @@ module Literal
|
|
98
126
|
end
|
99
127
|
end
|
100
128
|
|
101
|
-
require_relative "literal/
|
129
|
+
require_relative "literal/railtie" if defined?(Rails)
|
metadata
CHANGED
@@ -1,14 +1,28 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: literal
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.
|
4
|
+
version: 1.7.1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Joel Drapper
|
8
8
|
bindir: bin
|
9
9
|
cert_chain: []
|
10
|
-
date:
|
11
|
-
dependencies:
|
10
|
+
date: 1980-01-02 00:00:00.000000000 Z
|
11
|
+
dependencies:
|
12
|
+
- !ruby/object:Gem::Dependency
|
13
|
+
name: zeitwerk
|
14
|
+
requirement: !ruby/object:Gem::Requirement
|
15
|
+
requirements:
|
16
|
+
- - ">="
|
17
|
+
- !ruby/object:Gem::Version
|
18
|
+
version: '0'
|
19
|
+
type: :runtime
|
20
|
+
prerelease: false
|
21
|
+
version_requirements: !ruby/object:Gem::Requirement
|
22
|
+
requirements:
|
23
|
+
- - ">="
|
24
|
+
- !ruby/object:Gem::Version
|
25
|
+
version: '0'
|
12
26
|
description: Enums, properties, generics, structured objects and runtime type checking.
|
13
27
|
email:
|
14
28
|
- joel@drapper.me
|
@@ -22,13 +36,17 @@ files:
|
|
22
36
|
- lib/literal/array.rb
|
23
37
|
- lib/literal/data.rb
|
24
38
|
- lib/literal/data_structure.rb
|
25
|
-
- lib/literal/
|
39
|
+
- lib/literal/delegator.rb
|
26
40
|
- lib/literal/enum.rb
|
27
41
|
- lib/literal/errors/argument_error.rb
|
28
42
|
- lib/literal/errors/error.rb
|
29
43
|
- lib/literal/errors/type_error.rb
|
30
44
|
- lib/literal/failure.rb
|
31
45
|
- lib/literal/flags.rb
|
46
|
+
- lib/literal/flags/flags_16.rb
|
47
|
+
- lib/literal/flags/flags_32.rb
|
48
|
+
- lib/literal/flags/flags_64.rb
|
49
|
+
- lib/literal/flags/flags_8.rb
|
32
50
|
- lib/literal/hash.rb
|
33
51
|
- lib/literal/null.rb
|
34
52
|
- lib/literal/object.rb
|
@@ -36,11 +54,11 @@ files:
|
|
36
54
|
- lib/literal/properties/data_schema.rb
|
37
55
|
- lib/literal/properties/schema.rb
|
38
56
|
- lib/literal/property.rb
|
39
|
-
- lib/literal/rails.rb
|
57
|
+
- lib/literal/rails/active_record_relation_patch.rb
|
40
58
|
- lib/literal/rails/enum_serializer.rb
|
41
59
|
- lib/literal/rails/enum_type.rb
|
42
60
|
- lib/literal/rails/flags_type.rb
|
43
|
-
- lib/literal/rails/
|
61
|
+
- lib/literal/rails/relation_type.rb
|
44
62
|
- lib/literal/railtie.rb
|
45
63
|
- lib/literal/result.rb
|
46
64
|
- lib/literal/set.rb
|
@@ -55,6 +73,7 @@ files:
|
|
55
73
|
- lib/literal/types/boolean_type.rb
|
56
74
|
- lib/literal/types/class_type.rb
|
57
75
|
- lib/literal/types/constraint_type.rb
|
76
|
+
- lib/literal/types/deferred_type.rb
|
58
77
|
- lib/literal/types/descendant_type.rb
|
59
78
|
- lib/literal/types/enumerable_type.rb
|
60
79
|
- lib/literal/types/falsy_type.rb
|
@@ -67,12 +86,14 @@ files:
|
|
67
86
|
- lib/literal/types/never_type.rb
|
68
87
|
- lib/literal/types/nilable_type.rb
|
69
88
|
- lib/literal/types/not_type.rb
|
89
|
+
- lib/literal/types/predicate_type.rb
|
70
90
|
- lib/literal/types/range_type.rb
|
71
91
|
- lib/literal/types/set_type.rb
|
72
92
|
- lib/literal/types/truthy_type.rb
|
73
93
|
- lib/literal/types/tuple_type.rb
|
74
94
|
- lib/literal/types/union_type.rb
|
75
95
|
- lib/literal/types/void_type.rb
|
96
|
+
- lib/literal/value.rb
|
76
97
|
- lib/literal/version.rb
|
77
98
|
homepage: https://literal.fun
|
78
99
|
licenses:
|
@@ -97,7 +118,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
97
118
|
- !ruby/object:Gem::Version
|
98
119
|
version: '0'
|
99
120
|
requirements: []
|
100
|
-
rubygems_version: 3.6.
|
121
|
+
rubygems_version: 3.6.7
|
101
122
|
specification_version: 4
|
102
123
|
summary: Enums, properties, generics, structured objects and runtime type checking.
|
103
124
|
test_files: []
|
@@ -1,32 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
module ActiveRecord
|
4
|
-
class RelationType
|
5
|
-
def initialize(model_class)
|
6
|
-
unless Class === model_class && model_class < ActiveRecord::Base
|
7
|
-
raise Literal::TypeError.new(
|
8
|
-
context: Literal::TypeError::Context.new(
|
9
|
-
expected: ActiveRecord::Base, actual: model_class
|
10
|
-
)
|
11
|
-
)
|
12
|
-
end
|
13
|
-
|
14
|
-
@model_class = model_class
|
15
|
-
end
|
16
|
-
|
17
|
-
def inspect = "ActiveRecord::Relation(#{@model_class.name})"
|
18
|
-
|
19
|
-
def ===(value)
|
20
|
-
case value
|
21
|
-
when ActiveRecord::Relation, ActiveRecord::Associations::CollectionProxy, ActiveRecord::AssociationRelation
|
22
|
-
@model_class == value.model || value.model < @model_class
|
23
|
-
else
|
24
|
-
false
|
25
|
-
end
|
26
|
-
end
|
27
|
-
end
|
28
|
-
|
29
|
-
def self.Relation(model)
|
30
|
-
RelationType.new(model)
|
31
|
-
end
|
32
|
-
end
|
data/lib/literal/rails.rb
DELETED
@@ -1,10 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
require_relative "railtie"
|
4
|
-
require_relative "rails/patches/active_record"
|
5
|
-
|
6
|
-
module Literal::Rails
|
7
|
-
autoload :EnumType, "literal/rails/enum_type"
|
8
|
-
autoload :FlagsType, "literal/rails/flags_type"
|
9
|
-
autoload :EnumSerializer, "literal/rails/enum_serializer"
|
10
|
-
end
|