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 +4 -4
- data/README.md +30 -10
- data/lib/ulid/monotonic_generator.rb +1 -1
- data/lib/ulid/uuid/fields.rb +41 -0
- data/lib/ulid/uuid.rb +1 -30
- data/lib/ulid/version.rb +1 -1
- data/lib/ulid.rb +29 -19
- data/sig/ulid.rbs +22 -10
- metadata +5 -5
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 6c0ca476ab05b4b53ce593e893ffdfd6aa72b3c08563116b95f5a22f43a7926b
|
4
|
+
data.tar.gz: 7454acd393c8df299696d2907a71f994643dacc45103e2874561d186e1fa85c5
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
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.
|
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.
|
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.
|
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
|
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
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
|
-
# @
|
453
|
-
|
454
|
-
|
455
|
-
|
456
|
-
|
457
|
-
|
458
|
-
|
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
|
-
|
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
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
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
|
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
|
-
#
|
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
|
-
#
|
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.
|
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:
|
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.
|
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.
|
56
|
+
rubygems_version: 3.5.11
|
57
57
|
signing_key:
|
58
58
|
specification_version: 4
|
59
59
|
summary: ULID manipulation library
|