ruby-ulid 0.1.0 → 0.1.5

Sign up to get free protection for your applications and to get access to all the features.
data/lib/ulid/uuid.rb CHANGED
@@ -1,5 +1,6 @@
1
1
  # coding: us-ascii
2
2
  # frozen_string_literal: true
3
+
3
4
  # Copyright (C) 2021 Kenichi Kamiya
4
5
 
5
6
  # Extracted features around UUID from some reasons
@@ -8,7 +9,7 @@
8
9
  # * https://github.com/kachick/ruby-ulid/issues/76
9
10
  class ULID
10
11
  # Imported from https://stackoverflow.com/a/38191104/1212807, thank you!
11
- UUIDV4_PATTERN = /\A[0-9A-F]{8}-[0-9A-F]{4}-[4][0-9A-F]{3}-[89AB][0-9A-F]{3}-[0-9A-F]{12}\z/i.freeze
12
+ UUIDV4_PATTERN = /\A[0-9A-F]{8}-[0-9A-F]{4}-4[0-9A-F]{3}-[89AB][0-9A-F]{3}-[0-9A-F]{12}\z/i.freeze
12
13
  private_constant :UUIDV4_PATTERN
13
14
 
14
15
  # @param [String, #to_str] uuid
@@ -18,7 +19,7 @@ class ULID
18
19
  uuid = String.try_convert(uuid)
19
20
  raise ArgumentError, 'ULID.from_uuidv4 takes only strings' unless uuid
20
21
 
21
- prefix_trimmed = uuid.sub(/\Aurn:uuid:/, '')
22
+ prefix_trimmed = uuid.delete_prefix('urn:uuid:')
22
23
  unless UUIDV4_PATTERN.match?(prefix_trimmed)
23
24
  raise ParserError, "given `#{uuid}` does not match to `#{UUIDV4_PATTERN.inspect}`"
24
25
  end
data/lib/ulid/version.rb CHANGED
@@ -2,5 +2,5 @@
2
2
  # frozen_string_literal: true
3
3
 
4
4
  class ULID
5
- VERSION = '0.1.0'
5
+ VERSION = '0.1.5'
6
6
  end
data/sig/ulid.rbs CHANGED
@@ -1,5 +1,4 @@
1
- # Classes
2
- class ULID
1
+ class ULID < Object
3
2
  VERSION: String
4
3
  CROCKFORD_BASE32_ENCODING_STRING: String
5
4
  TIMESTAMP_ENCODED_LENGTH: 10
@@ -33,6 +32,9 @@ class ULID
33
32
  class ParserError < Error
34
33
  end
35
34
 
35
+ class UnexpectedError < Error
36
+ end
37
+
36
38
  module CrockfordBase32
37
39
  class SetupError < ScriptError
38
40
  end
@@ -41,27 +43,65 @@ class ULID
41
43
  CROCKFORD_BASE32_CHAR_PATTERN: Regexp
42
44
  CROCKFORD_BASE32_CHAR_BY_N32_CHAR: Hash[String, String]
43
45
  N32_CHAR_PATTERN: Regexp
46
+ STANDARD_BY_VARIANT: Hash[String, String]
47
+ VARIANT_PATTERN: Regexp
44
48
 
49
+ # A pribate API. Should not be used in your code.
45
50
  def self.encode: (Integer integer) -> String
51
+
52
+ # A pribate API. Should not be used in your code.
46
53
  def self.decode: (String string) -> Integer
54
+
55
+ # A pribate API. Should not be used in your code.
56
+ def self.normalize: (String string) -> String
47
57
  end
48
58
 
49
59
  class MonotonicGenerator
50
- attr_accessor latest_milliseconds: Integer
51
- attr_accessor latest_entropy: Integer
60
+ include MonitorMixin
61
+
62
+ # Returned value is `basically not` Thread-safety
63
+ # If you want to keep Thread-safety, keep to call {#generate} only in same {#synchronize} block
64
+ #
65
+ # ```ruby
66
+ # generator.synchronize do
67
+ # generator.prev
68
+ # generator.inspect
69
+ # generator.generate
70
+ # end
71
+ # ```
72
+ attr_reader prev: ULID | nil
73
+
74
+ # A pribate API. Should not be used in your code.
52
75
  def initialize: -> void
