ruby-ulid 0.8.0 → 0.9.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: 323b750a4e11157bd492b31d74833df2042192775c8627917880ef386dee4c1c
4
- data.tar.gz: 2dc8a91cbed7b473d6f9e28480dd227ab3469828ab0833f48a754111bd6e926c
3
+ metadata.gz: 6c0ca476ab05b4b53ce593e893ffdfd6aa72b3c08563116b95f5a22f43a7926b
4
+ data.tar.gz: 7454acd393c8df299696d2907a71f994643dacc45103e2874561d186e1fa85c5
5
5
  SHA512:
6
- metadata.gz: e78a5289863c1300a3f4c186b72a0f1d97cd709ce6043b69729d851f5e6ffcedac001e3bb691397d761ee497d609b5292c300db7f2ec3f8cf5be0ee5c095af80
7
- data.tar.gz: e19197709d7a896a79c6ebdc40fa919c2e7876284fa1dbf8895498ad7b80e989634cdd3e651362db5cf9f7c627fe17439ccc21e75c8e6598b002da6b19858aa0
6
+ metadata.gz: bfe19e20452a12edd7472ddaf3b9583d2eaa5640e03a081621c35bcfdf218f9ccf5d7c7625b0850312447f61c0592796d333aa4578a6c2f0281e6ff4e8392efd
7
+ data.tar.gz: cdd8dba77214852ea70d07a137f75098558097db686a4409dd14e611d533de33f4c510b9a38ee232e918dd0aae6b028f19a4dd7312ac42172890d726091f282b
data/README.md CHANGED
@@ -38,12 +38,12 @@ Instead, herein is proposed ULID:
38
38
 
39
39
  ### Install
40
40
 
41
- Tested only in the last 2 Rubies. So you need Ruby 3.1 or higher.
41
+ Tested only in the last 2 Rubies. So you need Ruby 3.2 or higher.
42
42
 
43
43
  Add this line to your `Gemfile`.
44
44
 
45
45
  ```ruby
46
- gem('ruby-ulid', '~> 0.8.0')
46
+ gem('ruby-ulid', '~> 0.9.0')
47
47
  ```
48
48
 
49
49
  And load it.
@@ -53,7 +53,18 @@ require 'ulid'
53
53
  ```
54
54
 
55
55
  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.8.0).
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).
57
+
58
+ In [Nix](https://nixos.org/), you can skip the installation steps for both ruby and ruby-ulid to try.
59
+
60
+ ```console
61
+ > nix run github:kachick/ruby-ulid#ruby -- -e 'p ULID.generate'
62
+ ULID(2024-03-03 18:37:06.152 UTC: 01HR2SNY789ZZ027EDJEHAGQ62)
63
+
64
+ > nix run github:kachick/ruby-ulid#irb
65
+ irb(main):001:0> ULID.parse('01H66XG2A9WWYRCYGPA62T4AZA')
66
+ => ULID(2023-07-25 16:18:12.937 UTC: 01H66XG2A9WWYRCYGPA62T4AZA)
67
+ ```
57
68
 
58
69
  ### Generator and Parser
59
70
 
@@ -269,7 +280,7 @@ ULID.min(time) #=> ULID(2000-01-01 00:00:00.123 UTC: 00VHNCZB3V0000000000000000)
269
280
  ULID.max(time) #=> ULID(2000-01-01 00:00:00.123 UTC: 00VHNCZB3VZZZZZZZZZZZZZZZZ)
270
281
  ```
271
282
 
272
- #### As element in Enumerable
283
+ #### As an element in Enumerable and Range
273
284
 
274
285
  `ULID#next` and `ULID#succ` returns next(successor) ULID.\
275
286
  Especially `ULID#succ` makes it possible `Range[ULID]#each`.
@@ -290,6 +301,17 @@ ULID.parse('01BX5ZZKBK0000000000000000').pred.to_s #=> "01BX5ZZKBJZZZZZZZZZZZZZZ
290
301
  ULID.parse('00000000000000000000000000').pred #=> nil
291
302
  ```
292
303
 
304
+ `ULID#+` is also provided to realize `Range#step` since [ruby-3.4.0 spec changes](https://bugs.ruby-lang.org/issues/18368).
305
+
306
+ ```ruby
307
+ # This code works only in ruby-3.4.0dev or later
308
+ (ULID.min...).step(42).take(3)
309
+ # =>
310
+ [ULID(1970-01-01 00:00:00.000 UTC: 00000000000000000000000000),
311
+ ULID(1970-01-01 00:00:00.000 UTC: 0000000000000000000000001A),
312
+ ULID(1970-01-01 00:00:00.000 UTC: 0000000000000000000000002M)]
313
+ ```
314
+
293
315
  #### Test helpers
