Skip to content

Commit 3e8145c

Browse files
committed
Add missing signatures for Random::Formatter
* uuid_v4 * uuid_v7 * gen_random * choose
1 parent 11bddb4 commit 3e8145c

2 files changed

Lines changed: 136 additions & 0 deletions

File tree

stdlib/random-formatter/0/random-formatter.rbs

Lines changed: 112 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -129,6 +129,89 @@ module RBS
129129
#
130130
def uuid: () -> String
131131

132+
# <!--
133+
# rdoc-file=lib/random/formatter.rb
134+
# - uuid_v4()
135+
# -->
136+
#
137+
%a{annotate:rdoc:copy:Random::Formatter#uuid_v4}
138+
alias uuid_v4 uuid
139+
140+
# <!--
141+
# rdoc-file=lib/random/formatter.rb
142+
# - uuid_v7(extra_timestamp_bits: 0)
143+
# -->
144+
# Generate a random v7 UUID (Universally Unique IDentifier).
145+
#
146+
# require 'random/formatter'
147+
#
148+
# Random.uuid_v7 # => "0188d4c3-1311-7f96-85c7-242a7aa58f1e"
149+
# Random.uuid_v7 # => "0188d4c3-16fe-744f-86af-38fa04c62bb5"
150+
# Random.uuid_v7 # => "0188d4c3-1af8-764f-b049-c204ce0afa23"
151+
# Random.uuid_v7 # => "0188d4c3-1e74-7085-b14f-ef6415dc6f31"
152+
# # |<--sorted-->| |<----- random ---->|
153+
#
154+
# # or
155+
# prng = Random.new
156+
# prng.uuid_v7 # => "0188ca51-5e72-7950-a11d-def7ff977c98"
157+
#
158+
# The version 7 UUID starts with the least significant 48 bits of a 64 bit Unix
159+
# timestamp (milliseconds since the epoch) and fills the remaining bits with
160+
# random data, excluding the version and variant bits.
161+
#
162+
# This allows version 7 UUIDs to be sorted by creation time. Time ordered UUIDs
163+
# can be used for better database index locality of newly inserted records,
164+
# which may have a significant performance benefit compared to random data
165+
# inserts.
166+
#
167+
# The result contains 74 random bits (9.25 random bytes).
168+
#
169+
# Note that this method cannot be made reproducible because its output includes
170+
# not only random bits but also timestamp.
171+
#
172+
# See [RFC9562](https://www.rfc-editor.org/rfc/rfc9562) for details of UUIDv7.
173+
#
174+
# #### Monotonicity
175+
#
176+
# UUIDv7 has millisecond precision by default, so multiple UUIDs created within
177+
# the same millisecond are not issued in monotonically increasing order. To
178+
# create UUIDs that are time-ordered with sub-millisecond precision, up to 12
179+
# bits of additional timestamp may added with `extra_timestamp_bits`. The extra
180+
# timestamp precision comes at the expense of random bits. Setting
181+
# `extra_timestamp_bits: 12` provides ~244ns of precision, but only 62 random
182+
# bits (7.75 random bytes).
183+
#
184+
# prng = Random.new
185+
# Array.new(4) { prng.uuid_v7(extra_timestamp_bits: 12) }
186+
# # =>
187+
# ["0188d4c7-13da-74f9-8b53-22a786ffdd5a",
188+
# "0188d4c7-13da-753b-83a5-7fb9b2afaeea",
189+
# "0188d4c7-13da-754a-88ea-ac0baeedd8db",
190+
# "0188d4c7-13da-7557-83e1-7cad9cda0d8d"]
191+
# # |<--- sorted --->| |<-- random --->|
192+
#
193+
# Array.new(4) { prng.uuid_v7(extra_timestamp_bits: 8) }
194+
# # =>
195+
# ["0188d4c7-3333-7a95-850a-de6edb858f7e",
196+
# "0188d4c7-3333-7ae8-842e-bc3a8b7d0cf9", # <- out of order
197+
# "0188d4c7-3333-7ae2-995a-9f135dc44ead", # <- out of order
198+
# "0188d4c7-3333-7af9-87c3-8f612edac82e"]
199+
# # |<--- sorted -->||<---- random --->|
200+
#
201+
# Any rollbacks of the system clock will break monotonicity. UUIDv7 is based on
202+
# UTC, which excludes leap seconds and can rollback the clock. To avoid this,
203+
# the system clock can synchronize with an NTP server configured to use a "leap
204+
# smear" approach. NTP or PTP will also be needed to synchronize across
205+
# distributed nodes.
206+
#
207+
# Counters and other mechanisms for stronger guarantees of monotonicity are not
208+
# implemented. Applications with stricter requirements should follow [Section
209+
# 6.2](https://www.rfc-editor.org/rfc/rfc9562.html#name-monotonicity-and-counter
210+
# s) of the specification.
211+
#
212+
%a{annotate:rdoc:copy:Random::Formatter#uuid_v7}
213+
def uuid_v7: (?extra_timestamp_bits: Integer) -> String
214+
132215
# <!--
133216
# rdoc-file=lib/random/formatter.rb
134217
# - alphanumeric(n = nil, chars: ALPHANUMERIC)
@@ -157,6 +240,35 @@ module RBS
157240
# prng.alphanumeric(10, chars: [*"!".."/"]) #=> ",.,++%/''."
158241
#
159242
def alphanumeric: (?Numeric?, ?chars: Array[String]) -> String
243+
244+
# <!--
245+
# rdoc-file=lib/random/formatter.rb
246+
# - gen_random(n)
247+
# -->
248+
# Internal interface to Random; Generate random data *n* bytes.
249+
#
250+
%a{annotate:rdoc:copy:Random::Formatter#gen_random}
251+
private def gen_random: (Integer n) -> String
252+
253+
# <!--
254+
# rdoc-file=lib/random/formatter.rb
255+
# - choose(source, n)
256+
# -->
257+
# Generate a string that randomly draws from a source array of characters.
258+
#
259+
# The argument *source* specifies the array of characters from which to generate
260+
# the string. The argument *n* specifies the length, in characters, of the
261+
# string to be generated.
262+
#
263+
# The result may contain whatever characters are in the source array.
264+
#
265+
# require 'random/formatter'
266+
#
267+
# prng.choose([*'l'..'r'], 16) #=> "lmrqpoonmmlqlron"
268+
# prng.choose([*'0'..'9'], 5) #=> "27309"
269+
#
270+
%a{annotate:rdoc:copy:Random::Formatter#choose}
271+
private def choose: (Array[String] source, Integer n) -> String
160272
end
161273
end
162274
end

test/stdlib/Random_Formatter_test.rb

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,13 @@ def test_uuid
4242
Random, :uuid
4343
end
4444

45+
def test_uuid_v7
46+
assert_send_type "() -> ::String",
47+
Random, :uuid_v7
48+
assert_send_type "(extra_timestamp_bits: ::Integer) -> ::String",
49+
Random, :uuid_v7, extra_timestamp_bits: 12
50+
end
51+
4552
def test_alphanumeric
4653
assert_send_type "() -> ::String",
4754
Random, :alphanumeric
@@ -93,6 +100,13 @@ def test_uuid
93100
Random.new, :uuid
94101
end
95102

103+
def test_uuid_v7
104+
assert_send_type "() -> ::String",
105+
Random.new, :uuid_v7
106+
assert_send_type "(extra_timestamp_bits: ::Integer) -> ::String",
107+
Random.new, :uuid_v7, extra_timestamp_bits: 12
108+
end
109+
96110
def test_alphanumeric
97111
assert_send_type "() -> ::String",
98112
Random.new, :alphanumeric
@@ -101,4 +115,14 @@ def test_alphanumeric
101115
assert_send_type "(::Integer, chars: Array[::String]) -> ::String",
102116
Random.new, :alphanumeric, 10, chars: ["a", "b", "c"]
103117
end
118+
119+
def test_gen_random
120+
assert_send_type "(::Integer) -> ::String",
121+
Random.new, :gen_random, 10
122+
end
123+
124+
def test_choose
125+
assert_send_type "(Array[::String], ::Integer) -> ::String",
126+
Random.new, :choose, ["a", "b", "c"], 3
127+
end
104128
end

0 commit comments

Comments
 (0)