literal 1.4.0 → 1.5.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 8ee13d939895155fc3ce4ae1717036b565b0a59d7a4e87b50ea0a1390cc40bf3
4
- data.tar.gz: 42df47f2efce39eb14976d226645adb7a9dacc681948a71a9254ca44e19d8d1f
3
+ metadata.gz: e3b0596d3836316a8c9f2dc13b42707da7e4b158cdf17af864c22be88856e76c
4
+ data.tar.gz: be38909c66845eb4d09187803903f46cbe8d4392d0245d089aa7aec03c0ac7af
5
5
  SHA512:
6
- metadata.gz: f3a9b286744de95185baea476e8d7387238912aeb7f956eeef4e7b203bd0a55313885baaf6c5e71e27eb6d252961d44f850ede7e09abbc05c323c88a099be6f6
7
- data.tar.gz: f2cc33927ce452c94b3146dc7714cd9078cd532da5523afbbae5372ec2a5aa0319460db07525d9d7a5d709deb9ff929b804d0f3a86425f3d4844bf641a5a669b
6
+ metadata.gz: cfe44962b770aa87464249cd41540e2c26cce61a1b59292fca71b3d79331595483214e22eaa907e3b8453d49a75365219291d196854d843ec09ac1c4ed3b19dd
7
+ data.tar.gz: 3b6cd6cfeb4fd440c43385462ac3147606389f2afe046eab45cdd3cd9b626dc1fd6e7cdce39c4c5f9b060ea659b99b6ffb7a9ab930a5edb393a11e64f7234557
data/README.md CHANGED
@@ -1,3 +1,3 @@
1
1
  # A Literal Ruby Gem
2
2
 