294
316
 
295
317
  `ULID.sample` returns random ULIDs.
@@ -390,6 +412,10 @@ ULID.max.to_uuidish #=> "ffffffff-ffff-ffff-ffff-ffffffffffff"
390
412
  ULID.max.to_uuidv4(force: true) #=> "ffffffff-ffff-4fff-bfff-ffffffffffff"
391
413
  ```
392
414
 
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
+
393
419
  ## Migration from other gems
394
420
 
395
421
  See [wiki page for gem migration](https://github.com/kachick/ruby-ulid/wiki/Gem-migration).
@@ -404,9 +430,3 @@ See [wiki page for gem migration](https://github.com/kachick/ruby-ulid/wiki/Gem-
404
430
  - [Repository](https://github.com/kachick/ruby-ulid)
405
431
  - [API documents](https://kachick.github.io/ruby-ulid/)
406
432
  - [ulid/spec](https://github.com/ulid/spec)
407
-
408
- ## Note
409
-
410
- - [UUIDv6, UUIDv7, UUIDv8](https://www.ietf.org/archive/id/draft-ietf-uuidrev-rfc4122bis-02.html) is another choice for sortable and randomness ID.
411
- \
412
- However they remain in draft state. Our tracker is: [ruby-ulid#37](https://github.com/kachick/ruby-ulid/issues/37)
@@ -10,7 +10,7 @@ require_relative('utils')
10
10
  class ULID
11
11
  class MonotonicGenerator
12
12
  # @note When use https://github.com/ko1/ractor-tvar might realize Ractor based thread safe monotonic generator.
13
- # However it is a C extention, I'm pending to use it for now.
13
+ # However it is a C extension, I'm pending to use it for now.
14
14
  include(MonitorMixin)
15
15
 
16
16
  # @return [ULID, nil]
@@ -0,0 +1,41 @@
1
+ # coding: us-ascii
2
+ # frozen_string_literal: true
3
+ # shareable_constant_value: literal
4
+
5
+ # Copyright (C) 2021 Kenichi Kamiya
6
+
7
+ class ULID
8
+ module UUID
9
+ # @see https://www.rfc-editor.org/rfc/rfc4122#section-4.1.2
10
+ # @note
11
+ # - Using `Fields = Data.define do; end` syntax made https://github.com/kachick/ruby-ulid/issues/233 again. So use class syntax instead
12
+ # - This file is extracted to avoid YARD warnings "Ruby::ClassHandler: Undocumentable superclass" https://github.com/lsegal/yard/issues/737
13
+ # Partially avoiding is hard in YARD, so extracting the code and using exclude filter in yardopts...
14
+ class Fields < Data.define(:time_low, :time_mid, :time_hi_and_version, :clock_seq_hi_and_res, :clk_seq_low, :node)
15
+ def self.raw_from_octets(octets)
16
+ case octets.pack('C*').unpack('NnnnnN')
17
+ in [Integer => time_low, Integer => time_mid, Integer => time_hi_and_version, Integer => clock_seq_hi_and_res, Integer => clk_seq_low, Integer => node]
18
+ new(time_low:, time_mid:, time_hi_and_version:, clock_seq_hi_and_res:, clk_seq_low:, node:).freeze
19
+ end
20
+ end
21
+
22
+ def self.forced_v4_from_octets(octets)
23
+ case octets.pack('C*').unpack('NnnnnN')
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
+ new(
26
+ time_low:,
27
+ time_mid:,
28
+ time_hi_and_version: (time_hi_and_version & 0x0fff) | 0x4000,
29
+ clock_seq_hi_and_res: (clock_seq_hi_and_res & 0x3fff) | 0x8000,
30
+ clk_seq_low:,
31
+ node:
32
+ ).freeze
33
+ end
34
+ end
35
+
36
+ def to_s
37
+ '%08x-%04x-%04x-%04x-%04x%08x' % deconstruct
38
+ end
39
+ end
40
+ end
41
+ end
data/lib/ulid/uuid.rb CHANGED
@@ -6,6 +6,7 @@
6
6
 
7
7
  require_relative('errors')
8
8
  require_relative('utils')
9
+ require_relative('uuid/fields')
9
10
 
10
11
  class ULID
11
12
  module UUID
@@ -37,36 +38,6 @@ class ULID
37
38
 
38
39
  parse_any_to_int(encoded)
39
40
  end
40
-
41
- # @see https://www.rfc-editor.org/rfc/rfc4122#section-4.1.2
42
- # @todo Replace to Data class after dropped Ruby 3.1
43
- # @note Using `Fields = Struct.new` syntax made https://github.com/kachick/ruby-ulid/issues/233 again. So use class syntax instead
44
- class Fields < Struct.new(:time_low, :time_mid, :time_hi_and_version, :clock_seq_hi_and_res, :clk_seq_low, :node, keyword_init: true)
45
- def self.raw_from_octets(octets)
46
- case octets.pack('C*').unpack('NnnnnN')
47
- in [Integer => time_low, Integer => time_mid, Integer => time_hi_and_version, Integer => clock_seq_hi_and_res, Integer => clk_seq_low, Integer => node]
48
- new(time_low:, time_mid:, time_hi_and_version:, clock_seq_hi_and_res:, clk_seq_low:, node:).freeze
49
- end
50
- end
51
-
52
- def self.forced_v4_from_octets(octets)
53
- case octets.pack('C*').unpack('NnnnnN')
54
- in [Integer => time_low, Integer => time_mid, Integer => time_hi_and_version, Integer => clock_seq_hi_and_res, Integer => clk_seq_low, Integer => node]
55
- new(
56
- time_low:,
57
- time_mid:,
58
- time_hi_and_version: (time_hi_and_version & 0x0fff) | 0x4000,
59
- clock_seq_hi_and_res: (clock_seq_hi_and_res & 0x3fff) | 0x8000,
60
- clk_seq_low:,
61
- node:
62
- ).freeze
63
- end
64
- end
65
-
66
- def to_s
67
- '%08x-%04x-%04x-%04x-%04x%08x' % values
68
- end
69
- end
70
41
  end
71
42
 
72
43
  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.8.0'
6
+ VERSION = '0.9.0'
7
7
  end
data/lib/ulid.rb CHANGED
@@ -449,33 +449,43 @@ class ULID
449
449
  @encoded.slice(TIMESTAMP_ENCODED_LENGTH, RANDOMNESS_ENCODED_LENGTH) || raise(UnexpectedError)
450
450
  end
451
451
 
452
- # @return [ULID, nil] when called on ULID as `7ZZZZZZZZZZZZZZZZZZZZZZZZZ`, returns `nil` instead of ULID
453
- def succ
454
- succ_int = @integer.succ
455
- if succ_int >= MAX_INTEGER
456
- if succ_int == MAX_INTEGER
457
- MAX
458
- else
452
+ # @param [Integer] other
453
+ # @return [ULID, nil] when returning URID might be greater than `7ZZZZZZZZZZZZZZZZZZZZZZZZZ`, returns `nil` instead of ULID
454
+ def +(other)
455
+ raise(ArgumentError, 'ULID#+ takes only integers') unless Integer === other
456
+
457
+ new_int = @integer + other
458
+ case new_int
459
+ when MAX_INTEGER
460
+ MAX
461
+ when 0
462
+ MIN
463
+ else
464
+ if new_int > MAX_INTEGER || new_int < 0
459
465
  nil
466
+ else
467
+ ULID.from_integer(new_int)
460
468
  end
461
- else
462
- ULID.from_integer(succ_int)
463
469
  end
464
470
  end
471
+
472
+ # @param [Integer] other
473
+ # @return [ULID, nil] when returning URID might be less than `00000000000000000000000000`, returns `nil` instead of ULID
474
+ def -(other)
475
+ raise(ArgumentError, 'ULID#- takes only integers') unless Integer === other
476
+
477
+ self + -other
478
+ end
479
+
480
+ # @return [ULID, nil] when called on ULID as `7ZZZZZZZZZZZZZZZZZZZZZZZZZ`, returns `nil` instead of ULID
481
+ def succ
482
+ self + 1
483
+ end
465
484
  alias_method(:next, :succ)
466
485
 
467
486
  # @return [ULID, nil] when called on ULID as `00000000000000000000000000`, returns `nil` instead of ULID
468
487
  def pred
469
- pred_int = @integer.pred
470
- if pred_int <= 0
471
- if pred_int == 0
472
- MIN
473
- else
474
- nil
475
- end
476
- else
477
- ULID.from_integer(pred_int)
478
- end
488
+ self - 1
479
489
  end
480
490
 
481
491
  # @return [Integer]
data/sig/ulid.rbs CHANGED
@@ -41,17 +41,17 @@ class ULID < Object
41
41
  def self.parse_any_to_int: (String) -> Integer
42
42
  def self.parse_v4_to_int: (String) -> Integer
43
43
 
44
- class Fields < Struct[Integer]
45
- attr_accessor time_low: Integer
46
- attr_accessor time_mid: Integer
47
- attr_accessor time_hi_and_version: Integer
48
- attr_accessor clock_seq_hi_and_res: Integer
49
- attr_accessor clk_seq_low: Integer
50
- attr_accessor node: Integer
44
+ class Fields
45
+ attr_reader time_low: Integer
46
+ attr_reader time_mid: Integer
47
+ attr_reader time_hi_and_version: Integer
48
+ attr_reader clock_seq_hi_and_res: Integer
49
+ attr_reader clk_seq_low: Integer
50
+ attr_reader node: Integer
51
51
  def self.raw_from_octets: (octets) -> Fields
52
52
  def self.forced_v4_from_octets: (octets) -> Fields
53
53
 
54
- def values: -> Array[Integer]
54
+ def deconstruct: -> Array[Integer]
55
55
 
56
56
  private
57
57
 
@@ -147,7 +147,7 @@ class ULID < Object
147
147
  @integer: Integer
148
148
  @encoded: String
149
149
 
150
- # Retuns a ULID
150
+ # Returns a ULID
151
151
  #
152
152
  # They are sortable when generated in different timestamp with milliseconds precision
153
153
  #
@@ -183,7 +183,7 @@ class ULID < Object
183
183
  #
184
184
  def self.generate: (?moment: moment, ?entropy: Integer) -> ULID
185
185
 
186
- # Retuns encoded and normalzied String.\
186
+ # Returns encoded and normalzied String.\
187
187
  # It has same arguments signatures as `.generate`\
188
188
  # So can be used for just ID creation usecases without needless object creation.
189
189
  #
@@ -594,6 +594,18 @@ class ULID < Object
594
594
  # ```