76
+
77
+ # See [How to keep `Sortable` even if in same timestamp](https://github.com/kachick/ruby-ulid#how-to-keep-sortable-even-if-in-same-timestamp)
78
+ # The `Thread-safety` is implemented with [Monitor](https://bugs.ruby-lang.org/issues/16255)
53
79
  def generate: (?moment: moment) -> ULID
54
- def reset: -> void
80
+
81
+ # Returned value is `basically not` Thread-safety
82
+ # If you want to keep Thread-safety, keep to call {#generate} only in same {#synchronize} block
83
+ #
84
+ # ```ruby
85
+ # generator.synchronize do
86
+ # generator.prev
87
+ # generator.inspect
88
+ # generator.generate
89
+ # end
90
+ # ```
91
+ def inspect: -> String
92
+ alias to_s inspect
55
93
  def freeze: -> void
56
94
  end
57
95
 
96
+ interface _ToULID
97
+ def to_ulid: () -> ULID
98
+ end
99
+
58
100
  type octets = [Integer, Integer, Integer, Integer, Integer, Integer, Integer, Integer, Integer, Integer, Integer, Integer, Integer, Integer, Integer, Integer]
59
101
  type timestamp_octets = [Integer, Integer, Integer, Integer, Integer, Integer]
60
102
  type randomness_octets = [Integer, Integer, Integer, Integer, Integer, Integer, Integer, Integer, Integer, Integer]
61
103
  type period = Range[Time] | Range[nil] | Range[ULID]
62
104
 
63
- @milliseconds: Integer
64
- @entropy: Integer
65
105
  @string: String?
66
106
  @integer: Integer
67
107
  @timestamp: String?
@@ -69,53 +109,437 @@ class ULID
69
109
  @inspect: String?
70
110
  @time: Time?
71
111
 
72
- def self.generate: (?moment: moment, ?entropy: Integer) -> self
73
- def self.at: (Time time) -> self
112
+ # Retuns a ULID
113
+ #
114
+ # They are sortable when generated in different timestamp with milliseconds precision
115
+ #
116
+ # ```ruby
117
+ # ulids = 1000.times.map do
118
+ # sleep(0.001)
119
+ # ULID.generate
120
+ # end
121
+ # ulids.uniq(&:to_time).size #=> 1000
122
+ # ulids.sort == ulids #=> true
123
+ # ```
124
+ #
125
+ # `ULID.generate` can take fixed `Time` instance.
126
+ # See also the short hand [ULID.at](https://kachick.github.io/ruby-ulid/ULID.html#at-class_method)
127
+ #
128
+ # ```ruby
129
+ # time = Time.at(946684800).utc #=> 2000-01-01 00:00:00 UTC
130
+ # ULID.generate(moment: time) #=> ULID(2000-01-01 00:00:00.000 UTC: 00VHNCZB00N018DCPJA4H9379P)
131
+ # ULID.generate(moment: time) #=> ULID(2000-01-01 00:00:00.000 UTC: 00VHNCZB006WQT3JTMN0T14EBP)
132
+ # ```
133
+ #
134
+ # The basic generator prefers `randomness`, it does not guarantee `sortable` for same milliseconds ULIDs.
135
+ #
136
+ # ```ruby
137
+ # ulids = 10000.times.map do
138
+ # ULID.generate
139
+ # end
140
+ # ulids.uniq(&:to_time).size #=> 35 (the size is not fixed, might be changed in environment)
141
+ # ulids.sort == ulids #=> false
142
+ # ```
143
+ #
144
+ # If you want to keep sortable even if in same timestamp, See also [ULID::MonotonicGenerator](https://github.com/kachick/ruby-ulid#how-to-keep-sortable-even-if-in-same-timestamp)
145
+ #
146
+ def self.generate: (?moment: moment, ?entropy: Integer) -> ULID
147
+
148
+ # Shorthand of `ULID.generate(moment: Time)`
149
+ # See also [ULID.generate](https://kachick.github.io/ruby-ulid/ULID.html#generate-class_method)
150
+ #
151
+ # ```ruby
152
+ # time = Time.at(946684800).utc #=> 2000-01-01 00:00:00 UTC
153
+ # ULID.at(time) #=> ULID(2000-01-01 00:00:00.000 UTC: 00VHNCZB002W5BGWWKN76N22H6)
154
+ #
155
+ # ulids = 1000.times.map do |n|
156
+ # ULID.at(time + n)
157
+ # end
158
+ # ulids.sort == ulids #=> true
159
+ # ```
160
+ def self.at: (Time time) -> ULID
161
+
162
+ # A pribate API. Should not be used in your code.
74
163
  def self.current_milliseconds: -> Integer
