literal 1.3.0 → 1.4.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: 9721432521677aa431dda4e94240521a54a8ac21ece07fef009393544d19214d
4
- data.tar.gz: c5b41c95f4c24ff4fad28869bf61ff93174118a2d3e5890928961b382bf9b285
3
+ metadata.gz: 8ee13d939895155fc3ce4ae1717036b565b0a59d7a4e87b50ea0a1390cc40bf3
4
+ data.tar.gz: 42df47f2efce39eb14976d226645adb7a9dacc681948a71a9254ca44e19d8d1f
5
5
  SHA512:
6
- metadata.gz: 715a03576aed152e2fd5737236eb227dd98da9f02b421a14722395a3b9992dc667302574490955f0f9d81192dc5f64f793d916b196bc4509244afad5daa8a37b
7
- data.tar.gz: 475df2645d537e5c8151ba6431e1469fdcfdd1a80d766489bfa00b135f3c3e57a86b0c09c7e6738c6033609a69864a596660a0b5498bd6762e314588a67bac35
6
+ metadata.gz: f3a9b286744de95185baea476e8d7387238912aeb7f956eeef4e7b203bd0a55313885baaf6c5e71e27eb6d252961d44f850ede7e09abbc05c323c88a099be6f6
7
+ data.tar.gz: f2cc33927ce452c94b3146dc7714cd9078cd532da5523afbbae5372ec2a5aa0319460db07525d9d7a5d709deb9ff929b804d0f3a86425f3d4844bf641a5a669b
data/lib/literal/array.rb CHANGED
@@ -23,7 +23,7 @@ class Literal::Array
23
23
  def >=(other)
24
24
  case other
25
25
  when Literal::Array::Generic
26
- @type >= other.type
26
+ Literal.subtype?(other.type, of: @type)
27
27
  else
28
28
  false
29
29
  end
@@ -256,6 +256,14 @@ class Literal::Array
256
256
  super
257
257
  end
258
258
 
259
+ def hash
260
+ [self.class, @__value__].hash
261
+ end
262
+
263
+ def include?(...)
264
+ @__value__.include?(...)
265
+ end
266
+
259
267
  alias_method :index, :find_index
260
268
 
261
269
  def insert(index, *value)
@@ -389,10 +397,44 @@ class Literal::Array
389
397
  @__value__.one?(...)
390
398
  end
391
399
 
400
+ def pack(...)
401
+ @__value__.pack(...)
402
+ end
403
+
392
404
  def pop(...)
393
405
  @__value__.pop(...)
394
406
  end
395
407
 
408
+ def product(*others, &)
409
+ if block_given?
410
+ @__value__.product(
411
+ *others.map do |other|
412
+ case other
413
+ when Array
414
+ other
415
+ when Literal::Array
416
+ other.__value__
417
+ end
418
+ end, &
419
+ )
420
+
421
+ self
422
+ elsif others.all?(Literal::Array)
423
+ tuple_type = Literal::Tuple(
424
+ @__type__,
425
+ *others.map(&:__type__)
426
+ )
427
+
428
+ values = @__value__.product(*others.map(&:__value__)).map do |tuple_values|
429
+ tuple_type.new(*tuple_values)
430
+ end
431
+
432
+ Literal::Array(tuple_type).new(*values)
433
+ else
434
+ @__value__.product(*others)
435
+ end
436
+ end
437
+
396
438
  def push(*value)
397
439
  Literal.check(actual: value, expected: _Array(@__type__)) do |c|
398
440
  c.fill_receiver(receiver: self, method: "#push")
@@ -434,6 +476,17 @@ class Literal::Array
434
476
  self
435
477
  end
436
478
 
479
+ alias_method :initialize_copy, :replace
480
+
481
+ def rotate(...)
482
+ __with__(@__value__.rotate(...))
483
+ end
484
+
485
+ def rotate!(...)
486
+ @__value__.rotate!(...)
487
+ self
488
+ end
489
+
437
490
  def sample(...)
438
491
  @__value__.sample(...)
439
492
  end
