snowflaked 0.2.0 → 0.3.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: 8614c6c1857513375925fcc710cae86379a5f3937e1128a76e7c0c9316e717d7
4
- data.tar.gz: 2a229cc5321964620d03261fcaa7b757e2a46ae31519ba9d03a0bb18a4b37f90
3
+ metadata.gz: bbac2ac16a2d9f982a2da3bebcf90feddd70b6b4c6b468948c8bc92b06bf6d33
4
+ data.tar.gz: 8000532e335f2c718628c7a16d7dca7c2300ecfd64f7716fc33233c2f3323e2c
5
5
  SHA512:
6
- metadata.gz: d54e7b37a266cfa15f98d07e9723db9d218aff9301b7c1c0939d82f750ea91cbbfde65a7470b2b29a34d08b23b8a8a969e88e07af13b7f1af16f6eb6322b5648
7
- data.tar.gz: a032245eec1c604d91bd3c51fefb3d5345cf693e8ff50c34dab29bd022d5c2c7fc77cabe32084e7a5955c25caaa7ffb903abc90d1d7d61b233fd6b0040f90a65
6
+ metadata.gz: b09efb54e7e5bd46464355bdb366752c5bc36b7a0c1d47616becffcdeaa83b30051690579d1b6698807e64dc46266e3f98644c473cf36bfed7dc4630f05248dd
7
+ data.tar.gz: 3383bbb6e929ad601c92018c36f0983ae14cf3b335f2713c19ca929db2d72be70170408030acd2f0aa5c56c05623022dac4848f5c8e4d22d5da3401c8dcdf93b
data/Cargo.lock ADDED
@@ -0,0 +1,563 @@
1
+ # This file is automatically @generated by Cargo.
2
+ # It is not intended for manual editing.
3
+ version = 4
4
+
5
+ [[package]]
6
+ name = "aho-corasick"
7
+ version = "1.1.4"
8
+ source = "registry+https://github.com/rust-lang/crates.io-index"
9
+ checksum = "ddd31a130427c27518df266943a5308ed92d4b226cc639f5a8f1002816174301"
10
+ dependencies = [
11
+ "memchr",
12
+ ]
13
+
14
+ [[package]]
15
+ name = "arc-swap"
16
+ version = "1.9.2"
17
+ source = "registry+https://github.com/rust-lang/crates.io-index"
18
+ checksum = "c049c0be4daef0b145cb3555416b3b8ef5b7888a38aea1a3a155801fe7b0810b"
19
+ dependencies = [
20
+ "rustversion",
21
+ ]
22
+
23
+ [[package]]
24
+ name = "bindgen"
25
+ version = "0.72.1"
26
+ source = "registry+https://github.com/rust-lang/crates.io-index"
27
+ checksum = "993776b509cfb49c750f11b8f07a46fa23e0a1386ffc01fb1e7d343efc387895"
28
+ dependencies = [
29
+ "bitflags",
30
+ "cexpr",
31
+ "clang-sys",
32
+ "itertools",
33
+ "proc-macro2",
34
+ "quote",
35
+ "regex",
36
+ "rustc-hash",
37
+ "shlex 1.3.0",
38
+ "syn",
39
+ ]
40
+
41
+ [[package]]
42
+ name = "bitflags"
43
+ version = "2.13.1"
44
+ source = "registry+https://github.com/rust-lang/crates.io-index"
45
+ checksum = "b588b76d00fde79687d7646a9b5bdf3cc0f655e0bbd080335a95d7e96f3587da"
46
+
47
+ [[package]]
48
+ name = "cc"
49
+ version = "1.2.67"
50
+ source = "registry+https://github.com/rust-lang/crates.io-index"
51
+ checksum = "e17dd265a7d0f31ef544e1b20e03add05d3b45b491b633b10d67145d2acc1a38"
52
+ dependencies = [
53
+ "find-msvc-tools",
54
+ "shlex 2.0.1",
55
+ ]
56
+
57
+ [[package]]
58
+ name = "cexpr"
59
+ version = "0.6.0"
60
+ source = "registry+https://github.com/rust-lang/crates.io-index"
61
+ checksum = "6fac387a98bb7c37292057cffc56d62ecb629900026402633ae9160df93a8766"
62
+ dependencies = [
63
+ "nom",
64
+ ]
65
+
66
+ [[package]]
67
+ name = "cfg-if"
68
+ version = "1.0.4"
69
+ source = "registry+https://github.com/rust-lang/crates.io-index"
70
+ checksum = "9330f8b2ff13f34540b44e946ef35111825727b38d33286ef986142615121801"
71
+
72
+ [[package]]
73
+ name = "clang-sys"
74
+ version = "1.8.1"
75
+ source = "registry+https://github.com/rust-lang/crates.io-index"
76
+ checksum = "0b023947811758c97c59bf9d1c188fd619ad4718dcaa767947df1cadb14f39f4"
77
+ dependencies = [
78
+ "glob",
79
+ "libc",
80
+ "libloading",
81
+ ]
82
+
83
+ [[package]]
84
+ name = "either"
85
+ version = "1.16.0"
86
+ source = "registry+https://github.com/rust-lang/crates.io-index"
87
+ checksum = "91622ff5e7162018101f2fea40d6ebf4a78bbe5a49736a2020649edf9693679e"
88
+
89
+ [[package]]
90
+ name = "find-msvc-tools"
91
+ version = "0.1.9"
92
+ source = "registry+https://github.com/rust-lang/crates.io-index"
93
+ checksum = "5baebc0774151f905a1a2cc41989300b1e6fbb29aff0ceffa1064fdd3088d582"
94
+
95
+ [[package]]
96
+ name = "generator"
97
+ version = "0.7.5"
98
+ source = "registry+https://github.com/rust-lang/crates.io-index"
99
+ checksum = "5cc16584ff22b460a382b7feec54b23d2908d858152e5739a120b949293bd74e"
100
+ dependencies = [
101
+ "cc",
102
+ "libc",
103
+ "log",
104
+ "rustversion",
105
+ "windows",
106
+ ]
107
+
108
+ [[package]]
109
+ name = "glob"
110
+ version = "0.3.3"
111
+ source = "registry+https://github.com/rust-lang/crates.io-index"
112
+ checksum = "0cc23270f6e1808e30a928bdc84dea0b9b4136a8bc82338574f23baf47bbd280"
113
+
114
+ [[package]]
115
+ name = "itertools"
116
+ version = "0.13.0"
117
+ source = "registry+https://github.com/rust-lang/crates.io-index"
118
+ checksum = "413ee7dfc52ee1a4949ceeb7dbc8a33f2d6c088194d9f922fb8318faf1f01186"
119
+ dependencies = [
120
+ "either",
121
+ ]
122
+
123
+ [[package]]
124
+ name = "lazy_static"
125
+ version = "1.5.0"
126
+ source = "registry+https://github.com/rust-lang/crates.io-index"
127
+ checksum = "bbd2bcb4c963f2ddae06a2efc7e9f3591312473c50c6685e1f298068316e66fe"
128
+
129
+ [[package]]
130
+ name = "libc"
131
+ version = "0.2.186"
132
+ source = "registry+https://github.com/rust-lang/crates.io-index"
133
+ checksum = "68ab91017fe16c622486840e4c83c9a37afeff978bd239b5293d61ece587de66"
134
+
135
+ [[package]]
136
+ name = "libloading"
137
+ version = "0.8.9"
138
+ source = "registry+https://github.com/rust-lang/crates.io-index"
139
+ checksum = "d7c4b02199fee7c5d21a5ae7d8cfa79a6ef5bb2fc834d6e9058e89c825efdc55"
140
+ dependencies = [
141
+ "cfg-if",
142
+ "windows-link",
143
+ ]
144
+
145
+ [[package]]
146
+ name = "log"
147
+ version = "0.4.33"
148
+ source = "registry+https://github.com/rust-lang/crates.io-index"
149
+ checksum = "0ceec5bc11778974d1bcb055b18002eba7f4b3518b6a0081b3af5f21666da9ad"
150
+
151
+ [[package]]
152
+ name = "loom"
153
+ version = "0.5.6"
154
+ source = "registry+https://github.com/rust-lang/crates.io-index"
155
+ checksum = "ff50ecb28bb86013e935fb6683ab1f6d3a20016f123c76fd4c27470076ac30f5"
156
+ dependencies = [
157
+ "cfg-if",
158
+ "generator",
159
+ "scoped-tls",
160
+ "tracing",
161
+ "tracing-subscriber",
162
+ ]
163
+
164
+ [[package]]
165
+ name = "magnus"
166
+ version = "0.8.2"
167
+ source = "registry+https://github.com/rust-lang/crates.io-index"
168
+ checksum = "3b36a5b126bbe97eb0d02d07acfeb327036c6319fd816139a49824a83b7f9012"
169
+ dependencies = [
170
+ "magnus-macros",
171
+ "rb-sys",
172
+ "rb-sys-env",
173
+ "seq-macro",
174
+ ]
175
+
176
+ [[package]]
177
+ name = "magnus-macros"
178
+ version = "0.8.0"
179
+ source = "registry+https://github.com/rust-lang/crates.io-index"
180
+ checksum = "47607461fd8e1513cb4f2076c197d8092d921a1ea75bd08af97398f593751892"
181
+ dependencies = [
182
+ "proc-macro2",
183
+ "quote",
184
+ "syn",
185
+ ]
186
+
187
+ [[package]]
188
+ name = "matchers"
189
+ version = "0.2.0"
190
+ source = "registry+https://github.com/rust-lang/crates.io-index"
191
+ checksum = "d1525a2a28c7f4fa0fc98bb91ae755d1e2d1505079e05539e35bc876b5d65ae9"
192
+ dependencies = [
193
+ "regex-automata",
194
+ ]
195
+
196
+ [[package]]
197
+ name = "memchr"
198
+ version = "2.8.3"
199
+ source = "registry+https://github.com/rust-lang/crates.io-index"
200
+ checksum = "cf8baf1c55e62ffcace7a9f06f4bd9cd3f0c4beb022d3b367256b91b87513d98"
201
+
202
+ [[package]]
203
+ name = "minimal-lexical"
204
+ version = "0.2.1"
205
+ source = "registry+https://github.com/rust-lang/crates.io-index"
206
+ checksum = "68354c5c6bd36d73ff3feceb05efa59b6acb7626617f4962be322a825e61f79a"
207
+
208
+ [[package]]
209
+ name = "nom"
210
+ version = "7.1.3"
211
+ source = "registry+https://github.com/rust-lang/crates.io-index"
212
+ checksum = "d273983c5a657a70a3e8f2a01329822f3b8c8172b73826411a55751e404a0a4a"
213
+ dependencies = [
214
+ "memchr",
215
+ "minimal-lexical",
216
+ ]
217
+
218
+ [[package]]
219
+ name = "nu-ansi-term"
220
+ version = "0.50.3"
221
+ source = "registry+https://github.com/rust-lang/crates.io-index"
222
+ checksum = "7957b9740744892f114936ab4a57b3f487491bbeafaf8083688b16841a4240e5"
223
+ dependencies = [
224
+ "windows-sys",
225
+ ]
226
+
227
+ [[package]]
228
+ name = "once_cell"
229
+ version = "1.21.4"
230
+ source = "registry+https://github.com/rust-lang/crates.io-index"
231
+ checksum = "9f7c3e4beb33f85d45ae3e3a1792185706c8e16d043238c593331cc7cd313b50"
232
+
233
+ [[package]]
234
+ name = "pin-project-lite"
235
+ version = "0.2.17"
236
+ source = "registry+https://github.com/rust-lang/crates.io-index"
237
+ checksum = "a89322df9ebe1c1578d689c92318e070967d1042b512afbe49518723f4e6d5cd"
238
+
239
+ [[package]]
240
+ name = "proc-macro2"
241
+ version = "1.0.106"
242
+ source = "registry+https://github.com/rust-lang/crates.io-index"
243
+ checksum = "8fd00f0bb2e90d81d1044c2b32617f68fcb9fa3bb7640c23e9c748e53fb30934"
244
+ dependencies = [
245
+ "unicode-ident",
246
+ ]
247
+
248
+ [[package]]
249
+ name = "quote"
250
+ version = "1.0.46"
251
+ source = "registry+https://github.com/rust-lang/crates.io-index"
252
+ checksum = "dfbc457d0c7a0759a614551b11a6409e5951f6c7537be1f1b7682b9ae9230368"
253
+ dependencies = [
254
+ "proc-macro2",
255
+ ]
256
+
257
+ [[package]]
258
+ name = "rb-sys"
259
+ version = "0.9.128"
260
+ source = "registry+https://github.com/rust-lang/crates.io-index"
261
+ checksum = "45ca28513560e56cfb79a62b1fce363c73af170a182024ce880c77ee9429920a"
262
+ dependencies = [
263
+ "rb-sys-build",
264
+ ]
265
+
266
+ [[package]]
267
+ name = "rb-sys-build"
268
+ version = "0.9.128"
269
+ source = "registry+https://github.com/rust-lang/crates.io-index"
270
+ checksum = "ce04b2c55eff3a21aaa623fcc655d94373238e72cac6b3e1a3641ff31649f99a"
271
+ dependencies = [
272
+ "bindgen",
273
+ "lazy_static",
274
+ "proc-macro2",
275
+ "quote",
276
+ "regex",
277
+ "shell-words",
278
+ "syn",
279
+ ]
280
+
281
+ [[package]]
282
+ name = "rb-sys-env"
283
+ version = "0.2.3"
284
+ source = "registry+https://github.com/rust-lang/crates.io-index"
285
+ checksum = "cca7ad6a7e21e72151d56fe2495a259b5670e204c3adac41ee7ef676ea08117a"
286
+
287
+ [[package]]
288
+ name = "regex"
289
+ version = "1.13.1"
290
+ source = "registry+https://github.com/rust-lang/crates.io-index"
291
+ checksum = "f020237b6c8eed93db2e2cb53c00c60a8e1bc73da7d073199a1180401450218d"
292
+ dependencies = [
293
+ "aho-corasick",
294
+ "memchr",
295
+ "regex-automata",
296
+ "regex-syntax",
297
+ ]
298
+
299
+ [[package]]
300
+ name = "regex-automata"
301
+ version = "0.4.16"
302
+ source = "registry+https://github.com/rust-lang/crates.io-index"
303
+ checksum = "8fcfdb36bda0c880c5931cdc7a2bcdc8ba4556847b9d912bca70bc94708711ad"
304
+ dependencies = [
305
+ "aho-corasick",
306
+ "memchr",
307
+ "regex-syntax",
308
+ ]
309
+
310
+ [[package]]
311
+ name = "regex-syntax"
312
+ version = "0.8.11"
313
+ source = "registry+https://github.com/rust-lang/crates.io-index"
314
+ checksum = "d6f6ff9a378485b298a5286656da665ba74413d36db0979633275d2e708145d4"
315
+
316
+ [[package]]
317
+ name = "rustc-hash"
318
+ version = "2.1.3"
319
+ source = "registry+https://github.com/rust-lang/crates.io-index"
320
+ checksum = "6b1e7f9a428571be2dc5bc0505c13fb6bf936822b894ec87abf8a08a4e51742d"
321
+
322
+ [[package]]
323
+ name = "rustversion"
324
+ version = "1.0.23"
325
+ source = "registry+https://github.com/rust-lang/crates.io-index"
326
+ checksum = "cf54715a573b99ac80df0bc206da022bcd442c974952c7b9720069370852e21f"
327
+
328
+ [[package]]
329
+ name = "scoped-tls"
330
+ version = "1.0.1"
331
+ source = "registry+https://github.com/rust-lang/crates.io-index"
332
+ checksum = "e1cf6437eb19a8f4a6cc0f7dca544973b0b78843adbfeb3683d1a94a0024a294"
333
+
334
+ [[package]]
335
+ name = "seq-macro"
336
+ version = "0.3.6"
337
+ source = "registry+https://github.com/rust-lang/crates.io-index"
338
+ checksum = "1bc711410fbe7399f390ca1c3b60ad0f53f80e95c5eb935e52268a0e2cd49acc"
339
+
340
+ [[package]]
341
+ name = "sharded-slab"
342
+ version = "0.1.7"
343
+ source = "registry+https://github.com/rust-lang/crates.io-index"
344
+ checksum = "f40ca3c46823713e0d4209592e8d6e826aa57e928f09752619fc696c499637f6"
345
+ dependencies = [
346
+ "lazy_static",
347
+ ]
348
+
349
+ [[package]]
350
+ name = "shell-words"
351
+ version = "1.1.1"
352
+ source = "registry+https://github.com/rust-lang/crates.io-index"
353
+ checksum = "dc6fe69c597f9c37bfeeeeeb33da3530379845f10be461a66d16d03eca2ded77"
354
+
355
+ [[package]]
356
+ name = "shlex"
357
+ version = "1.3.0"
358
+ source = "registry+https://github.com/rust-lang/crates.io-index"
359
+ checksum = "0fda2ff0d084019ba4d7c6f371c95d8fd75ce3524c3cb8fb653a3023f6323e64"
360
+
361
+ [[package]]
362
+ name = "shlex"
363
+ version = "2.0.1"
364
+ source = "registry+https://github.com/rust-lang/crates.io-index"
365
+ checksum = "f8fadd59c855ef2080decdef8ff161eb6661b86933c9d82e5ba29dc602a55aba"
366
+
367
+ [[package]]
368
+ name = "smallvec"
369
+ version = "1.15.2"
370
+ source = "registry+https://github.com/rust-lang/crates.io-index"
371
+ checksum = "8ed6a63f02c8539c91a8685a86f4099661ba3da017932f6ebbea6de3f0fa7c90"
372
+
373
+ [[package]]
374
+ name = "snowflaked"
375
+ version = "0.3.0"
376
+ dependencies = [
377
+ "arc-swap",
378
+ "magnus",
379
+ "snowflaked 1.0.3",
380
+ ]
381
+
382
+ [[package]]
383
+ name = "snowflaked"
384
+ version = "1.0.3"
385
+ source = "registry+https://github.com/rust-lang/crates.io-index"
386
+ checksum = "398d462c4c454399be452039b24b0aa0ecb4c7a57f6ae615f5d25de2b032f850"
387
+ dependencies = [
388
+ "loom",
389
+ ]
390
+
391
+ [[package]]
392
+ name = "syn"
393
+ version = "2.0.119"
394
+ source = "registry+https://github.com/rust-lang/crates.io-index"
395
+ checksum = "872831b642d1a07999a962a351ed35b955ea2cfc8f3862091e2a240a84f17297"
396
+ dependencies = [
397
+ "proc-macro2",
398
+ "quote",
399
+ "unicode-ident",
400
+ ]
401
+
402
+ [[package]]
403
+ name = "thread_local"
404
+ version = "1.1.10"
405
+ source = "registry+https://github.com/rust-lang/crates.io-index"
406
+ checksum = "1ad99c4c6d32803332c548b1af0540b357b3f5fc0be8f6c6bfe8b2e6ae784070"
407
+ dependencies = [
408
+ "cfg-if",
409
+ ]
410
+
411
+ [[package]]
412
+ name = "tracing"
413
+ version = "0.1.44"
414
+ source = "registry+https://github.com/rust-lang/crates.io-index"
415
+ checksum = "63e71662fa4b2a2c3a26f570f037eb95bb1f85397f3cd8076caed2f026a6d100"
416
+ dependencies = [
417
+ "pin-project-lite",
418
+ "tracing-attributes",
419
+ "tracing-core",
420
+ ]
421
+
422
+ [[package]]
423
+ name = "tracing-attributes"
424
+ version = "0.1.31"
425
+ source = "registry+https://github.com/rust-lang/crates.io-index"
426
+ checksum = "7490cfa5ec963746568740651ac6781f701c9c5ea257c58e057f3ba8cf69e8da"
427
+ dependencies = [
428
+ "proc-macro2",
429
+ "quote",
430
+ "syn",
431
+ ]
432
+
433
+ [[package]]
434
+ name = "tracing-core"
435
+ version = "0.1.36"
436
+ source = "registry+https://github.com/rust-lang/crates.io-index"
437
+ checksum = "db97caf9d906fbde555dd62fa95ddba9eecfd14cb388e4f491a66d74cd5fb79a"
438
+ dependencies = [
439
+ "once_cell",
440
+ "valuable",
441
+ ]
442
+
443
+ [[package]]
444
+ name = "tracing-log"
445
+ version = "0.2.0"
446
+ source = "registry+https://github.com/rust-lang/crates.io-index"
447
+ checksum = "ee855f1f400bd0e5c02d150ae5de3840039a3f54b025156404e34c23c03f47c3"
448
+ dependencies = [
449
+ "log",
450
+ "once_cell",
451
+ "tracing-core",
452
+ ]
453
+
454
+ [[package]]
455
+ name = "tracing-subscriber"
456
+ version = "0.3.23"
457
+ source = "registry+https://github.com/rust-lang/crates.io-index"
458
+ checksum = "cb7f578e5945fb242538965c2d0b04418d38ec25c79d160cd279bf0731c8d319"
459
+ dependencies = [
460
+ "matchers",
461
+ "nu-ansi-term",
462
+ "once_cell",
463
+ "regex-automata",
464
+ "sharded-slab",
465
+ "smallvec",
466
+ "thread_local",
467
+ "tracing",
468
+ "tracing-core",
469
+ "tracing-log",
470
+ ]
471
+
472
+ [[package]]
473
+ name = "unicode-ident"
474
+ version = "1.0.24"
475
+ source = "registry+https://github.com/rust-lang/crates.io-index"
476
+ checksum = "e6e4313cd5fcd3dad5cafa179702e2b244f760991f45397d14d4ebf38247da75"
477
+
478
+ [[package]]
479
+ name = "valuable"
480
+ version = "0.1.1"
481
+ source = "registry+https://github.com/rust-lang/crates.io-index"
482
+ checksum = "ba73ea9cf16a25df0c8caa16c51acb937d5712a8429db78a3ee29d5dcacd3a65"
483
+
484
+ [[package]]
485
+ name = "windows"
486
+ version = "0.48.0"
487
+ source = "registry+https://github.com/rust-lang/crates.io-index"
488
+ checksum = "e686886bc078bc1b0b600cac0147aadb815089b6e4da64016cbd754b6342700f"
489
+ dependencies = [
490
+ "windows-targets",
491
+ ]
492
+
493
+ [[package]]
494
+ name = "windows-link"
495
+ version = "0.2.1"
496
+ source = "registry+https://github.com/rust-lang/crates.io-index"
497
+ checksum = "f0805222e57f7521d6a62e36fa9163bc891acd422f971defe97d64e70d0a4fe5"
498
+
499
+ [[package]]
500
+ name = "windows-sys"
501
+ version = "0.61.2"
502
+ source = "registry+https://github.com/rust-lang/crates.io-index"
503
+ checksum = "ae137229bcbd6cdf0f7b80a31df61766145077ddf49416a728b02cb3921ff3fc"
504
+ dependencies = [
505
+ "windows-link",
506
+ ]
507
+
508
+ [[package]]
509
+ name = "windows-targets"
510
+ version = "0.48.5"
511
+ source = "registry+https://github.com/rust-lang/crates.io-index"
512
+ checksum = "9a2fa6e2155d7247be68c096456083145c183cbbbc2764150dda45a87197940c"
513
+ dependencies = [
514
+ "windows_aarch64_gnullvm",
515
+ "windows_aarch64_msvc",
516
+ "windows_i686_gnu",
517
+ "windows_i686_msvc",
518
+ "windows_x86_64_gnu",
519
+ "windows_x86_64_gnullvm",
520
+ "windows_x86_64_msvc",
521
+ ]
522
+
523
+ [[package]]
524
+ name = "windows_aarch64_gnullvm"
525
+ version = "0.48.5"
526
+ source = "registry+https://github.com/rust-lang/crates.io-index"
527
+ checksum = "2b38e32f0abccf9987a4e3079dfb67dcd799fb61361e53e2882c3cbaf0d905d8"
528
+
529
+ [[package]]
530
+ name = "windows_aarch64_msvc"
531
+ version = "0.48.5"
532
+ source = "registry+https://github.com/rust-lang/crates.io-index"
533
+ checksum = "dc35310971f3b2dbbf3f0690a219f40e2d9afcf64f9ab7cc1be722937c26b4bc"
534
+
535
+ [[package]]
536
+ name = "windows_i686_gnu"
537
+ version = "0.48.5"
538
+ source = "registry+https://github.com/rust-lang/crates.io-index"
539
+ checksum = "a75915e7def60c94dcef72200b9a8e58e5091744960da64ec734a6c6e9b3743e"
540
+
541
+ [[package]]
542
+ name = "windows_i686_msvc"
543
+ version = "0.48.5"
544
+ source = "registry+https://github.com/rust-lang/crates.io-index"
545
+ checksum = "8f55c233f70c4b27f66c523580f78f1004e8b5a8b659e05a4eb49d4166cca406"
546
+
547
+ [[package]]
548
+ name = "windows_x86_64_gnu"
549
+ version = "0.48.5"
550
+ source = "registry+https://github.com/rust-lang/crates.io-index"
551
+ checksum = "53d40abd2583d23e4718fddf1ebec84dbff8381c07cae67ff7768bbf19c6718e"
552
+
553
+ [[package]]
554
+ name = "windows_x86_64_gnullvm"
555
+ version = "0.48.5"
556
+ source = "registry+https://github.com/rust-lang/crates.io-index"
557
+ checksum = "0b7b52767868a23d5bab768e390dc5f5c55825b6d30b86c844ff2dc7414044cc"
558
+
559
+ [[package]]
560
+ name = "windows_x86_64_msvc"
561
+ version = "0.48.5"
562
+ source = "registry+https://github.com/rust-lang/crates.io-index"
563
+ checksum = "ed94fce61571a4006852b7389a063ab983c02eb1bb37b47f8272ce92d06d9538"
data/Cargo.toml CHANGED
@@ -1,3 +1,6 @@
1
1
  [workspace]