164
+
165
+ # A pribate API. Should not be used in your code.
75
166
  def self.milliseconds_from_moment: (moment moment) -> Integer
167
+
168
+ # `ULID` can be element of the `Range`. If you generated the IDs in monotonic generator, ID based filtering is easy and reliable
169
+ #
170
+ # ```ruby
171
+ # include_end = ulid1..ulid2
172
+ # exclude_end = ulid1...ulid2
173
+ #
174
+ # ulids.grep(one_of_the_above)
175
+ # ulids.grep_v(one_of_the_above)
176
+ # ```
177
+ #
178
+ # When want to filter ULIDs with `Time`, we should consider to handle the precision.
179
+ # So this gem provides `ULID.range` to generate reasonable `Range[ULID]` from `Range[Time]`
180
+ #
181
+ # ```ruby
182
+ # # Both of below, The begin of `Range[ULID]` will be the minimum in the floored milliseconds of the time1
183
+ # include_end = ULID.range(time1..time2) #=> The end of `Range[ULID]` will be the maximum in the floored milliseconds of the time2
184
+ # exclude_end = ULID.range(time1...time2) #=> The end of `Range[ULID]` will be the minimum in the floored milliseconds of the time2
185
+ #
186
+ # # Below patterns are acceptable
187
+ # pinpointing = ULID.range(time1..time1) #=> This will match only for all IDs in `time1`
188
+ # until_the_end = ULID.range(..time1) #=> This will match only for all IDs upto `time1` (The `nil` starting `Range` can be used since Ruby 2.7)
189
+ # until_the_end = ULID.range(ULID.min.to_time..time1) #=> This is same as above for Ruby 2.6
190
+ # until_the_ulid_limit = ULID.range(time1..) # This will match only for all IDs from `time1` to max value of the ULID limit
191
+ #
192
+ # # So you can use the generated range objects as below
193
+ # ulids.grep(one_of_the_above)
194
+ # ulids.grep_v(one_of_the_above)
195
+ # #=> I hope the results should be actually you want!
196
+ # ```
197
+ #
76
198
  def self.range: (period period) -> Range[ULID]
199
+
200
+ # Returns new `Time` with truncating excess precisions in ULID spec.
201
+ #
202
+ # ```ruby
203
+ # time = Time.at(946684800, Rational('123456.789')).utc
204
+ # #=> 2000-01-01 00:00:00.123456789 UTC
205
+ # ULID.floor(time) #=> 2000-01-01 00:00:00.123 UTC
206
+ # ```
77
207
  def self.floor: (Time time) -> Time
78
- def self.reasonable_entropy: -> Integer
79
- def self.parse: (String string) -> self
208
+
209
+ # Get ULID instance from encoded String.
210
+ #
211
+ # ```ruby
212
+ # ulid = ULID.parse('01ARZ3NDEKTSV4RRFFQ69G5FAV')
213
+ # #=> ULID(2016-07-30 23:54:10.259 UTC: 01ARZ3NDEKTSV4RRFFQ69G5FAV)
214
+ # ```
215
+ def self.parse: (_ToStr string) -> ULID
216
+
217
+ # ```ruby
218
+ # # Currently experimental feature, so needed to load the extension.
219
+ # require 'ulid/uuid'
220
+ #
221
+ # # Basically reversible
222
+ # ulid = ULID.from_uuidv4('0983d0a2-ff15-4d83-8f37-7dd945b5aa39')
223
+ # #=> ULID(2301-07-10 00:28:28.821 UTC: 09GF8A5ZRN9P1RYDVXV52VBAHS)
224
+ # ulid.to_uuidv4 #=> "0983d0a2-ff15-4d83-8f37-7dd945b5aa39"
225
+ # ```
226
+ #
227
+ # See also [Why this is experimental?](https://github.com/kachick/ruby-ulid/issues/76)
80
228
  def self.from_uuidv4: (String uuid) -> ULID
