Skip to content

Commit 4482ed2

Browse files
authored
Merge pull request #2680 from ksss/random-formatter-uuid_v7
Add missing signatures for `Random::Formatter`
2 parents aed019e + fc3edcc commit 4482ed2

File tree

2 files changed

+139
-0
lines changed

2 files changed

+139
-0
lines changed

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

Lines changed: 115 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -104,6 +104,7 @@ module RBS
104104
#
105105
# See RFC 3548 for the definition of URL-safe base64.
106106
#
107+
%a{annotate:rdoc:copy:Random::Formatter#urlsafe_base64}
107108
def urlsafe_base64: (?Integer? n, ?boolish padding) -> String
108109

109110
# <!--
@@ -127,8 +128,92 @@ module RBS
127128
#
128129
# See [RFC9562](https://www.rfc-editor.org/rfc/rfc9562) for details of UUIDv4.
129130
#
131+
%a{annotate:rdoc:copy:Random::Formatter#uuid}
130132
def uuid: () -> String
131133

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