2
2
  members = ["./ext/snowflaked"]
3
3
  resolver = "2"
4
+
5
+ [profile.release]
6
+ strip = "none"
data/README.md CHANGED
@@ -83,14 +83,16 @@ end
83
83
  ```ruby
84
84
  Snowflaked.configure do |config|
85
85
  config.machine_id = 42
86
- config.epoch = Time.utc(1989, 1, 3) # When not configured, the epoch is set to the Unix epoch (January 1, 1970)
86
+ config.epoch = Time.utc(1989, 1, 3) # Defaults to DEFAULT_EPOCH (2024-01-01) if not configured
87
87
  end
88
88
  ```
89
89
 
90
+ Configuration is locked after `Snowflaked.configure` or the first generated/parsed ID. Set it during application boot, before request threads start.
91
+
90
92
  ### Machine ID
91
93
 
92
94
  > [!TIP]
93
- > For multi-process servers like Puma, it is recommended to **not** configure `machine_id` explicitly. The gem automatically calculates a unique machine ID using `(hostname.hash ^ pid) % 1024`, which ensures each forked worker process gets a different ID and avoids duplicate Snowflake IDs.
95
+ > For multi-process servers like Puma, it is recommended to **not** configure `machine_id` explicitly. The gem automatically calculates a process-local machine ID using `(hostname.hash ^ pid) % 1024`, so forked workers do not reuse the parent's cached machine ID.
94
96
 