81
- def self.from_integer: (Integer integer) -> self
229
+ def self.from_integer: (Integer integer) -> ULID
230
+
231
+ # Returns termination values for ULID spec.
232
+ #
233
+ # ```ruby
234
+ # ULID.min
235
+ # #=> ULID(1970-01-01 00:00:00.000 UTC: 00000000000000000000000000)
236
+ # ```
237
+ #
238
+ # It can take `Time` instance as an optional argument.
239
+ # Then returns ULID that has minimum value of randomness part in the timestamp.
240
+ #
241
+ # ```ruby
242
+ # time = Time.at(946684800, Rational('123456.789')).utc
243
+ # #=> 2000-01-01 00:00:00.123456789 UTC
244
+ # ULID.min(time)
245
+ # #=> ULID(2000-01-01 00:00:00.123 UTC: 00VHNCZB3V0000000000000000)
246
+ # ```
247
+ #
248
+ # See also [ULID.max](https://kachick.github.io/ruby-ulid/ULID.html#max-class_method)
82
249
  def self.min: (?moment moment) -> ULID
250
+
251
+ # Returns termination values for ULID spec.
252
+ #
253
+ # ```ruby
254
+ # ULID.max
255
+ # #=> ULID(10889-08-02 05:31:50.655 UTC: 7ZZZZZZZZZZZZZZZZZZZZZZZZZ)
256
+ # ```
257
+ #
258
+ # It can take `Time` instance as an optional argument.
259
+ # Then returns ULID that has maximum value of randomness part in the timestamp.
260
+ #
261
+ # ```ruby
262
+ # time = Time.at(946684800, Rational('123456.789')).utc
263
+ # #=> 2000-01-01 00:00:00.123456789 UTC
264
+ # ULID.max(time)
265
+ # #=> ULID(2000-01-01 00:00:00.123 UTC: 00VHNCZB3VZZZZZZZZZZZZZZZZ)
266
+ # ```
267
+ #
268
+ # See also [ULID.min](https://kachick.github.io/ruby-ulid/ULID.html#min-class_method)
83
269
  def self.max: (?moment moment) -> ULID
