ruby-ulid 0.4.0 → 0.5.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 +26 -75
- data/lib/ulid/version.rb +1 -1
- data/lib/ulid.rb +36 -8
- data/sig/ulid.rbs +54 -8
- metadata +4 -4
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 4d7356366d0184815a725d1947f4f685b3abba0320ae60800b5a015dc7c649e9
|
4
|
+
data.tar.gz: 04b55b6d92dbf02865a7803be352f5cd385f3417c061269f2ad197474202154d
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: aa826d204cbdc1e6850fbeab278dc72e5b683926db9af7ed477ec2e74837d32829dbfb468c1156d6dcf5be604f9fdeb8fd0a282999b47a627884152b2a2cd5d4
|
7
|
+
data.tar.gz: 0b1208e76af50f9952c8c4835d1410c7e1fd114313cc71d39a143c9bc04ac4f1a35ba49be88a49406606c441e4f4fa7cad5fc938d74fcecde0d612319a6890b3
|
data/README.md
CHANGED
@@ -7,8 +7,7 @@
|
|
7
7
|
|
8
8
|
[ulid/spec](https://github.com/ulid/spec) is useful.
|
9
9
|
Especially possess all `uniqueness`, `randomness`, `extractable timestamps` and `sortable` features.
|
10
|
-
This gem aims to provide the generator,
|
11
|
-
Also providing [RBS](https://github.com/ruby/rbs) signatures.
|
10
|
+
This gem aims to provide the generator, optional monotonicity, parser and other manipulation features around ULID with included [RBS](https://github.com/ruby/rbs).
|
12
11
|
|
13
12
|
---
|
14
13
|
|
@@ -50,7 +49,7 @@ Should be installed!
|
|
50
49
|
Add this line in your Gemfile.
|
51
50
|
|
52
51
|
```ruby
|
53
|
-
gem('ruby-ulid', '~> 0.
|
52
|
+
gem('ruby-ulid', '~> 0.5.0')
|
54
53
|
```
|
55
54
|
|
56
55
|
### How to use
|
@@ -58,8 +57,8 @@ gem('ruby-ulid', '~> 0.4.0')
|
|
58
57
|
```ruby
|
59
58
|
require 'ulid'
|
60
59
|
|
61
|
-
|
62
|
-
# => "
|
60
|
+
ULID::VERSION
|
61
|
+
# => "0.5.0"
|
63
62
|
```
|
64
63
|
|
65
64
|
### Basic Generator
|
@@ -72,7 +71,7 @@ ulid = ULID.generate #=> ULID(2021-04-27 17:27:22.826 UTC: 01F4A5Y1YAQCYAYCTC7GR
|
|
72
71
|
|
73
72
|
### Parser
|
74
73
|
|
75
|
-
|
74
|
+
Get the objects from exists encoded ULIDs.
|
76
75
|
|
77
76
|
```ruby
|
78
77
|
ulid = ULID.parse('01ARZ3NDEKTSV4RRFFQ69G5FAV') #=> ULID(2016-07-30 23:54:10.259 UTC: 01ARZ3NDEKTSV4RRFFQ69G5FAV)
|
@@ -80,7 +79,7 @@ ulid = ULID.parse('01ARZ3NDEKTSV4RRFFQ69G5FAV') #=> ULID(2016-07-30 23:54:10.259
|
|
80
79
|
|
81
80
|
### ULID object
|
82
81
|
|
83
|
-
|
82
|
+
Extract timestamps and binary formats.
|
84
83
|
|
85
84
|
```ruby
|
86
85
|
ulid = ULID.parse('01F4A5Y1YAQCYAYCTC7GRMJ9AA') #=> ULID(2021-04-27 17:27:22.826 UTC: 01F4A5Y1YAQCYAYCTC7GRMJ9AA)
|
@@ -120,7 +119,7 @@ end
|
|
120
119
|
ulids.sort == ulids #=> true
|
121
120
|
```
|
122
121
|
|
123
|
-
|
122
|
+
Basic generator prefers `randomness`, it does not guarantee `sortable` for same milliseconds ULIDs.
|
124
123
|
|
125
124
|
```ruby
|
126
125
|
ulids = 10000.times.map do
|
@@ -202,7 +201,7 @@ time = Time.at(946684800, Rational('123456.789')).utc #=> 2000-01-01 00:00:00.12
|
|
202
201
|
ULID.floor(time) #=> 2000-01-01 00:00:00.123 UTC
|
203
202
|
```
|
204
203
|
|
205
|
-
###
|
204
|
+
### Tools
|
206
205
|
|
207
206
|
#### Scanner for string (e.g. `JSON`)
|
208
207
|
|
@@ -341,31 +340,32 @@ ULID.sample(5, period: ulid1.to_time..ulid2.to_time)
|
|
341
340
|
|
342
341
|
I'm afraid so, we should consider [Current ULID spec](https://github.com/ulid/spec/tree/d0c7170df4517939e70129b4d6462cc162f2d5bf#universally-unique-lexicographically-sortable-identifier) has `orthographical variants of the format` possibilities.
|
343
342
|
|
343
|
+
>Case insensitive
|
344
|
+
|
345
|
+
I can understand it might be considered in actual use-case. So `ULID.parse` accepts upcase and downcase.
|
346
|
+
However it is a controversial point, discussing in [ulid/spec#3](https://github.com/ulid/spec/issues/3).
|
347
|
+
|
344
348
|
>Uses Crockford's base32 for better efficiency and readability (5 bits per character)
|
345
349
|
|
346
350
|
The original `Crockford's base32` maps `I`, `L` to `1`, `O` to `0`.
|
347
351
|
And accepts freestyle inserting `Hyphens (-)`.
|
348
352
|
To consider this patterns or not is different in each implementations.
|
349
353
|
|
350
|
-
|
351
|
-
I have suggested it would be clarified in [ulid/spec#57](https://github.com/ulid/spec/pull/57).
|
352
|
-
|
353
|
-
>Case insensitive
|
354
|
-
|
355
|
-
I can understand it might be considered in actual use-case.
|
356
|
-
But it is a controversial point, discussing in [ulid/spec#3](https://github.com/ulid/spec/issues/3).
|
354
|
+
I have suggested to clarify `subset of Crockford's base32` in [ulid/spec#57](https://github.com/ulid/spec/pull/57).
|
357
355
|
|
358
|
-
|
356
|
+
This gem provides some methods to handle the nasty possibilities.
|
359
357
|
|
360
|
-
`ULID.normalize` and `ULID.
|
358
|
+
`ULID.normalize`, `ULID.normalized?`, `ULID.valid_as_variant_format?` and `ULID.parse_variant_format`
|
361
359
|
|
362
360
|
```ruby
|
363
|
-
ULID.normalize('-
|
364
|
-
ULID.normalized?('-
|
365
|
-
ULID.normalized?('
|
361
|
+
ULID.normalize('01g70y0y7g-z1xwdarexergsddd') #=> "01G70Y0Y7GZ1XWDAREXERGSDDD"
|
362
|
+
ULID.normalized?('01g70y0y7g-z1xwdarexergsddd') #=> false
|
363
|
+
ULID.normalized?('01G70Y0Y7GZ1XWDAREXERGSDDD') #=> true
|
364
|
+
ULID.valid_as_variant_format?('01g70y0y7g-z1xwdarexergsddd') #=> true
|
365
|
+
ULID.parse_variant_format('01G70Y0Y7G-ZLXWDIREXERGSDoD') #=> ULID(2022-07-03 02:25:22.672 UTC: 01G70Y0Y7GZ1XWD1REXERGSD0D)
|
366
366
|
```
|
367
367
|
|
368
|
-
#### UUIDv4 converter
|
368
|
+
#### UUIDv4 converter (experimental)
|
369
369
|
|
370
370
|
`ULID.from_uuidv4` and `ULID#to_uuidv4` is the converter.
|
371
371
|
The imported timestamp is meaningless. So ULID's benefit will lost.
|
@@ -398,68 +398,19 @@ ULID.min == reversed_min #=> false
|
|
398
398
|
ULID.max == reversed_max #=> false
|
399
399
|
```
|
400
400
|
|
401
|
-
##
|
402
|
-
|
403
|
-
As far as I know, major prior arts are below
|
404
|
-
|
405
|
-
### [ulid gem](https://rubygems.org/gems/ulid) - [rafaelsales/ulid](https://github.com/rafaelsales/ulid)
|
406
|
-
|
407
|
-
It is just providing basic `String` generator only.
|
408
|
-
So you can replace the code as below
|
409
|
-
|
410
|
-
```diff
|
411
|
-
-ULID.generate
|
412
|
-
+ULID.generate.to_s
|
413
|
-
```
|
414
|
-
|
415
|
-
NOTE: In version before `1.3.0`, timestamps might not be correct value.
|
416
|
-
|
417
|
-
1. [Sort order does not respect millisecond ordering](https://github.com/rafaelsales/ulid/issues/22)
|
418
|
-
1. [Fixed in this PR](https://github.com/rafaelsales/ulid/pull/23)
|
419
|
-
1. [Released in 1.3.0](https://github.com/rafaelsales/ulid/compare/1.2.0...v1.3.0)
|
420
|
-
|
421
|
-
### [ulid-ruby gem](https://rubygems.org/gems/ulid-ruby) - [abachman/ulid-ruby](https://github.com/abachman/ulid-ruby)
|
422
|
-
|
423
|
-
It is providing basic generator(except monotonic generator) and parser.
|
424
|
-
Major methods can be replaced as below.
|
425
|
-
|
426
|
-
```diff
|
427
|
-
-ULID.generate
|
428
|
-
+ULID.generate.to_s
|
429
|
-
-ULID.at(time)
|
430
|
-
+ULID.at(time).to_s
|
431
|
-
-ULID.time(string)
|
432
|
-
+ULID.parse(string).to_time
|
433
|
-
-ULID.min_ulid_at(time)
|
434
|
-
+ULID.min(time).to_s
|
435
|
-
-ULID.max_ulid_at(time)
|
436
|
-
+ULID.max(time).to_s
|
437
|
-
```
|
438
|
-
|
439
|
-
NOTE: In version before `1.0.2`, timestamps might not be correct value.
|
440
|
-
|
441
|
-
1. [Parsed time object has more than milliseconds](https://github.com/abachman/ulid-ruby/issues/3)
|
442
|
-
1. [Fix to handle timestamp precision in parser](https://github.com/abachman/ulid-ruby/pull/5)
|
443
|
-
1. [Fix to handle timestamp precision in generator](https://github.com/abachman/ulid-ruby/pull/4)
|
444
|
-
1. [Released in 1.0.2](https://github.com/abachman/ulid-ruby/compare/v1.0.0...v1.0.2)
|
445
|
-
|
446
|
-
### Compare performance with them
|
447
|
-
|
448
|
-
See [Benchmark](https://github.com/kachick/ruby-ulid/wiki/Benchmark).
|
401
|
+
## Migration from other gems
|
449
402
|
|
450
|
-
|
403
|
+
See [wiki page for gem migration](https://github.com/kachick/ruby-ulid/wiki/Gem-migration).
|
451
404
|
|
452
|
-
##
|
405
|
+
## RBS
|
453
406
|
|
454
|
-
|
407
|
+
Try at [examples/rbs_sandbox](https://github.com/kachick/ruby-ulid/tree/main/examples/rbs_sandbox).
|
455
408
|
|
456
409
|
I have checked the behavior with [ruby/rbs@2.6.0](https://github.com/ruby/rbs) + [soutaro/steep@1.0.1](https://github.com/soutaro/steep) + [soutaro/steep-vscode](https://github.com/soutaro/steep-vscode).
|
457
410
|
|
458
411
|
* 
|
459
412
|
* 
|
460
413
|
* 
|
461
|
-
* 
|
462
|
-
* 
|
463
414
|
|
464
415
|
## References
|
465
416
|
|
data/lib/ulid/version.rb
CHANGED
data/lib/ulid.rb
CHANGED
@@ -268,6 +268,17 @@ class ULID
|
|
268
268
|
from_integer(CrockfordBase32.decode(string))
|
269
269
|
end
|
270
270
|
|
271
|
+
# @param [String, #to_str] string
|
272
|
+
# @return [ULID]
|
273
|
+
# @raise [ParserError] if the given format is not correct for ULID specs
|
274
|
+
def self.parse_variant_format(string)
|
275
|
+
string = String.try_convert(string)
|
276
|
+
raise(ArgumentError, 'ULID.parse_variant_format takes only strings') unless string
|
277
|
+
|
278
|
+
normalized_in_crockford = CrockfordBase32.normalize(string)
|
279
|
+
parse(normalized_in_crockford)
|
280
|
+
end
|
281
|
+
|
271
282
|
# @param [String, #to_str] string
|
272
283
|
# @return [String]
|
273
284
|
# @raise [ParserError] if the given format is not correct for ULID specs, even if ignored `orthographical variants of the format`
|
@@ -275,23 +286,40 @@ class ULID
|
|
275
286
|
string = String.try_convert(string)
|
276
287
|
raise(ArgumentError, 'ULID.normalize takes only strings') unless string
|
277
288
|
|
278
|
-
normalized_in_crockford = CrockfordBase32.normalize(string)
|
279
289
|
# Ensure the ULID correctness, because CrockfordBase32 does not always mean to satisfy ULID format
|
280
|
-
|
290
|
+
parse_variant_format(string).to_s
|
291
|
+
end
|
292
|
+
|
293
|
+
# @param [String, #to_str] string
|
294
|
+
# @return [Boolean]
|
295
|
+
def self.normalized?(string)
|
296
|
+
normalized = normalize(string)
|
297
|
+
rescue Exception
|
298
|
+
false
|
299
|
+
else
|
300
|
+
normalized == string
|
281
301
|
end
|
282
302
|
|
303
|
+
# @param [String, #to_str] string
|
283
304
|
# @return [Boolean]
|
284
|
-
def self.
|
285
|
-
|
305
|
+
def self.valid_as_variant_format?(string)
|
306
|
+
normalize(string)
|
286
307
|
rescue Exception
|
287
308
|
false
|
288
309
|
else
|
289
|
-
|
310
|
+
true
|
290
311
|
end
|
291
312
|
|
313
|
+
# @deprecated Use [.valid_as_variant_format?] or [.normalized?] instead
|
314
|
+
#
|
315
|
+
# Returns `true` if it is normalized string.
|
316
|
+
# Basically the difference of normalized? is to accept downcase or not. This returns true for downcased ULIDs.
|
317
|
+
#
|
292
318
|
# @return [Boolean]
|
293
|
-
def self.valid?(
|
294
|
-
|
319
|
+
def self.valid?(string)
|
320
|
+
warn_kwargs = (RUBY_VERSION >= '3.0') ? { category: :deprecated } : {}
|
321
|
+
Warning.warn('ULID.valid? is deprecated. Use ULID.valid_as_variant_format? or ULID.normalized? instead.', **warn_kwargs)
|
322
|
+
string = String.try_convert(string)
|
295
323
|
string ? STRICT_PATTERN_WITH_CROCKFORD_BASE32_SUBSET.match?(string) : false
|
296
324
|
end
|
297
325
|
|
@@ -392,7 +420,7 @@ class ULID
|
|
392
420
|
[ULID, @integer].hash
|
393
421
|
end
|
394
422
|
|
395
|
-
# @return [
|
423
|
+
# @return [-1, 0, 1, nil]
|
396
424
|
def <=>(other)
|
397
425
|
(ULID === other) ? (@integer <=> other.to_i) : nil
|
398
426
|
end
|
data/sig/ulid.rbs
CHANGED
@@ -213,6 +213,21 @@ class ULID < Object
|
|
213
213
|
# ```
|
214
214
|
def self.parse: (_ToStr string) -> ULID
|
215
215
|
|
216
|
+
# Get ULID instance from unnormalized String that encoded in Crockford's base32.
|
217
|
+
#
|
218
|
+
# http://www.crockford.com/base32.html
|
219
|
+
#
|
220
|
+
# * Ignore Hyphens (-)
|
221
|
+
# * Mapping 0 O o => 0, 1 I i L l => 1
|
222
|
+
#
|
223
|
+
# ```ruby
|
224
|
+
# ulid = ULID.parse_variant_format('01G70Y0Y7G-ZLXWDIREXERGSDoD')
|
225
|
+
# #=> ULID(2022-07-03 02:25:22.672 UTC: 01G70Y0Y7GZ1XWD1REXERGSD0D)
|
226
|
+
# ```
|
227
|
+
#
|
228
|
+
# See also [ulid/spec#57](https://github.com/ulid/spec/pull/57) and [ulid/spec#3](https://github.com/ulid/spec/issues/3)
|
229
|
+
def self.parse_variant_format: (_ToStr string) -> ULID
|
230
|
+
|
216
231
|
# ```ruby
|
217
232
|
# # Currently experimental feature, so needed to load the extension.
|
218
233
|
# require 'ulid/uuid'
|
@@ -309,14 +324,13 @@ class ULID < Object
|
|
309
324
|
# ```
|
310
325
|
def self.sample: (?period: period) -> ULID
|
311
326
|
| (Integer number, ?period: period?) -> Array[ULID]
|
312
|
-
def self.valid?: (untyped) -> bool
|
313
327
|
|
314
328
|
# Returns normalized string
|
315
329
|
#
|
316
330
|
# ```ruby
|
331
|
+
# ULID.normalize('01G70Y0Y7G-Z1XWDAREXERGSDDD') #=> "01G70Y0Y7GZ1XWDAREXERGSDDD"
|
317
332
|
# ULID.normalize('-olarz3-noekisv4rrff-q6ig5fav--') #=> "01ARZ3N0EK1SV4RRFFQ61G5FAV"
|
318
|
-
# ULID.
|
319
|
-
# ULID.normalized?('01ARZ3N0EK1SV4RRFFQ61G5FAV') #=> true
|
333
|
+
# ULID.normalize('01G70Y0Y7G_Z1XWDAREXERGSDDD') #=> ULID::ParserError
|
320
334
|
# ```
|
321
335
|
#
|
322
336
|
# See also [ulid/spec#57](https://github.com/ulid/spec/pull/57) and [ulid/spec#3](https://github.com/ulid/spec/issues/3)
|
@@ -325,13 +339,40 @@ class ULID < Object
|
|
325
339
|
# Returns `true` if it is normalized string
|
326
340
|
#
|
327
341
|
# ```ruby
|
328
|
-
# ULID.
|
329
|
-
# ULID.normalized?('-
|
330
|
-
# ULID.normalized?(
|
342
|
+
# ULID.normalized?('01G70Y0Y7GZ1XWDAREXERGSDDD') #=> true
|
343
|
+
# ULID.normalized?('01G70Y0Y7G-Z1XWDAREXERGSDDD') #=> false
|
344
|
+
# ULID.normalized?(ULID.generate.to_s.downcase) #=> false
|
345
|
+
# ULID.normalized?('01G70Y0Y7G_Z1XWDAREXERGSDDD') #=> false (Not raising ULID::ParserError)
|
331
346
|
# ```
|
332
347
|
#
|
333
348
|
# See also [ulid/spec#57](https://github.com/ulid/spec/pull/57) and [ulid/spec#3](https://github.com/ulid/spec/issues/3)
|
334
|
-
def self.normalized?: (
|
349
|
+
def self.normalized?: (_ToStr string) -> bool
|
350
|
+
| (untyped) -> false
|
351
|
+
|
352
|
+
# Returns `true` if it is valid in ULID format variants
|
353
|
+
#
|
354
|
+
# ```ruby
|
355
|
+
# ULID.valid_as_variant_format?(ULID.generate.to_s.downcase) #=> true
|
356
|
+
# ULID.valid_as_variant_format?('01G70Y0Y7G-Z1XWDAREXERGSDDD') #=> true
|
357
|
+
# ULID.valid_as_variant_format?('01G70Y0Y7G_Z1XWDAREXERGSDDD') #=> false
|
358
|
+
# ```
|
359
|
+
#
|
360
|
+
# See also [ulid/spec#57](https://github.com/ulid/spec/pull/57) and [ulid/spec#3](https://github.com/ulid/spec/issues/3)
|
361
|
+
def self.valid_as_variant_format?: (_ToStr string) -> bool
|
362
|
+
| (untyped) -> false
|
363
|
+
|
364
|
+
# DEPRECATED Use valid_as_variant_format? instead
|
365
|
+
#
|
366
|
+
# Returns `true` if it is normalized string.
|
367
|
+
# Basically the difference of normalized? is to accept downcase or not. This returns true for downcased ULIDs.
|
368
|
+
#
|
369
|
+
# ```ruby
|
370
|
+
# ULID.valid?(ULID.generate.to_s.downcase) #=> true
|
371
|
+
# ```
|
372
|
+
#
|
373
|
+
# See also [ulid/spec#57](https://github.com/ulid/spec/pull/57) and [ulid/spec#3](https://github.com/ulid/spec/issues/3)
|
374
|
+
def self.valid?: (_ToStr string) -> bool
|
375
|
+
| (untyped) -> false
|
335
376
|
|
336
377
|
# Returns parsed ULIDs from given String for rough operations.
|
337
378
|
#
|
@@ -411,7 +452,12 @@ class ULID < Object
|
|
411
452
|
# #=> true
|
412
453
|
# ```
|
413
454
|
#
|
414
|
-
# To be precise, this sorting unaffected with `case sensitive or not` and might handle [ulid/spec#57](https://github.com/ulid/spec/pull/57) in future.
|
455
|
+
# To be precise, this sorting unaffected with `case sensitive or not` and might handle [ulid/spec#57](https://github.com/ulid/spec/pull/57) in future.
|
456
|
+
# So preferable than `lexicographically sortable` in actual case.
|
457
|
+
#
|
458
|
+
# This returns -1 | 0 | 1 for ULIDs. However defined as returning Integer. It is caused on ruby/rbs current definition.
|
459
|
+
# https://github.com/ruby/ruby/blob/cd34f56d450f2310cceaf4c5f34d23eddfda58e8/numeric.c#L4646-L4660
|
460
|
+
# https://github.com/ruby/rbs/blob/14abbbae8885a09a2ed82de2ef31d67a9c0a108d/core/integer.rbs#L461-L462
|
415
461
|
#
|
416
462
|
def <=>: (ULID other) -> Integer
|
417
463
|
| (untyped other) -> nil
|
metadata
CHANGED
@@ -1,17 +1,17 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: ruby-ulid
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.5.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: 2022-07-
|
11
|
+
date: 2022-07-03 00:00:00.000000000 Z
|
12
12
|
dependencies: []
|
13
|
-
description: " generator,
|
14
|
-
|
13
|
+
description: " generator, optional monotonicity, parser and tools for ULID (RBS
|
14
|
+
included)\n"
|
15
15
|
email:
|
16
16
|
- kachick1+ruby@gmail.com
|
17
17
|
executables: []
|