3
- See the website for [documentation](https://literal.fun/docs).
3
+ See the website for [documentation](https://literal.fun/docs/).
data/lib/literal/array.rb CHANGED
@@ -32,6 +32,19 @@ class Literal::Array
32
32
  def inspect
33
33
  "Literal::Array(#{@type.inspect})"
34
34
  end
35
+
36
+ def coerce(value)
37
+ case value
38
+ when self
39
+ value
40
+ when Array
41
+ Literal::Array.new(value, type: @type)
42
+ end
43
+ end
44
+
45
+ def to_proc
46
+ method(:coerce).to_proc
47
+ end
35
48
  end
36
49
 
37
50
  include Enumerable
@@ -224,6 +237,10 @@ class Literal::Array
224
237
  @__value__.each(...)
225
238
  end
226
239
 
240
+ def each_index(...)
241
+ @__value__.each_index(...)
242
+ end
243
+
227
244
  def empty?
228
245
  @__value__.empty?
229
246
  end
@@ -276,7 +293,7 @@ class Literal::Array
276
293
  end
277
294
 
278
295
  def inspect
279
- @__value__.inspect
296
+ "Literal::Array(#{@__type__.inspect})#{@__value__.inspect}"
280
297
  end
281
298
 
282
299
  def intersect?(other)
@@ -497,6 +514,7 @@ class Literal::Array
497
514
 
498
515
  def select!(...)
499
516
  @__value__.select!(...)
517
+ self
500
518
  end
501
519
 
502
520
  def shift(...)
@@ -525,17 +543,50 @@ class Literal::Array
525
543
  self
526
544
  end
527
545
 
546
+ def sort_by!(...)
547
+ @__value__.sort_by!(...)
548
+ self
549
+ end
550
+
528
551
  def take(...)
529
552
  __with__(@__value__.take(...))
530
553
  end
531
554
 
555
+ def take_while(...)
556
+ __with__(@__value__.take_while(...))
557
+ end
558
+
559
+ def transpose
560
+ case @__type__
561
+ when Literal::Tuple::Generic
562
+ tuple_types = @__type__.types
563
+ new_array_types = tuple_types.map { |t| Literal::Array(t) }
564
+
565
+ Literal::Tuple(*new_array_types).new(
566
+ *new_array_types.each_with_index.map do |t, i|
567
+ t.new(
568
+ *@__value__.map { |it| it[i] }
569
+ )
570
+ end
571
+ )
572
+ when Literal::Array::Generic
573
+ __with__(
574
+ @__value__.map(&:to_a).transpose.map! { |it| @__type__.new(*it) }
575
+ )
576
+ else
577
+ @__value__.transpose
578
+ end
579
+ end
580
+
532
581
  def to_a
533
582
  @__value__.dup
534
583
  end
535
584
 
536
585
  alias_method :to_ary, :to_a
537
586
 
538
- alias_method :to_s, :inspect
587
+ def to_s
588
+ @__value__.to_s
589
+ end
539
590
 
540
591
  def uniq
541
592
  __with__(@__value__.uniq)
@@ -607,4 +658,75 @@ class Literal::Array
607
658
  def fetch(...)
608
659
  @__value__.fetch(...)
609
660
  end
661
+
662
+ def zip(*others)
663
+ other_types = others.map do |other|
664
+ case other
665
+ when Literal::Array
666
+ other.__type__
667
+ when Array
668
+ _Any?
669
+ else
670
+ raise ArgumentError
671
+ end
672
+ end
673
+
674
+ tuple = Literal::Tuple(
675
+ @__type__,
676
+ *other_types
677
+ )
678
+
679
+ my_length = length
680
+ max_length = [my_length, *others.map(&:length)].max
681
+
682
+ # Check we match the max length or our type is nilable
683
+ unless my_length == max_length || @__type__ === nil
684
+ raise ArgumentError.new(<<~MESSAGE)
685
+ The literal array could not be zipped becuase its type is not nilable and it has fewer items than the maximum number of items in the other arrays.
686
+
687
+ You can either make the type of this array nilable, or add more items so its length matches the others.
688
+
689
+ #{inspect}
690
+ MESSAGE
691
+ end
692
+
693
+ # Check others match the max length or their types is nilable
694
+ others.each_with_index do |other, index|
695
+ unless other.length == max_length || other_types[index] === nil
696
+ raise ArgumentError.new(<<~MESSAGE)
697
+ The literal array could not be zipped becuase its type is not nilable and it has fewer items than the maximum number of items in the other arrays.
698
+
699
+ You can either make the type of this array nilable, or add more items so its length matches the others.
700
+
701
+ #{inspect}
702
+ MESSAGE
703
+ end
704
+ end
705
+
706
+ i = 0
707
+
708
+ if block_given?
709
+ while i < max_length
710
+ yield tuple.new(
711
+ @__value__[i],
712
+ *others.map { |it| it[i] }
713
+ )
714
+ i += 1
715
+ end
716
+
717
+ nil
718
+ else
719
+ result_value = []
720
+
721
+ while i < max_length
722
+ result_value << tuple.new(
723
+ @__value__[i],
724
+ *others.map { |it| it[i] }
725
+ )
726
+ i += 1
727
+ end
728
+
729
+ __with__(result_value)
730
+ end
731
+ end
610
732
  end
data/lib/literal/enum.rb CHANGED
@@ -9,17 +9,19 @@ class Literal::Enum
9
9
  attr_reader :members
10
10
 
11
11
  def values = @values.keys
12
+ def names = @names
12
13
 
13
- def prop(name, type, kind = :keyword, reader: :public, default: nil)
14
- super(name, type, kind, reader:, writer: false, default:)
14
+ def prop(name, type, kind = :keyword, reader: :public, predicate: false, default: nil)
15
+ super(name, type, kind, reader:, writer: false, predicate:, default:)
15
16
  end
16
17
 
17
18
  def inherited(subclass)
18
19
  subclass.instance_exec do
19
20
  @values = {}
20
- @members = Set[]
21
+ @members = []
22
+ @indexes_definitions = {}
21
23
  @indexes = {}
22
- @index = {}
24
+ @names = {}
23
25
  end
24
26
 
25
27
  if RUBY_ENGINE != "truffleruby"
@@ -32,8 +34,16 @@ class Literal::Enum
32
34
  end
33
35
  end
34
36
 
37
+ def position_of(member)
38
+ coerce(member).__position__
39
+ end
40
+
41
+ def at_position(n)
42
+ @members[n]
43
+ end
44
+
35
45
  def index(name, type, unique: true, &block)
36
- @indexes[name] = [type, unique, block || name.to_proc]
46
+ @indexes_definitions[name] = [type, unique, block || name.to_proc]
37
47
  end
38
48
 
39
49
  def where(**kwargs)
@@ -43,11 +53,11 @@ class Literal::Enum
43
53
 
44
54
  key, value = kwargs.first
45
55
 
46
- types = @indexes.fetch(key)
56
+ types = @indexes_definitions.fetch(key)
47
57
  type = types.first
48
58
  Literal.check(actual: value, expected: type) { |c| raise NotImplementedError }
49
59
 
50
- @index.fetch(key)[value]
60
+ @indexes.fetch(key)[value]
51
61
  end
52
62
 
53
63
  def find_by(**kwargs)
@@ -57,15 +67,15 @@ class Literal::Enum
57
67
 
58
68
  key, value = kwargs.first
59
69
 
60
- unless @indexes.fetch(key)[1]
70
+ unless @indexes_definitions.fetch(key)[1]
61
71
  raise ArgumentError.new("You can only use `find_by` on unique indexes.")
62
72
  end
63
73
 
64
- unless (type = @indexes.fetch(key)[0]) === value
74
+ unless (type = @indexes_definitions.fetch(key)[0]) === value
65
75
  raise Literal::TypeError.expected(value, to_be_a: type)
66
76
  end
67
77
 
68
- @index.fetch(key)[value]&.first
78
+ @indexes.fetch(key)[value]&.first
69
79
  end
70
80
 
71
81
  def _load(data)
@@ -77,12 +87,8 @@ class Literal::Enum
77
87
  object = const_get(name)
78
88
 
79
89
  if self === object
80
- if @values.key?(object.value)
81
- raise ArgumentError.new("The value #{object.value} is already used by #{@values[object.value].name}.")
82
- end
83
- object.instance_variable_set(:@name, name)
84
- @values[object.value] = object
85
- @members << object
90
+ # object.instance_variable_set(:@name, name)
91
+ @names[object] = name
86
92
  define_method("#{name.to_s.gsub(/([^A-Z])([A-Z]+)/, '\1_\2').downcase}?") { self == object }
87
93
  object.freeze
88
94
  end
@@ -90,12 +96,21 @@ class Literal::Enum
90
96
 
91
97
  def new(*args, **kwargs, &block)
92
98
  raise ArgumentError if frozen?
99
+
93
100
  new_object = super(*args, **kwargs, &nil)
94
101
 
95
- if block
96
- new_object.instance_exec(&block)
102
+ if @values.key?(new_object.value)
103
+ raise ArgumentError.new("The value #{new_object.value} is already used by #{@values[new_object.value].name}.")
97
104
  end
98
105
 
106
+ @values[new_object.value] = new_object
107
+
108
+ new_object.instance_variable_set(:@__position__, @members.length)
109
+
110
+ @members << new_object
111
+
112
+ new_object.instance_exec(&block) if block
113
+
99
114
  new_object
100
115
  end
101
116
 
@@ -106,7 +121,7 @@ class Literal::Enum
106
121
  constants(false).each { |name| const_added(name) }
107
122
  end
108
123
 
109
- @indexes.each do |name, (type, unique, block)|
124
+ @indexes_definitions.each do |name, (type, unique, block)|
110
125
  index = @members.group_by(&block).freeze
111
126
 
112
127
  index.each do |key, values|
@@ -119,7 +134,7 @@ class Literal::Enum
119
134
  end
120
135
  end
121
136
 
122
- @index[name] = index
137
+ @indexes[name] = index
123
138
  end
124
139
 
125
140
  @values.freeze
@@ -149,8 +164,20 @@ class Literal::Enum
149
164
  case value
150
165
  when self
151
166
  value
167
+ when Symbol
168
+ self[value] || begin
169
+ const_get(value)
170
+ rescue NameError
171
+ raise ArgumentError.new(
172
+ "Can't coerce #{value.inspect} into a #{inspect}."
173
+ )
174
+ end
152
175
  else
153
- self[value]
176
+ self[value] || raise(
177
+ ArgumentError.new(
178
+ "Can't coerce #{value.inspect} into a #{inspect}."
179
+ )
180
+ )
154
181
  end
155
182
  end
156
183
 
@@ -167,20 +194,13 @@ class Literal::Enum
167
194
  end
168
195
  end
169
196
 
170
- def initialize(name, value, &block)
171
- @name = name
172
- @value = value
173
- instance_exec(&block) if block
174
- freeze
175
- end
176
-
177
- attr_reader :value
178
-
179
197
  def name
180
- "#{self.class.name}::#{@name}"
198
+ klass = self.class
199
+ "#{klass.name}::#{klass.names[self]}"
181
200
  end
182
201
 
183
202
  alias_method :inspect, :name
203
+ alias_method :to_s, :name
184
204
 
185
205
  def deconstruct
186
206
  [@value]
@@ -194,4 +214,27 @@ class Literal::Enum
194
214
  def _dump(level)
195
215
  Marshal.dump(@value)
196
216
  end
217
+
218
+ def <=>(other)
219
+ case other
220
+ when self.class
221
+ @__position__ <=> other.__position__
222
+ else
223
+ raise ArgumentError.new("Can't compare instances of #{other.class} to instances of #{self.class}")
224
+ end
225
+ end
226
+
227
+ def succ
228
+ self.class.members[@__position__ + 1]
229
+ end
230
+
231
+ def pred
232
+ if @__position__ <= 0
233
+ nil
234
+ else
235
+ self.class.members[@__position__ - 1]
236
+ end
237
+ end
238
+
239
+ attr_reader :__position__
197
240
  end
@@ -0,0 +1,7 @@
1
+ # frozen_string_literal: true
2
+
3
+ class Literal::Failure < Literal::Result
4
+ def initialize(error)
5
+ @error = error
6
+ end
7
+ end
data/lib/literal/null.rb CHANGED
@@ -5,5 +5,9 @@ module Literal::Null
5
5
  "Literal::Null"
6
6
  end
7
7
 
8
+ def self.===(value)
9
+ self == value
10
+ end
11
+
8
12
  freeze
9
13
  end
@@ -118,29 +118,18 @@ class Literal::Property
118
118
  "\n value\nend\n"
119
119
  end
120
120
 
121
- if Literal::TYPE_CHECKS_DISABLED
122
- def generate_writer_method(buffer = +"")
123
- buffer <<
124
- (@writer ? @writer.name : "public") <<
125
- " def " <<
126
- @name.name <<
127
- "=(value)\n" <<
128
- " @#{@name.name} = value\nend\n"
129
- end
130
- else # type checks are enabled
131
- def generate_writer_method(buffer = +"")
132
- buffer <<
133
- (@writer ? @writer.name : "public") <<
134
- " def " <<
135
- @name.name <<
136
- "=(value)\n" <<
137
- " self.class.literal_properties[:" <<
138
- @name.name <<
139
- "].check_writer(self, value)\n" <<
140
- " @" << @name.name << " = value\n" <<
141
- "rescue Literal::TypeError => error\n error.set_backtrace(caller(1))\n raise\n" <<
142
- "end\n"
143
- end
121
+ def generate_writer_method(buffer = +"")
122
+ buffer <<
123
+ (@writer ? @writer.name : "public") <<
124
+ " def " <<
125
+ @name.name <<
126
+ "=(value)\n" <<
127
+ " self.class.literal_properties[:" <<
128
+ @name.name <<
129
+ "].check_writer(self, value)\n" <<
130
+ " @" << @name.name << " = value\n" <<
131
+ "rescue Literal::TypeError => error\n error.set_backtrace(caller(1))\n raise\n" <<
132
+ "end\n"
144
133
  end
145
134
 
146
135
  def generate_predicate_method(buffer = +"")
@@ -171,10 +160,7 @@ class Literal::Property
171
160
  generate_initializer_coerce_property(buffer)
172
161
  end
173
162
 
174
- unless Literal::TYPE_CHECKS_DISABLED
175
- generate_initializer_check_type(buffer)
176
- end
177
-
163
+ generate_initializer_check_type(buffer)
178
164
  generate_initializer_assign_value(buffer)
179
165
  end
180
166
 
@@ -8,10 +8,10 @@ class Literal::Rails::EnumType < ActiveModel::Type::Value
8
8
 
9
9
  def cast(value)
10
10
  case value
11
- when @enum
12
- value
11
+ when nil
12
+ nil
13
13
  else
14
- deserialize(value)
14
+ @enum.coerce(value)
15
15
  end
16
16
  end
17
17
 
@@ -19,12 +19,8 @@ class Literal::Rails::EnumType < ActiveModel::Type::Value
19
19
  case value
20
20
  when nil
21
21
  nil
22
- when @enum
23
- value.value
24
22
  else
25
- raise Literal::ArgumentError.new(
26
- "Invalid value: #{value.inspect}. Expected an #{@enum.inspect}.",
27
- )
23
+ @enum.coerce(value).value
28
24
  end
29
25
  end
30
26
 
@@ -33,9 +29,7 @@ class Literal::Rails::EnumType < ActiveModel::Type::Value
33
29
  when nil
34
30
  nil
35
31
  else
36
- @enum[value] || raise(
37
- ArgumentError.new("Invalid value: #{value.inspect} for #{@enum}"),
38
- )
32
+ @enum.coerce(value)
39
33
  end
40
34
  end
41
35
  end
@@ -4,9 +4,10 @@ module ActiveRecord
4
4
  class RelationType
5
5
  def initialize(model_class)
6
6
  unless Class === model_class && model_class < ActiveRecord::Base
7
- raise Literal::TypeError.expected(
8
- model_class,
9
- to_be_a: ActiveRecord::Base,
7
+ raise Literal::TypeError.new(
8
+ context: Literal::TypeError::Context.new(
9
+ expected: ActiveRecord::Base, actual: model_class
10
+ )
10
11
  )
11
12
  end
12
13
 
@@ -2,20 +2,14 @@
2
2
 
3
3
  class Literal::Railtie < Rails::Railtie
4
4
  initializer "literal.register_literal_enum_type" do
5
- ActiveRecord::Type.register(:literal_enum) do |name, type:|
6
- Literal::Rails::EnumType.new(type)
7
- end
8
-
9
- ActiveRecord::Type.register(:literal_flags) do |name, type:|
10
- Literal::Rails::FlagsType.new(type)
11
- end
12
-
13
- ActiveModel::Type.register(:literal_enum) do |name, type:|
14
- Literal::Rails::EnumType.new(type)
15
- end
16
-
17
- ActiveModel::Type.register(:literal_flags) do |name, type:|
18
- Literal::Rails::FlagsType.new(type)
5
+ [ActiveRecord::Type, ActiveModel::Type].each do |registry|
6
+ registry.register(:literal_enum) do |name, type:|
7
+ Literal::Rails::EnumType.new(type)
8
+ end
9
+
10
+ registry.register(:literal_flags) do |name, type:|
11
+ Literal::Rails::FlagsType.new(type)
12
+ end
19
13
  end
20
14
  end
21
15
  end
@@ -0,0 +1,4 @@
1
+ # frozen_string_literal: true
2
+
3
+ class Literal::Result
4
+ end
@@ -0,0 +1,7 @@
1
+ # frozen_string_literal: true
2
+
3
+ class Literal::Success < Literal::Result
4
+ def initialize(value)
5
+ @value = value
6
+ end
7
+ end
@@ -54,6 +54,7 @@ Literal::TRANSFORMS = {
54
54
  to_str: String,
55
55
  upcase: String,
56
56
  valid_encoding?: Literal::Types::BooleanType::Instance,
57
+ to_i: Integer,
57
58
  },
58
59
  Numeric => {
59
60
  to_i: Integer,
data/lib/literal/tuple.rb CHANGED
@@ -56,5 +56,17 @@ class Literal::Tuple
56
56
  @__types__ = types
57
57
  end
58
58
 
59
+ def inspect
60
+ "Literal::Tuple(#{@__types__.map(&:inspect).join(', ')})#{@__values__.inspect}"
61
+ end
62
+
59
63
  attr_reader :__values__, :__types__
64
+
65
+ def ==(other)
66
+ (Literal::Tuple === other) && (@__values__ == other.__values__)
67
+ end
68
+
69
+ def [](index)
70
+ @__values__[index]
71
+ end
60
72
  end
@@ -25,14 +25,19 @@ class Literal::Types::ConstraintType
25
25
  i += 1
26
26
  end
27
27
 
28
+ result = true
29
+
28
30
  @property_constraints.each do |a, t|
29
- return false unless t === value.public_send(a)
31
+ # We intentionally don’t return early here becuase it triggers an allocation.
32
+ if result && !(t === value.public_send(a))
33
+ result = false
34
+ end
30
35
  rescue NoMethodError => e
31
36
  raise unless e.name == a && e.receiver == value
32
37
  return false
33
38
  end
34
39
 
35
- true
40
+ result
36
41
  end
37
42
 
38
43
  def >=(other)
data/lib/literal/types.rb CHANGED
@@ -103,6 +103,19 @@ module Literal::Types
103
103
  )
104
104
  end
105
105
 
106
+ # Matches if the value is a `Date` and matches the given constraints.
107
+ # If you don't need any constraints, use `Date` instead of `_Date`.
108
+ def _Date(...)
109
+ _Constraint(Date, ...)
110
+ end
111
+
112
+ # Nilable version of `_Date`
113
+ def _Date?(...)
114
+ _Nilable(
115
+ _Date(...)
116
+ )
117
+ end
118
+
106
119
  def _Deferred(...)
107
120
  DeferredType.new(...)
108
121
  end
@@ -324,6 +337,19 @@ module Literal::Types
324
337
  )
325
338
  end
326
339
 
340
+ # Matches if the value is a `Time` and matches the given constraints.
341
+ # If you don't need any constraints, use `Time` instead of `_Time`.
342
+ def _Time(...)
343
+ _Constraint(Time, ...)
344
+ end
345
+
346
+ # Nilable version of `_Time`
347
+ def _Time?(...)
348
+ _Nilable(
349
+ _Time(...)
350
+ )
351
+ end
352
+
327
353
  # Matches *"truthy"* values (anything except `nil` and `false`).
328
354
  def _Truthy
329
355
  TruthyType::Instance
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Literal
4
- VERSION = "1.4.0"
4
+ VERSION = "1.5.0"
5
5
  end
data/lib/literal.rb CHANGED
@@ -1,8 +1,6 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Literal
4
- TYPE_CHECKS_DISABLED = ENV["LITERAL_TYPE_CHECKS"] == "false"
5
-
6
4
  autoload :Array, "literal/array"
7
5
  autoload :Data, "literal/data"
8
6
  autoload :DataProperty, "literal/data_property"
@@ -33,7 +31,7 @@ module Literal
33
31
 
34
32
  def self.Enum(type)
35
33
  Class.new(Literal::Enum) do
36
- prop :value, type, :positional
34
+ prop :value, type, :positional, reader: :public
37
35
  end
38
36
  end
39
37
 
metadata CHANGED
@@ -1,14 +1,13 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: literal
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.4.0
4
+ version: 1.5.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Joel Drapper
8
- autorequire:
9
8
  bindir: bin
10
9
  cert_chain: []
11
- date: 2024-12-10 00:00:00.000000000 Z
10
+ date: 2025-01-17 00:00:00.000000000 Z
12
11
  dependencies: []
13
12
  description: Enums, properties, generics, structured objects and runtime type checking.
14
13
  email:
@@ -28,6 +27,7 @@ files:
28
27
  - lib/literal/errors/argument_error.rb
29
28
  - lib/literal/errors/error.rb
30
29
  - lib/literal/errors/type_error.rb
30
+ - lib/literal/failure.rb
31
31
  - lib/literal/flags.rb
32
32
  - lib/literal/hash.rb
33
33
  - lib/literal/null.rb
@@ -42,8 +42,10 @@ files:
42
42
  - lib/literal/rails/flags_type.rb
43
43
  - lib/literal/rails/patches/active_record.rb
44
44
  - lib/literal/railtie.rb
45
+ - lib/literal/result.rb
45
46
  - lib/literal/set.rb
46
47
  - lib/literal/struct.rb
48
+ - lib/literal/success.rb
47
49
  - lib/literal/transforms.rb
48
50
  - lib/literal/tuple.rb
49
51
  - lib/literal/type.rb
@@ -81,7 +83,6 @@ metadata:
81
83
  changelog_uri: https://github.com/joeldrapper/literal/releases
82
84
  funding_uri: https://github.com/sponsors/joeldrapper
83
85
  rubygems_mfa_required: 'true'
84
- post_install_message:
85
86
  rdoc_options: []
86
87
  require_paths:
87
88
  - lib
@@ -96,8 +97,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
96
97
  - !ruby/object:Gem::Version
97
98
  version: '0'
98
99
  requirements: []
99
- rubygems_version: 3.5.18
100
- signing_key:
100
+ rubygems_version: 3.6.2
101
101
  specification_version: 4
102
102
  summary: Enums, properties, generics, structured objects and runtime type checking.
103
103
  test_files: []