84
- def self.sample: (?period: period) -> self
85
- | (Integer number, ?period: period) -> Array[self]
86
- def self.valid?: (untyped string) -> bool
87
- def self.scan: (String string) -> Enumerator[self, singleton(ULID)]
88
- | (String string) { (self ulid) -> void } -> singleton(ULID)
89
- def self.from_milliseconds_and_entropy: (milliseconds: Integer, entropy: Integer) -> self
270
+
271
+ # Returns random ULIDs.
272
+ #
273
+ # Basically ignores generating time.
274
+ #
275
+ # ```ruby
276
+ # ULID.sample #=> ULID(2545-07-26 06:51:20.085 UTC: 0GGKQ45GMNMZR6N8A8GFG0ZXST)
277
+ # ULID.sample #=> ULID(5098-07-26 21:31:06.946 UTC: 2SSBNGGYA272J7BMDCG4Z6EEM5)
278
+ # ULID.sample(0) #=> []
279
+ # ULID.sample(1) #=> [ULID(2241-04-16 03:31:18.440 UTC: 07S52YWZ98AZ8T565MD9VRYMQH)]
280
+ # ULID.sample(5)
281
+ # #=>
282
+ # #[ULID(5701-04-29 12:41:19.647 UTC: 3B2YH2DV0ZYDDATGTYSKMM1CMT),
283
+ # # ULID(2816-08-01 01:21:46.612 UTC: 0R9GT6RZKMK3RG02Q2HAFVKEY2),
284
+ # # ULID(10408-10-05 17:06:27.848 UTC: 7J6CPTEEC86Y24EQ4F1Y93YYN0),
285
+ # # ULID(2741-09-02 16:24:18.803 UTC: 0P4Q4V34KKAJW46QW47WQB5463),
286
+ # # ULID(2665-03-16 14:50:22.724 UTC: 0KYFW9DWM4CEGFNTAC6YFAVVJ6)]
287
+ # ```
288
+ #
289
+ # You can specify a range object for the timestamp restriction, See also [ULID.range](https://kachick.github.io/ruby-ulid/ULID.html#range-class_method).
290
+ #
291
+ # ```ruby
292
+ # ulid1 = ULID.parse('01F4A5Y1YAQCYAYCTC7GRMJ9AA') #=> ULID(2021-04-27 17:27:22.826 UTC: 01F4A5Y1YAQCYAYCTC7GRMJ9AA)
293
+ # ulid2 = ULID.parse('01F4PTVCSN9ZPFKYTY2DDJVRK4') #=> ULID(2021-05-02 15:23:48.917 UTC: 01F4PTVCSN9ZPFKYTY2DDJVRK4)
294
+ # ulids = ULID.sample(1000, period: ulid1..ulid2)
295
+ # ulids.uniq.size #=> 1000
296
+ # ulids.take(10)
297
+ # #=>
298
+ # #[ULID(2021-05-02 06:57:19.954 UTC: 01F4NXW02JNB8H0J0TK48JD39X),
299
+ # # ULID(2021-05-02 07:06:07.458 UTC: 01F4NYC372GVP7NS0YAYQGT4VZ),
300
+ # # ULID(2021-05-01 06:16:35.791 UTC: 01F4K94P6F6P68K0H64WRDSFKW),
301
+ # # ULID(2021-04-27 22:17:37.844 UTC: 01F4APHGSMFJZQTGXKZBFFBPJP),
302
+ # # ULID(2021-04-28 20:17:55.357 UTC: 01F4D231MXQJXAR8G2JZHEJNH3),
303
+ # # ULID(2021-04-30 07:18:54.307 UTC: 01F4GTA2332AS2VPHC4FMKC7R5),
304
+ # # ULID(2021-05-02 12:26:03.480 UTC: 01F4PGNXARG554Y3HYVBDW4T9S),
305
+ # # ULID(2021-04-29 09:52:15.107 UTC: 01F4EGP483ZX2747FQPWQNPPMW),
306
+ # # ULID(2021-04-29 03:18:24.152 UTC: 01F4DT4Z4RA0QV8WFQGRAG63EH),
307
+ # # ULID(2021-05-02 13:27:16.394 UTC: 01F4PM605ABF5SDVMEHBH8JJ9R)]
308
+ # ULID.sample(10, period: ulid1.to_time..ulid2.to_time)
309
+ # #=>
310
+ # # [ULID(2021-04-29 06:44:41.513 UTC: 01F4E5YPD9XQ3MYXWK8ZJKY8SW),
311
+ # # ULID(2021-05-01 00:35:06.629 UTC: 01F4JNKD85SVK1EAEYSJGF53A2),
312
+ # # ULID(2021-05-02 12:45:28.408 UTC: 01F4PHSEYRG9BWBEWMRW1XE6WW),
313
+ # # ULID(2021-05-01 03:06:09.130 UTC: 01F4JY7ZBABCBMX16XH2Q4JW4W),
314
+ # # ULID(2021-04-29 21:38:58.109 UTC: 01F4FS45DX4049JEQK4W6TER6G),
315
+ # # ULID(2021-04-29 17:14:14.116 UTC: 01F4F9ZDQ449BE8BBZFEHYQWG2),
316
+ # # ULID(2021-04-30 16:18:08.205 UTC: 01F4HS5DPD1HWDVJNJ6YKJXKSK),
317
+ # # ULID(2021-04-30 10:31:33.602 UTC: 01F4H5ATF2A1CSQF0XV5NKZ288),
318
+ # # ULID(2021-04-28 16:49:06.484 UTC: 01F4CP4PDM214Q6H3KJP7DYJRR),
319
+ # # ULID(2021-04-28 15:05:06.808 UTC: 01F4CG68ZRST94T056KRZ5K9S4)]
320
+ # ```
321
+ def self.sample: (?period: period) -> ULID
322
+ | (Integer number, ?period: period) -> Array[ULID]
323
+ def self.valid?: (untyped) -> bool
324
+
325
+ # Returns normalized string
326
+ #
327
+ # ```ruby
328
+ # ULID.normalize('-olarz3-noekisv4rrff-q6ig5fav--') #=> "01ARZ3N0EK1SV4RRFFQ61G5FAV"
329
+ # ULID.normalized?('-olarz3-noekisv4rrff-q6ig5fav--') #=> false
330
+ # ULID.normalized?('01ARZ3N0EK1SV4RRFFQ61G5FAV') #=> true
331
+ # ```
332
+ #
333
+ # 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.normalize: (_ToStr string) -> String
335
+
336
+ # Returns `true` if it is normalized string
337
+ #
338
+ # ```ruby
339
+ # ULID.normalize('-olarz3-noekisv4rrff-q6ig5fav--') #=> "01ARZ3N0EK1SV4RRFFQ61G5FAV"
340
+ # ULID.normalized?('-olarz3-noekisv4rrff-q6ig5fav--') #=> false
341
+ # ULID.normalized?('01ARZ3N0EK1SV4RRFFQ61G5FAV') #=> true
342
+ # ```
343
+ #
344
+ # See also [ulid/spec#57](https://github.com/ulid/spec/pull/57) and [ulid/spec#3](https://github.com/ulid/spec/issues/3)
345
+ def self.normalized?: (untyped) -> bool
346
+
347
+ # Returns parsed ULIDs from given String for rough operations.
348
+ #
349
+ # ```ruby
350
+ # json =<<'EOD'
351
+ # {
352
+ # "id": "01F4GNAV5ZR6FJQ5SFQC7WDSY3",
353
+ # "author": {
354
+ # "id": "01F4GNBXW1AM2KWW52PVT3ZY9X",
355
+ # "name": "kachick"
356
+ # },
357
+ # "title": "My awesome blog post",
358
+ # "comments": [
359
+ # {
360
+ # "id": "01F4GNCNC3CH0BCRZBPPDEKBKS",
361
+ # "commenter": {
362
+ # "id": "01F4GNBXW1AM2KWW52PVT3ZY9X",
363
+ # "name": "kachick"
364
+ # }
365
+ # },
366
+ # {
367
+ # "id": "01F4GNCXAMXQ1SGBH5XCR6ZH0M",
368
+ # "commenter": {
369
+ # "id": "01F4GND4RYYSKNAADHQ9BNXAWJ",
370
+ # "name": "pankona"
371
+ # }
372
+ # }
373
+ # ]
374
+ # }
375
+ # EOD
376
+ #
377
+ # ULID.scan(json).to_a
378
+ # #=>
379
+ # # [ULID(2021-04-30 05:51:57.119 UTC: 01F4GNAV5ZR6FJQ5SFQC7WDSY3),
380
+ # # ULID(2021-04-30 05:52:32.641 UTC: 01F4GNBXW1AM2KWW52PVT3ZY9X),
381
+ # # ULID(2021-04-30 05:52:56.707 UTC: 01F4GNCNC3CH0BCRZBPPDEKBKS),
382
+ # # ULID(2021-04-30 05:52:32.641 UTC: 01F4GNBXW1AM2KWW52PVT3ZY9X),
383
+ # # ULID(2021-04-30 05:53:04.852 UTC: 01F4GNCXAMXQ1SGBH5XCR6ZH0M),
384
+ # # ULID(2021-04-30 05:53:12.478 UTC: 01F4GND4RYYSKNAADHQ9BNXAWJ)]
385
+ # ```
386
+ def self.scan: (_ToStr string) -> Enumerator[self, singleton(ULID)]
387
+ | (_ToStr string) { (ULID ulid) -> void } -> singleton(ULID)
388
+ def self.from_milliseconds_and_entropy: (milliseconds: Integer, entropy: Integer) -> ULID
389
+ def self.try_convert: (_ToULID) -> ULID
390
+ | (untyped) -> nil
391
+
392
+ # ```ruby
393
+ # ulid = ULID.generate
394
+ # #=> ULID(2021-04-27 17:27:22.826 UTC: 01F4A5Y1YAQCYAYCTC7GRMJ9AA)
395
+ # ulid.milliseconds #=> 1619544442826
396
+ # ```
90
397
  attr_reader milliseconds: Integer