@@ -450,6 +503,15 @@ class Literal::Array
450
503
  @__value__.shift(...)
451
504
  end
452
505
 
506
+ def shuffle(...)
507
+ __with__(@__value__.shuffle(...))
508
+ end
509
+
510
+ def shuffle!(...)
511
+ @__value__.shuffle!(...)
512
+ self
513
+ end
514
+
453
515
  def size(...)
454
516
  @__value__.size(...)
455
517
  end
@@ -463,6 +525,10 @@ class Literal::Array
463
525
  self
464
526
  end
465
527
 
528
+ def take(...)
529
+ __with__(@__value__.take(...))
530
+ end
531
+
466
532
  def to_a
467
533
  @__value__.dup
468
534
  end
data/lib/literal/data.rb CHANGED
@@ -9,17 +9,11 @@ class Literal::Data < Literal::DataStructure
9
9
  def literal_properties
10
10
  return @literal_properties if defined?(@literal_properties)
11
11
 
12
- if superclass.is_a?(Literal::Data)
12
+ if superclass < Literal::Data
13
13
  @literal_properties = superclass.literal_properties.dup
14
14
  else
15
15
  @literal_properties = Literal::Properties::DataSchema.new
16
16
  end
17
17
  end
18
-
19
- private
20
-
21
- def __literal_property_class__
22
- Literal::DataProperty
23
- end
24
18
  end
25
19
  end
data/lib/literal/enum.rb CHANGED
@@ -77,6 +77,9 @@ class Literal::Enum
77
77
  object = const_get(name)
78
78
 
79
79
  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
80
83
  object.instance_variable_set(:@name, name)
81
84
  @values[object.value] = object
82
85
  @members << object
@@ -155,8 +158,12 @@ class Literal::Enum
155
158
  method(:coerce).to_proc
156
159
  end
157
160
 
158
- def to_h(*args)
159
- @values.dup
161
+ def to_h(&)
162
+ if block_given?
163
+ @members.to_h(&)
164
+ else
165
+ @members.to_h { |it| [it, it.value] }
166
+ end
160
167
  end
161
168
  end
162
169
 
@@ -157,7 +157,7 @@ class Literal::Property
157
157
 
158
158
  def generate_initializer_handle_property(buffer = +"")
159
159
  buffer << " # " << @name.name << "\n" <<
160
- " property = __properties__[:" << @name.name << "]\n"
160
+ " __property__ = __properties__[:" << @name.name << "]\n"
161
161
 
162
162
  if @kind == :keyword && ruby_keyword?
163
163
  generate_initializer_escape_keyword(buffer)
@@ -191,7 +191,7 @@ class Literal::Property
191
191
  def generate_initializer_coerce_property(buffer = +"")
192
192
  buffer <<
193
193
  escaped_name <<
194
- "= property.coerce(" <<
194
+ "= __property__.coerce(" <<
195
195
  escaped_name <<
196
196
  ", context: self)\n"
197
197
  end
@@ -204,12 +204,12 @@ class Literal::Property
204
204
  escaped_name <<
205
205
  "\n " <<
206
206
  escaped_name <<
207
- " = property.default_value\n end\n"
207
+ " = __property__.default_value\n end\n"
208
208
  end
209
209
 
210
210
  def generate_initializer_check_type(buffer = +"")
211
211
  buffer <<
212
- " property.check_initializer(self, " << escaped_name << ")\n"
212
+ " __property__.check_initializer(self, " << escaped_name << ")\n"
213
213
  end
214
214
 
215
215
  def generate_initializer_assign_value(buffer = +"")
