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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 7b50cb3fee0b304a62ebd460e7d08b932d3c58c1f7810a1dc24b5166df10ceaf
4
- data.tar.gz: b84a2ad766640fa7c87e4bbb5b0fdd637bf831407f235989cdd043ea5b1189aa
3
+ metadata.gz: 4d7356366d0184815a725d1947f4f685b3abba0320ae60800b5a015dc7c649e9
4
+ data.tar.gz: 04b55b6d92dbf02865a7803be352f5cd385f3417c061269f2ad197474202154d
5
5
  SHA512:
6
- metadata.gz: e44eadac5ad4c83f1c8da74fbfa502a3b3b7293dda8eb44855bb477070687afd815d46237a9cc15266223f7cd0981b69670165767b366156d23728cdb76c878e
7
- data.tar.gz: 349b2e8c2b16d5c9ae58270fdb5e87a3c364eef4b3ae2972680cb5de119ba737ed035db36bb7283fc96ff7c7a54663be5de8c0725e0de1975d8f66de34dd052c
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, monotonic generator, parser and handy manipulation features around ULID.
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.4.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
- defined? ULID
62
- # => "constant"
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
- You can get the objects from exists encoded ULIDs.
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
- You can extract timestamps and binary formats.
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
- The basic generator prefers `randomness`, it does not guarantee `sortable` for same milliseconds ULIDs.
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
- ### Some methods to help manipulations
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
- Current parser/validator/matcher aims to cover `subset of Crockford's base32`.
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
- Be that as it may, this gem provides API for handling the nasty possibilities.
356
+ This gem provides some methods to handle the nasty possibilities.
359
357
 
360
- `ULID.normalize` and `ULID.normalized?`
358
+ `ULID.normalize`, `ULID.normalized?`, `ULID.valid_as_variant_format?` and `ULID.parse_variant_format`
361
359
 
362
360
  ```ruby
363
- ULID.normalize('-olarz3-noekisv4rrff-q6ig5fav--') #=> "01ARZ3N0EK1SV4RRFFQ61G5FAV"
364
- ULID.normalized?('-olarz3-noekisv4rrff-q6ig5fav--') #=> false
365
- ULID.normalized?('01ARZ3N0EK1SV4RRFFQ61G5FAV') #=> true
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 for migration use-cases
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
- ## How to migrate from other gems
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
- The results are not something to be proud of.
403
+ See [wiki page for gem migration](https://github.com/kachick/ruby-ulid/wiki/Gem-migration).
451
404
 
452
- ## How to use rbs
405
+ ## RBS
453
406
 
454
- See structure at [examples/rbs_sandbox](https://github.com/kachick/ruby-ulid/tree/main/examples/rbs_sandbox)
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
  * ![rbs overview](./assets/ulid-rbs-overview.png?raw=true.png)
459
412
  * ![rbs mix](./assets/ulid-rbs-mix.png?raw=true.png)
460
413
  * ![rbs ng-to_str](./assets/ulid-rbs-ng-to_str.png?raw=true.png)
461
- * ![rbs ok-at-time](./assets/ulid-rbs-ok-at-time.png?raw=true.png)
462
- * ![rbs ng-at-int](./assets/ulid-rbs-ng-at-int.png?raw=true.png)
463
414
 
464
415
  ## References
465
416
 
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.4.0'
6
+ VERSION = '0.5.0'
7
7
  end
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
- parse(normalized_in_crockford).to_s
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.normalized?(object)
285
- normalized = normalize(object)
305
+ def self.valid_as_variant_format?(string)
306
+ normalize(string)
286
307
  rescue Exception
287
308
  false
288
309
  else
289
- normalized == object
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?(object)
294
- string = String.try_convert(object)
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 [Integer, nil]
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.normalized?('-olarz3-noekisv4rrff-q6ig5fav--') #=> false
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.normalize('-olarz3-noekisv4rrff-q6ig5fav--') #=> "01ARZ3N0EK1SV4RRFFQ61G5FAV"
329
- # ULID.normalized?('-olarz3-noekisv4rrff-q6ig5fav--') #=> false
330
- # ULID.normalized?('01ARZ3N0EK1SV4RRFFQ61G5FAV') #=> true
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?: (untyped) -> bool
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. So preferable than `lexicographically sortable` in actual case.
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.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-02 00:00:00.000000000 Z
11
+ date: 2022-07-03 00:00:00.000000000 Z
12
12
  dependencies: []
13
- description: " generator, monotonic generator, parser and manipulations for ULID
14
- (RBS included)\n"
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: []