91
398
  attr_reader entropy: Integer
92
- def initialize: (milliseconds: Integer, entropy: Integer, integer: Integer) -> void
399
+
400
+ # ```ruby
401
+ # ulid = ULID.generate
402
+ # #=> ULID(2021-04-27 17:27:22.826 UTC: 01F4A5Y1YAQCYAYCTC7GRMJ9AA)
403
+ # ulid.to_s #=> "01F4A5Y1YAQCYAYCTC7GRMJ9AA"
404
+ # ```
93
405
  def to_s: -> String
406
+
407
+ # ```ruby
408
+ # ulid = ULID.generate
409
+ # #=> ULID(2021-04-27 17:27:22.826 UTC: 01F4A5Y1YAQCYAYCTC7GRMJ9AA)
410
+ # ulid.to_i #=> 1957909092946624190749577070267409738
411
+ # ```
94
412
  def to_i: -> Integer
95
413
  alias hash to_i
414
+
415
+ # Basically same as String based sort.
416
+ #
417
+ # ```ruby
418
+ # ulids = ULID.sample(10000); nil
419
+ # ulids.map(&:to_s).sort == ulids.sort.map(&:to_s)
420
+ # #=> true
421
+ # ```
422
+ #
423
+ # 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.
424
+ #
96
425
  def <=>: (ULID other) -> Integer
