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 +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
|