95
97
  If you must set `machine_id` explicitly, use environment variables that differ per worker process.
96
98
 
@@ -102,14 +104,12 @@ If `machine_id` is not explicitly configured, it resolves in this order:
102
104
  2. `MACHINE_ID` environment variable
103
105
  3. Auto-detected using the following formula: `(hostname.hash ^ pid) % 1024`
104
106
 
105
- For Kubernetes deployments, you can set the machine ID using an environment variable:
107
+ For Kubernetes deployments, set the machine ID to a numeric value between `0` and `1023`:
106
108
 
107
109
  ```yaml
108
110
  env:
109
111
  - name: SNOWFLAKED_MACHINE_ID
110
- valueFrom:
111
- fieldRef:
112
- fieldPath: metadata.name
112
+ value: "42"
113
113
  ```
114
114
 
115
115
  Or use a StatefulSet ordinal for guaranteed unique values:
@@ -151,9 +151,8 @@ tl;dr: Snowflake IDs have a negligible performance impact compared to database-b
151
151
 
152
152
  ## Requirements
153
153
 
154
- - Ruby >= 3.2
155
- - rustc >= 1.81.0
156
- - cargo >= 1.81.0
154
+ - Ruby >= 3.3
155
+ - rustc / cargo >= 1.81.0 (development uses the toolchain pinned in `mise.toml`)
157
156
  - Mise