97
426
  | (untyped other) -> nil
427
+
428
+ # ```ruby
429
+ # ulid = ULID.generate
430
+ # ulid.inspect #=> "ULID(2021-04-27 17:27:22.826 UTC: 01F4A5Y1YAQCYAYCTC7GRMJ9AA)"
431
+ # ```
98
432
  def inspect: -> String
433
+
434
+ # ```ruby
435
+ # ULID.parse('4NNB20D9C1ME2NGMTX51ERZJX0') == ULID.parse('4nnb20d9c1me2ngmtx51erzjx0')
436
+ # #=> true
437
+ # ```
99
438
  def eql?: (untyped other) -> bool
100
439
  alias == eql?
101
440
  def ===: (untyped other) -> bool
441
+
442
+ # ```ruby
443
+ # ulid = ULID.generate
444
+ # #=> ULID(2021-04-27 17:27:22.826 UTC: 01F4A5Y1YAQCYAYCTC7GRMJ9AA)
445
+ # ulid.to_time #=> 2021-04-27 17:27:22.826 UTC
446
+ # ```
102
447
  def to_time: -> Time
448
+
449
+ # ```ruby
450
+ # ulid = ULID.generate
451
+ # #=> ULID(2021-04-27 17:27:22.826 UTC: 01F4A5Y1YAQCYAYCTC7GRMJ9AA)
452
+ # ulid.timestamp #=> "01F4A5Y1YA"
453
+ # ```
103
454
  def timestamp: -> String
455
+
456
+ # ```ruby
457
+ # ulid = ULID.generate
458
+ # #=> ULID(2021-04-27 17:27:22.826 UTC: 01F4A5Y1YAQCYAYCTC7GRMJ9AA)
459
+ # ulid.randomness #=> "QCYAYCTC7GRMJ9AA"
460
+ # ```
104
461
  def randomness: -> String
462
+
463
+ # Intentionally avoiding to use `Record type` ref: https://github.com/ruby/rbs/blob/4fb4c33b2325d1a73d79ff7aaeb49f21cec1e0e5/docs/syntax.md#record-type
464
+ # Because the returning values are not fixed.
105
465
  def patterns: -> Hash[Symbol, Regexp | String]
106
466
  def octets: -> octets
107
467
  def timestamp_octets: -> timestamp_octets
108
468
  def randomness_octets: -> randomness_octets
