ruby-ulid 0.8.0 → 0.9.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: 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