ruby-ulid 0.4.0 → 0.5.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: 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: []