469
+
470
+ # ```ruby
471
+ # # Currently experimental feature, so needed to load the extension.
472
+ # require 'ulid/uuid'
473
+ #
474
+ # # Basically reversible
475
+ # ulid = ULID.from_uuidv4('0983d0a2-ff15-4d83-8f37-7dd945b5aa39')
476
+ # #=> ULID(2301-07-10 00:28:28.821 UTC: 09GF8A5ZRN9P1RYDVXV52VBAHS)
477
+ # ulid.to_uuidv4 #=> "0983d0a2-ff15-4d83-8f37-7dd945b5aa39"
478
+ # ```
479
+ #
480
+ # See also [Why this is experimental?](https://github.com/kachick/ruby-ulid/issues/76)
109
481
  def to_uuidv4: -> String
110
- def next: -> ULID?
111
- alias succ next
482
+
483
+ # Returns next(successor) ULID.
484
+ # Especially `ULID#succ` makes it possible `Range[ULID]#each`.
485
+ #
486
+ # NOTE: But basically `Range[ULID]#each` should not be used, incrementing 128 bits IDs are not reasonable operation in most case
487
+ #
488
+ # ```ruby
489
+ # ULID.parse('01BX5ZZKBKZZZZZZZZZZZZZZZY').next.to_s #=> "01BX5ZZKBKZZZZZZZZZZZZZZZZ"
490
+ # ULID.parse('01BX5ZZKBKZZZZZZZZZZZZZZZZ').next.to_s #=> "01BX5ZZKBM0000000000000000"
491
+ # ULID.parse('7ZZZZZZZZZZZZZZZZZZZZZZZZZ').next #=> nil
492
+ # ```
493
+ #
494
+ # See also [ULID#pred](https://kachick.github.io/ruby-ulid/ULID.html#pred-instance_method)
495
+ def succ: -> ULID?
496
+ alias next succ
497
+
498
+ # Returns predecessor ULID.
499
+ #
500
+ # ```ruby
501
+ # ULID.parse('01BX5ZZKBK0000000000000001').pred.to_s #=> "01BX5ZZKBK0000000000000000"
502
+ # ULID.parse('01BX5ZZKBK0000000000000000').pred.to_s #=> "01BX5ZZKBJZZZZZZZZZZZZZZZZ"
503
+ # ULID.parse('00000000000000000000000000').pred #=> nil
504
+ # ```
505
+ #
506
+ # See also [ULID#succ](https://kachick.github.io/ruby-ulid/ULID.html#succ-instance_method)
112
507
  def pred: -> ULID?
113
508
  def freeze: -> self
509
+
510
+ # A pribate API. Should not be used in your code.
511
+ def marshal_dump: -> Integer
512
+
513
+ # A pribate API. Should not be used in your code.
514
+ def marshal_load: (Integer integer) -> void
515
+
516
+ # Returns `self`
517
+ def to_ulid: -> self
518
+
519
+ # Returns `self`. Not a new instance.
114
520
  def dup: -> self
115
- # Same as https://github.com/ruby/rbs/blob/4fb4c33b2325d1a73d79ff7aaeb49f21cec1e0e5/core/object.rbs#L79
521
+
522
+ # Same API as [Object#clone](https://github.com/ruby/rbs/blob/4fb4c33b2325d1a73d79ff7aaeb49f21cec1e0e5/core/object.rbs#L79)
523
+ # But actually returns `self`. Not a new instance.
116
524
  def clone: (?freeze: bool) -> self
117
525
 
118
526
  private
527
+
528
+ # A pribate API. Should not be used in your code.
529
+ def self.new: (milliseconds: Integer, entropy: Integer, integer: Integer) -> self
530
+
531
+ # A pribate API. Should not be used in your code.
532
+ def self.reasonable_entropy: -> Integer
533
+
534
+ # A pribate API. Should not be used in your code.
119
535
  def self.milliseconds_from_time: (Time time) -> Integer
536
+
537
+ # A pribate API. Should not be used in your code.
538
+ def self.safe_get_class_name: (untyped object) -> String
539
+
540
+ # A pribate API. Should not be used in your code.
541
+ def initialize: (milliseconds: Integer, entropy: Integer, integer: Integer) -> void
542
+
543
+ # A pribate API. Should not be used in your code.
120
544
  def cache_all_instance_variables: -> void
121
545
  end