158
157
 
159
158
  ## Development
@@ -1,6 +1,6 @@
1
1
  [package]
2
2
  name = "snowflaked"
3
- version = "0.2.0"
3
+ version = "0.3.0"
4
4
  edition = "2021"
5
5
  publish = false
6
6
 
@@ -10,4 +10,4 @@ crate-type = ["cdylib"]
10
10
  [dependencies]
11
11
  magnus = { version = "0.8" }
12
12
  snowflaked = { version = "1.0.3", features = ["sync"] }
13
- arc-swap = "1.8.2"
13
+ arc-swap = "1.9.1"
@@ -4,3 +4,6 @@ require "mkmf"
4
4
  require "rb_sys/mkmf"
5
5
 
6
6
  create_rust_makefile("snowflaked/snowflaked")
7
+
8
+ makefile = File.read("Makefile")
9
+ File.write("Makefile", makefile) if makefile.gsub!('install_name_tool -id ""', 'install_name_tool -id "$(notdir $(DLLIB))"')
@@ -8,7 +8,6 @@ use std::time::UNIX_EPOCH;
8
8
  struct GeneratorState {
9
9
  generator: Generator,
10
10
  epoch_offset: u64,
11
- machine_id: u16,
12
11
  init_pid: u32,
13
12
  }