595
595
  def octets: -> octets
596
596
 
597
+ # Returns incremented ULID.\
598
+ # Especially providing for Range#step since ruby-3.4.0 spec changes
599
+ #
600
+ # See also [ruby-lang#18368](https://bugs.ruby-lang.org/issues/18368)
601
+ # ```
602
+ def +: (Integer other) -> ULID?
603
+
604
+ # Returns decremented ULID.\
605
+ # Providing for realizing natural API convention with the `ULID#+`
606
+ # ```
607
+ def -: (Integer other) -> ULID?
608
+
597
609
  # Returns next(successor) ULID.\
598
610
  # Especially `ULID#succ` makes it possible `Range[ULID]#each`.
599
611
  #
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: ruby-ulid
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.8.0
4
+ version: 0.9.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Kenichi Kamiya
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2023-03-08 00:00:00.000000000 Z
11
+ date: 2024-08-28 00:00:00.000000000 Z
12
12
  dependencies: []
13
13
  description: " generator, optional monotonicity, parser and tools for ULID (RBS
14
14
  included)\n"
@@ -27,6 +27,7 @@ files:
27
27
  - lib/ulid/monotonic_generator.rb
28
28
  - lib/ulid/utils.rb
29
29
  - lib/ulid/uuid.rb
30
+ - lib/ulid/uuid/fields.rb
30
31
  - lib/ulid/version.rb
31
32
  - sig/ulid.rbs
32
33
  homepage: https://github.com/kachick/ruby-ulid
@@ -34,7 +35,6 @@ licenses:
34
35
  - MIT
35
36
  metadata:
36
37
  documentation_uri: https://kachick.github.io/ruby-ulid/
37
- homepage_uri: https://github.com/kachick/ruby-ulid
38
38
  source_code_uri: https://github.com/kachick/ruby-ulid
39
39
  bug_tracker_uri: https://github.com/kachick/ruby-ulid/issues
40
40
  rubygems_mfa_required: 'true'
@@ -46,14 +46,14 @@ required_ruby_version: !ruby/object:Gem::Requirement
46
46
  requirements:
47
47
  - - ">="
48
48
  - !ruby/object:Gem::Version
49
- version: '3.1'
49
+ version: '3.2'
50
50
  required_rubygems_version: !ruby/object:Gem::Requirement
51
51
  requirements:
52
52
  - - ">="
53
53
  - !ruby/object:Gem::Version
54
54
  version: '0'
55
55
  requirements: []
56
- rubygems_version: 3.4.6
56
+ rubygems_version: 3.5.11
57
57
  signing_key:
58
58
  specification_version: 4
59
59
  summary: ULID manipulation library