ruby-ulid 0.9.0 → 1.0.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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 6c0ca476ab05b4b53ce593e893ffdfd6aa72b3c08563116b95f5a22f43a7926b
4
- data.tar.gz: 7454acd393c8df299696d2907a71f994643dacc45103e2874561d186e1fa85c5
3
+ metadata.gz: 3b0c26b06cd815f96d9ffc78836ceb69ed4677a4f5acfac6e15c016e093e0d18
4
+ data.tar.gz: '09acd9841d6ee33b87687dd12a7912ef262c9cad3d85b37db6215912048b36e1'
5
5
  SHA512:
6
- metadata.gz: bfe19e20452a12edd7472ddaf3b9583d2eaa5640e03a081621c35bcfdf218f9ccf5d7c7625b0850312447f61c0592796d333aa4578a6c2f0281e6ff4e8392efd
7
- data.tar.gz: cdd8dba77214852ea70d07a137f75098558097db686a4409dd14e611d533de33f4c510b9a38ee232e918dd0aae6b028f19a4dd7312ac42172890d726091f282b
6
+ metadata.gz: bd7f5fe5b75a1d8f91d5a016a81a6a132debaf4247f075918ad4a52dfc96a6bef937ef433663d71610a008621eac3e5c997f35f15249c8030bbc095357882a78
7
+ data.tar.gz: d444cfac8c9b66ce72850236a7cd7367873a3ea8c51a6c67bc5d34bb0a549fb4192c120cbaa13ba92b4e4c49ccc45fe2cf7a3a6a01882daee287428ca29dd597
data/README.md CHANGED
@@ -3,6 +3,9 @@
3
3
  [![Build Status](https://github.com/kachick/ruby-ulid/actions/workflows/ci.yml/badge.svg?branch=main)](https://github.com/kachick/ruby-ulid/actions/workflows/ci.yml?query=branch%3Amain)
4
4
  [![Gem Version](https://badge.fury.io/rb/ruby-ulid.svg)](http://badge.fury.io/rb/ruby-ulid)
5
5
 
6
+ This gem is in maintenance mode, I have no plan to add new features.\
7
+ The reason is UUID v7 has been accepted in [IETF](https://www.rfc-editor.org/rfc/rfc9562.html) and [ruby's securerandom](https://github.com/ruby/securerandom/pull/19). See [UUID section](#uuid) for detail.
8
+
6
9
  ## Overview
7
10
 
8
11
  [ulid/spec](https://github.com/ulid/spec) defines some useful features.\
@@ -38,12 +41,12 @@ Instead, herein is proposed ULID:
38
41
 
39
42
  ### Install
40
43
 
41
- Tested only in the last 2 Rubies. So you need Ruby 3.2 or higher.
44
+ Tested only in the Ruby 4.
42
45
 
43
46
  Add this line to your `Gemfile`.
44
47
 
45
48
  ```ruby
46
- gem('ruby-ulid', '~> 0.9.0')
49
+ gem('ruby-ulid', '~> 1.0.0')
47
50
  ```
48
51
 
49
52
  And load it.
@@ -53,7 +56,7 @@ require 'ulid'
53
56
  ```
54
57
 
55
58
  NOTE: This README contains information about the development version.\
56
- If you would like to see released version's one. [Look at the ref](https://github.com/kachick/ruby-ulid/tree/v0.9.0).
59
+ If you would like to see released version's one. [Look at the ref](https://github.com/kachick/ruby-ulid/tree/v1.0.0).
57
60
 
58
61
  In [Nix](https://nixos.org/), you can skip the installation steps for both ruby and ruby-ulid to try.
59
62
 
@@ -378,44 +381,49 @@ ULID.parse_variant_format('01G70Y0Y7G-ZLXWDIREXERGSDoD') #=> ULID(2022-07-03 02:
378
381
 
379
382
  #### UUID
380
383
 
381
- Both ULID and UUID are 128-bit IDs. But with different specs. Especially UUID has some versions probably UUIDv4.
384
+ Both ULID and UUID are 128-bit IDs. But with different specs. Especially, UUID has some versions, for example, UUIDv4 and UUIDv7.
382
385
 
383
- All UUIDv4s can be converted to ULID, but this will not have the correct "timestamp".\
384
- Most ULIDs cannot be converted to UUIDv4 while maintaining reversibility, because UUIDv4 requires version and variants in the fields.
386
+ All UUIDs can be converted to ULID, but only [new versions](https://datatracker.ietf.org/doc/rfc9562/) have a correct "timestamp".\
387
+ Most ULIDs cannot be converted to UUID while maintaining reversibility, because UUID requires version and variants in the fields.
385
388
 
386
389
  See also [ulid/spec#64](https://github.com/ulid/spec/issues/64) for further detail.
387
390
 
388
- For now, this gem provides 4 methods for UUIDs.
391
+ For now, this gem provides some methods for UUIDs.
389
392
 
390
393
  - Reversibility is preferred: `ULID.from_uuidish`, `ULID.to_uuidish`
391
- - Prefer UUIDv4 specification: `ULID.from_uuidv4`, `ULID.to_uuidv4`
394
+ - Prefer variants specification: `ULID.from_uuid_v4`, `ULID.from_uuid_v7`, `ULID.to_uuid_v4`, `ULID.to_uuid_v7`
392
395
 
393
396
  ```ruby
394
- # All UUIDv4 IDs can be reversible even if converted to ULID
395
- uuid = SecureRandom.uuid
396
- ULID.from_uuidish(uuid) == ULID.from_uuidv4(uuid) #=> true
397
- ULID.from_uuidish(uuid).to_uuidish == ULID.from_uuidv4(uuid).to_uuidv4 #=> true
397
+ # All UUIDv4 and UUIDv7 IDs can be reversible even if converted to ULID
398
+ uuid_v4 = SecureRandom.uuid_v4
399
+ ULID.from_uuidish(uuid_v4) == ULID.from_uuid_v4(uuid_v4) #=> true
400
+ ULID.from_uuidish(uuid_v4).to_uuidish == ULID.from_uuid_v4(uuid_v4).to_uuid_v4 #=> true
401
+
402
+ # v4 does not have timestamp, v7 has it.
403
+
404
+ ULID.from_uuid_v4(SecureRandom.uuid_v4).to_time
405
+ # 'f80b3f53-043a-4298-a674-cd83a7fd5d22' => 10612-05-19 16:58:53.882 UTC
398
406
 
399
- # But most ULIDs cannot be converted to UUIDv4
407
+ ULID.from_uuid_v7(SecureRandom.uuid_v7).to_time
408
+ # '01946f9e-bf58-7be3-8fd4-4606606b05aa' => 2025-01-16 14:57:42.232 UTC
409
+ # ULID is officially defined milliseconds precision for the spec. So omit the nanoseconds precisions even if the UUID v7 ID was generated with extra_timestamp_bits >= 1.
410
+
411
+ # However most ULIDs cannot be converted to versioned UUID
400
412
  ulid = ULID.parse('01F4A5Y1YAQCYAYCTC7GRMJ9AA')
401
- ulid.to_uuidv4 #=> ULID::IrreversibleUUIDError
413
+ ulid.to_uuid_v4 #=> ULID::IrreversibleUUIDError
402
414
  # So 2 ways to get substitute strings that might satisfy the use case
403
- ulid.to_uuidv4(force: true) #=> "0179145f-07ca-4b3c-af33-4c3c3149254a" this cannot be reverse to source ULID
404
- ulid == ULID.from_uuidv4(ulid.to_uuidv4(force: true)) #=> false
415
+ ulid.to_uuid_v4(force: true) #=> "0179145f-07ca-4b3c-af33-4c3c3149254a" this cannot be reverse to source ULID
416
+ ulid == ULID.from_uuid_v4(ulid.to_uuid_v4(force: true)) #=> false
405
417
  ulid.to_uuidish #=> "0179145f-07ca-bb3c-af33-4c3c3149254a" does not satisfy UUIDv4 spec
406
418
  ulid == ULID.from_uuidish(ulid.to_uuidish) #=> true
407
419
 
408
420
  # Seeing boundary IDs makes it easier to understand
409
421
  ULID.min.to_uuidish #=> "00000000-0000-0000-0000-000000000000"
410
- ULID.min.to_uuidv4(force: true) #=> "00000000-0000-4000-8000-000000000000"
422
+ ULID.min.to_uuid_v4(force: true) #=> "00000000-0000-4000-8000-000000000000"
411
423
  ULID.max.to_uuidish #=> "ffffffff-ffff-ffff-ffff-ffffffffffff"
412
- ULID.max.to_uuidv4(force: true) #=> "ffffffff-ffff-4fff-bfff-ffffffffffff"
424
+ ULID.max.to_uuid_v4(force: true) #=> "ffffffff-ffff-4fff-bfff-ffffffffffff"
413
425
  ```
414
426
 
415
- [UUIDv6, UUIDv7, UUIDv8](https://www.ietf.org/archive/id/draft-ietf-uuidrev-rfc4122bis-02.html) are other candidates for sortable and randomness ID.\
416
- Latest [ruby/securerandom merged the UUIDv7 generator](https://github.com/ruby/securerandom/pull/19).\
417
- See [tracker](https://bugs.ruby-lang.org/issues/19735) for further detail.
418
-
419
427
  ## Migration from other gems
420
428
 
421
429
  See [wiki page for gem migration](https://github.com/kachick/ruby-ulid/wiki/Gem-migration).
data/lib/ulid/utils.rb CHANGED
@@ -7,20 +7,16 @@
7
7
  require('securerandom')
8
8
 
9
9
  class ULID
10
- # @note I don't have confidence for the naming of `Utils`. However some standard libraries have same name.
11
- # https://github.com/ruby/webrick/blob/14612a7540fdd7373344461851c4bfff64985b3e/lib/webrick/utils.rb#L17
12
- # https://docs.ruby-lang.org/ja/latest/class/ERB=3a=3aUtil.html
13
- # https://github.com/ruby/rss/blob/af1c3c9c9630ec0a48abec48ed1ef348ba82aa13/lib/rss/utils.rb#L9
14
10
  module Utils
15
11
  # @return [Integer]
16
12
  def self.current_milliseconds
17
- milliseconds_from_time(Time.now)
18
- end
19
-
20
- # @param [Time] time
21
- # @return [Integer]
22
- def self.milliseconds_from_time(time)
23
- (time.to_r * 1000).to_i
13
+ # There are different recommendations for this featrure with the accuracy and other context
14
+ # At here, I prefer to adjust with Ruby UUID v7 imeplementation and respect monotonicity use-case
15
+ # https://github.com/ruby/securerandom/pull/19/files#diff-cad52e37612706fe31d85599bb8bc789e90fd382f091ed31fdd036119af3e5cdR252
16
+ # Other resources
17
+ # - https://blog.dnsimple.com/2018/03/elapsed-time-with-ruby-the-right-way/
18
+ # - https://github.com/ruby/ruby/blob/5df20ab0b49b55c9cf858879f3e6e30cc3dcd803/process.c#L8131
19
+ Process.clock_gettime(Process::CLOCK_REALTIME, :millisecond)
24
20
  end
25
21
 
26
22
  # @param [Time, Integer] moment
@@ -30,7 +26,7 @@ class ULID
30
26
  when Integer
31
27
  moment
32
28
  when Time
33
- milliseconds_from_time(moment)
29
+ (moment.to_r * 1000).to_i
34
30
  else
35
31
  raise(ArgumentError, '`moment` should be a `Time` or `Integer as milliseconds`')
36
32
  end
@@ -19,13 +19,13 @@ class ULID
19
19
  end
20
20
  end
21
21
 
22
- def self.forced_v4_from_octets(octets)
22
+ def self.forced_version_from_octets(octets, mask:)
23
23
  case octets.pack('C*').unpack('NnnnnN')
24
24
  in [Integer => time_low, Integer => time_mid, Integer => time_hi_and_version, Integer => clock_seq_hi_and_res, Integer => clk_seq_low, Integer => node]
25
25
  new(
26
26
  time_low:,
27
27
  time_mid:,
28
- time_hi_and_version: (time_hi_and_version & 0x0fff) | 0x4000,
28
+ time_hi_and_version: (time_hi_and_version & 0x0fff) | mask,
29
29
  clock_seq_hi_and_res: (clock_seq_hi_and_res & 0x3fff) | 0x8000,
30
30
  clk_seq_low:,
31
31
  node:
data/lib/ulid/uuid.rb CHANGED
@@ -13,6 +13,7 @@ class ULID
13
13
  BASE_PATTERN = /\A[0-9A-F]{8}-[0-9A-F]{4}-[0-9A-F]{4}-[0-9A-F]{4}-[0-9A-F]{12}\z/i
14
14
  # Imported from https://stackoverflow.com/a/38191104/1212807, thank you!
15
15
  V4_PATTERN = /\A[0-9A-F]{8}-[0-9A-F]{4}-4[0-9A-F]{3}-[89AB][0-9A-F]{3}-[0-9A-F]{12}\z/i
16
+ V7_PATTERN = /\A[0-9A-F]{8}-[0-9A-F]{4}-7[0-9A-F]{3}-[89AB][0-9A-F]{3}-[0-9A-F]{12}\z/i
16
17
 
17
18
  def self.parse_any_to_int(uuidish)
18
19
  encoded = String.try_convert(uuidish)
@@ -38,6 +39,18 @@ class ULID
38
39
 
39
40
  parse_any_to_int(encoded)
40
41
  end
42
+
43
+ def self.parse_v7_to_int(uuid)
44
+ encoded = String.try_convert(uuid)
45
+ raise(ArgumentError, 'should pass a string for UUID parser') unless encoded
46
+
47
+ prefix_trimmed = encoded.delete_prefix('urn:uuid:')
48
+ unless V7_PATTERN.match?(prefix_trimmed)
49
+ raise(ParserError, "given `#{encoded}` does not match to `#{V7_PATTERN.inspect}`")
50
+ end
51
+
52
+ parse_any_to_int(encoded)
53
+ end
41
54
  end
42
55
 
43
56
  Ractor.make_shareable(UUID)
data/lib/ulid/version.rb CHANGED
@@ -3,5 +3,5 @@
3
3
  # shareable_constant_value: literal
4
4
 
5
5
  class ULID
6
- VERSION = '0.9.0'
6
+ VERSION = '1.0.0'
7
7
  end
data/lib/ulid.rb CHANGED
@@ -40,7 +40,7 @@ class ULID
40
40
  SCANNING_PATTERN = /\b[0-7][#{CrockfordBase32::ENCODING_STRING}]{#{TIMESTAMP_ENCODED_LENGTH - 1}}[#{CrockfordBase32::ENCODING_STRING}]{#{RANDOMNESS_ENCODED_LENGTH}}\b/i
41
41
 
42
42
  # Similar as Time#inspect since Ruby 2.7, however it is NOT same.
43
- # Time#inspect trancates needless digits. Keeping full milliseconds with "%3N" will fit for ULID.
43
+ # Time#inspect truncates needless digits. Keeping full milliseconds with "%3N" will fit for ULID.
44
44
  # @see https://bugs.ruby-lang.org/issues/15958
45
45
  # @see https://github.com/ruby/ruby/blob/744d17ff6c33b09334508e8110007ea2a82252f5/time.c#L4026-L4078
46
46
  TIME_FORMAT_IN_INSPECT = '%Y-%m-%d %H:%M:%S.%3N %Z'
@@ -351,10 +351,17 @@ class ULID
351
351
  # @param [String, #to_str] uuid
352
352
  # @return [ULID]
353
353
  # @raise [ParserError] if the given format is not correct for UUIDv4 specs
354
- def self.from_uuidv4(uuid)
354
+ def self.from_uuid_v4(uuid)
355
355
  from_integer(UUID.parse_v4_to_int(uuid))
356
356
  end
357
357
 
358
+ # @param [String, #to_str] uuid
359
+ # @return [ULID]
360
+ # @raise [ParserError] if the given format is not correct for UUIDv4 specs
361
+ def self.from_uuid_v7(uuid)
362
+ from_integer(UUID.parse_v7_to_int(uuid))
363
+ end
364
+
358
365
  attr_reader(:milliseconds, :entropy, :encoded)
359
366
  protected(:encoded)
360
367
 
@@ -510,8 +517,8 @@ class ULID
510
517
  self
511
518
  end
512
519
 
513
- # Generate a UUID-like string that does not set the version and variants field.
514
- # It means wrong in UUIDv4 spec, but reversible
520
+ # Generate a UUID-like string that does not touch the version and variants field.
521
+ # It means basically wrong in UUID specs, but reversible
515
522
  #
516
523
  # @return [String]
517
524
  def to_uuidish
@@ -526,8 +533,8 @@ class ULID
526
533
  # @see https://github.com/kachick/ruby-ulid/issues/76
527
534
  # @param [bool] force
528
535
  # @return [String]
529
- def to_uuidv4(force: false)
530
- v4 = UUID::Fields.forced_v4_from_octets(octets)
536
+ def to_uuid_v4(force: false)
537
+ v4 = UUID::Fields.forced_version_from_octets(octets, mask: 0x4000)
531
538
  unless force
532
539
  uuidish = UUID::Fields.raw_from_octets(octets)
533
540
  raise(IrreversibleUUIDError) unless uuidish == v4
@@ -536,6 +543,19 @@ class ULID
536
543
  v4.to_s.freeze
537
544
  end
538
545
 
546
+ # @see [#to_uuid_v4] and https://datatracker.ietf.org/doc/rfc9562/
547
+ # @param [bool] force
548
+ # @return [String]
549
+ def to_uuid_v7(force: false)
550
+ v7 = UUID::Fields.forced_version_from_octets(octets, mask: 0x7000)
551
+ unless force
552
+ uuidish = UUID::Fields.raw_from_octets(octets)
553
+ raise(IrreversibleUUIDError) unless uuidish == v7
554
+ end
555
+
556
+ v7.to_s.freeze
557
+ end
558
+
539
559
  # @return [ULID]
540
560
  def dup
541
561
  super.freeze
data/sig/ulid.rbs CHANGED
@@ -37,9 +37,11 @@ class ULID < Object
37
37
  module UUID
38
38
  BASE_PATTERN: Regexp
39
39
  V4_PATTERN: Regexp
40
+ V7_PATTERN: Regexp
40
41
 
41
42
  def self.parse_any_to_int: (String) -> Integer
42
43
  def self.parse_v4_to_int: (String) -> Integer
44
+ def self.parse_v7_to_int: (String) -> Integer
43
45
 
44
46
  class Fields
45
47
  attr_reader time_low: Integer
@@ -49,7 +51,7 @@ class ULID < Object
49
51
  attr_reader clk_seq_low: Integer
50
52
  attr_reader node: Integer
51
53
  def self.raw_from_octets: (octets) -> Fields
52
- def self.forced_v4_from_octets: (octets) -> Fields
54
+ def self.forced_version_from_octets: (octets, mask: Integer) -> Fields
53
55
 
54
56
  def deconstruct: -> Array[Integer]
55
57
 
@@ -69,8 +71,6 @@ class ULID < Object
69
71
 
70
72
  def self.reasonable_entropy: -> Integer
71
73
 
72
- def self.milliseconds_from_time: (Time time) -> milliseconds
73
-
74
74
  def self.safe_get_class_name: (untyped object) -> String
75
75
 
76
76
  def self.make_sharable_constants: (Module) -> void
@@ -287,20 +287,23 @@ class ULID < Object
287
287
  # #=> ULID(2605-08-20 10:28:29.979 UTC: 0J7S2PFT4V2B9T8NJ2CRA1EG00)
288
288
  # ```
289
289
  #
290
- # See also [ULID.from_uuidv4]
290
+ # See also [ULID.from_uuid_v4]
291
291
  def self.from_uuidish: (String uuidish) -> ULID
292
292
 
293
293
  # Load a UUIDv4 string with checking version and variants.
294
294
  #
295
295
  # ```ruby
296
- # ULID.from_uuidv4('0983d0a2-ff15-4d83-8f37-7dd945b5aa39')
296
+ # ULID.from_uuid_v4('0983d0a2-ff15-4d83-8f37-7dd945b5aa39')
297
297
  # #=> ULID(2301-07-10 00:28:28.821 UTC: 09GF8A5ZRN9P1RYDVXV52VBAHS)
298
- # ULID.from_uuidv4('123e4567-e89b-12d3-a456-426614174000')
298
+ # ULID.from_uuid_v4('123e4567-e89b-12d3-a456-426614174000')
299
299
  # #=> ULID::ParserError
300
300
  # ```
301
301
  #
302
302
  # See also [ULID.from_uuidish]
303
- def self.from_uuidv4: (String uuid) -> ULID
303
+ def self.from_uuid_v4: (String uuid) -> ULID
304
+
305
+ # See also [ULID.from_uuid_v4]
306
+ def self.from_uuid_v7: (String uuid) -> ULID
304
307
 
305
308
  # Load integer as ULID
306
309
  #
@@ -648,7 +651,7 @@ class ULID < Object
648
651
  # ULID.from_uuidish(ulid.to_uuidish) #=> ULID(2023-03-07 11:48:07.469 UTC: 01GTXYCWNDKRYH14DBZ77TRSD7)
649
652
  # ```
650
653
  #
651
- # See also [ULID.from_uuidish], [ULID#to_uuidv4], [ulid/spec#64](https://github.com/ulid/spec/issues/64)
654
+ # See also [ULID.from_uuidish], [ULID#to_uuid_v4], [ulid/spec#64](https://github.com/ulid/spec/issues/64)
652
655
  def to_uuidish: -> String
653
656
 
654
657
  # Generate a UUIDv4-like string that sets the version and variants field.\
@@ -657,18 +660,21 @@ class ULID < Object
657
660
  #
658
661
  # ```ruby
659
662
  # uuid = '0983d0a2-ff15-4d83-8f37-7dd945b5aa39'
660
- # ulid = ULID.from_uuidv4(uuid)
661
- # ulid.to_uuidv4 #=> 0983d0a2-ff15-4d83-8f37-7dd945b5aa39
663
+ # ulid = ULID.from_uuid_v4(uuid)
664
+ # ulid.to_uuid_v4 #=> 0983d0a2-ff15-4d83-8f37-7dd945b5aa39
662
665
  # ```
663
666
  #
664
667
  # ```ruby
665
668
  # ulid = ULID.from_uuidish('0186bbe6-72ad-9e3d-1091-abf9cfac65a7')
666
- # ulid.to_uuidv4 #=> ULID::IrreversibleUUIDError
667
- # ulid.to_uuidv4(force: true) #=> '0186bbe6-72ad-4e3d-9091-abf9cfac65a7'
669
+ # ulid.to_uuid_v4 #=> ULID::IrreversibleUUIDError
670
+ # ulid.to_uuid_v4(force: true) #=> '0186bbe6-72ad-4e3d-9091-abf9cfac65a7'
668
671
  # ```
669
672
  #
670
- # See also [ULID.from_uuidv4], [ULID#to_uuidish], [ulid/spec#64](https://github.com/ulid/spec/issues/64)
671
- def to_uuidv4: (?force: boolish) -> String
673
+ # See also [ULID.from_uuid_v4], [ULID#to_uuidish], [ulid/spec#64](https://github.com/ulid/spec/issues/64)
674
+ def to_uuid_v4: (?force: boolish) -> String
675
+
676
+ # See also [ULID.from_uuid_v7], [ULID#to_uuidish]
677
+ def to_uuid_v7: (?force: boolish) -> String
672
678
 
673
679
  # Returns same ID with different Ruby object.
674
680
  def dup: -> ULID
metadata CHANGED
@@ -1,14 +1,13 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: ruby-ulid
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.9.0
4
+ version: 1.0.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Kenichi Kamiya
8
- autorequire:
9
8
  bindir: bin
10
9
  cert_chain: []
11
- date: 2024-08-28 00:00:00.000000000 Z
10
+ date: 1980-01-02 00:00:00.000000000 Z
12
11
  dependencies: []
13
12
  description: " generator, optional monotonicity, parser and tools for ULID (RBS
14
13
  included)\n"
@@ -38,7 +37,6 @@ metadata:
38
37
  source_code_uri: https://github.com/kachick/ruby-ulid
39
38
  bug_tracker_uri: https://github.com/kachick/ruby-ulid/issues
40
39
  rubygems_mfa_required: 'true'
41
- post_install_message:
42
40
  rdoc_options: []
43
41
  require_paths:
44
42
  - lib
@@ -46,15 +44,14 @@ required_ruby_version: !ruby/object:Gem::Requirement
46
44
  requirements:
47
45
  - - ">="
48
46
  - !ruby/object:Gem::Version
49
- version: '3.2'
47
+ version: '4.0'
50
48
  required_rubygems_version: !ruby/object:Gem::Requirement
51
49
  requirements:
52
50
  - - ">="
53
51
  - !ruby/object:Gem::Version
54
52
  version: '0'
55
53
  requirements: []
56
- rubygems_version: 3.5.11
57
- signing_key:
54
+ rubygems_version: 4.0.3
58
55
  specification_version: 4
59
56
  summary: ULID manipulation library
60
57
  test_files: []