14
13
 
@@ -29,11 +28,10 @@ fn ensure_state(machine_id: u16, epoch_offset: u64, current_pid: u32) -> (Arc<Ge
29
28
  let new_state = Arc::new(GeneratorState {
30
29
  generator: build_generator(machine_id, epoch_offset),
31
30
  epoch_offset,
32
- machine_id,
33
31
  init_pid: current_pid,
34
32
  });
35
33
 
36
- let prev_state = STATE.rcu(|current| {
34
+ STATE.rcu(|current| {
37
35
  if let Some(c) = current {
38
36
  if c.init_pid == current_pid {
39
37
  return Arc::clone(c);
@@ -42,10 +40,10 @@ fn ensure_state(machine_id: u16, epoch_offset: u64, current_pid: u32) -> (Arc<Ge
42
40
  Arc::clone(&new_state)
43
41
  });
44
42
 
45
- match prev_state.as_ref() {
46
- Some(s) if s.init_pid == current_pid => (Arc::clone(s), false),
47
- _ => (new_state, true),
48
- }
43
+ let state = STATE.load_full().expect("generator state should be initialized");
44
+ let swapped = Arc::ptr_eq(&state, &new_state);
45
+
46
+ (state, swapped)
49
47
  }
50
48
 
51
49
  fn init_generator(machine_id: u16, epoch_ms: Option<u64>) -> bool {
@@ -53,30 +51,23 @@ fn init_generator(machine_id: u16, epoch_ms: Option<u64>) -> bool {
53
51
  swapped
54
52
  }
55
53
 
56
- fn validate_config(ruby: &Ruby, s: &GeneratorState, machine_id: u16, epoch_offset: u64) -> Result<(), Error> {
57
- if s.machine_id != machine_id || s.epoch_offset != epoch_offset {
58
- return Err(Error::new(
59
- ruby.exception_runtime_error(),
60
- "Generator already initialized with a different machine_id or epoch for this process",
61
- ));
62
- }
63
- Ok(())
54
+ fn current_state(ruby: &Ruby) -> Result<Arc<GeneratorState>, Error> {
55
+ STATE
56
+ .load_full()
57
+ .filter(|s| s.init_pid == std::process::id())
58
+ .ok_or_else(|| Error::new(ruby.exception_runtime_error(), "Generator not initialized"))
64
59
  }
65
60
 
66
- fn generate(ruby: &Ruby, machine_id: u16, epoch_ms: Option<u64>) -> Result<u64, Error> {
67
- let epoch_offset = epoch_ms.unwrap_or(0);
68
- let (state, _) = ensure_state(machine_id, epoch_offset, std::process::id());
61
+ fn generate(ruby: &Ruby) -> Result<u64, Error> {
62
+ let state = current_state(ruby)?;
69
63
 
70
- validate_config(ruby, &state, machine_id, epoch_offset)?;
71
- Ok(state.generator.generate())
64
+ std::panic::catch_unwind(std::panic::AssertUnwindSafe(|| state.generator.generate::<i64>()))
65
+ .map(|id| id as u64)
66
+ .map_err(|_| Error::new(ruby.exception_runtime_error(), "Snowflaked: system clock moved backwards; cannot generate a monotonic ID"))
72
67
  }
73
68
 
74
69
  fn epoch_offset(ruby: &Ruby) -> Result<u64, Error> {
75
- STATE
76
- .load()
77
- .as_ref()
78
- .map(|s| s.epoch_offset)
79
- .ok_or_else(|| Error::new(ruby.exception_runtime_error(), "Generator not initialized"))
70
+ current_state(ruby).map(|s| s.epoch_offset)
80
71
  }
81
72
 
82
73
  fn parse(ruby: &Ruby, id: u64) -> Result<RHash, Error> {
@@ -106,23 +97,18 @@ fn is_initialized() -> bool {
106
97
  STATE.load().as_ref().is_some_and(|s| s.init_pid == std::process::id())
107
98
  }
108
99
 
109
- fn configured_machine_id() -> Option<u16> {
110
- STATE.load().as_ref().filter(|s| s.init_pid == std::process::id()).map(|s| s.machine_id)
111
- }
112
-
113
100
  #[magnus::init]
114
101
  fn init(ruby: &Ruby) -> Result<(), Error> {
115
102
  let module = ruby.define_module("Snowflaked")?;
116
103
  let internal = module.define_module("Native")?;
117
104
 
118
105
  internal.define_singleton_method("init_generator", function!(init_generator, 2))?;
119
- internal.define_singleton_method("generate", function!(generate, 2))?;
106
+ internal.define_singleton_method("generate", function!(generate, 0))?;
120
107
  internal.define_singleton_method("parse", function!(parse, 1))?;
121
108
  internal.define_singleton_method("timestamp_ms", function!(timestamp_ms, 1))?;
122
109
  internal.define_singleton_method("machine_id", function!(machine_id_from_id, 1))?;
123
110
  internal.define_singleton_method("sequence", function!(sequence, 1))?;
124
111
  internal.define_singleton_method("initialized?", function!(is_initialized, 0))?;
125
- internal.define_singleton_method("configured_machine_id", function!(configured_machine_id, 0))?;
126
112
 
127
113
  Ok(())
128
114
  }
@@ -20,10 +20,14 @@ module Snowflaked
20
20
  def _snowflake_columns_from_comments
21
21
  return @_snowflake_columns_from_comments if defined?(@_snowflake_columns_from_comments)
22
22
 
23
- @_snowflake_columns_from_comments = table_exists? ? columns.filter_map { |col| col.name.to_sym if col.comment == Snowflaked::SchemaDefinitions::COMMENT } : []
23
+ return [] unless table_exists?
24
+
25
+ @_snowflake_columns_from_comments = columns.filter_map { |col| col.name.to_sym if col.comment == Snowflaked::SchemaDefinitions::COMMENT }
24
26
  end
25
27
 
26
28
  def _snowflake_attributes_with_columns
29
+ return _snowflake_attributes unless table_exists?
30
+
27
31
  @_snowflake_attributes_with_columns ||= (_snowflake_attributes | _snowflake_columns_from_comments)
28
32
  end
29
33
  end
@@ -42,10 +42,9 @@ module Snowflaked
42
42
  end
43
43
 
44
44
  initializer "snowflaked.model_extensions", after: "active_record.initialize_database" do
45
- ActiveSupport.on_load(:active_record) do
46
- require "snowflaked/model_extensions"
47
- ActiveRecord::Base.include(Snowflaked::ModelExtensions)
48
- end
45
+ require "snowflaked/model_extensions"
46
+
47
+ ActiveSupport.on_load(:active_record) { include Snowflaked::ModelExtensions }
49
48
  end
50
49
  end
51
50
  end
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Snowflaked
4
- VERSION = "0.2.0"
4
+ VERSION = "0.3.0"
5
5
  end
data/lib/snowflaked.rb CHANGED
@@ -16,40 +16,81 @@ require_relative "snowflaked/railtie" if defined?(Rails::Railtie)
16
16
 
17
17
  module Snowflaked
18
18
  MAX_MACHINE_ID = 1023
19
+ DEFAULT_EPOCH = Time.utc(2024, 1, 1).freeze
19
20
 
20
21
  class Error < StandardError; end
21
22
  class ConfigurationError < Error; end
22
23
 
23
24
  class Configuration
24
- attr_accessor :machine_id, :epoch
25
+ attr_reader :machine_id, :epoch
25
26
 
26
27
  def initialize
27
28
  @machine_id = nil
28
- @epoch = nil
29
+ @epoch = DEFAULT_EPOCH
30
+ @sealed = false
31
+ end
32
+
33
+ def machine_id=(value)
34
+ raise_if_sealed!(:machine_id)
35
+
36
+ @machine_id = value.nil? ? nil : checked_machine_id(value)
37
+ @machine_id_value = nil
38
+ @machine_id_value_pid = nil
39
+ end
40
+
41
+ def epoch=(value)
42
+ raise_if_sealed!(:epoch)
43
+
44
+ @epoch = value
45
+ @epoch_ms = nil
46
+ end
47
+
48
+ def seal!
49
+ @sealed = true
29
50
  end
30
51
 
31
52
  def machine_id_value
32
- (@machine_id || default_machine_id) % (MAX_MACHINE_ID + 1)
53
+ if @machine_id_value_pid != Process.pid
54
+ @machine_id_value = resolve_machine_id
55
+ @machine_id_value_pid = Process.pid
56
+ end
57
+
58
+ @machine_id_value
33
59
  end
34
60
 
35
61
  def epoch_ms
36
62
  return nil unless @epoch
37
63
 
38
- (@epoch.to_f * 1000).to_i
64
+ @epoch_ms ||= (@epoch.to_r * 1000).to_i
39
65
  end
40
66
 
41
67
  private
42
68
 
43
- def default_machine_id
44
- env_machine_id || hostname_pid_hash
69
+ # Resolution order: explicit config, then env vars, then an auto fallback.
70
+ # Explicit and env values are range-checked; the fallback is always valid.
71
+ def resolve_machine_id
72
+ return @machine_id unless @machine_id.nil?
73
+
74
+ env = ENV["SNOWFLAKED_MACHINE_ID"] || ENV.fetch("MACHINE_ID", nil)
75
+ return checked_machine_id(env) if env
76
+
77
+ # Unique-enough per process without coordination: varies by host and by
78
+ # pid, so forked workers each get a different id. % keeps it in range.
79
+ (Socket.gethostname.hash ^ Process.pid) % (MAX_MACHINE_ID + 1)
45
80
  end
46
81
 
47
- def env_machine_id
48
- (ENV["SNOWFLAKED_MACHINE_ID"] || ENV.fetch("MACHINE_ID", nil))&.to_i
82
+ # Coerce to Integer and ensure it fits in 0..MAX_MACHINE_ID, else raise.
83
+ def checked_machine_id(value)
84
+ id = Integer(value, exception: false)
85
+ return id if id&.between?(0, MAX_MACHINE_ID)
86
+
87
+ raise ConfigurationError, "machine_id must be an integer between 0 and #{MAX_MACHINE_ID}, got #{value.inspect}"
49
88
  end
50
89
 
51
- def hostname_pid_hash
52
- (Socket.gethostname.hash ^ Process.pid) % (MAX_MACHINE_ID + 1)
90
+ def raise_if_sealed!(attribute)
91
+ return unless @sealed
92
+
93
+ raise ConfigurationError, "#{attribute} cannot be changed after Snowflaked has been configured"
53
94
  end
54
95
  end
55
96
 
@@ -66,8 +107,8 @@ module Snowflaked
66
107
  end
67
108
 
68
109
  def id
69
- config = configuration
70
- Native.generate(config.machine_id_value, config.epoch_ms)
110
+ ensure_initialized!
111
+ Native.generate
71
112
  end
72
113
 
73
114
  def parse(id)
@@ -78,10 +119,15 @@ module Snowflaked
78
119
  def timestamp(id)
79
120
  ensure_initialized!
80
121
  seconds, milliseconds = Native.timestamp_ms(id).divmod(1000)
81
- Time.at(seconds, milliseconds * 1000, :usec)
122
+
123
+ if defined?(Time.zone) && Time.zone
124
+ Time.zone.at(seconds, milliseconds * 1000, :usec)
125
+ else
126
+ Time.at(seconds, milliseconds * 1000, :usec).utc
127
+ end
82
128
  end
83
129
 
84
- def machine_id(id)
130
+ def machine_id(id) # rubocop:disable Rails/Delegate
85
131
  Native.machine_id(id)
86
132
  end
87
133
 
@@ -90,16 +136,20 @@ module Snowflaked
90
136
  Native.timestamp_ms(id)
91
137
  end
92
138
 
93
- def sequence(id)
139
+ def sequence(id) # rubocop:disable Rails/Delegate
94
140
  Native.sequence(id)
95
141
  end
96
142
 
97
143
  private
98
144
 
99
145
  def ensure_initialized!
100
- return if Native.initialized?
146
+ return if @native_initialized_pid == Process.pid
147
+
148
+ config = configuration
149
+ config.seal!
101
150
 
102
- Native.init_generator(configuration.machine_id_value, configuration.epoch_ms)
151
+ Native.init_generator(config.machine_id_value, config.epoch_ms)
152
+ @native_initialized_pid = Process.pid
103
153
  end
104
154
  end
105
155
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: snowflaked
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.2.0
4
+ version: 0.3.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Luiz Eduardo Kowalski
@@ -9,6 +9,20 @@ bindir: bin
9
9
  cert_chain: []
10
10
  date: 1980-01-02 00:00:00.000000000 Z
11
11
  dependencies:
12
+ - !ruby/object:Gem::Dependency
13
+ name: railties
14
+ requirement: !ruby/object:Gem::Requirement
15
+ requirements:
16
+ - - ">="
17
+ - !ruby/object:Gem::Version
18
+ version: '8.0'
19
+ type: :runtime
20
+ prerelease: false
21
+ version_requirements: !ruby/object:Gem::Requirement
22
+ requirements:
23
+ - - ">="
24
+ - !ruby/object:Gem::Version
25
+ version: '8.0'
12
26
  - !ruby/object:Gem::Dependency
13
27
  name: rb_sys
14
28
  requirement: !ruby/object:Gem::Requirement
@@ -30,6 +44,7 @@ extensions:
30
44
  - ext/snowflaked/extconf.rb
31
45
  extra_rdoc_files: []
32
46
  files:
47
+ - Cargo.lock
33
48
  - Cargo.toml
34
49
  - LICENSE.txt
35
50
  - README.md
@@ -59,14 +74,14 @@ required_ruby_version: !ruby/object:Gem::Requirement
59
74
  requirements:
60
75
  - - ">="
61
76
  - !ruby/object:Gem::Version
62
- version: '3.2'
77
+ version: '3.3'
63
78
  required_rubygems_version: !ruby/object:Gem::Requirement
64
79
  requirements:
65
80
  - - ">="
66
81
  - !ruby/object:Gem::Version
67
82
  version: '0'
68
83
  requirements: []
69
- rubygems_version: 4.0.3
84
+ rubygems_version: 4.0.16
70
85
  specification_version: 4
71
86
  summary: Fast Snowflake ID generator with Rust backend
72
87
  test_files: []