@@ -0,0 +1,60 @@
1
+ # frozen_string_literal: true
2
+
3
+ class Literal::Tuple
4
+ class Generic
5
+ include Literal::Type
6
+
7
+ def initialize(*types)
8
+ @types = types
9
+ end
10
+
11
+ attr_reader :types
12
+
13
+ def ===(other)
14
+ return false unless Literal::Tuple === other
15
+ types = @types
16
+ other_types = other.__types__
17
+
18
+ return false unless types.size == other_types.size
19
+
20
+ i, len = 0, types.size
21
+ while i < len
22
+ return false unless Literal.subtype?(other_types[i], of: types[i])
23
+ i += 1
24
+ end
25
+
26
+ true
27
+ end
28
+
29
+ def >=(other)
30
+ case other
31
+ when Literal::Tuple::Generic
32
+ types = @types
33
+ other_types = other.types
34
+
35
+ return false unless types.size == other_types.size
36
+
37
+ i, len = 0, types.size
38
+ while i < len
39
+ return false unless Literal.subtype?(other_types[i], of: types[i])
40
+ i += 1
41
+ end
42
+
43
+ true
44
+ else
45
+ false
46
+ end
47
+ end
48
+
49
+ def new(*values)
50
+ Literal::Tuple.new(values, @types)
51
+ end
52
+ end
53
+
54
+ def initialize(values, types)
55
+ @__values__ = values
56
+ @__types__ = types
57
+ end
58
+
59
+ attr_reader :__values__, :__types__
60
+ end
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Literal
4
- VERSION = "1.3.0"
4
+ VERSION = "1.4.0"
5
5
  end
data/lib/literal.rb CHANGED
@@ -22,6 +22,7 @@ module Literal
22
22
  autoload :Struct, "literal/struct"
23
23
  autoload :Type, "literal/type"
24
24
  autoload :Types, "literal/types"
25
+ autoload :Tuple, "literal/tuple"
25
26
 
26
27
  # Errors
27
28
  autoload :Error, "literal/errors/error"
@@ -48,6 +49,10 @@ module Literal
48
49
  Literal::Hash::Generic.new(key_type, value_type)
49
50
  end
50
51
 
52
+ def self.Tuple(*types)
53
+ Literal::Tuple::Generic.new(*types)
54
+ end
55
+
51
56
  def self.check(actual:, expected:)
52
57
  if expected === actual
53
58
  true
metadata CHANGED
@@ -1,16 +1,16 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: literal
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.3.0
4
+ version: 1.4.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-29 00:00:00.000000000 Z
11
+ date: 2024-12-10 00:00:00.000000000 Z
12
12
  dependencies: []
13
- description: A literal Ruby gem.
13
+ description: Enums, properties, generics, structured objects and runtime type checking.
14
14
  email:
15
15
  - joel@drapper.me
16
16
  executables: []
@@ -22,7 +22,6 @@ files:
22
22
  - lib/literal.rb
23
23
  - lib/literal/array.rb
24
24
  - lib/literal/data.rb
25
- - lib/literal/data_property.rb
26
25
  - lib/literal/data_structure.rb
27
26
  - lib/literal/deferred_type.rb
28
27
  - lib/literal/enum.rb
@@ -46,6 +45,7 @@ files:
46
45
  - lib/literal/set.rb
47
46
  - lib/literal/struct.rb
48
47
  - lib/literal/transforms.rb
48
+ - lib/literal/tuple.rb
49
49
  - lib/literal/type.rb
50
50
  - lib/literal/types.rb
51
51
  - lib/literal/types/any_type.rb
@@ -78,7 +78,7 @@ licenses:
78
78
  metadata:
79
79
  homepage_uri: https://literal.fun
80
80
  source_code_uri: https://github.com/joeldrapper/literal
81
- changelog_uri: https://github.com/joeldrapper/literal/blob/main/CHANGELOG.md
81
+ changelog_uri: https://github.com/joeldrapper/literal/releases
82
82
  funding_uri: https://github.com/sponsors/joeldrapper
83
83
  rubygems_mfa_required: 'true'
84
84
  post_install_message:
@@ -1,16 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- class Literal::DataProperty < Literal::Property
4
- def generate_initializer_assign_value(buffer = +"")
5
- buffer <<
6
- "@" <<
7
- @name.name <<
8
- " = " <<
9
- escaped_name <<
10
- ".frozen? ? " <<
11
- escaped_name <<
12
- " : " <<
13
- escaped_name <<
14
- ".dup.freeze\n"
15
- end
16
- end