+16
.sqlx/query-21be3b3aca589adf8645ba819a423b5c4e942ab1689d71eb55cdaf6748b59317.json
+16
.sqlx/query-21be3b3aca589adf8645ba819a423b5c4e942ab1689d71eb55cdaf6748b59317.json
···
1
+
{
2
+
"db_name": "PostgreSQL",
3
+
"query": "INSERT INTO deleted_record (SELECT did, collection, rkey, rev, cid, live, data FROM record WHERE (did, collection, rkey) = ($1, $2, $3))",
4
+
"describe": {
5
+
"columns": [],
6
+
"parameters": {
7
+
"Left": [
8
+
"Text",
9
+
"Text",
10
+
"Text"
11
+
]
12
+
},
13
+
"nullable": []
14
+
},
15
+
"hash": "21be3b3aca589adf8645ba819a423b5c4e942ab1689d71eb55cdaf6748b59317"
16
+
}
+30
.sqlx/query-61e1b073c39dd8231d37c3dfd61459de6f0d1fdba50469fed8e1065a829f43db.json
+30
.sqlx/query-61e1b073c39dd8231d37c3dfd61459de6f0d1fdba50469fed8e1065a829f43db.json
···
1
+
{
2
+
"db_name": "PostgreSQL",
3
+
"query": "INSERT INTO identity (did, handle, active, status) VALUES ($1, $2, $3, $4) ON CONFLICT ON CONSTRAINT identity_pkey DO UPDATE SET (handle, active, status) = (EXCLUDED.handle, EXCLUDED.active, EXCLUDED.status)",
4
+
"describe": {
5
+
"columns": [],
6
+
"parameters": {
7
+
"Left": [
8
+
"Text",
9
+
"Text",
10
+
"Bool",
11
+
{
12
+
"Custom": {
13
+
"name": "identity_status",
14
+
"kind": {
15
+
"Enum": [
16
+
"active",
17
+
"takendown",
18
+
"suspended",
19
+
"deactivated",
20
+
"deleted"
21
+
]
22
+
}
23
+
}
24
+
}
25
+
]
26
+
},
27
+
"nullable": []
28
+
},
29
+
"hash": "61e1b073c39dd8231d37c3dfd61459de6f0d1fdba50469fed8e1065a829f43db"
30
+
}
+16
.sqlx/query-c793a6e15d42d14529d811a4b22014263b52489b6a608e2da2ef8073d7a7e8f6.json
+16
.sqlx/query-c793a6e15d42d14529d811a4b22014263b52489b6a608e2da2ef8073d7a7e8f6.json
···
1
+
{
2
+
"db_name": "PostgreSQL",
3
+
"query": "DELETE FROM record WHERE (did, collection, rkey) = ($1, $2, $3)",
4
+
"describe": {
5
+
"columns": [],
6
+
"parameters": {
7
+
"Left": [
8
+
"Text",
9
+
"Text",
10
+
"Text"
11
+
]
12
+
},
13
+
"nullable": []
14
+
},
15
+
"hash": "c793a6e15d42d14529d811a4b22014263b52489b6a608e2da2ef8073d7a7e8f6"
16
+
}
+20
.sqlx/query-de600b912681a60c29576ac6dcb417bf357e8eafd0cfb007be836b8defb8377d.json
+20
.sqlx/query-de600b912681a60c29576ac6dcb417bf357e8eafd0cfb007be836b8defb8377d.json
···
1
+
{
2
+
"db_name": "PostgreSQL",
3
+
"query": "SELECT did FROM identity",
4
+
"describe": {
5
+
"columns": [
6
+
{
7
+
"ordinal": 0,
8
+
"name": "did",
9
+
"type_info": "Text"
10
+
}
11
+
],
12
+
"parameters": {
13
+
"Left": []
14
+
},
15
+
"nullable": [
16
+
false
17
+
]
18
+
},
19
+
"hash": "de600b912681a60c29576ac6dcb417bf357e8eafd0cfb007be836b8defb8377d"
20
+
}
+20
.sqlx/query-eea727151b4f26df90b6023548bf059e1bc5645e7600fe159cd20d09030e44dd.json
+20
.sqlx/query-eea727151b4f26df90b6023548bf059e1bc5645e7600fe159cd20d09030e44dd.json
···
1
+
{
2
+
"db_name": "PostgreSQL",
3
+
"query": "INSERT INTO record (did, collection, rkey, rev, cid, live, data)\n VALUES ($1, $2, $3, $4, $5, $6, $7)\n ON CONFLICT\n ON CONSTRAINT record_pkey\n DO UPDATE\n SET (rev, cid, live, data) = (EXCLUDED.rev, EXCLUDED.cid, EXCLUDED.live, EXCLUDED.data)\n WHERE EXCLUDED.rev > record.rev\n",
4
+
"describe": {
5
+
"columns": [],
6
+
"parameters": {
7
+
"Left": [
8
+
"Text",
9
+
"Text",
10
+
"Text",
11
+
"Text",
12
+
"Text",
13
+
"Bool",
14
+
"Jsonb"
15
+
]
16
+
},
17
+
"nullable": []
18
+
},
19
+
"hash": "eea727151b4f26df90b6023548bf059e1bc5645e7600fe159cd20d09030e44dd"
20
+
}
+2895
Cargo.lock
+2895
Cargo.lock
···
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 = "allocator-api2"
16
+
version = "0.2.21"
17
+
source = "registry+https://github.com/rust-lang/crates.io-index"
18
+
checksum = "683d7910e743518b0e34f1186f92494becacb047c7b6bf616c96772180fef923"
19
+
20
+
[[package]]
21
+
name = "anstream"
22
+
version = "0.6.21"
23
+
source = "registry+https://github.com/rust-lang/crates.io-index"
24
+
checksum = "43d5b281e737544384e969a5ccad3f1cdd24b48086a0fc1b2a5262a26b8f4f4a"
25
+
dependencies = [
26
+
"anstyle",
27
+
"anstyle-parse",
28
+
"anstyle-query",
29
+
"anstyle-wincon",
30
+
"colorchoice",
31
+
"is_terminal_polyfill",
32
+
"utf8parse",
33
+
]
34
+
35
+
[[package]]
36
+
name = "anstyle"
37
+
version = "1.0.13"
38
+
source = "registry+https://github.com/rust-lang/crates.io-index"
39
+
checksum = "5192cca8006f1fd4f7237516f40fa183bb07f8fbdfedaa0036de5ea9b0b45e78"
40
+
41
+
[[package]]
42
+
name = "anstyle-parse"
43
+
version = "0.2.7"
44
+
source = "registry+https://github.com/rust-lang/crates.io-index"
45
+
checksum = "4e7644824f0aa2c7b9384579234ef10eb7efb6a0deb83f9630a49594dd9c15c2"
46
+
dependencies = [
47
+
"utf8parse",
48
+
]
49
+
50
+
[[package]]
51
+
name = "anstyle-query"
52
+
version = "1.1.5"
53
+
source = "registry+https://github.com/rust-lang/crates.io-index"
54
+
checksum = "40c48f72fd53cd289104fc64099abca73db4166ad86ea0b4341abe65af83dadc"
55
+
dependencies = [
56
+
"windows-sys 0.61.2",
57
+
]
58
+
59
+
[[package]]
60
+
name = "anstyle-wincon"
61
+
version = "3.0.11"
62
+
source = "registry+https://github.com/rust-lang/crates.io-index"
63
+
checksum = "291e6a250ff86cd4a820112fb8898808a366d8f9f58ce16d1f538353ad55747d"
64
+
dependencies = [
65
+
"anstyle",
66
+
"once_cell_polyfill",
67
+
"windows-sys 0.61.2",
68
+
]
69
+
70
+
[[package]]
71
+
name = "anyhow"
72
+
version = "1.0.100"
73
+
source = "registry+https://github.com/rust-lang/crates.io-index"
74
+
checksum = "a23eb6b1614318a8071c9b2521f36b424b2c83db5eb3a0fead4a6c0809af6e61"
75
+
76
+
[[package]]
77
+
name = "atoi"
78
+
version = "2.0.0"
79
+
source = "registry+https://github.com/rust-lang/crates.io-index"
80
+
checksum = "f28d99ec8bfea296261ca1af174f24225171fea9664ba9003cbebee704810528"
81
+
dependencies = [
82
+
"num-traits",
83
+
]
84
+
85
+
[[package]]
86
+
name = "atomic-waker"
87
+
version = "1.1.2"
88
+
source = "registry+https://github.com/rust-lang/crates.io-index"
89
+
checksum = "1505bd5d3d116872e7271a6d4e16d81d0c8570876c8de68093a09ac269d8aac0"
90
+
91
+
[[package]]
92
+
name = "autocfg"
93
+
version = "1.5.0"
94
+
source = "registry+https://github.com/rust-lang/crates.io-index"
95
+
checksum = "c08606f8c3cbf4ce6ec8e28fb0014a2c086708fe954eaa885384a6165172e7e8"
96
+
97
+
[[package]]
98
+
name = "base64"
99
+
version = "0.22.1"
100
+
source = "registry+https://github.com/rust-lang/crates.io-index"
101
+
checksum = "72b3254f16251a8381aa12e40e3c4d2f0199f8c6508fbecb9d91f575e0fbb8c6"
102
+
103
+
[[package]]
104
+
name = "base64ct"
105
+
version = "1.8.1"
106
+
source = "registry+https://github.com/rust-lang/crates.io-index"
107
+
checksum = "0e050f626429857a27ddccb31e0aca21356bfa709c04041aefddac081a8f068a"
108
+
109
+
[[package]]
110
+
name = "bitflags"
111
+
version = "2.10.0"
112
+
source = "registry+https://github.com/rust-lang/crates.io-index"
113
+
checksum = "812e12b5285cc515a9c72a5c1d3b6d46a19dac5acfef5265968c166106e31dd3"
114
+
dependencies = [
115
+
"serde_core",
116
+
]
117
+
118
+
[[package]]
119
+
name = "block-buffer"
120
+
version = "0.10.4"
121
+
source = "registry+https://github.com/rust-lang/crates.io-index"
122
+
checksum = "3078c7629b62d3f0439517fa394996acacc5cbc91c5a20d8c658e77abd503a71"
123
+
dependencies = [
124
+
"generic-array",
125
+
]
126
+
127
+
[[package]]
128
+
name = "bumpalo"
129
+
version = "3.19.1"
130
+
source = "registry+https://github.com/rust-lang/crates.io-index"
131
+
checksum = "5dd9dc738b7a8311c7ade152424974d8115f2cdad61e8dab8dac9f2362298510"
132
+
133
+
[[package]]
134
+
name = "byteorder"
135
+
version = "1.5.0"
136
+
source = "registry+https://github.com/rust-lang/crates.io-index"
137
+
checksum = "1fd0f2584146f6f2ef48085050886acf353beff7305ebd1ae69500e27c67f64b"
138
+
139
+
[[package]]
140
+
name = "bytes"
141
+
version = "1.11.0"
142
+
source = "registry+https://github.com/rust-lang/crates.io-index"
143
+
checksum = "b35204fbdc0b3f4446b89fc1ac2cf84a8a68971995d0bf2e925ec7cd960f9cb3"
144
+
145
+
[[package]]
146
+
name = "cc"
147
+
version = "1.2.49"
148
+
source = "registry+https://github.com/rust-lang/crates.io-index"
149
+
checksum = "90583009037521a116abf44494efecd645ba48b6622457080f080b85544e2215"
150
+
dependencies = [
151
+
"find-msvc-tools",
152
+
"shlex",
153
+
]
154
+
155
+
[[package]]
156
+
name = "cfg-if"
157
+
version = "1.0.4"
158
+
source = "registry+https://github.com/rust-lang/crates.io-index"
159
+
checksum = "9330f8b2ff13f34540b44e946ef35111825727b38d33286ef986142615121801"
160
+
161
+
[[package]]
162
+
name = "clap"
163
+
version = "4.5.53"
164
+
source = "registry+https://github.com/rust-lang/crates.io-index"
165
+
checksum = "c9e340e012a1bf4935f5282ed1436d1489548e8f72308207ea5df0e23d2d03f8"
166
+
dependencies = [
167
+
"clap_builder",
168
+
"clap_derive",
169
+
]
170
+
171
+
[[package]]
172
+
name = "clap_builder"
173
+
version = "4.5.53"
174
+
source = "registry+https://github.com/rust-lang/crates.io-index"
175
+
checksum = "d76b5d13eaa18c901fd2f7fca939fefe3a0727a953561fefdf3b2922b8569d00"
176
+
dependencies = [
177
+
"anstream",
178
+
"anstyle",
179
+
"clap_lex",
180
+
"strsim",
181
+
]
182
+
183
+
[[package]]
184
+
name = "clap_derive"
185
+
version = "4.5.49"
186
+
source = "registry+https://github.com/rust-lang/crates.io-index"
187
+
checksum = "2a0b5487afeab2deb2ff4e03a807ad1a03ac532ff5a2cee5d86884440c7f7671"
188
+
dependencies = [
189
+
"heck",
190
+
"proc-macro2",
191
+
"quote",
192
+
"syn",
193
+
]
194
+
195
+
[[package]]
196
+
name = "clap_lex"
197
+
version = "0.7.6"
198
+
source = "registry+https://github.com/rust-lang/crates.io-index"
199
+
checksum = "a1d728cc89cf3aee9ff92b05e62b19ee65a02b5702cff7d5a377e32c6ae29d8d"
200
+
201
+
[[package]]
202
+
name = "colorchoice"
203
+
version = "1.0.4"
204
+
source = "registry+https://github.com/rust-lang/crates.io-index"
205
+
checksum = "b05b61dc5112cbb17e4b6cd61790d9845d13888356391624cbe7e41efeac1e75"
206
+
207
+
[[package]]
208
+
name = "concurrent-queue"
209
+
version = "2.5.0"
210
+
source = "registry+https://github.com/rust-lang/crates.io-index"
211
+
checksum = "4ca0197aee26d1ae37445ee532fefce43251d24cc7c166799f4d46817f1d3973"
212
+
dependencies = [
213
+
"crossbeam-utils",
214
+
]
215
+
216
+
[[package]]
217
+
name = "const-oid"
218
+
version = "0.9.6"
219
+
source = "registry+https://github.com/rust-lang/crates.io-index"
220
+
checksum = "c2459377285ad874054d797f3ccebf984978aa39129f6eafde5cdc8315b612f8"
221
+
222
+
[[package]]
223
+
name = "core-foundation"
224
+
version = "0.9.4"
225
+
source = "registry+https://github.com/rust-lang/crates.io-index"
226
+
checksum = "91e195e091a93c46f7102ec7818a2aa394e1e1771c3ab4825963fa03e45afb8f"
227
+
dependencies = [
228
+
"core-foundation-sys",
229
+
"libc",
230
+
]
231
+
232
+
[[package]]
233
+
name = "core-foundation-sys"
234
+
version = "0.8.7"
235
+
source = "registry+https://github.com/rust-lang/crates.io-index"
236
+
checksum = "773648b94d0e5d620f64f280777445740e61fe701025087ec8b57f45c791888b"
237
+
238
+
[[package]]
239
+
name = "cpufeatures"
240
+
version = "0.2.17"
241
+
source = "registry+https://github.com/rust-lang/crates.io-index"
242
+
checksum = "59ed5838eebb26a2bb2e58f6d5b5316989ae9d08bab10e0e6d103e656d1b0280"
243
+
dependencies = [
244
+
"libc",
245
+
]
246
+
247
+
[[package]]
248
+
name = "crc"
249
+
version = "3.4.0"
250
+
source = "registry+https://github.com/rust-lang/crates.io-index"
251
+
checksum = "5eb8a2a1cd12ab0d987a5d5e825195d372001a4094a0376319d5a0ad71c1ba0d"
252
+
dependencies = [
253
+
"crc-catalog",
254
+
]
255
+
256
+
[[package]]
257
+
name = "crc-catalog"
258
+
version = "2.4.0"
259
+
source = "registry+https://github.com/rust-lang/crates.io-index"
260
+
checksum = "19d374276b40fb8bbdee95aef7c7fa6b5316ec764510eb64b8dd0e2ed0d7e7f5"
261
+
262
+
[[package]]
263
+
name = "crossbeam-queue"
264
+
version = "0.3.12"
265
+
source = "registry+https://github.com/rust-lang/crates.io-index"
266
+
checksum = "0f58bbc28f91df819d0aa2a2c00cd19754769c2fad90579b3592b1c9ba7a3115"
267
+
dependencies = [
268
+
"crossbeam-utils",
269
+
]
270
+
271
+
[[package]]
272
+
name = "crossbeam-utils"
273
+
version = "0.8.21"
274
+
source = "registry+https://github.com/rust-lang/crates.io-index"
275
+
checksum = "d0a5c400df2834b80a4c3327b3aad3a4c4cd4de0629063962b03235697506a28"
276
+
277
+
[[package]]
278
+
name = "crypto-common"
279
+
version = "0.1.7"
280
+
source = "registry+https://github.com/rust-lang/crates.io-index"
281
+
checksum = "78c8292055d1c1df0cce5d180393dc8cce0abec0a7102adb6c7b1eef6016d60a"
282
+
dependencies = [
283
+
"generic-array",
284
+
"typenum",
285
+
]
286
+
287
+
[[package]]
288
+
name = "data-encoding"
289
+
version = "2.9.0"
290
+
source = "registry+https://github.com/rust-lang/crates.io-index"
291
+
checksum = "2a2330da5de22e8a3cb63252ce2abb30116bf5265e89c0e01bc17015ce30a476"
292
+
293
+
[[package]]
294
+
name = "der"
295
+
version = "0.7.10"
296
+
source = "registry+https://github.com/rust-lang/crates.io-index"
297
+
checksum = "e7c1832837b905bbfb5101e07cc24c8deddf52f93225eee6ead5f4d63d53ddcb"
298
+
dependencies = [
299
+
"const-oid",
300
+
"pem-rfc7468",
301
+
"zeroize",
302
+
]
303
+
304
+
[[package]]
305
+
name = "deranged"
306
+
version = "0.5.5"
307
+
source = "registry+https://github.com/rust-lang/crates.io-index"
308
+
checksum = "ececcb659e7ba858fb4f10388c250a7252eb0a27373f1a72b8748afdd248e587"
309
+
dependencies = [
310
+
"powerfmt",
311
+
]
312
+
313
+
[[package]]
314
+
name = "digest"
315
+
version = "0.10.7"
316
+
source = "registry+https://github.com/rust-lang/crates.io-index"
317
+
checksum = "9ed9a281f7bc9b7576e61468ba615a66a5c8cfdff42420a70aa82701a3b1e292"
318
+
dependencies = [
319
+
"block-buffer",
320
+
"const-oid",
321
+
"crypto-common",
322
+
"subtle",
323
+
]
324
+
325
+
[[package]]
326
+
name = "displaydoc"
327
+
version = "0.2.5"
328
+
source = "registry+https://github.com/rust-lang/crates.io-index"
329
+
checksum = "97369cbbc041bc366949bc74d34658d6cda5621039731c6310521892a3a20ae0"
330
+
dependencies = [
331
+
"proc-macro2",
332
+
"quote",
333
+
"syn",
334
+
]
335
+
336
+
[[package]]
337
+
name = "dotenvy"
338
+
version = "0.15.7"
339
+
source = "registry+https://github.com/rust-lang/crates.io-index"
340
+
checksum = "1aaf95b3e5c8f23aa320147307562d361db0ae0d51242340f558153b4eb2439b"
341
+
342
+
[[package]]
343
+
name = "either"
344
+
version = "1.15.0"
345
+
source = "registry+https://github.com/rust-lang/crates.io-index"
346
+
checksum = "48c757948c5ede0e46177b7add2e67155f70e33c07fea8284df6576da70b3719"
347
+
dependencies = [
348
+
"serde",
349
+
]
350
+
351
+
[[package]]
352
+
name = "encoding_rs"
353
+
version = "0.8.35"
354
+
source = "registry+https://github.com/rust-lang/crates.io-index"
355
+
checksum = "75030f3c4f45dafd7586dd6780965a8c7e8e285a5ecb86713e63a79c5b2766f3"
356
+
dependencies = [
357
+
"cfg-if",
358
+
]
359
+
360
+
[[package]]
361
+
name = "equivalent"
362
+
version = "1.0.2"
363
+
source = "registry+https://github.com/rust-lang/crates.io-index"
364
+
checksum = "877a4ace8713b0bcf2a4e7eec82529c029f1d0619886d18145fea96c3ffe5c0f"
365
+
366
+
[[package]]
367
+
name = "errno"
368
+
version = "0.3.14"
369
+
source = "registry+https://github.com/rust-lang/crates.io-index"
370
+
checksum = "39cab71617ae0d63f51a36d69f866391735b51691dbda63cf6f96d042b63efeb"
371
+
dependencies = [
372
+
"libc",
373
+
"windows-sys 0.61.2",
374
+
]
375
+
376
+
[[package]]
377
+
name = "etcetera"
378
+
version = "0.8.0"
379
+
source = "registry+https://github.com/rust-lang/crates.io-index"
380
+
checksum = "136d1b5283a1ab77bd9257427ffd09d8667ced0570b6f938942bc7568ed5b943"
381
+
dependencies = [
382
+
"cfg-if",
383
+
"home",
384
+
"windows-sys 0.48.0",
385
+
]
386
+
387
+
[[package]]
388
+
name = "event-listener"
389
+
version = "5.4.1"
390
+
source = "registry+https://github.com/rust-lang/crates.io-index"
391
+
checksum = "e13b66accf52311f30a0db42147dadea9850cb48cd070028831ae5f5d4b856ab"
392
+
dependencies = [
393
+
"concurrent-queue",
394
+
"parking",
395
+
"pin-project-lite",
396
+
]
397
+
398
+
[[package]]
399
+
name = "fastrand"
400
+
version = "2.3.0"
401
+
source = "registry+https://github.com/rust-lang/crates.io-index"
402
+
checksum = "37909eebbb50d72f9059c3b6d82c0463f2ff062c9e95845c43a6c9c0355411be"
403
+
404
+
[[package]]
405
+
name = "find-msvc-tools"
406
+
version = "0.1.5"
407
+
source = "registry+https://github.com/rust-lang/crates.io-index"
408
+
checksum = "3a3076410a55c90011c298b04d0cfa770b00fa04e1e3c97d3f6c9de105a03844"
409
+
410
+
[[package]]
411
+
name = "flume"
412
+
version = "0.11.1"
413
+
source = "registry+https://github.com/rust-lang/crates.io-index"
414
+
checksum = "da0e4dd2a88388a1f4ccc7c9ce104604dab68d9f408dc34cd45823d5a9069095"
415
+
dependencies = [
416
+
"futures-core",
417
+
"futures-sink",
418
+
"spin",
419
+
]
420
+
421
+
[[package]]
422
+
name = "fnv"
423
+
version = "1.0.7"
424
+
source = "registry+https://github.com/rust-lang/crates.io-index"
425
+
checksum = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1"
426
+
427
+
[[package]]
428
+
name = "foldhash"
429
+
version = "0.1.5"
430
+
source = "registry+https://github.com/rust-lang/crates.io-index"
431
+
checksum = "d9c4f5dac5e15c24eb999c26181a6ca40b39fe946cbe4c263c7209467bc83af2"
432
+
433
+
[[package]]
434
+
name = "foreign-types"
435
+
version = "0.3.2"
436
+
source = "registry+https://github.com/rust-lang/crates.io-index"
437
+
checksum = "f6f339eb8adc052cd2ca78910fda869aefa38d22d5cb648e6485e4d3fc06f3b1"
438
+
dependencies = [
439
+
"foreign-types-shared",
440
+
]
441
+
442
+
[[package]]
443
+
name = "foreign-types-shared"
444
+
version = "0.1.1"
445
+
source = "registry+https://github.com/rust-lang/crates.io-index"
446
+
checksum = "00b0228411908ca8685dba7fc2cdd70ec9990a6e753e89b6ac91a84c40fbaf4b"
447
+
448
+
[[package]]
449
+
name = "form_urlencoded"
450
+
version = "1.2.2"
451
+
source = "registry+https://github.com/rust-lang/crates.io-index"
452
+
checksum = "cb4cb245038516f5f85277875cdaa4f7d2c9a0fa0468de06ed190163b1581fcf"
453
+
dependencies = [
454
+
"percent-encoding",
455
+
]
456
+
457
+
[[package]]
458
+
name = "futures-channel"
459
+
version = "0.3.31"
460
+
source = "registry+https://github.com/rust-lang/crates.io-index"
461
+
checksum = "2dff15bf788c671c1934e366d07e30c1814a8ef514e1af724a602e8a2fbe1b10"
462
+
dependencies = [
463
+
"futures-core",
464
+
"futures-sink",
465
+
]
466
+
467
+
[[package]]
468
+
name = "futures-core"
469
+
version = "0.3.31"
470
+
source = "registry+https://github.com/rust-lang/crates.io-index"
471
+
checksum = "05f29059c0c2090612e8d742178b0580d2dc940c837851ad723096f87af6663e"
472
+
473
+
[[package]]
474
+
name = "futures-executor"
475
+
version = "0.3.31"
476
+
source = "registry+https://github.com/rust-lang/crates.io-index"
477
+
checksum = "1e28d1d997f585e54aebc3f97d39e72338912123a67330d723fdbb564d646c9f"
478
+
dependencies = [
479
+
"futures-core",
480
+
"futures-task",
481
+
"futures-util",
482
+
]
483
+
484
+
[[package]]
485
+
name = "futures-intrusive"
486
+
version = "0.5.0"
487
+
source = "registry+https://github.com/rust-lang/crates.io-index"
488
+
checksum = "1d930c203dd0b6ff06e0201a4a2fe9149b43c684fd4420555b26d21b1a02956f"
489
+
dependencies = [
490
+
"futures-core",
491
+
"lock_api",
492
+
"parking_lot",
493
+
]
494
+
495
+
[[package]]
496
+
name = "futures-io"
497
+
version = "0.3.31"
498
+
source = "registry+https://github.com/rust-lang/crates.io-index"
499
+
checksum = "9e5c1b78ca4aae1ac06c48a526a655760685149f0d465d21f37abfe57ce075c6"
500
+
501
+
[[package]]
502
+
name = "futures-macro"
503
+
version = "0.3.31"
504
+
source = "registry+https://github.com/rust-lang/crates.io-index"
505
+
checksum = "162ee34ebcb7c64a8abebc059ce0fee27c2262618d7b60ed8faf72fef13c3650"
506
+
dependencies = [
507
+
"proc-macro2",
508
+
"quote",
509
+
"syn",
510
+
]
511
+
512
+
[[package]]
513
+
name = "futures-sink"
514
+
version = "0.3.31"
515
+
source = "registry+https://github.com/rust-lang/crates.io-index"
516
+
checksum = "e575fab7d1e0dcb8d0c7bcf9a63ee213816ab51902e6d244a95819acacf1d4f7"
517
+
518
+
[[package]]
519
+
name = "futures-task"
520
+
version = "0.3.31"
521
+
source = "registry+https://github.com/rust-lang/crates.io-index"
522
+
checksum = "f90f7dce0722e95104fcb095585910c0977252f286e354b5e3bd38902cd99988"
523
+
524
+
[[package]]
525
+
name = "futures-util"
526
+
version = "0.3.31"
527
+
source = "registry+https://github.com/rust-lang/crates.io-index"
528
+
checksum = "9fa08315bb612088cc391249efdc3bc77536f16c91f6cf495e6fbe85b20a4a81"
529
+
dependencies = [
530
+
"futures-core",
531
+
"futures-io",
532
+
"futures-macro",
533
+
"futures-sink",
534
+
"futures-task",
535
+
"memchr",
536
+
"pin-project-lite",
537
+
"pin-utils",
538
+
"slab",
539
+
]
540
+
541
+
[[package]]
542
+
name = "generic-array"
543
+
version = "0.14.7"
544
+
source = "registry+https://github.com/rust-lang/crates.io-index"
545
+
checksum = "85649ca51fd72272d7821adaf274ad91c288277713d9c18820d8499a7ff69e9a"
546
+
dependencies = [
547
+
"typenum",
548
+
"version_check",
549
+
]
550
+
551
+
[[package]]
552
+
name = "getrandom"
553
+
version = "0.2.16"
554
+
source = "registry+https://github.com/rust-lang/crates.io-index"
555
+
checksum = "335ff9f135e4384c8150d6f27c6daed433577f86b4750418338c01a1a2528592"
556
+
dependencies = [
557
+
"cfg-if",
558
+
"libc",
559
+
"wasi",
560
+
]
561
+
562
+
[[package]]
563
+
name = "getrandom"
564
+
version = "0.3.4"
565
+
source = "registry+https://github.com/rust-lang/crates.io-index"
566
+
checksum = "899def5c37c4fd7b2664648c28120ecec138e4d395b459e5ca34f9cce2dd77fd"
567
+
dependencies = [
568
+
"cfg-if",
569
+
"libc",
570
+
"r-efi",
571
+
"wasip2",
572
+
]
573
+
574
+
[[package]]
575
+
name = "h2"
576
+
version = "0.4.12"
577
+
source = "registry+https://github.com/rust-lang/crates.io-index"
578
+
checksum = "f3c0b69cfcb4e1b9f1bf2f53f95f766e4661169728ec61cd3fe5a0166f2d1386"
579
+
dependencies = [
580
+
"atomic-waker",
581
+
"bytes",
582
+
"fnv",
583
+
"futures-core",
584
+
"futures-sink",
585
+
"http",
586
+
"indexmap",
587
+
"slab",
588
+
"tokio",
589
+
"tokio-util",
590
+
"tracing",
591
+
]
592
+
593
+
[[package]]
594
+
name = "hashbrown"
595
+
version = "0.15.5"
596
+
source = "registry+https://github.com/rust-lang/crates.io-index"
597
+
checksum = "9229cfe53dfd69f0609a49f65461bd93001ea1ef889cd5529dd176593f5338a1"
598
+
dependencies = [
599
+
"allocator-api2",
600
+
"equivalent",
601
+
"foldhash",
602
+
]
603
+
604
+
[[package]]
605
+
name = "hashbrown"
606
+
version = "0.16.1"
607
+
source = "registry+https://github.com/rust-lang/crates.io-index"
608
+
checksum = "841d1cc9bed7f9236f321df977030373f4a4163ae1a7dbfe1a51a2c1a51d9100"
609
+
610
+
[[package]]
611
+
name = "hashlink"
612
+
version = "0.10.0"
613
+
source = "registry+https://github.com/rust-lang/crates.io-index"
614
+
checksum = "7382cf6263419f2d8df38c55d7da83da5c18aef87fc7a7fc1fb1e344edfe14c1"
615
+
dependencies = [
616
+
"hashbrown 0.15.5",
617
+
]
618
+
619
+
[[package]]
620
+
name = "heck"
621
+
version = "0.5.0"
622
+
source = "registry+https://github.com/rust-lang/crates.io-index"
623
+
checksum = "2304e00983f87ffb38b55b444b5e3b60a884b5d30c0fca7d82fe33449bbe55ea"
624
+
625
+
[[package]]
626
+
name = "hex"
627
+
version = "0.4.3"
628
+
source = "registry+https://github.com/rust-lang/crates.io-index"
629
+
checksum = "7f24254aa9a54b5c858eaee2f5bccdb46aaf0e486a595ed5fd8f86ba55232a70"
630
+
631
+
[[package]]
632
+
name = "hkdf"
633
+
version = "0.12.4"
634
+
source = "registry+https://github.com/rust-lang/crates.io-index"
635
+
checksum = "7b5f8eb2ad728638ea2c7d47a21db23b7b58a72ed6a38256b8a1849f15fbbdf7"
636
+
dependencies = [
637
+
"hmac",
638
+
]
639
+
640
+
[[package]]
641
+
name = "hmac"
642
+
version = "0.12.1"
643
+
source = "registry+https://github.com/rust-lang/crates.io-index"
644
+
checksum = "6c49c37c09c17a53d937dfbb742eb3a961d65a994e6bcdcf37e7399d0cc8ab5e"
645
+
dependencies = [
646
+
"digest",
647
+
]
648
+
649
+
[[package]]
650
+
name = "home"
651
+
version = "0.5.12"
652
+
source = "registry+https://github.com/rust-lang/crates.io-index"
653
+
checksum = "cc627f471c528ff0c4a49e1d5e60450c8f6461dd6d10ba9dcd3a61d3dff7728d"
654
+
dependencies = [
655
+
"windows-sys 0.61.2",
656
+
]
657
+
658
+
[[package]]
659
+
name = "http"
660
+
version = "1.4.0"
661
+
source = "registry+https://github.com/rust-lang/crates.io-index"
662
+
checksum = "e3ba2a386d7f85a81f119ad7498ebe444d2e22c2af0b86b069416ace48b3311a"
663
+
dependencies = [
664
+
"bytes",
665
+
"itoa",
666
+
]
667
+
668
+
[[package]]
669
+
name = "http-body"
670
+
version = "1.0.1"
671
+
source = "registry+https://github.com/rust-lang/crates.io-index"
672
+
checksum = "1efedce1fb8e6913f23e0c92de8e62cd5b772a67e7b3946df930a62566c93184"
673
+
dependencies = [
674
+
"bytes",
675
+
"http",
676
+
]
677
+
678
+
[[package]]
679
+
name = "http-body-util"
680
+
version = "0.1.3"
681
+
source = "registry+https://github.com/rust-lang/crates.io-index"
682
+
checksum = "b021d93e26becf5dc7e1b75b1bed1fd93124b374ceb73f43d4d4eafec896a64a"
683
+
dependencies = [
684
+
"bytes",
685
+
"futures-core",
686
+
"http",
687
+
"http-body",
688
+
"pin-project-lite",
689
+
]
690
+
691
+
[[package]]
692
+
name = "httparse"
693
+
version = "1.10.1"
694
+
source = "registry+https://github.com/rust-lang/crates.io-index"
695
+
checksum = "6dbf3de79e51f3d586ab4cb9d5c3e2c14aa28ed23d180cf89b4df0454a69cc87"
696
+
697
+
[[package]]
698
+
name = "hyper"
699
+
version = "1.8.1"
700
+
source = "registry+https://github.com/rust-lang/crates.io-index"
701
+
checksum = "2ab2d4f250c3d7b1c9fcdff1cece94ea4e2dfbec68614f7b87cb205f24ca9d11"
702
+
dependencies = [
703
+
"atomic-waker",
704
+
"bytes",
705
+
"futures-channel",
706
+
"futures-core",
707
+
"h2",
708
+
"http",
709
+
"http-body",
710
+
"httparse",
711
+
"itoa",
712
+
"pin-project-lite",
713
+
"pin-utils",
714
+
"smallvec",
715
+
"tokio",
716
+
"want",
717
+
]
718
+
719
+
[[package]]
720
+
name = "hyper-rustls"
721
+
version = "0.27.7"
722
+
source = "registry+https://github.com/rust-lang/crates.io-index"
723
+
checksum = "e3c93eb611681b207e1fe55d5a71ecf91572ec8a6705cdb6857f7d8d5242cf58"
724
+
dependencies = [
725
+
"http",
726
+
"hyper",
727
+
"hyper-util",
728
+
"rustls",
729
+
"rustls-pki-types",
730
+
"tokio",
731
+
"tokio-rustls",
732
+
"tower-service",
733
+
]
734
+
735
+
[[package]]
736
+
name = "hyper-tls"
737
+
version = "0.6.0"
738
+
source = "registry+https://github.com/rust-lang/crates.io-index"
739
+
checksum = "70206fc6890eaca9fde8a0bf71caa2ddfc9fe045ac9e5c70df101a7dbde866e0"
740
+
dependencies = [
741
+
"bytes",
742
+
"http-body-util",
743
+
"hyper",
744
+
"hyper-util",
745
+
"native-tls",
746
+
"tokio",
747
+
"tokio-native-tls",
748
+
"tower-service",
749
+
]
750
+
751
+
[[package]]
752
+
name = "hyper-util"
753
+
version = "0.1.19"
754
+
source = "registry+https://github.com/rust-lang/crates.io-index"
755
+
checksum = "727805d60e7938b76b826a6ef209eb70eaa1812794f9424d4a4e2d740662df5f"
756
+
dependencies = [
757
+
"base64",
758
+
"bytes",
759
+
"futures-channel",
760
+
"futures-core",
761
+
"futures-util",
762
+
"http",
763
+
"http-body",
764
+
"hyper",
765
+
"ipnet",
766
+
"libc",
767
+
"percent-encoding",
768
+
"pin-project-lite",
769
+
"socket2",
770
+
"system-configuration",
771
+
"tokio",
772
+
"tower-service",
773
+
"tracing",
774
+
"windows-registry",
775
+
]
776
+
777
+
[[package]]
778
+
name = "icu_collections"
779
+
version = "2.1.1"
780
+
source = "registry+https://github.com/rust-lang/crates.io-index"
781
+
checksum = "4c6b649701667bbe825c3b7e6388cb521c23d88644678e83c0c4d0a621a34b43"
782
+
dependencies = [
783
+
"displaydoc",
784
+
"potential_utf",
785
+
"yoke",
786
+
"zerofrom",
787
+
"zerovec",
788
+
]
789
+
790
+
[[package]]
791
+
name = "icu_locale_core"
792
+
version = "2.1.1"
793
+
source = "registry+https://github.com/rust-lang/crates.io-index"
794
+
checksum = "edba7861004dd3714265b4db54a3c390e880ab658fec5f7db895fae2046b5bb6"
795
+
dependencies = [
796
+
"displaydoc",
797
+
"litemap",
798
+
"tinystr",
799
+
"writeable",
800
+
"zerovec",
801
+
]
802
+
803
+
[[package]]
804
+
name = "icu_normalizer"
805
+
version = "2.1.1"
806
+
source = "registry+https://github.com/rust-lang/crates.io-index"
807
+
checksum = "5f6c8828b67bf8908d82127b2054ea1b4427ff0230ee9141c54251934ab1b599"
808
+
dependencies = [
809
+
"icu_collections",
810
+
"icu_normalizer_data",
811
+
"icu_properties",
812
+
"icu_provider",
813
+
"smallvec",
814
+
"zerovec",
815
+
]
816
+
817
+
[[package]]
818
+
name = "icu_normalizer_data"
819
+
version = "2.1.1"
820
+
source = "registry+https://github.com/rust-lang/crates.io-index"
821
+
checksum = "7aedcccd01fc5fe81e6b489c15b247b8b0690feb23304303a9e560f37efc560a"
822
+
823
+
[[package]]
824
+
name = "icu_properties"
825
+
version = "2.1.2"
826
+
source = "registry+https://github.com/rust-lang/crates.io-index"
827
+
checksum = "020bfc02fe870ec3a66d93e677ccca0562506e5872c650f893269e08615d74ec"
828
+
dependencies = [
829
+
"icu_collections",
830
+
"icu_locale_core",
831
+
"icu_properties_data",
832
+
"icu_provider",
833
+
"zerotrie",
834
+
"zerovec",
835
+
]
836
+
837
+
[[package]]
838
+
name = "icu_properties_data"
839
+
version = "2.1.2"
840
+
source = "registry+https://github.com/rust-lang/crates.io-index"
841
+
checksum = "616c294cf8d725c6afcd8f55abc17c56464ef6211f9ed59cccffe534129c77af"
842
+
843
+
[[package]]
844
+
name = "icu_provider"
845
+
version = "2.1.1"
846
+
source = "registry+https://github.com/rust-lang/crates.io-index"
847
+
checksum = "85962cf0ce02e1e0a629cc34e7ca3e373ce20dda4c4d7294bbd0bf1fdb59e614"
848
+
dependencies = [
849
+
"displaydoc",
850
+
"icu_locale_core",
851
+
"writeable",
852
+
"yoke",
853
+
"zerofrom",
854
+
"zerotrie",
855
+
"zerovec",
856
+
]
857
+
858
+
[[package]]
859
+
name = "idna"
860
+
version = "1.1.0"
861
+
source = "registry+https://github.com/rust-lang/crates.io-index"
862
+
checksum = "3b0875f23caa03898994f6ddc501886a45c7d3d62d04d2d90788d47be1b1e4de"
863
+
dependencies = [
864
+
"idna_adapter",
865
+
"smallvec",
866
+
"utf8_iter",
867
+
]
868
+
869
+
[[package]]
870
+
name = "idna_adapter"
871
+
version = "1.2.1"
872
+
source = "registry+https://github.com/rust-lang/crates.io-index"
873
+
checksum = "3acae9609540aa318d1bc588455225fb2085b9ed0c4f6bd0d9d5bcd86f1a0344"
874
+
dependencies = [
875
+
"icu_normalizer",
876
+
"icu_properties",
877
+
]
878
+
879
+
[[package]]
880
+
name = "indexmap"
881
+
version = "2.12.1"
882
+
source = "registry+https://github.com/rust-lang/crates.io-index"
883
+
checksum = "0ad4bb2b565bca0645f4d68c5c9af97fba094e9791da685bf83cb5f3ce74acf2"
884
+
dependencies = [
885
+
"equivalent",
886
+
"hashbrown 0.16.1",
887
+
]
888
+
889
+
[[package]]
890
+
name = "ipnet"
891
+
version = "2.11.0"
892
+
source = "registry+https://github.com/rust-lang/crates.io-index"
893
+
checksum = "469fb0b9cefa57e3ef31275ee7cacb78f2fdca44e4765491884a2b119d4eb130"
894
+
895
+
[[package]]
896
+
name = "iri-string"
897
+
version = "0.7.9"
898
+
source = "registry+https://github.com/rust-lang/crates.io-index"
899
+
checksum = "4f867b9d1d896b67beb18518eda36fdb77a32ea590de864f1325b294a6d14397"
900
+
dependencies = [
901
+
"memchr",
902
+
"serde",
903
+
]
904
+
905
+
[[package]]
906
+
name = "is_terminal_polyfill"
907
+
version = "1.70.2"
908
+
source = "registry+https://github.com/rust-lang/crates.io-index"
909
+
checksum = "a6cb138bb79a146c1bd460005623e142ef0181e3d0219cb493e02f7d08a35695"
910
+
911
+
[[package]]
912
+
name = "itoa"
913
+
version = "1.0.15"
914
+
source = "registry+https://github.com/rust-lang/crates.io-index"
915
+
checksum = "4a5f13b858c8d314ee3e8f639011f7ccefe71f97f96e50151fb991f267928e2c"
916
+
917
+
[[package]]
918
+
name = "js-sys"
919
+
version = "0.3.83"
920
+
source = "registry+https://github.com/rust-lang/crates.io-index"
921
+
checksum = "464a3709c7f55f1f721e5389aa6ea4e3bc6aba669353300af094b29ffbdde1d8"
922
+
dependencies = [
923
+
"once_cell",
924
+
"wasm-bindgen",
925
+
]
926
+
927
+
[[package]]
928
+
name = "lazy_static"
929
+
version = "1.5.0"
930
+
source = "registry+https://github.com/rust-lang/crates.io-index"
931
+
checksum = "bbd2bcb4c963f2ddae06a2efc7e9f3591312473c50c6685e1f298068316e66fe"
932
+
dependencies = [
933
+
"spin",
934
+
]
935
+
936
+
[[package]]
937
+
name = "libc"
938
+
version = "0.2.178"
939
+
source = "registry+https://github.com/rust-lang/crates.io-index"
940
+
checksum = "37c93d8daa9d8a012fd8ab92f088405fb202ea0b6ab73ee2482ae66af4f42091"
941
+
942
+
[[package]]
943
+
name = "libm"
944
+
version = "0.2.15"
945
+
source = "registry+https://github.com/rust-lang/crates.io-index"
946
+
checksum = "f9fbbcab51052fe104eb5e5d351cf728d30a5be1fe14d9be8a3b097481fb97de"
947
+
948
+
[[package]]
949
+
name = "libredox"
950
+
version = "0.1.11"
951
+
source = "registry+https://github.com/rust-lang/crates.io-index"
952
+
checksum = "df15f6eac291ed1cf25865b1ee60399f57e7c227e7f51bdbd4c5270396a9ed50"
953
+
dependencies = [
954
+
"bitflags",
955
+
"libc",
956
+
"redox_syscall 0.6.0",
957
+
]
958
+
959
+
[[package]]
960
+
name = "libsqlite3-sys"
961
+
version = "0.30.1"
962
+
source = "registry+https://github.com/rust-lang/crates.io-index"
963
+
checksum = "2e99fb7a497b1e3339bc746195567ed8d3e24945ecd636e3619d20b9de9e9149"
964
+
dependencies = [
965
+
"pkg-config",
966
+
"vcpkg",
967
+
]
968
+
969
+
[[package]]
970
+
name = "linux-raw-sys"
971
+
version = "0.11.0"
972
+
source = "registry+https://github.com/rust-lang/crates.io-index"
973
+
checksum = "df1d3c3b53da64cf5760482273a98e575c651a67eec7f77df96b5b642de8f039"
974
+
975
+
[[package]]
976
+
name = "litemap"
977
+
version = "0.8.1"
978
+
source = "registry+https://github.com/rust-lang/crates.io-index"
979
+
checksum = "6373607a59f0be73a39b6fe456b8192fcc3585f602af20751600e974dd455e77"
980
+
981
+
[[package]]
982
+
name = "lock_api"
983
+
version = "0.4.14"
984
+
source = "registry+https://github.com/rust-lang/crates.io-index"
985
+
checksum = "224399e74b87b5f3557511d98dff8b14089b3dadafcab6bb93eab67d3aace965"
986
+
dependencies = [
987
+
"scopeguard",
988
+
]
989
+
990
+
[[package]]
991
+
name = "log"
992
+
version = "0.4.29"
993
+
source = "registry+https://github.com/rust-lang/crates.io-index"
994
+
checksum = "5e5032e24019045c762d3c0f28f5b6b8bbf38563a65908389bf7978758920897"
995
+
996
+
[[package]]
997
+
name = "matchers"
998
+
version = "0.2.0"
999
+
source = "registry+https://github.com/rust-lang/crates.io-index"
1000
+
checksum = "d1525a2a28c7f4fa0fc98bb91ae755d1e2d1505079e05539e35bc876b5d65ae9"
1001
+
dependencies = [
1002
+
"regex-automata",
1003
+
]
1004
+
1005
+
[[package]]
1006
+
name = "md-5"
1007
+
version = "0.10.6"
1008
+
source = "registry+https://github.com/rust-lang/crates.io-index"
1009
+
checksum = "d89e7ee0cfbedfc4da3340218492196241d89eefb6dab27de5df917a6d2e78cf"
1010
+
dependencies = [
1011
+
"cfg-if",
1012
+
"digest",
1013
+
]
1014
+
1015
+
[[package]]
1016
+
name = "memchr"
1017
+
version = "2.7.6"
1018
+
source = "registry+https://github.com/rust-lang/crates.io-index"
1019
+
checksum = "f52b00d39961fc5b2736ea853c9cc86238e165017a493d1d5c8eac6bdc4cc273"
1020
+
1021
+
[[package]]
1022
+
name = "mime"
1023
+
version = "0.3.17"
1024
+
source = "registry+https://github.com/rust-lang/crates.io-index"
1025
+
checksum = "6877bb514081ee2a7ff5ef9de3281f14a4dd4bceac4c09388074a6b5df8a139a"
1026
+
1027
+
[[package]]
1028
+
name = "mio"
1029
+
version = "1.1.1"
1030
+
source = "registry+https://github.com/rust-lang/crates.io-index"
1031
+
checksum = "a69bcab0ad47271a0234d9422b131806bf3968021e5dc9328caf2d4cd58557fc"
1032
+
dependencies = [
1033
+
"libc",
1034
+
"wasi",
1035
+
"windows-sys 0.61.2",
1036
+
]
1037
+
1038
+
[[package]]
1039
+
name = "native-tls"
1040
+
version = "0.2.14"
1041
+
source = "registry+https://github.com/rust-lang/crates.io-index"
1042
+
checksum = "87de3442987e9dbec73158d5c715e7ad9072fda936bb03d19d7fa10e00520f0e"
1043
+
dependencies = [
1044
+
"libc",
1045
+
"log",
1046
+
"openssl",
1047
+
"openssl-probe",
1048
+
"openssl-sys",
1049
+
"schannel",
1050
+
"security-framework",
1051
+
"security-framework-sys",
1052
+
"tempfile",
1053
+
]
1054
+
1055
+
[[package]]
1056
+
name = "nu-ansi-term"
1057
+
version = "0.50.3"
1058
+
source = "registry+https://github.com/rust-lang/crates.io-index"
1059
+
checksum = "7957b9740744892f114936ab4a57b3f487491bbeafaf8083688b16841a4240e5"
1060
+
dependencies = [
1061
+
"windows-sys 0.61.2",
1062
+
]
1063
+
1064
+
[[package]]
1065
+
name = "num-bigint-dig"
1066
+
version = "0.8.6"
1067
+
source = "registry+https://github.com/rust-lang/crates.io-index"
1068
+
checksum = "e661dda6640fad38e827a6d4a310ff4763082116fe217f279885c97f511bb0b7"
1069
+
dependencies = [
1070
+
"lazy_static",
1071
+
"libm",
1072
+
"num-integer",
1073
+
"num-iter",
1074
+
"num-traits",
1075
+
"rand 0.8.5",
1076
+
"smallvec",
1077
+
"zeroize",
1078
+
]
1079
+
1080
+
[[package]]
1081
+
name = "num-conv"
1082
+
version = "0.1.0"
1083
+
source = "registry+https://github.com/rust-lang/crates.io-index"
1084
+
checksum = "51d515d32fb182ee37cda2ccdcb92950d6a3c2893aa280e540671c2cd0f3b1d9"
1085
+
1086
+
[[package]]
1087
+
name = "num-integer"
1088
+
version = "0.1.46"
1089
+
source = "registry+https://github.com/rust-lang/crates.io-index"
1090
+
checksum = "7969661fd2958a5cb096e56c8e1ad0444ac2bbcd0061bd28660485a44879858f"
1091
+
dependencies = [
1092
+
"num-traits",
1093
+
]
1094
+
1095
+
[[package]]
1096
+
name = "num-iter"
1097
+
version = "0.1.45"
1098
+
source = "registry+https://github.com/rust-lang/crates.io-index"
1099
+
checksum = "1429034a0490724d0075ebb2bc9e875d6503c3cf69e235a8941aa757d83ef5bf"
1100
+
dependencies = [
1101
+
"autocfg",
1102
+
"num-integer",
1103
+
"num-traits",
1104
+
]
1105
+
1106
+
[[package]]
1107
+
name = "num-traits"
1108
+
version = "0.2.19"
1109
+
source = "registry+https://github.com/rust-lang/crates.io-index"
1110
+
checksum = "071dfc062690e90b734c0b2273ce72ad0ffa95f0c74596bc250dcfd960262841"
1111
+
dependencies = [
1112
+
"autocfg",
1113
+
"libm",
1114
+
]
1115
+
1116
+
[[package]]
1117
+
name = "once_cell"
1118
+
version = "1.21.3"
1119
+
source = "registry+https://github.com/rust-lang/crates.io-index"
1120
+
checksum = "42f5e15c9953c5e4ccceeb2e7382a716482c34515315f7b03532b8b4e8393d2d"
1121
+
1122
+
[[package]]
1123
+
name = "once_cell_polyfill"
1124
+
version = "1.70.2"
1125
+
source = "registry+https://github.com/rust-lang/crates.io-index"
1126
+
checksum = "384b8ab6d37215f3c5301a95a4accb5d64aa607f1fcb26a11b5303878451b4fe"
1127
+
1128
+
[[package]]
1129
+
name = "openssl"
1130
+
version = "0.10.75"
1131
+
source = "registry+https://github.com/rust-lang/crates.io-index"
1132
+
checksum = "08838db121398ad17ab8531ce9de97b244589089e290a384c900cb9ff7434328"
1133
+
dependencies = [
1134
+
"bitflags",
1135
+
"cfg-if",
1136
+
"foreign-types",
1137
+
"libc",
1138
+
"once_cell",
1139
+
"openssl-macros",
1140
+
"openssl-sys",
1141
+
]
1142
+
1143
+
[[package]]
1144
+
name = "openssl-macros"
1145
+
version = "0.1.1"
1146
+
source = "registry+https://github.com/rust-lang/crates.io-index"
1147
+
checksum = "a948666b637a0f465e8564c73e89d4dde00d72d4d473cc972f390fc3dcee7d9c"
1148
+
dependencies = [
1149
+
"proc-macro2",
1150
+
"quote",
1151
+
"syn",
1152
+
]
1153
+
1154
+
[[package]]
1155
+
name = "openssl-probe"
1156
+
version = "0.1.6"
1157
+
source = "registry+https://github.com/rust-lang/crates.io-index"
1158
+
checksum = "d05e27ee213611ffe7d6348b942e8f942b37114c00cc03cec254295a4a17852e"
1159
+
1160
+
[[package]]
1161
+
name = "openssl-sys"
1162
+
version = "0.9.111"
1163
+
source = "registry+https://github.com/rust-lang/crates.io-index"
1164
+
checksum = "82cab2d520aa75e3c58898289429321eb788c3106963d0dc886ec7a5f4adc321"
1165
+
dependencies = [
1166
+
"cc",
1167
+
"libc",
1168
+
"pkg-config",
1169
+
"vcpkg",
1170
+
]
1171
+
1172
+
[[package]]
1173
+
name = "parking"
1174
+
version = "2.2.1"
1175
+
source = "registry+https://github.com/rust-lang/crates.io-index"
1176
+
checksum = "f38d5652c16fde515bb1ecef450ab0f6a219d619a7274976324d5e377f7dceba"
1177
+
1178
+
[[package]]
1179
+
name = "parking_lot"
1180
+
version = "0.12.5"
1181
+
source = "registry+https://github.com/rust-lang/crates.io-index"
1182
+
checksum = "93857453250e3077bd71ff98b6a65ea6621a19bb0f559a85248955ac12c45a1a"
1183
+
dependencies = [
1184
+
"lock_api",
1185
+
"parking_lot_core",
1186
+
]
1187
+
1188
+
[[package]]
1189
+
name = "parking_lot_core"
1190
+
version = "0.9.12"
1191
+
source = "registry+https://github.com/rust-lang/crates.io-index"
1192
+
checksum = "2621685985a2ebf1c516881c026032ac7deafcda1a2c9b7850dc81e3dfcb64c1"
1193
+
dependencies = [
1194
+
"cfg-if",
1195
+
"libc",
1196
+
"redox_syscall 0.5.18",
1197
+
"smallvec",
1198
+
"windows-link",
1199
+
]
1200
+
1201
+
[[package]]
1202
+
name = "pem-rfc7468"
1203
+
version = "0.7.0"
1204
+
source = "registry+https://github.com/rust-lang/crates.io-index"
1205
+
checksum = "88b39c9bfcfc231068454382784bb460aae594343fb030d46e9f50a645418412"
1206
+
dependencies = [
1207
+
"base64ct",
1208
+
]
1209
+
1210
+
[[package]]
1211
+
name = "percent-encoding"
1212
+
version = "2.3.2"
1213
+
source = "registry+https://github.com/rust-lang/crates.io-index"
1214
+
checksum = "9b4f627cb1b25917193a259e49bdad08f671f8d9708acfd5fe0a8c1455d87220"
1215
+
1216
+
[[package]]
1217
+
name = "pin-project-lite"
1218
+
version = "0.2.16"
1219
+
source = "registry+https://github.com/rust-lang/crates.io-index"
1220
+
checksum = "3b3cff922bd51709b605d9ead9aa71031d81447142d828eb4a6eba76fe619f9b"
1221
+
1222
+
[[package]]
1223
+
name = "pin-utils"
1224
+
version = "0.1.0"
1225
+
source = "registry+https://github.com/rust-lang/crates.io-index"
1226
+
checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184"
1227
+
1228
+
[[package]]
1229
+
name = "pkcs1"
1230
+
version = "0.7.5"
1231
+
source = "registry+https://github.com/rust-lang/crates.io-index"
1232
+
checksum = "c8ffb9f10fa047879315e6625af03c164b16962a5368d724ed16323b68ace47f"
1233
+
dependencies = [
1234
+
"der",
1235
+
"pkcs8",
1236
+
"spki",
1237
+
]
1238
+
1239
+
[[package]]
1240
+
name = "pkcs8"
1241
+
version = "0.10.2"
1242
+
source = "registry+https://github.com/rust-lang/crates.io-index"
1243
+
checksum = "f950b2377845cebe5cf8b5165cb3cc1a5e0fa5cfa3e1f7f55707d8fd82e0a7b7"
1244
+
dependencies = [
1245
+
"der",
1246
+
"spki",
1247
+
]
1248
+
1249
+
[[package]]
1250
+
name = "pkg-config"
1251
+
version = "0.3.32"
1252
+
source = "registry+https://github.com/rust-lang/crates.io-index"
1253
+
checksum = "7edddbd0b52d732b21ad9a5fab5c704c14cd949e5e9a1ec5929a24fded1b904c"
1254
+
1255
+
[[package]]
1256
+
name = "potential_utf"
1257
+
version = "0.1.4"
1258
+
source = "registry+https://github.com/rust-lang/crates.io-index"
1259
+
checksum = "b73949432f5e2a09657003c25bca5e19a0e9c84f8058ca374f49e0ebe605af77"
1260
+
dependencies = [
1261
+
"zerovec",
1262
+
]
1263
+
1264
+
[[package]]
1265
+
name = "powerfmt"
1266
+
version = "0.2.0"
1267
+
source = "registry+https://github.com/rust-lang/crates.io-index"
1268
+
checksum = "439ee305def115ba05938db6eb1644ff94165c5ab5e9420d1c1bcedbba909391"
1269
+
1270
+
[[package]]
1271
+
name = "ppv-lite86"
1272
+
version = "0.2.21"
1273
+
source = "registry+https://github.com/rust-lang/crates.io-index"
1274
+
checksum = "85eae3c4ed2f50dcfe72643da4befc30deadb458a9b590d720cde2f2b1e97da9"
1275
+
dependencies = [
1276
+
"zerocopy",
1277
+
]
1278
+
1279
+
[[package]]
1280
+
name = "proc-macro2"
1281
+
version = "1.0.103"
1282
+
source = "registry+https://github.com/rust-lang/crates.io-index"
1283
+
checksum = "5ee95bc4ef87b8d5ba32e8b7714ccc834865276eab0aed5c9958d00ec45f49e8"
1284
+
dependencies = [
1285
+
"unicode-ident",
1286
+
]
1287
+
1288
+
[[package]]
1289
+
name = "quote"
1290
+
version = "1.0.42"
1291
+
source = "registry+https://github.com/rust-lang/crates.io-index"
1292
+
checksum = "a338cc41d27e6cc6dce6cefc13a0729dfbb81c262b1f519331575dd80ef3067f"
1293
+
dependencies = [
1294
+
"proc-macro2",
1295
+
]
1296
+
1297
+
[[package]]
1298
+
name = "r-efi"
1299
+
version = "5.3.0"
1300
+
source = "registry+https://github.com/rust-lang/crates.io-index"
1301
+
checksum = "69cdb34c158ceb288df11e18b4bd39de994f6657d83847bdffdbd7f346754b0f"
1302
+
1303
+
[[package]]
1304
+
name = "rand"
1305
+
version = "0.8.5"
1306
+
source = "registry+https://github.com/rust-lang/crates.io-index"
1307
+
checksum = "34af8d1a0e25924bc5b7c43c079c942339d8f0a8b57c39049bef581b46327404"
1308
+
dependencies = [
1309
+
"libc",
1310
+
"rand_chacha 0.3.1",
1311
+
"rand_core 0.6.4",
1312
+
]
1313
+
1314
+
[[package]]
1315
+
name = "rand"
1316
+
version = "0.9.2"
1317
+
source = "registry+https://github.com/rust-lang/crates.io-index"
1318
+
checksum = "6db2770f06117d490610c7488547d543617b21bfa07796d7a12f6f1bd53850d1"
1319
+
dependencies = [
1320
+
"rand_chacha 0.9.0",
1321
+
"rand_core 0.9.3",
1322
+
]
1323
+
1324
+
[[package]]
1325
+
name = "rand_chacha"
1326
+
version = "0.3.1"
1327
+
source = "registry+https://github.com/rust-lang/crates.io-index"
1328
+
checksum = "e6c10a63a0fa32252be49d21e7709d4d4baf8d231c2dbce1eaa8141b9b127d88"
1329
+
dependencies = [
1330
+
"ppv-lite86",
1331
+
"rand_core 0.6.4",
1332
+
]
1333
+
1334
+
[[package]]
1335
+
name = "rand_chacha"
1336
+
version = "0.9.0"
1337
+
source = "registry+https://github.com/rust-lang/crates.io-index"
1338
+
checksum = "d3022b5f1df60f26e1ffddd6c66e8aa15de382ae63b3a0c1bfc0e4d3e3f325cb"
1339
+
dependencies = [
1340
+
"ppv-lite86",
1341
+
"rand_core 0.9.3",
1342
+
]
1343
+
1344
+
[[package]]
1345
+
name = "rand_core"
1346
+
version = "0.6.4"
1347
+
source = "registry+https://github.com/rust-lang/crates.io-index"
1348
+
checksum = "ec0be4795e2f6a28069bec0b5ff3e2ac9bafc99e6a9a7dc3547996c5c816922c"
1349
+
dependencies = [
1350
+
"getrandom 0.2.16",
1351
+
]
1352
+
1353
+
[[package]]
1354
+
name = "rand_core"
1355
+
version = "0.9.3"
1356
+
source = "registry+https://github.com/rust-lang/crates.io-index"
1357
+
checksum = "99d9a13982dcf210057a8a78572b2217b667c3beacbf3a0d8b454f6f82837d38"
1358
+
dependencies = [
1359
+
"getrandom 0.3.4",
1360
+
]
1361
+
1362
+
[[package]]
1363
+
name = "redox_syscall"
1364
+
version = "0.5.18"
1365
+
source = "registry+https://github.com/rust-lang/crates.io-index"
1366
+
checksum = "ed2bf2547551a7053d6fdfafda3f938979645c44812fbfcda098faae3f1a362d"
1367
+
dependencies = [
1368
+
"bitflags",
1369
+
]
1370
+
1371
+
[[package]]
1372
+
name = "redox_syscall"
1373
+
version = "0.6.0"
1374
+
source = "registry+https://github.com/rust-lang/crates.io-index"
1375
+
checksum = "ec96166dafa0886eb81fe1c0a388bece180fbef2135f97c1e2cf8302e74b43b5"
1376
+
dependencies = [
1377
+
"bitflags",
1378
+
]
1379
+
1380
+
[[package]]
1381
+
name = "regex-automata"
1382
+
version = "0.4.13"
1383
+
source = "registry+https://github.com/rust-lang/crates.io-index"
1384
+
checksum = "5276caf25ac86c8d810222b3dbb938e512c55c6831a10f3e6ed1c93b84041f1c"
1385
+
dependencies = [
1386
+
"aho-corasick",
1387
+
"memchr",
1388
+
"regex-syntax",
1389
+
]
1390
+
1391
+
[[package]]
1392
+
name = "regex-syntax"
1393
+
version = "0.8.8"
1394
+
source = "registry+https://github.com/rust-lang/crates.io-index"
1395
+
checksum = "7a2d987857b319362043e95f5353c0535c1f58eec5336fdfcf626430af7def58"
1396
+
1397
+
[[package]]
1398
+
name = "reqwest"
1399
+
version = "0.12.26"
1400
+
source = "registry+https://github.com/rust-lang/crates.io-index"
1401
+
checksum = "3b4c14b2d9afca6a60277086b0cc6a6ae0b568f6f7916c943a8cdc79f8be240f"
1402
+
dependencies = [
1403
+
"base64",
1404
+
"bytes",
1405
+
"encoding_rs",
1406
+
"futures-core",
1407
+
"h2",
1408
+
"http",
1409
+
"http-body",
1410
+
"http-body-util",
1411
+
"hyper",
1412
+
"hyper-rustls",
1413
+
"hyper-tls",
1414
+
"hyper-util",
1415
+
"js-sys",
1416
+
"log",
1417
+
"mime",
1418
+
"native-tls",
1419
+
"percent-encoding",
1420
+
"pin-project-lite",
1421
+
"rustls-pki-types",
1422
+
"serde",
1423
+
"serde_json",
1424
+
"serde_urlencoded",
1425
+
"sync_wrapper",
1426
+
"tokio",
1427
+
"tokio-native-tls",
1428
+
"tower",
1429
+
"tower-http",
1430
+
"tower-service",
1431
+
"url",
1432
+
"wasm-bindgen",
1433
+
"wasm-bindgen-futures",
1434
+
"web-sys",
1435
+
]
1436
+
1437
+
[[package]]
1438
+
name = "ring"
1439
+
version = "0.17.14"
1440
+
source = "registry+https://github.com/rust-lang/crates.io-index"
1441
+
checksum = "a4689e6c2294d81e88dc6261c768b63bc4fcdb852be6d1352498b114f61383b7"
1442
+
dependencies = [
1443
+
"cc",
1444
+
"cfg-if",
1445
+
"getrandom 0.2.16",
1446
+
"libc",
1447
+
"untrusted",
1448
+
"windows-sys 0.52.0",
1449
+
]
1450
+
1451
+
[[package]]
1452
+
name = "rsa"
1453
+
version = "0.9.9"
1454
+
source = "registry+https://github.com/rust-lang/crates.io-index"
1455
+
checksum = "40a0376c50d0358279d9d643e4bf7b7be212f1f4ff1da9070a7b54d22ef75c88"
1456
+
dependencies = [
1457
+
"const-oid",
1458
+
"digest",
1459
+
"num-bigint-dig",
1460
+
"num-integer",
1461
+
"num-traits",
1462
+
"pkcs1",
1463
+
"pkcs8",
1464
+
"rand_core 0.6.4",
1465
+
"signature",
1466
+
"spki",
1467
+
"subtle",
1468
+
"zeroize",
1469
+
]
1470
+
1471
+
[[package]]
1472
+
name = "rustix"
1473
+
version = "1.1.2"
1474
+
source = "registry+https://github.com/rust-lang/crates.io-index"
1475
+
checksum = "cd15f8a2c5551a84d56efdc1cd049089e409ac19a3072d5037a17fd70719ff3e"
1476
+
dependencies = [
1477
+
"bitflags",
1478
+
"errno",
1479
+
"libc",
1480
+
"linux-raw-sys",
1481
+
"windows-sys 0.61.2",
1482
+
]
1483
+
1484
+
[[package]]
1485
+
name = "rustls"
1486
+
version = "0.23.35"
1487
+
source = "registry+https://github.com/rust-lang/crates.io-index"
1488
+
checksum = "533f54bc6a7d4f647e46ad909549eda97bf5afc1585190ef692b4286b198bd8f"
1489
+
dependencies = [
1490
+
"once_cell",
1491
+
"rustls-pki-types",
1492
+
"rustls-webpki",
1493
+
"subtle",
1494
+
"zeroize",
1495
+
]
1496
+
1497
+
[[package]]
1498
+
name = "rustls-pki-types"
1499
+
version = "1.13.2"
1500
+
source = "registry+https://github.com/rust-lang/crates.io-index"
1501
+
checksum = "21e6f2ab2928ca4291b86736a8bd920a277a399bba1589409d72154ff87c1282"
1502
+
dependencies = [
1503
+
"zeroize",
1504
+
]
1505
+
1506
+
[[package]]
1507
+
name = "rustls-webpki"
1508
+
version = "0.103.8"
1509
+
source = "registry+https://github.com/rust-lang/crates.io-index"
1510
+
checksum = "2ffdfa2f5286e2247234e03f680868ac2815974dc39e00ea15adc445d0aafe52"
1511
+
dependencies = [
1512
+
"ring",
1513
+
"rustls-pki-types",
1514
+
"untrusted",
1515
+
]
1516
+
1517
+
[[package]]
1518
+
name = "rustversion"
1519
+
version = "1.0.22"
1520
+
source = "registry+https://github.com/rust-lang/crates.io-index"
1521
+
checksum = "b39cdef0fa800fc44525c84ccb54a029961a8215f9619753635a9c0d2538d46d"
1522
+
1523
+
[[package]]
1524
+
name = "ryu"
1525
+
version = "1.0.20"
1526
+
source = "registry+https://github.com/rust-lang/crates.io-index"
1527
+
checksum = "28d3b2b1366ec20994f1fd18c3c594f05c5dd4bc44d8bb0c1c632c8d6829481f"
1528
+
1529
+
[[package]]
1530
+
name = "schannel"
1531
+
version = "0.1.28"
1532
+
source = "registry+https://github.com/rust-lang/crates.io-index"
1533
+
checksum = "891d81b926048e76efe18581bf793546b4c0eaf8448d72be8de2bbee5fd166e1"
1534
+
dependencies = [
1535
+
"windows-sys 0.61.2",
1536
+
]
1537
+
1538
+
[[package]]
1539
+
name = "scopeguard"
1540
+
version = "1.2.0"
1541
+
source = "registry+https://github.com/rust-lang/crates.io-index"
1542
+
checksum = "94143f37725109f92c262ed2cf5e59bce7498c01bcc1502d7b9afe439a4e9f49"
1543
+
1544
+
[[package]]
1545
+
name = "security-framework"
1546
+
version = "2.11.1"
1547
+
source = "registry+https://github.com/rust-lang/crates.io-index"
1548
+
checksum = "897b2245f0b511c87893af39b033e5ca9cce68824c4d7e7630b5a1d339658d02"
1549
+
dependencies = [
1550
+
"bitflags",
1551
+
"core-foundation",
1552
+
"core-foundation-sys",
1553
+
"libc",
1554
+
"security-framework-sys",
1555
+
]
1556
+
1557
+
[[package]]
1558
+
name = "security-framework-sys"
1559
+
version = "2.15.0"
1560
+
source = "registry+https://github.com/rust-lang/crates.io-index"
1561
+
checksum = "cc1f0cbffaac4852523ce30d8bd3c5cdc873501d96ff467ca09b6767bb8cd5c0"
1562
+
dependencies = [
1563
+
"core-foundation-sys",
1564
+
"libc",
1565
+
]
1566
+
1567
+
[[package]]
1568
+
name = "serde"
1569
+
version = "1.0.228"
1570
+
source = "registry+https://github.com/rust-lang/crates.io-index"
1571
+
checksum = "9a8e94ea7f378bd32cbbd37198a4a91436180c5bb472411e48b5ec2e2124ae9e"
1572
+
dependencies = [
1573
+
"serde_core",
1574
+
"serde_derive",
1575
+
]
1576
+
1577
+
[[package]]
1578
+
name = "serde_core"
1579
+
version = "1.0.228"
1580
+
source = "registry+https://github.com/rust-lang/crates.io-index"
1581
+
checksum = "41d385c7d4ca58e59fc732af25c3983b67ac852c1a25000afe1175de458b67ad"
1582
+
dependencies = [
1583
+
"serde_derive",
1584
+
]
1585
+
1586
+
[[package]]
1587
+
name = "serde_derive"
1588
+
version = "1.0.228"
1589
+
source = "registry+https://github.com/rust-lang/crates.io-index"
1590
+
checksum = "d540f220d3187173da220f885ab66608367b6574e925011a9353e4badda91d79"
1591
+
dependencies = [
1592
+
"proc-macro2",
1593
+
"quote",
1594
+
"syn",
1595
+
]
1596
+
1597
+
[[package]]
1598
+
name = "serde_json"
1599
+
version = "1.0.145"
1600
+
source = "registry+https://github.com/rust-lang/crates.io-index"
1601
+
checksum = "402a6f66d8c709116cf22f558eab210f5a50187f702eb4d7e5ef38d9a7f1c79c"
1602
+
dependencies = [
1603
+
"itoa",
1604
+
"memchr",
1605
+
"ryu",
1606
+
"serde",
1607
+
"serde_core",
1608
+
]
1609
+
1610
+
[[package]]
1611
+
name = "serde_urlencoded"
1612
+
version = "0.7.1"
1613
+
source = "registry+https://github.com/rust-lang/crates.io-index"
1614
+
checksum = "d3491c14715ca2294c4d6a88f15e84739788c1d030eed8c110436aafdaa2f3fd"
1615
+
dependencies = [
1616
+
"form_urlencoded",
1617
+
"itoa",
1618
+
"ryu",
1619
+
"serde",
1620
+
]
1621
+
1622
+
[[package]]
1623
+
name = "sha1"
1624
+
version = "0.10.6"
1625
+
source = "registry+https://github.com/rust-lang/crates.io-index"
1626
+
checksum = "e3bf829a2d51ab4a5ddf1352d8470c140cadc8301b2ae1789db023f01cedd6ba"
1627
+
dependencies = [
1628
+
"cfg-if",
1629
+
"cpufeatures",
1630
+
"digest",
1631
+
]
1632
+
1633
+
[[package]]
1634
+
name = "sha2"
1635
+
version = "0.10.9"
1636
+
source = "registry+https://github.com/rust-lang/crates.io-index"
1637
+
checksum = "a7507d819769d01a365ab707794a4084392c824f54a7a6a7862f8c3d0892b283"
1638
+
dependencies = [
1639
+
"cfg-if",
1640
+
"cpufeatures",
1641
+
"digest",
1642
+
]
1643
+
1644
+
[[package]]
1645
+
name = "sharded-slab"
1646
+
version = "0.1.7"
1647
+
source = "registry+https://github.com/rust-lang/crates.io-index"
1648
+
checksum = "f40ca3c46823713e0d4209592e8d6e826aa57e928f09752619fc696c499637f6"
1649
+
dependencies = [
1650
+
"lazy_static",
1651
+
]
1652
+
1653
+
[[package]]
1654
+
name = "shlex"
1655
+
version = "1.3.0"
1656
+
source = "registry+https://github.com/rust-lang/crates.io-index"
1657
+
checksum = "0fda2ff0d084019ba4d7c6f371c95d8fd75ce3524c3cb8fb653a3023f6323e64"
1658
+
1659
+
[[package]]
1660
+
name = "signal-hook-registry"
1661
+
version = "1.4.7"
1662
+
source = "registry+https://github.com/rust-lang/crates.io-index"
1663
+
checksum = "7664a098b8e616bdfcc2dc0e9ac44eb231eedf41db4e9fe95d8d32ec728dedad"
1664
+
dependencies = [
1665
+
"libc",
1666
+
]
1667
+
1668
+
[[package]]
1669
+
name = "signature"
1670
+
version = "2.2.0"
1671
+
source = "registry+https://github.com/rust-lang/crates.io-index"
1672
+
checksum = "77549399552de45a898a580c1b41d445bf730df867cc44e6c0233bbc4b8329de"
1673
+
dependencies = [
1674
+
"digest",
1675
+
"rand_core 0.6.4",
1676
+
]
1677
+
1678
+
[[package]]
1679
+
name = "slab"
1680
+
version = "0.4.11"
1681
+
source = "registry+https://github.com/rust-lang/crates.io-index"
1682
+
checksum = "7a2ae44ef20feb57a68b23d846850f861394c2e02dc425a50098ae8c90267589"
1683
+
1684
+
[[package]]
1685
+
name = "smallvec"
1686
+
version = "1.15.1"
1687
+
source = "registry+https://github.com/rust-lang/crates.io-index"
1688
+
checksum = "67b1b7a3b5fe4f1376887184045fcf45c69e92af734b7aaddc05fb777b6fbd03"
1689
+
dependencies = [
1690
+
"serde",
1691
+
]
1692
+
1693
+
[[package]]
1694
+
name = "socket2"
1695
+
version = "0.6.1"
1696
+
source = "registry+https://github.com/rust-lang/crates.io-index"
1697
+
checksum = "17129e116933cf371d018bb80ae557e889637989d8638274fb25622827b03881"
1698
+
dependencies = [
1699
+
"libc",
1700
+
"windows-sys 0.60.2",
1701
+
]
1702
+
1703
+
[[package]]
1704
+
name = "spin"
1705
+
version = "0.9.8"
1706
+
source = "registry+https://github.com/rust-lang/crates.io-index"
1707
+
checksum = "6980e8d7511241f8acf4aebddbb1ff938df5eebe98691418c4468d0b72a96a67"
1708
+
dependencies = [
1709
+
"lock_api",
1710
+
]
1711
+
1712
+
[[package]]
1713
+
name = "spki"
1714
+
version = "0.7.3"
1715
+
source = "registry+https://github.com/rust-lang/crates.io-index"
1716
+
checksum = "d91ed6c858b01f942cd56b37a94b3e0a1798290327d1236e4d9cf4eaca44d29d"
1717
+
dependencies = [
1718
+
"base64ct",
1719
+
"der",
1720
+
]
1721
+
1722
+
[[package]]
1723
+
name = "sqlx"
1724
+
version = "0.8.6"
1725
+
source = "registry+https://github.com/rust-lang/crates.io-index"
1726
+
checksum = "1fefb893899429669dcdd979aff487bd78f4064e5e7907e4269081e0ef7d97dc"
1727
+
dependencies = [
1728
+
"sqlx-core",
1729
+
"sqlx-macros",
1730
+
"sqlx-mysql",
1731
+
"sqlx-postgres",
1732
+
"sqlx-sqlite",
1733
+
]
1734
+
1735
+
[[package]]
1736
+
name = "sqlx-core"
1737
+
version = "0.8.6"
1738
+
source = "registry+https://github.com/rust-lang/crates.io-index"
1739
+
checksum = "ee6798b1838b6a0f69c007c133b8df5866302197e404e8b6ee8ed3e3a5e68dc6"
1740
+
dependencies = [
1741
+
"base64",
1742
+
"bytes",
1743
+
"crc",
1744
+
"crossbeam-queue",
1745
+
"either",
1746
+
"event-listener",
1747
+
"futures-core",
1748
+
"futures-intrusive",
1749
+
"futures-io",
1750
+
"futures-util",
1751
+
"hashbrown 0.15.5",
1752
+
"hashlink",
1753
+
"indexmap",
1754
+
"log",
1755
+
"memchr",
1756
+
"native-tls",
1757
+
"once_cell",
1758
+
"percent-encoding",
1759
+
"serde",
1760
+
"serde_json",
1761
+
"sha2",
1762
+
"smallvec",
1763
+
"thiserror",
1764
+
"time",
1765
+
"tokio",
1766
+
"tokio-stream",
1767
+
"tracing",
1768
+
"url",
1769
+
]
1770
+
1771
+
[[package]]
1772
+
name = "sqlx-macros"
1773
+
version = "0.8.6"
1774
+
source = "registry+https://github.com/rust-lang/crates.io-index"
1775
+
checksum = "a2d452988ccaacfbf5e0bdbc348fb91d7c8af5bee192173ac3636b5fb6e6715d"
1776
+
dependencies = [
1777
+
"proc-macro2",
1778
+
"quote",
1779
+
"sqlx-core",
1780
+
"sqlx-macros-core",
1781
+
"syn",
1782
+
]
1783
+
1784
+
[[package]]
1785
+
name = "sqlx-macros-core"
1786
+
version = "0.8.6"
1787
+
source = "registry+https://github.com/rust-lang/crates.io-index"
1788
+
checksum = "19a9c1841124ac5a61741f96e1d9e2ec77424bf323962dd894bdb93f37d5219b"
1789
+
dependencies = [
1790
+
"dotenvy",
1791
+
"either",
1792
+
"heck",
1793
+
"hex",
1794
+
"once_cell",
1795
+
"proc-macro2",
1796
+
"quote",
1797
+
"serde",
1798
+
"serde_json",
1799
+
"sha2",
1800
+
"sqlx-core",
1801
+
"sqlx-mysql",
1802
+
"sqlx-postgres",
1803
+
"sqlx-sqlite",
1804
+
"syn",
1805
+
"tokio",
1806
+
"url",
1807
+
]
1808
+
1809
+
[[package]]
1810
+
name = "sqlx-mysql"
1811
+
version = "0.8.6"
1812
+
source = "registry+https://github.com/rust-lang/crates.io-index"
1813
+
checksum = "aa003f0038df784eb8fecbbac13affe3da23b45194bd57dba231c8f48199c526"
1814
+
dependencies = [
1815
+
"atoi",
1816
+
"base64",
1817
+
"bitflags",
1818
+
"byteorder",
1819
+
"bytes",
1820
+
"crc",
1821
+
"digest",
1822
+
"dotenvy",
1823
+
"either",
1824
+
"futures-channel",
1825
+
"futures-core",
1826
+
"futures-io",
1827
+
"futures-util",
1828
+
"generic-array",
1829
+
"hex",
1830
+
"hkdf",
1831
+
"hmac",
1832
+
"itoa",
1833
+
"log",
1834
+
"md-5",
1835
+
"memchr",
1836
+
"once_cell",
1837
+
"percent-encoding",
1838
+
"rand 0.8.5",
1839
+
"rsa",
1840
+
"serde",
1841
+
"sha1",
1842
+
"sha2",
1843
+
"smallvec",
1844
+
"sqlx-core",
1845
+
"stringprep",
1846
+
"thiserror",
1847
+
"time",
1848
+
"tracing",
1849
+
"whoami",
1850
+
]
1851
+
1852
+
[[package]]
1853
+
name = "sqlx-postgres"
1854
+
version = "0.8.6"
1855
+
source = "registry+https://github.com/rust-lang/crates.io-index"
1856
+
checksum = "db58fcd5a53cf07c184b154801ff91347e4c30d17a3562a635ff028ad5deda46"
1857
+
dependencies = [
1858
+
"atoi",
1859
+
"base64",
1860
+
"bitflags",
1861
+
"byteorder",
1862
+
"crc",
1863
+
"dotenvy",
1864
+
"etcetera",
1865
+
"futures-channel",
1866
+
"futures-core",
1867
+
"futures-util",
1868
+
"hex",
1869
+
"hkdf",
1870
+
"hmac",
1871
+
"home",
1872
+
"itoa",
1873
+
"log",
1874
+
"md-5",
1875
+
"memchr",
1876
+
"once_cell",
1877
+
"rand 0.8.5",
1878
+
"serde",
1879
+
"serde_json",
1880
+
"sha2",
1881
+
"smallvec",
1882
+
"sqlx-core",
1883
+
"stringprep",
1884
+
"thiserror",
1885
+
"time",
1886
+
"tracing",
1887
+
"whoami",
1888
+
]
1889
+
1890
+
[[package]]
1891
+
name = "sqlx-sqlite"
1892
+
version = "0.8.6"
1893
+
source = "registry+https://github.com/rust-lang/crates.io-index"
1894
+
checksum = "c2d12fe70b2c1b4401038055f90f151b78208de1f9f89a7dbfd41587a10c3eea"
1895
+
dependencies = [
1896
+
"atoi",
1897
+
"flume",
1898
+
"futures-channel",
1899
+
"futures-core",
1900
+
"futures-executor",
1901
+
"futures-intrusive",
1902
+
"futures-util",
1903
+
"libsqlite3-sys",
1904
+
"log",
1905
+
"percent-encoding",
1906
+
"serde",
1907
+
"serde_urlencoded",
1908
+
"sqlx-core",
1909
+
"thiserror",
1910
+
"time",
1911
+
"tracing",
1912
+
"url",
1913
+
]
1914
+
1915
+
[[package]]
1916
+
name = "stable_deref_trait"
1917
+
version = "1.2.1"
1918
+
source = "registry+https://github.com/rust-lang/crates.io-index"
1919
+
checksum = "6ce2be8dc25455e1f91df71bfa12ad37d7af1092ae736f3a6cd0e37bc7810596"
1920
+
1921
+
[[package]]
1922
+
name = "stringprep"
1923
+
version = "0.1.5"
1924
+
source = "registry+https://github.com/rust-lang/crates.io-index"
1925
+
checksum = "7b4df3d392d81bd458a8a621b8bffbd2302a12ffe288a9d931670948749463b1"
1926
+
dependencies = [
1927
+
"unicode-bidi",
1928
+
"unicode-normalization",
1929
+
"unicode-properties",
1930
+
]
1931
+
1932
+
[[package]]
1933
+
name = "strsim"
1934
+
version = "0.11.1"
1935
+
source = "registry+https://github.com/rust-lang/crates.io-index"
1936
+
checksum = "7da8b5736845d9f2fcb837ea5d9e2628564b3b043a70948a3f0b778838c5fb4f"
1937
+
1938
+
[[package]]
1939
+
name = "subtle"
1940
+
version = "2.6.1"
1941
+
source = "registry+https://github.com/rust-lang/crates.io-index"
1942
+
checksum = "13c2bddecc57b384dee18652358fb23172facb8a2c51ccc10d74c157bdea3292"
1943
+
1944
+
[[package]]
1945
+
name = "syn"
1946
+
version = "2.0.111"
1947
+
source = "registry+https://github.com/rust-lang/crates.io-index"
1948
+
checksum = "390cc9a294ab71bdb1aa2e99d13be9c753cd2d7bd6560c77118597410c4d2e87"
1949
+
dependencies = [
1950
+
"proc-macro2",
1951
+
"quote",
1952
+
"unicode-ident",
1953
+
]
1954
+
1955
+
[[package]]
1956
+
name = "sync_wrapper"
1957
+
version = "1.0.2"
1958
+
source = "registry+https://github.com/rust-lang/crates.io-index"
1959
+
checksum = "0bf256ce5efdfa370213c1dabab5935a12e49f2c58d15e9eac2870d3b4f27263"
1960
+
dependencies = [
1961
+
"futures-core",
1962
+
]
1963
+
1964
+
[[package]]
1965
+
name = "synstructure"
1966
+
version = "0.13.2"
1967
+
source = "registry+https://github.com/rust-lang/crates.io-index"
1968
+
checksum = "728a70f3dbaf5bab7f0c4b1ac8d7ae5ea60a4b5549c8a5914361c99147a709d2"
1969
+
dependencies = [
1970
+
"proc-macro2",
1971
+
"quote",
1972
+
"syn",
1973
+
]
1974
+
1975
+
[[package]]
1976
+
name = "system-configuration"
1977
+
version = "0.6.1"
1978
+
source = "registry+https://github.com/rust-lang/crates.io-index"
1979
+
checksum = "3c879d448e9d986b661742763247d3693ed13609438cf3d006f51f5368a5ba6b"
1980
+
dependencies = [
1981
+
"bitflags",
1982
+
"core-foundation",
1983
+
"system-configuration-sys",
1984
+
]
1985
+
1986
+
[[package]]
1987
+
name = "system-configuration-sys"
1988
+
version = "0.6.0"
1989
+
source = "registry+https://github.com/rust-lang/crates.io-index"
1990
+
checksum = "8e1d1b10ced5ca923a1fcb8d03e96b8d3268065d724548c0211415ff6ac6bac4"
1991
+
dependencies = [
1992
+
"core-foundation-sys",
1993
+
"libc",
1994
+
]
1995
+
1996
+
[[package]]
1997
+
name = "tempfile"
1998
+
version = "3.23.0"
1999
+
source = "registry+https://github.com/rust-lang/crates.io-index"
2000
+
checksum = "2d31c77bdf42a745371d260a26ca7163f1e0924b64afa0b688e61b5a9fa02f16"
2001
+
dependencies = [
2002
+
"fastrand",
2003
+
"getrandom 0.3.4",
2004
+
"once_cell",
2005
+
"rustix",
2006
+
"windows-sys 0.61.2",
2007
+
]
2008
+
2009
+
[[package]]
2010
+
name = "thiserror"
2011
+
version = "2.0.17"
2012
+
source = "registry+https://github.com/rust-lang/crates.io-index"
2013
+
checksum = "f63587ca0f12b72a0600bcba1d40081f830876000bb46dd2337a3051618f4fc8"
2014
+
dependencies = [
2015
+
"thiserror-impl",
2016
+
]
2017
+
2018
+
[[package]]
2019
+
name = "thiserror-impl"
2020
+
version = "2.0.17"
2021
+
source = "registry+https://github.com/rust-lang/crates.io-index"
2022
+
checksum = "3ff15c8ecd7de3849db632e14d18d2571fa09dfc5ed93479bc4485c7a517c913"
2023
+
dependencies = [
2024
+
"proc-macro2",
2025
+
"quote",
2026
+
"syn",
2027
+
]
2028
+
2029
+
[[package]]
2030
+
name = "thread_local"
2031
+
version = "1.1.9"
2032
+
source = "registry+https://github.com/rust-lang/crates.io-index"
2033
+
checksum = "f60246a4944f24f6e018aa17cdeffb7818b76356965d03b07d6a9886e8962185"
2034
+
dependencies = [
2035
+
"cfg-if",
2036
+
]
2037
+
2038
+
[[package]]
2039
+
name = "time"
2040
+
version = "0.3.44"
2041
+
source = "registry+https://github.com/rust-lang/crates.io-index"
2042
+
checksum = "91e7d9e3bb61134e77bde20dd4825b97c010155709965fedf0f49bb138e52a9d"
2043
+
dependencies = [
2044
+
"deranged",
2045
+
"itoa",
2046
+
"num-conv",
2047
+
"powerfmt",
2048
+
"serde",
2049
+
"time-core",
2050
+
"time-macros",
2051
+
]
2052
+
2053
+
[[package]]
2054
+
name = "time-core"
2055
+
version = "0.1.6"
2056
+
source = "registry+https://github.com/rust-lang/crates.io-index"
2057
+
checksum = "40868e7c1d2f0b8d73e4a8c7f0ff63af4f6d19be117e90bd73eb1d62cf831c6b"
2058
+
2059
+
[[package]]
2060
+
name = "time-macros"
2061
+
version = "0.2.24"
2062
+
source = "registry+https://github.com/rust-lang/crates.io-index"
2063
+
checksum = "30cfb0125f12d9c277f35663a0a33f8c30190f4e4574868a330595412d34ebf3"
2064
+
dependencies = [
2065
+
"num-conv",
2066
+
"time-core",
2067
+
]
2068
+
2069
+
[[package]]
2070
+
name = "tinystr"
2071
+
version = "0.8.2"
2072
+
source = "registry+https://github.com/rust-lang/crates.io-index"
2073
+
checksum = "42d3e9c45c09de15d06dd8acf5f4e0e399e85927b7f00711024eb7ae10fa4869"
2074
+
dependencies = [
2075
+
"displaydoc",
2076
+
"zerovec",
2077
+
]
2078
+
2079
+
[[package]]
2080
+
name = "tinyvec"
2081
+
version = "1.10.0"
2082
+
source = "registry+https://github.com/rust-lang/crates.io-index"
2083
+
checksum = "bfa5fdc3bce6191a1dbc8c02d5c8bffcf557bafa17c124c5264a458f1b0613fa"
2084
+
dependencies = [
2085
+
"tinyvec_macros",
2086
+
]
2087
+
2088
+
[[package]]
2089
+
name = "tinyvec_macros"
2090
+
version = "0.1.1"
2091
+
source = "registry+https://github.com/rust-lang/crates.io-index"
2092
+
checksum = "1f3ccbac311fea05f86f61904b462b55fb3df8837a366dfc601a0161d0532f20"
2093
+
2094
+
[[package]]
2095
+
name = "tokio"
2096
+
version = "1.48.0"
2097
+
source = "registry+https://github.com/rust-lang/crates.io-index"
2098
+
checksum = "ff360e02eab121e0bc37a2d3b4d4dc622e6eda3a8e5253d5435ecf5bd4c68408"
2099
+
dependencies = [
2100
+
"bytes",
2101
+
"libc",
2102
+
"mio",
2103
+
"pin-project-lite",
2104
+
"signal-hook-registry",
2105
+
"socket2",
2106
+
"tokio-macros",
2107
+
"windows-sys 0.61.2",
2108
+
]
2109
+
2110
+
[[package]]
2111
+
name = "tokio-macros"
2112
+
version = "2.6.0"
2113
+
source = "registry+https://github.com/rust-lang/crates.io-index"
2114
+
checksum = "af407857209536a95c8e56f8231ef2c2e2aff839b22e07a1ffcbc617e9db9fa5"
2115
+
dependencies = [
2116
+
"proc-macro2",
2117
+
"quote",
2118
+
"syn",
2119
+
]
2120
+
2121
+
[[package]]
2122
+
name = "tokio-native-tls"
2123
+
version = "0.3.1"
2124
+
source = "registry+https://github.com/rust-lang/crates.io-index"
2125
+
checksum = "bbae76ab933c85776efabc971569dd6119c580d8f5d448769dec1764bf796ef2"
2126
+
dependencies = [
2127
+
"native-tls",
2128
+
"tokio",
2129
+
]
2130
+
2131
+
[[package]]
2132
+
name = "tokio-rustls"
2133
+
version = "0.26.4"
2134
+
source = "registry+https://github.com/rust-lang/crates.io-index"
2135
+
checksum = "1729aa945f29d91ba541258c8df89027d5792d85a8841fb65e8bf0f4ede4ef61"
2136
+
dependencies = [
2137
+
"rustls",
2138
+
"tokio",
2139
+
]
2140
+
2141
+
[[package]]
2142
+
name = "tokio-stream"
2143
+
version = "0.1.17"
2144
+
source = "registry+https://github.com/rust-lang/crates.io-index"
2145
+
checksum = "eca58d7bba4a75707817a2c44174253f9236b2d5fbd055602e9d5c07c139a047"
2146
+
dependencies = [
2147
+
"futures-core",
2148
+
"pin-project-lite",
2149
+
"tokio",
2150
+
]
2151
+
2152
+
[[package]]
2153
+
name = "tokio-tungstenite"
2154
+
version = "0.28.0"
2155
+
source = "registry+https://github.com/rust-lang/crates.io-index"
2156
+
checksum = "d25a406cddcc431a75d3d9afc6a7c0f7428d4891dd973e4d54c56b46127bf857"
2157
+
dependencies = [
2158
+
"futures-util",
2159
+
"log",
2160
+
"native-tls",
2161
+
"tokio",
2162
+
"tokio-native-tls",
2163
+
"tungstenite",
2164
+
]
2165
+
2166
+
[[package]]
2167
+
name = "tokio-util"
2168
+
version = "0.7.17"
2169
+
source = "registry+https://github.com/rust-lang/crates.io-index"
2170
+
checksum = "2efa149fe76073d6e8fd97ef4f4eca7b67f599660115591483572e406e165594"
2171
+
dependencies = [
2172
+
"bytes",
2173
+
"futures-core",
2174
+
"futures-sink",
2175
+
"pin-project-lite",
2176
+
"tokio",
2177
+
]
2178
+
2179
+
[[package]]
2180
+
name = "tower"
2181
+
version = "0.5.2"
2182
+
source = "registry+https://github.com/rust-lang/crates.io-index"
2183
+
checksum = "d039ad9159c98b70ecfd540b2573b97f7f52c3e8d9f8ad57a24b916a536975f9"
2184
+
dependencies = [
2185
+
"futures-core",
2186
+
"futures-util",
2187
+
"pin-project-lite",
2188
+
"sync_wrapper",
2189
+
"tokio",
2190
+
"tower-layer",
2191
+
"tower-service",
2192
+
]
2193
+
2194
+
[[package]]
2195
+
name = "tower-http"
2196
+
version = "0.6.8"
2197
+
source = "registry+https://github.com/rust-lang/crates.io-index"
2198
+
checksum = "d4e6559d53cc268e5031cd8429d05415bc4cb4aefc4aa5d6cc35fbf5b924a1f8"
2199
+
dependencies = [
2200
+
"bitflags",
2201
+
"bytes",
2202
+
"futures-util",
2203
+
"http",
2204
+
"http-body",
2205
+
"iri-string",
2206
+
"pin-project-lite",
2207
+
"tower",
2208
+
"tower-layer",
2209
+
"tower-service",
2210
+
]
2211
+
2212
+
[[package]]
2213
+
name = "tower-layer"
2214
+
version = "0.3.3"
2215
+
source = "registry+https://github.com/rust-lang/crates.io-index"
2216
+
checksum = "121c2a6cda46980bb0fcd1647ffaf6cd3fc79a013de288782836f6df9c48780e"
2217
+
2218
+
[[package]]
2219
+
name = "tower-service"
2220
+
version = "0.3.3"
2221
+
source = "registry+https://github.com/rust-lang/crates.io-index"
2222
+
checksum = "8df9b6e13f2d32c91b9bd719c00d1958837bc7dec474d94952798cc8e69eeec3"
2223
+
2224
+
[[package]]
2225
+
name = "tracing"
2226
+
version = "0.1.43"
2227
+
source = "registry+https://github.com/rust-lang/crates.io-index"
2228
+
checksum = "2d15d90a0b5c19378952d479dc858407149d7bb45a14de0142f6c534b16fc647"
2229
+
dependencies = [
2230
+
"log",
2231
+
"pin-project-lite",
2232
+
"tracing-attributes",
2233
+
"tracing-core",
2234
+
]
2235
+
2236
+
[[package]]
2237
+
name = "tracing-attributes"
2238
+
version = "0.1.31"
2239
+
source = "registry+https://github.com/rust-lang/crates.io-index"
2240
+
checksum = "7490cfa5ec963746568740651ac6781f701c9c5ea257c58e057f3ba8cf69e8da"
2241
+
dependencies = [
2242
+
"proc-macro2",
2243
+
"quote",
2244
+
"syn",
2245
+
]
2246
+
2247
+
[[package]]
2248
+
name = "tracing-core"
2249
+
version = "0.1.35"
2250
+
source = "registry+https://github.com/rust-lang/crates.io-index"
2251
+
checksum = "7a04e24fab5c89c6a36eb8558c9656f30d81de51dfa4d3b45f26b21d61fa0a6c"
2252
+
dependencies = [
2253
+
"once_cell",
2254
+
"valuable",
2255
+
]
2256
+
2257
+
[[package]]
2258
+
name = "tracing-log"
2259
+
version = "0.2.0"
2260
+
source = "registry+https://github.com/rust-lang/crates.io-index"
2261
+
checksum = "ee855f1f400bd0e5c02d150ae5de3840039a3f54b025156404e34c23c03f47c3"
2262
+
dependencies = [
2263
+
"log",
2264
+
"once_cell",
2265
+
"tracing-core",
2266
+
]
2267
+
2268
+
[[package]]
2269
+
name = "tracing-subscriber"
2270
+
version = "0.3.22"
2271
+
source = "registry+https://github.com/rust-lang/crates.io-index"
2272
+
checksum = "2f30143827ddab0d256fd843b7a66d164e9f271cfa0dde49142c5ca0ca291f1e"
2273
+
dependencies = [
2274
+
"matchers",
2275
+
"nu-ansi-term",
2276
+
"once_cell",
2277
+
"regex-automata",
2278
+
"sharded-slab",
2279
+
"smallvec",
2280
+
"thread_local",
2281
+
"tracing",
2282
+
"tracing-core",
2283
+
"tracing-log",
2284
+
]
2285
+
2286
+
[[package]]
2287
+
name = "trap"
2288
+
version = "0.0.0"
2289
+
dependencies = [
2290
+
"anyhow",
2291
+
"clap",
2292
+
"data-encoding",
2293
+
"futures-util",
2294
+
"reqwest",
2295
+
"serde",
2296
+
"serde_json",
2297
+
"sqlx",
2298
+
"thiserror",
2299
+
"tokio",
2300
+
"tokio-tungstenite",
2301
+
"tracing",
2302
+
"tracing-subscriber",
2303
+
"url",
2304
+
]
2305
+
2306
+
[[package]]
2307
+
name = "try-lock"
2308
+
version = "0.2.5"
2309
+
source = "registry+https://github.com/rust-lang/crates.io-index"
2310
+
checksum = "e421abadd41a4225275504ea4d6566923418b7f05506fbc9c0fe86ba7396114b"
2311
+
2312
+
[[package]]
2313
+
name = "tungstenite"
2314
+
version = "0.28.0"
2315
+
source = "registry+https://github.com/rust-lang/crates.io-index"
2316
+
checksum = "8628dcc84e5a09eb3d8423d6cb682965dea9133204e8fb3efee74c2a0c259442"
2317
+
dependencies = [
2318
+
"bytes",
2319
+
"data-encoding",
2320
+
"http",
2321
+
"httparse",
2322
+
"log",
2323
+
"native-tls",
2324
+
"rand 0.9.2",
2325
+
"sha1",
2326
+
"thiserror",
2327
+
"utf-8",
2328
+
]
2329
+
2330
+
[[package]]
2331
+
name = "typenum"
2332
+
version = "1.19.0"
2333
+
source = "registry+https://github.com/rust-lang/crates.io-index"
2334
+
checksum = "562d481066bde0658276a35467c4af00bdc6ee726305698a55b86e61d7ad82bb"
2335
+
2336
+
[[package]]
2337
+
name = "unicode-bidi"
2338
+
version = "0.3.18"
2339
+
source = "registry+https://github.com/rust-lang/crates.io-index"
2340
+
checksum = "5c1cb5db39152898a79168971543b1cb5020dff7fe43c8dc468b0885f5e29df5"
2341
+
2342
+
[[package]]
2343
+
name = "unicode-ident"
2344
+
version = "1.0.22"
2345
+
source = "registry+https://github.com/rust-lang/crates.io-index"
2346
+
checksum = "9312f7c4f6ff9069b165498234ce8be658059c6728633667c526e27dc2cf1df5"
2347
+
2348
+
[[package]]
2349
+
name = "unicode-normalization"
2350
+
version = "0.1.25"
2351
+
source = "registry+https://github.com/rust-lang/crates.io-index"
2352
+
checksum = "5fd4f6878c9cb28d874b009da9e8d183b5abc80117c40bbd187a1fde336be6e8"
2353
+
dependencies = [
2354
+
"tinyvec",
2355
+
]
2356
+
2357
+
[[package]]
2358
+
name = "unicode-properties"
2359
+
version = "0.1.4"
2360
+
source = "registry+https://github.com/rust-lang/crates.io-index"
2361
+
checksum = "7df058c713841ad818f1dc5d3fd88063241cc61f49f5fbea4b951e8cf5a8d71d"
2362
+
2363
+
[[package]]
2364
+
name = "untrusted"
2365
+
version = "0.9.0"
2366
+
source = "registry+https://github.com/rust-lang/crates.io-index"
2367
+
checksum = "8ecb6da28b8a351d773b68d5825ac39017e680750f980f3a1a85cd8dd28a47c1"
2368
+
2369
+
[[package]]
2370
+
name = "url"
2371
+
version = "2.5.7"
2372
+
source = "registry+https://github.com/rust-lang/crates.io-index"
2373
+
checksum = "08bc136a29a3d1758e07a9cca267be308aeebf5cfd5a10f3f67ab2097683ef5b"
2374
+
dependencies = [
2375
+
"form_urlencoded",
2376
+
"idna",
2377
+
"percent-encoding",
2378
+
"serde",
2379
+
]
2380
+
2381
+
[[package]]
2382
+
name = "utf-8"
2383
+
version = "0.7.6"
2384
+
source = "registry+https://github.com/rust-lang/crates.io-index"
2385
+
checksum = "09cc8ee72d2a9becf2f2febe0205bbed8fc6615b7cb429ad062dc7b7ddd036a9"
2386
+
2387
+
[[package]]
2388
+
name = "utf8_iter"
2389
+
version = "1.0.4"
2390
+
source = "registry+https://github.com/rust-lang/crates.io-index"
2391
+
checksum = "b6c140620e7ffbb22c2dee59cafe6084a59b5ffc27a8859a5f0d494b5d52b6be"
2392
+
2393
+
[[package]]
2394
+
name = "utf8parse"
2395
+
version = "0.2.2"
2396
+
source = "registry+https://github.com/rust-lang/crates.io-index"
2397
+
checksum = "06abde3611657adf66d383f00b093d7faecc7fa57071cce2578660c9f1010821"
2398
+
2399
+
[[package]]
2400
+
name = "valuable"
2401
+
version = "0.1.1"
2402
+
source = "registry+https://github.com/rust-lang/crates.io-index"
2403
+
checksum = "ba73ea9cf16a25df0c8caa16c51acb937d5712a8429db78a3ee29d5dcacd3a65"
2404
+
2405
+
[[package]]
2406
+
name = "vcpkg"
2407
+
version = "0.2.15"
2408
+
source = "registry+https://github.com/rust-lang/crates.io-index"
2409
+
checksum = "accd4ea62f7bb7a82fe23066fb0957d48ef677f6eeb8215f372f52e48bb32426"
2410
+
2411
+
[[package]]
2412
+
name = "version_check"
2413
+
version = "0.9.5"
2414
+
source = "registry+https://github.com/rust-lang/crates.io-index"
2415
+
checksum = "0b928f33d975fc6ad9f86c8f283853ad26bdd5b10b7f1542aa2fa15e2289105a"
2416
+
2417
+
[[package]]
2418
+
name = "want"
2419
+
version = "0.3.1"
2420
+
source = "registry+https://github.com/rust-lang/crates.io-index"
2421
+
checksum = "bfa7760aed19e106de2c7c0b581b509f2f25d3dacaf737cb82ac61bc6d760b0e"
2422
+
dependencies = [
2423
+
"try-lock",
2424
+
]
2425
+
2426
+
[[package]]
2427
+
name = "wasi"
2428
+
version = "0.11.1+wasi-snapshot-preview1"
2429
+
source = "registry+https://github.com/rust-lang/crates.io-index"
2430
+
checksum = "ccf3ec651a847eb01de73ccad15eb7d99f80485de043efb2f370cd654f4ea44b"
2431
+
2432
+
[[package]]
2433
+
name = "wasip2"
2434
+
version = "1.0.1+wasi-0.2.4"
2435
+
source = "registry+https://github.com/rust-lang/crates.io-index"
2436
+
checksum = "0562428422c63773dad2c345a1882263bbf4d65cf3f42e90921f787ef5ad58e7"
2437
+
dependencies = [
2438
+
"wit-bindgen",
2439
+
]
2440
+
2441
+
[[package]]
2442
+
name = "wasite"
2443
+
version = "0.1.0"
2444
+
source = "registry+https://github.com/rust-lang/crates.io-index"
2445
+
checksum = "b8dad83b4f25e74f184f64c43b150b91efe7647395b42289f38e50566d82855b"
2446
+
2447
+
[[package]]
2448
+
name = "wasm-bindgen"
2449
+
version = "0.2.106"
2450
+
source = "registry+https://github.com/rust-lang/crates.io-index"
2451
+
checksum = "0d759f433fa64a2d763d1340820e46e111a7a5ab75f993d1852d70b03dbb80fd"
2452
+
dependencies = [
2453
+
"cfg-if",
2454
+
"once_cell",
2455
+
"rustversion",
2456
+
"wasm-bindgen-macro",
2457
+
"wasm-bindgen-shared",
2458
+
]
2459
+
2460
+
[[package]]
2461
+
name = "wasm-bindgen-futures"
2462
+
version = "0.4.56"
2463
+
source = "registry+https://github.com/rust-lang/crates.io-index"
2464
+
checksum = "836d9622d604feee9e5de25ac10e3ea5f2d65b41eac0d9ce72eb5deae707ce7c"
2465
+
dependencies = [
2466
+
"cfg-if",
2467
+
"js-sys",
2468
+
"once_cell",
2469
+
"wasm-bindgen",
2470
+
"web-sys",
2471
+
]
2472
+
2473
+
[[package]]
2474
+
name = "wasm-bindgen-macro"
2475
+
version = "0.2.106"
2476
+
source = "registry+https://github.com/rust-lang/crates.io-index"
2477
+
checksum = "48cb0d2638f8baedbc542ed444afc0644a29166f1595371af4fecf8ce1e7eeb3"
2478
+
dependencies = [
2479
+
"quote",
2480
+
"wasm-bindgen-macro-support",
2481
+
]
2482
+
2483
+
[[package]]
2484
+
name = "wasm-bindgen-macro-support"
2485
+
version = "0.2.106"
2486
+
source = "registry+https://github.com/rust-lang/crates.io-index"
2487
+
checksum = "cefb59d5cd5f92d9dcf80e4683949f15ca4b511f4ac0a6e14d4e1ac60c6ecd40"
2488
+
dependencies = [
2489
+
"bumpalo",
2490
+
"proc-macro2",
2491
+
"quote",
2492
+
"syn",
2493
+
"wasm-bindgen-shared",
2494
+
]
2495
+
2496
+
[[package]]
2497
+
name = "wasm-bindgen-shared"
2498
+
version = "0.2.106"
2499
+
source = "registry+https://github.com/rust-lang/crates.io-index"
2500
+
checksum = "cbc538057e648b67f72a982e708d485b2efa771e1ac05fec311f9f63e5800db4"
2501
+
dependencies = [
2502
+
"unicode-ident",
2503
+
]
2504
+
2505
+
[[package]]
2506
+
name = "web-sys"
2507
+
version = "0.3.83"
2508
+
source = "registry+https://github.com/rust-lang/crates.io-index"
2509
+
checksum = "9b32828d774c412041098d182a8b38b16ea816958e07cf40eec2bc080ae137ac"
2510
+
dependencies = [
2511
+
"js-sys",
2512
+
"wasm-bindgen",
2513
+
]
2514
+
2515
+
[[package]]
2516
+
name = "whoami"
2517
+
version = "1.6.1"
2518
+
source = "registry+https://github.com/rust-lang/crates.io-index"
2519
+
checksum = "5d4a4db5077702ca3015d3d02d74974948aba2ad9e12ab7df718ee64ccd7e97d"
2520
+
dependencies = [
2521
+
"libredox",
2522
+
"wasite",
2523
+
]
2524
+
2525
+
[[package]]
2526
+
name = "windows-link"
2527
+
version = "0.2.1"
2528
+
source = "registry+https://github.com/rust-lang/crates.io-index"
2529
+
checksum = "f0805222e57f7521d6a62e36fa9163bc891acd422f971defe97d64e70d0a4fe5"
2530
+
2531
+
[[package]]
2532
+
name = "windows-registry"
2533
+
version = "0.6.1"
2534
+
source = "registry+https://github.com/rust-lang/crates.io-index"
2535
+
checksum = "02752bf7fbdcce7f2a27a742f798510f3e5ad88dbe84871e5168e2120c3d5720"
2536
+
dependencies = [
2537
+
"windows-link",
2538
+
"windows-result",
2539
+
"windows-strings",
2540
+
]
2541
+
2542
+
[[package]]
2543
+
name = "windows-result"
2544
+
version = "0.4.1"
2545
+
source = "registry+https://github.com/rust-lang/crates.io-index"
2546
+
checksum = "7781fa89eaf60850ac3d2da7af8e5242a5ea78d1a11c49bf2910bb5a73853eb5"
2547
+
dependencies = [
2548
+
"windows-link",
2549
+
]
2550
+
2551
+
[[package]]
2552
+
name = "windows-strings"
2553
+
version = "0.5.1"
2554
+
source = "registry+https://github.com/rust-lang/crates.io-index"
2555
+
checksum = "7837d08f69c77cf6b07689544538e017c1bfcf57e34b4c0ff58e6c2cd3b37091"
2556
+
dependencies = [
2557
+
"windows-link",
2558
+
]
2559
+
2560
+
[[package]]
2561
+
name = "windows-sys"
2562
+
version = "0.48.0"
2563
+
source = "registry+https://github.com/rust-lang/crates.io-index"
2564
+
checksum = "677d2418bec65e3338edb076e806bc1ec15693c5d0104683f2efe857f61056a9"
2565
+
dependencies = [
2566
+
"windows-targets 0.48.5",
2567
+
]
2568
+
2569
+
[[package]]
2570
+
name = "windows-sys"
2571
+
version = "0.52.0"
2572
+
source = "registry+https://github.com/rust-lang/crates.io-index"
2573
+
checksum = "282be5f36a8ce781fad8c8ae18fa3f9beff57ec1b52cb3de0789201425d9a33d"
2574
+
dependencies = [
2575
+
"windows-targets 0.52.6",
2576
+
]
2577
+
2578
+
[[package]]
2579
+
name = "windows-sys"
2580
+
version = "0.60.2"
2581
+
source = "registry+https://github.com/rust-lang/crates.io-index"
2582
+
checksum = "f2f500e4d28234f72040990ec9d39e3a6b950f9f22d3dba18416c35882612bcb"
2583
+
dependencies = [
2584
+
"windows-targets 0.53.5",
2585
+
]
2586
+
2587
+
[[package]]
2588
+
name = "windows-sys"
2589
+
version = "0.61.2"
2590
+
source = "registry+https://github.com/rust-lang/crates.io-index"
2591
+
checksum = "ae137229bcbd6cdf0f7b80a31df61766145077ddf49416a728b02cb3921ff3fc"
2592
+
dependencies = [
2593
+
"windows-link",
2594
+
]
2595
+
2596
+
[[package]]
2597
+
name = "windows-targets"
2598
+
version = "0.48.5"
2599
+
source = "registry+https://github.com/rust-lang/crates.io-index"
2600
+
checksum = "9a2fa6e2155d7247be68c096456083145c183cbbbc2764150dda45a87197940c"
2601
+
dependencies = [
2602
+
"windows_aarch64_gnullvm 0.48.5",
2603
+
"windows_aarch64_msvc 0.48.5",
2604
+
"windows_i686_gnu 0.48.5",
2605
+
"windows_i686_msvc 0.48.5",
2606
+
"windows_x86_64_gnu 0.48.5",
2607
+
"windows_x86_64_gnullvm 0.48.5",
2608
+
"windows_x86_64_msvc 0.48.5",
2609
+
]
2610
+
2611
+
[[package]]
2612
+
name = "windows-targets"
2613
+
version = "0.52.6"
2614
+
source = "registry+https://github.com/rust-lang/crates.io-index"
2615
+
checksum = "9b724f72796e036ab90c1021d4780d4d3d648aca59e491e6b98e725b84e99973"
2616
+
dependencies = [
2617
+
"windows_aarch64_gnullvm 0.52.6",
2618
+
"windows_aarch64_msvc 0.52.6",
2619
+
"windows_i686_gnu 0.52.6",
2620
+
"windows_i686_gnullvm 0.52.6",
2621
+
"windows_i686_msvc 0.52.6",
2622
+
"windows_x86_64_gnu 0.52.6",
2623
+
"windows_x86_64_gnullvm 0.52.6",
2624
+
"windows_x86_64_msvc 0.52.6",
2625
+
]
2626
+
2627
+
[[package]]
2628
+
name = "windows-targets"
2629
+
version = "0.53.5"
2630
+
source = "registry+https://github.com/rust-lang/crates.io-index"
2631
+
checksum = "4945f9f551b88e0d65f3db0bc25c33b8acea4d9e41163edf90dcd0b19f9069f3"
2632
+
dependencies = [
2633
+
"windows-link",
2634
+
"windows_aarch64_gnullvm 0.53.1",
2635
+
"windows_aarch64_msvc 0.53.1",
2636
+
"windows_i686_gnu 0.53.1",
2637
+
"windows_i686_gnullvm 0.53.1",
2638
+
"windows_i686_msvc 0.53.1",
2639
+
"windows_x86_64_gnu 0.53.1",
2640
+
"windows_x86_64_gnullvm 0.53.1",
2641
+
"windows_x86_64_msvc 0.53.1",
2642
+
]
2643
+
2644
+
[[package]]
2645
+
name = "windows_aarch64_gnullvm"
2646
+
version = "0.48.5"
2647
+
source = "registry+https://github.com/rust-lang/crates.io-index"
2648
+
checksum = "2b38e32f0abccf9987a4e3079dfb67dcd799fb61361e53e2882c3cbaf0d905d8"
2649
+
2650
+
[[package]]
2651
+
name = "windows_aarch64_gnullvm"
2652
+
version = "0.52.6"
2653
+
source = "registry+https://github.com/rust-lang/crates.io-index"
2654
+
checksum = "32a4622180e7a0ec044bb555404c800bc9fd9ec262ec147edd5989ccd0c02cd3"
2655
+
2656
+
[[package]]
2657
+
name = "windows_aarch64_gnullvm"
2658
+
version = "0.53.1"
2659
+
source = "registry+https://github.com/rust-lang/crates.io-index"
2660
+
checksum = "a9d8416fa8b42f5c947f8482c43e7d89e73a173cead56d044f6a56104a6d1b53"
2661
+
2662
+
[[package]]
2663
+
name = "windows_aarch64_msvc"
2664
+
version = "0.48.5"
2665
+
source = "registry+https://github.com/rust-lang/crates.io-index"
2666
+
checksum = "dc35310971f3b2dbbf3f0690a219f40e2d9afcf64f9ab7cc1be722937c26b4bc"
2667
+
2668
+
[[package]]
2669
+
name = "windows_aarch64_msvc"
2670
+
version = "0.52.6"
2671
+
source = "registry+https://github.com/rust-lang/crates.io-index"
2672
+
checksum = "09ec2a7bb152e2252b53fa7803150007879548bc709c039df7627cabbd05d469"
2673
+
2674
+
[[package]]
2675
+
name = "windows_aarch64_msvc"
2676
+
version = "0.53.1"
2677
+
source = "registry+https://github.com/rust-lang/crates.io-index"
2678
+
checksum = "b9d782e804c2f632e395708e99a94275910eb9100b2114651e04744e9b125006"
2679
+
2680
+
[[package]]
2681
+
name = "windows_i686_gnu"
2682
+
version = "0.48.5"
2683
+
source = "registry+https://github.com/rust-lang/crates.io-index"
2684
+
checksum = "a75915e7def60c94dcef72200b9a8e58e5091744960da64ec734a6c6e9b3743e"
2685
+
2686
+
[[package]]
2687
+
name = "windows_i686_gnu"
2688
+
version = "0.52.6"
2689
+
source = "registry+https://github.com/rust-lang/crates.io-index"
2690
+
checksum = "8e9b5ad5ab802e97eb8e295ac6720e509ee4c243f69d781394014ebfe8bbfa0b"
2691
+
2692
+
[[package]]
2693
+
name = "windows_i686_gnu"
2694
+
version = "0.53.1"
2695
+
source = "registry+https://github.com/rust-lang/crates.io-index"
2696
+
checksum = "960e6da069d81e09becb0ca57a65220ddff016ff2d6af6a223cf372a506593a3"
2697
+
2698
+
[[package]]
2699
+
name = "windows_i686_gnullvm"
2700
+
version = "0.52.6"
2701
+
source = "registry+https://github.com/rust-lang/crates.io-index"
2702
+
checksum = "0eee52d38c090b3caa76c563b86c3a4bd71ef1a819287c19d586d7334ae8ed66"
2703
+
2704
+
[[package]]
2705
+
name = "windows_i686_gnullvm"
2706
+
version = "0.53.1"
2707
+
source = "registry+https://github.com/rust-lang/crates.io-index"
2708
+
checksum = "fa7359d10048f68ab8b09fa71c3daccfb0e9b559aed648a8f95469c27057180c"
2709
+
2710
+
[[package]]
2711
+
name = "windows_i686_msvc"
2712
+
version = "0.48.5"
2713
+
source = "registry+https://github.com/rust-lang/crates.io-index"
2714
+
checksum = "8f55c233f70c4b27f66c523580f78f1004e8b5a8b659e05a4eb49d4166cca406"
2715
+
2716
+
[[package]]
2717
+
name = "windows_i686_msvc"
2718
+
version = "0.52.6"
2719
+
source = "registry+https://github.com/rust-lang/crates.io-index"
2720
+
checksum = "240948bc05c5e7c6dabba28bf89d89ffce3e303022809e73deaefe4f6ec56c66"
2721
+
2722
+
[[package]]
2723
+
name = "windows_i686_msvc"
2724
+
version = "0.53.1"
2725
+
source = "registry+https://github.com/rust-lang/crates.io-index"
2726
+
checksum = "1e7ac75179f18232fe9c285163565a57ef8d3c89254a30685b57d83a38d326c2"
2727
+
2728
+
[[package]]
2729
+
name = "windows_x86_64_gnu"
2730
+
version = "0.48.5"
2731
+
source = "registry+https://github.com/rust-lang/crates.io-index"
2732
+
checksum = "53d40abd2583d23e4718fddf1ebec84dbff8381c07cae67ff7768bbf19c6718e"
2733
+
2734
+
[[package]]
2735
+
name = "windows_x86_64_gnu"
2736
+
version = "0.52.6"
2737
+
source = "registry+https://github.com/rust-lang/crates.io-index"
2738
+
checksum = "147a5c80aabfbf0c7d901cb5895d1de30ef2907eb21fbbab29ca94c5b08b1a78"
2739
+
2740
+
[[package]]
2741
+
name = "windows_x86_64_gnu"
2742
+
version = "0.53.1"
2743
+
source = "registry+https://github.com/rust-lang/crates.io-index"
2744
+
checksum = "9c3842cdd74a865a8066ab39c8a7a473c0778a3f29370b5fd6b4b9aa7df4a499"
2745
+
2746
+
[[package]]
2747
+
name = "windows_x86_64_gnullvm"
2748
+
version = "0.48.5"
2749
+
source = "registry+https://github.com/rust-lang/crates.io-index"
2750
+
checksum = "0b7b52767868a23d5bab768e390dc5f5c55825b6d30b86c844ff2dc7414044cc"
2751
+
2752
+
[[package]]
2753
+
name = "windows_x86_64_gnullvm"
2754
+
version = "0.52.6"
2755
+
source = "registry+https://github.com/rust-lang/crates.io-index"
2756
+
checksum = "24d5b23dc417412679681396f2b49f3de8c1473deb516bd34410872eff51ed0d"
2757
+
2758
+
[[package]]
2759
+
name = "windows_x86_64_gnullvm"
2760
+
version = "0.53.1"
2761
+
source = "registry+https://github.com/rust-lang/crates.io-index"
2762
+
checksum = "0ffa179e2d07eee8ad8f57493436566c7cc30ac536a3379fdf008f47f6bb7ae1"
2763
+
2764
+
[[package]]
2765
+
name = "windows_x86_64_msvc"
2766
+
version = "0.48.5"
2767
+
source = "registry+https://github.com/rust-lang/crates.io-index"
2768
+
checksum = "ed94fce61571a4006852b7389a063ab983c02eb1bb37b47f8272ce92d06d9538"
2769
+
2770
+
[[package]]
2771
+
name = "windows_x86_64_msvc"
2772
+
version = "0.52.6"
2773
+
source = "registry+https://github.com/rust-lang/crates.io-index"
2774
+
checksum = "589f6da84c646204747d1270a2a5661ea66ed1cced2631d546fdfb155959f9ec"
2775
+
2776
+
[[package]]
2777
+
name = "windows_x86_64_msvc"
2778
+
version = "0.53.1"
2779
+
source = "registry+https://github.com/rust-lang/crates.io-index"
2780
+
checksum = "d6bbff5f0aada427a1e5a6da5f1f98158182f26556f345ac9e04d36d0ebed650"
2781
+
2782
+
[[package]]
2783
+
name = "wit-bindgen"
2784
+
version = "0.46.0"
2785
+
source = "registry+https://github.com/rust-lang/crates.io-index"
2786
+
checksum = "f17a85883d4e6d00e8a97c586de764dabcc06133f7f1d55dce5cdc070ad7fe59"
2787
+
2788
+
[[package]]
2789
+
name = "writeable"
2790
+
version = "0.6.2"
2791
+
source = "registry+https://github.com/rust-lang/crates.io-index"
2792
+
checksum = "9edde0db4769d2dc68579893f2306b26c6ecfbe0ef499b013d731b7b9247e0b9"
2793
+
2794
+
[[package]]
2795
+
name = "yoke"
2796
+
version = "0.8.1"
2797
+
source = "registry+https://github.com/rust-lang/crates.io-index"
2798
+
checksum = "72d6e5c6afb84d73944e5cedb052c4680d5657337201555f9f2a16b7406d4954"
2799
+
dependencies = [
2800
+
"stable_deref_trait",
2801
+
"yoke-derive",
2802
+
"zerofrom",
2803
+
]
2804
+
2805
+
[[package]]
2806
+
name = "yoke-derive"
2807
+
version = "0.8.1"
2808
+
source = "registry+https://github.com/rust-lang/crates.io-index"
2809
+
checksum = "b659052874eb698efe5b9e8cf382204678a0086ebf46982b79d6ca3182927e5d"
2810
+
dependencies = [
2811
+
"proc-macro2",
2812
+
"quote",
2813
+
"syn",
2814
+
"synstructure",
2815
+
]
2816
+
2817
+
[[package]]
2818
+
name = "zerocopy"
2819
+
version = "0.8.31"
2820
+
source = "registry+https://github.com/rust-lang/crates.io-index"
2821
+
checksum = "fd74ec98b9250adb3ca554bdde269adf631549f51d8a8f8f0a10b50f1cb298c3"
2822
+
dependencies = [
2823
+
"zerocopy-derive",
2824
+
]
2825
+
2826
+
[[package]]
2827
+
name = "zerocopy-derive"
2828
+
version = "0.8.31"
2829
+
source = "registry+https://github.com/rust-lang/crates.io-index"
2830
+
checksum = "d8a8d209fdf45cf5138cbb5a506f6b52522a25afccc534d1475dad8e31105c6a"
2831
+
dependencies = [
2832
+
"proc-macro2",
2833
+
"quote",
2834
+
"syn",
2835
+
]
2836
+
2837
+
[[package]]
2838
+
name = "zerofrom"
2839
+
version = "0.1.6"
2840
+
source = "registry+https://github.com/rust-lang/crates.io-index"
2841
+
checksum = "50cc42e0333e05660c3587f3bf9d0478688e15d870fab3346451ce7f8c9fbea5"
2842
+
dependencies = [
2843
+
"zerofrom-derive",
2844
+
]
2845
+
2846
+
[[package]]
2847
+
name = "zerofrom-derive"
2848
+
version = "0.1.6"
2849
+
source = "registry+https://github.com/rust-lang/crates.io-index"
2850
+
checksum = "d71e5d6e06ab090c67b5e44993ec16b72dcbaabc526db883a360057678b48502"
2851
+
dependencies = [
2852
+
"proc-macro2",
2853
+
"quote",
2854
+
"syn",
2855
+
"synstructure",
2856
+
]
2857
+
2858
+
[[package]]
2859
+
name = "zeroize"
2860
+
version = "1.8.2"
2861
+
source = "registry+https://github.com/rust-lang/crates.io-index"
2862
+
checksum = "b97154e67e32c85465826e8bcc1c59429aaaf107c1e4a9e53c8d8ccd5eff88d0"
2863
+
2864
+
[[package]]
2865
+
name = "zerotrie"
2866
+
version = "0.2.3"
2867
+
source = "registry+https://github.com/rust-lang/crates.io-index"
2868
+
checksum = "2a59c17a5562d507e4b54960e8569ebee33bee890c70aa3fe7b97e85a9fd7851"
2869
+
dependencies = [
2870
+
"displaydoc",
2871
+
"yoke",
2872
+
"zerofrom",
2873
+
]
2874
+
2875
+
[[package]]
2876
+
name = "zerovec"
2877
+
version = "0.11.5"
2878
+
source = "registry+https://github.com/rust-lang/crates.io-index"
2879
+
checksum = "6c28719294829477f525be0186d13efa9a3c602f7ec202ca9e353d310fb9a002"
2880
+
dependencies = [
2881
+
"yoke",
2882
+
"zerofrom",
2883
+
"zerovec-derive",
2884
+
]
2885
+
2886
+
[[package]]
2887
+
name = "zerovec-derive"
2888
+
version = "0.11.2"
2889
+
source = "registry+https://github.com/rust-lang/crates.io-index"
2890
+
checksum = "eadce39539ca5cb3985590102671f2567e659fca9666581ad3411d59207951f3"
2891
+
dependencies = [
2892
+
"proc-macro2",
2893
+
"quote",
2894
+
"syn",
2895
+
]
+26
Cargo.toml
+26
Cargo.toml
···
1
+
[package]
2
+
name = "trap"
3
+
version= "0.0.0"
4
+
edition = "2024"
5
+
publish = false
6
+
7
+
[dependencies]
8
+
anyhow = "1.0.100"
9
+
clap = { version = "4.5.53", features = ["derive", "env"] }
10
+
data-encoding = "2.9.0"
11
+
futures-util = { version = "0.3.31", features = ["sink"] }
12
+
reqwest = { version = "0.12.26", features = ["json"] }
13
+
serde = { version = "1.0.228", features = ["derive"] }
14
+
serde_json = "1.0.145"
15
+
sqlx = { version = "0.8.6", features = ["runtime-tokio", "tls-native-tls", "postgres", "time", "json", "macros", "derive"] }
16
+
thiserror = "2.0.17"
17
+
tokio = { version = "1.47.1", features = ["io-util", "macros", "net", "process", "signal", "rt-multi-thread"] }
18
+
tokio-tungstenite = { version = "0.28.0", features = ["native-tls"] }
19
+
tracing = "0.1.43"
20
+
tracing-subscriber = { version = "0.3.20", features = ["env-filter"] }
21
+
url = "2.5.7"
22
+
23
+
[profile.release]
24
+
panic = "abort"
25
+
lto = "fat"
26
+
strip = true
+102
README.md
+102
README.md
···
1
+
# Trap
2
+
3
+
Traverse records received from a Tap service and dump into a PostgreSQL database.
4
+
5
+
## Example Usage
6
+
7
+
In this example we'll *tap into* (😉) everything in the "sh.tangled.*" NSID starting from the @tangled.org repo (ATproto repo, not git repo).
8
+
9
+
1. Setup a PostgreSQL cluster and create a database
10
+
11
+
...
12
+
13
+
Let's assume you've created a DB called `trap_tangled`.
14
+
15
+
2. Tap
16
+
17
+
```bash
18
+
TAP_COLLECTION_FILTERS="sh.tangled.*" TAP_BIND=127.0.0.1:2480 tap run
19
+
```
20
+
21
+
`trap` will collect *any* records the Tap service sends. You can control this with the `TAP_COLLECTION_FILTERS` variable.
22
+
23
+
3. Trap
24
+
25
+
Run `trap`, seeding from the DID of @tangled.org:
26
+
27
+
```bash
28
+
RUST_LOG=debug,sqlx=warn INDEX_DATABASE_URL=postgresql:///trap_tangled trap --seed did:plc:wshs7t2adsemcrrd4snkeqli
29
+
```
30
+
31
+
`trap` will submit the seed DIDs to the Tap service. Each record return by Tap will be scanned, and any DIDs found will also be added to the Tap service.
32
+
33
+
4. Wait.
34
+
35
+
*Eventually*, and I mean *eventually*, you'll end up with a table named `record` filled with every "sh.tangled.*" record reachable from the @tangled.org repo.
36
+
37
+
5. Perform *Data Science*
38
+
39
+
Time to jump into `psql`!
40
+
41
+
The `record_by_collection` view counts how many records have been indexed for each collection.
42
+
43
+
```
44
+
trap_tangled=# select * from record_by_collection ;
45
+
collection | count
46
+
-------------------------------+-------
47
+
sh.tangled.feed.star | 5350
48
+
sh.tangled.spindle.member | 4821
49
+
sh.tangled.graph.follow | 4425
50
+
sh.tangled.knot.member | 3607
51
+
sh.tangled.repo | 2618
52
+
sh.tangled.repo.pull | 1785
53
+
sh.tangled.repo.issue | 1390
54
+
sh.tangled.repo.issue.comment | 1386
55
+
sh.tangled.publicKey | 1298
56
+
sh.tangled.repo.pull.comment | 1127
57
+
sh.tangled.actor.profile | 713
58
+
sh.tangled.label.op | 628
59
+
sh.tangled.feed.reaction | 479
60
+
sh.tangled.string | 364
61
+
sh.tangled.repo.issue.state | 320
62
+
sh.tangled.knot | 158
63
+
sh.tangled.repo.collaborator | 146
64
+
sh.tangled.label.definition | 106
65
+
sh.tangled.repo.artifact | 69
66
+
sh.tangled.spindle | 51
67
+
(20 rows)
68
+
69
+
trap_tangled=#
70
+
```
71
+
72
+
Analyse SSH public-key statistics:
73
+
74
+
```
75
+
trap_tangled=# SELECT split_part(data->>'key', ' ', 1) AS key_type,
76
+
count(*) AS count
77
+
FROM record
78
+
WHERE collection = 'sh.tangled.publicKey'
79
+
GROUP BY (split_part(data->>'key', ' ', 1))
80
+
ORDER BY (count(*)) DESC;
81
+
key_type | count
82
+
------------------------------------+-------
83
+
ssh-ed25519 | 989
84
+
ssh-rsa | 239
85
+
sk-ssh-ed25519@openssh.com | 44
86
+
ecdsa-sha2-nistp256 | 22
87
+
sh-ed25519 | 2
88
+
sk-ecdsa-sha2-nistp256@openssh.com | 1
89
+
ecdsa-sha2-nistp521 | 1
90
+
(7 rows)
91
+
92
+
trap_tangled=#
93
+
```
94
+
95
+
Fascinating!
96
+
97
+
## Future work
98
+
99
+
????
100
+
101
+
Suggestions and PRs welcome!
102
+
+10
migrations/20251216142421_init.down.sql
+10
migrations/20251216142421_init.down.sql
+48
migrations/20251216142421_init.up.sql
+48
migrations/20251216142421_init.up.sql
···
1
+
CREATE TABLE IF NOT EXISTS record (
2
+
did text NOT NULL,
3
+
collection text NOT NULL,
4
+
rkey text NOT NULL,
5
+
rev text NOT NULL,
6
+
cid text NOT NULL,
7
+
live boolean NOT NULL,
8
+
data jsonb NOT NULL,
9
+
10
+
PRIMARY KEY (did, collection, rkey)
11
+
);
12
+
13
+
CREATE INDEX ON record (collection);
14
+
15
+
CREATE TABLE IF NOT EXISTS deleted_record (
16
+
LIKE record
17
+
INCLUDING all
18
+
);
19
+
20
+
DO $$ BEGIN
21
+
CREATE TYPE identity_status AS ENUM (
22
+
'active',
23
+
'takendown',
24
+
'suspended',
25
+
'deactivated',
26
+
'deleted'
27
+
);
28
+
EXCEPTION
29
+
WHEN duplicate_object THEN null;
30
+
END $$;
31
+
32
+
CREATE TABLE IF NOT EXISTS identity (
33
+
did text NOT NULL,
34
+
handle text NOT NULL,
35
+
active boolean NOT NULL,
36
+
status identity_status NOT NULL,
37
+
38
+
PRIMARY KEY (did)
39
+
);
40
+
41
+
CREATE INDEX ON identity (handle);
42
+
43
+
CREATE OR REPLACE VIEW record_by_collection AS
44
+
SELECT collection,
45
+
count(*) AS count
46
+
FROM record
47
+
GROUP BY collection
48
+
ORDER BY (count(*)) DESC;
+7
queries/upsert_record.sql
+7
queries/upsert_record.sql
···
1
+
INSERT INTO record (did, collection, rkey, rev, cid, live, data)
2
+
VALUES ($1, $2, $3, $4, $5, $6, $7)
3
+
ON CONFLICT
4
+
ON CONSTRAINT record_pkey
5
+
DO UPDATE
6
+
SET (rev, cid, live, data) = (EXCLUDED.rev, EXCLUDED.cid, EXCLUDED.live, EXCLUDED.data)
7
+
WHERE EXCLUDED.rev > record.rev
+31
src/cli.rs
+31
src/cli.rs
···
1
+
use clap::Parser;
2
+
use url::Url;
3
+
4
+
/// Traverse records from Tap, saving to a PostgreSQL DB.
5
+
#[derive(Debug, Parser)]
6
+
pub struct Arguments {
7
+
/// URL for the PostgreSQL database.
8
+
#[arg(long, short = 'd', env = "TAP_DUMP_DATABASE_URL")]
9
+
pub db: Url,
10
+
11
+
/// URL for the Tap service.
12
+
#[arg(
13
+
long,
14
+
short = 'H',
15
+
env = "TAP_DUMP_TAP_URL",
16
+
default_value = "http://localhost:2480"
17
+
)]
18
+
pub tap: Url,
19
+
20
+
/// Admin password for the Tap service.
21
+
#[arg(long, short = 'p', env = "TAP_DUMP_TAP_PASSWORD")]
22
+
pub tap_password: Option<String>,
23
+
24
+
/// DIDs to seed from.
25
+
#[arg(long, value_delimiter = ',', env = "TAP_DUMP_SEED")]
26
+
pub seed: Vec<String>,
27
+
}
28
+
29
+
pub fn parse() -> Arguments {
30
+
Arguments::parse()
31
+
}
+305
src/main.rs
+305
src/main.rs
···
1
+
mod cli;
2
+
mod query;
3
+
4
+
use std::{
5
+
collections::{HashSet, VecDeque},
6
+
io,
7
+
ops::ControlFlow::{self, *},
8
+
time::Duration,
9
+
};
10
+
11
+
use futures_util::StreamExt;
12
+
use serde_json::Value;
13
+
use sqlx::PgPool;
14
+
use tokio::{
15
+
sync::{mpsc, watch},
16
+
task::JoinSet,
17
+
};
18
+
use tracing::level_filters::LevelFilter;
19
+
use tracing_subscriber::{EnvFilter, layer::SubscriberExt as _, util::SubscriberInitExt as _};
20
+
use trap::{
21
+
tap::{IdentityEvent, RecordAction, RecordEvent, TapChannel, TapClient, TapEvent},
22
+
util::with_shutdown,
23
+
};
24
+
25
+
/// DID provenance.
26
+
#[derive(Debug)]
27
+
#[allow(unused)]
28
+
enum DidSource {
29
+
Seed,
30
+
Record(Box<str>),
31
+
}
32
+
33
+
#[tokio::main]
34
+
async fn main() -> anyhow::Result<()> {
35
+
setup_tracing()?;
36
+
37
+
let arguments = cli::parse();
38
+
let pool = PgPool::connect(arguments.db.as_str()).await?;
39
+
let version = db_version(&pool).await?;
40
+
tracing::info!(%version, "connected to db");
41
+
42
+
sqlx::migrate!().run(&pool).await?;
43
+
44
+
let (shutdown_tx, shutdown_rx) = watch::channel(false);
45
+
let (did_tx, did_rx) = mpsc::unbounded_channel::<(String, DidSource)>();
46
+
47
+
let tap = TapClient::new(arguments.tap, arguments.tap_password.as_deref())?;
48
+
let (tap_channel, tap_task) = tap.channel();
49
+
50
+
let mut tasks = JoinSet::new();
51
+
tasks.spawn(async move {
52
+
let unsent_acks = tap_task.await?;
53
+
if !unsent_acks.is_empty() {
54
+
tracing::error!(?unsent_acks, "failed to clear Acks");
55
+
}
56
+
Ok(())
57
+
});
58
+
59
+
tasks.spawn(event_consumer(
60
+
tap_channel,
61
+
pool.clone(),
62
+
did_tx.clone(),
63
+
shutdown_rx.clone(),
64
+
));
65
+
66
+
tasks.spawn(did_task(tap, pool, did_rx, shutdown_rx.clone()));
67
+
tasks.spawn(shutdown_task(shutdown_tx.clone()));
68
+
69
+
// Submit seed DIDs to the Tap service.
70
+
for did in arguments.seed.into_iter().filter(|s| possible_did(s)) {
71
+
did_tx.send((did, DidSource::Seed))?;
72
+
}
73
+
74
+
for task in tasks.join_all().await {
75
+
if let Err(error) = task {
76
+
tracing::error!(?error, "task failed");
77
+
shutdown_tx.send(true)?;
78
+
}
79
+
}
80
+
81
+
Ok(())
82
+
}
83
+
84
+
fn setup_tracing() -> anyhow::Result<()> {
85
+
tracing_subscriber::registry()
86
+
.with(
87
+
EnvFilter::builder()
88
+
.with_default_directive(LevelFilter::INFO.into())
89
+
.from_env()?,
90
+
)
91
+
.with(tracing_subscriber::fmt::layer().with_writer(io::stderr))
92
+
.try_init()?;
93
+
94
+
Ok(())
95
+
}
96
+
97
+
async fn db_version(pool: &PgPool) -> sqlx::Result<String> {
98
+
let row: (String,) = sqlx::query_as("SELECT version()").fetch_one(pool).await?;
99
+
Ok(row.0)
100
+
}
101
+
102
+
#[tracing::instrument(skip(channel, pool, tx, rx))]
103
+
async fn event_consumer(
104
+
mut channel: TapChannel,
105
+
pool: PgPool,
106
+
tx: mpsc::UnboundedSender<(String, DidSource)>,
107
+
mut rx: watch::Receiver<bool>,
108
+
) -> anyhow::Result<()> {
109
+
use ControlFlow::Continue;
110
+
111
+
while let Continue(Some((event, ack))) = with_shutdown(channel.recv(), &mut rx).await {
112
+
let mut transaction = pool.begin().await?;
113
+
match event {
114
+
TapEvent::Record(record) => {
115
+
let (record, parsed_record) = handle_record(record, &mut transaction).await?;
116
+
117
+
// Expand the network of tracked DIDs.
118
+
let nsid = record.collection.into_boxed_str();
119
+
for did in extract_dids(&parsed_record) {
120
+
tx.send((did, DidSource::Record(nsid.clone())))?;
121
+
}
122
+
}
123
+
TapEvent::Identity(identity) => {
124
+
handle_identity(identity, &mut transaction).await?;
125
+
}
126
+
}
127
+
128
+
transaction.commit().await?;
129
+
ack.acknowledge().await?;
130
+
}
131
+
132
+
tracing::info!("complete");
133
+
Ok(())
134
+
}
135
+
136
+
async fn handle_identity(
137
+
identity_event: IdentityEvent,
138
+
transaction: &mut sqlx::Transaction<'static, sqlx::Postgres>,
139
+
) -> anyhow::Result<()> {
140
+
let IdentityEvent {
141
+
id: _,
142
+
did,
143
+
handle,
144
+
is_active,
145
+
status,
146
+
} = identity_event;
147
+
148
+
query::upsert_identity(&did, &handle, &status, is_active)
149
+
.execute(&mut **transaction)
150
+
.await?;
151
+
152
+
Ok(())
153
+
}
154
+
155
+
async fn handle_record(
156
+
record_event: RecordEvent,
157
+
transaction: &mut sqlx::Transaction<'static, sqlx::Postgres>,
158
+
) -> anyhow::Result<(RecordEvent, Value)> {
159
+
let RecordEvent {
160
+
id: _,
161
+
did,
162
+
rev,
163
+
collection,
164
+
rkey,
165
+
action,
166
+
record,
167
+
cid,
168
+
live,
169
+
} = &record_event;
170
+
171
+
let parsed_record: Value = record
172
+
.as_ref()
173
+
.map(|record| serde_json::from_str(record.get()))
174
+
.transpose()?
175
+
.unwrap_or_default();
176
+
177
+
match action {
178
+
RecordAction::Create | RecordAction::Update => {
179
+
sqlx::query_file!(
180
+
"queries/upsert_record.sql",
181
+
did.as_str(),
182
+
collection,
183
+
rkey,
184
+
rev,
185
+
cid.as_deref(),
186
+
live,
187
+
parsed_record
188
+
)
189
+
.execute(&mut **transaction)
190
+
.await?;
191
+
}
192
+
RecordAction::Delete => {
193
+
query::archive_record(did, collection, rkey)
194
+
.execute(&mut **transaction)
195
+
.await?;
196
+
query::delete_record(did, collection, rkey)
197
+
.execute(&mut **transaction)
198
+
.await?;
199
+
}
200
+
}
201
+
202
+
Ok((record_event, parsed_record))
203
+
}
204
+
205
+
#[tracing::instrument(skip(tap, pool, did_rx, shutdown_rx))]
206
+
async fn did_task(
207
+
tap: TapClient,
208
+
pool: PgPool,
209
+
mut did_rx: mpsc::UnboundedReceiver<(String, DidSource)>,
210
+
mut shutdown_rx: watch::Receiver<bool>,
211
+
) -> anyhow::Result<()> {
212
+
const BATCH: usize = 64;
213
+
214
+
let mut seen: HashSet<String> = HashSet::with_capacity(10_000);
215
+
let mut dids = Vec::new();
216
+
217
+
// Query known DIDs from the database.
218
+
let mut query = sqlx::query!("SELECT did FROM identity").fetch(&pool);
219
+
while let Some(Ok(row)) = query.next().await {
220
+
seen.insert(row.did);
221
+
}
222
+
223
+
tracing::debug!(count = seen.len(), "loaded tracked DIDs from database");
224
+
225
+
loop {
226
+
tokio::time::sleep(Duration::from_millis(200)).await;
227
+
match with_shutdown(did_rx.recv_many(&mut dids, BATCH), &mut shutdown_rx).await {
228
+
Continue(0) | Break(_) => break,
229
+
Continue(_) => {}
230
+
}
231
+
232
+
// Convert Vec<Box<Did>> to a Vec<&Did>.
233
+
let mut dedup: HashSet<&str> = HashSet::new();
234
+
let mut slice = Vec::with_capacity(dids.len());
235
+
for (did, source) in &dids {
236
+
if !dedup.insert(did) {
237
+
continue;
238
+
}
239
+
240
+
if !seen.contains(did) || slice.contains(&did.as_ref()) {
241
+
tracing::info!(?did, ?source, "tracking DID");
242
+
slice.push(did.as_ref());
243
+
}
244
+
}
245
+
246
+
tap.add_repos(&slice).await?;
247
+
248
+
dids.drain(..).for_each(|(did, _)| _ = seen.insert(did));
249
+
}
250
+
251
+
tracing::info!("complete");
252
+
Ok(())
253
+
}
254
+
255
+
#[tracing::instrument(skip(tx))]
256
+
async fn shutdown_task(tx: watch::Sender<bool>) -> anyhow::Result<()> {
257
+
tokio::signal::ctrl_c().await?;
258
+
eprintln!();
259
+
tracing::info!("shutdown signal received");
260
+
tx.send(true)?;
261
+
Ok(())
262
+
}
263
+
264
+
/// Extract any strings that look like DIDs from a JSON document.
265
+
fn extract_dids(value: &Value) -> HashSet<String> {
266
+
let mut dids = HashSet::new();
267
+
268
+
let mut queue = VecDeque::from_iter([value]);
269
+
while let Some(value) = queue.pop_front() {
270
+
match value {
271
+
Value::Null | Value::Bool(_) | Value::Number(_) => {}
272
+
Value::Array(values) => {
273
+
for value in values {
274
+
queue.push_back(value);
275
+
}
276
+
}
277
+
Value::Object(map) => {
278
+
for (_, value) in map {
279
+
queue.push_back(value);
280
+
}
281
+
}
282
+
Value::String(maybe_did) => {
283
+
if possible_did(maybe_did) {
284
+
dids.insert(maybe_did.to_string());
285
+
continue;
286
+
}
287
+
288
+
// First segment of an "at://..." URI might be a DID.
289
+
if let Some(uri) = maybe_did.strip_prefix("at://")
290
+
&& let Some((maybe_did, _)) = uri.split_once('/')
291
+
&& possible_did(maybe_did)
292
+
{
293
+
dids.insert(maybe_did.to_string());
294
+
continue;
295
+
}
296
+
}
297
+
}
298
+
}
299
+
300
+
dids
301
+
}
302
+
303
+
fn possible_did(s: &str) -> bool {
304
+
s.starts_with("did:plc") || s.starts_with("did:web")
305
+
}
+42
src/query.rs
+42
src/query.rs
···
1
+
use trap::tap::IdentityStatus;
2
+
3
+
pub fn archive_record<'a>(
4
+
did: &'a str,
5
+
collection: &'a str,
6
+
rkey: &'a str,
7
+
) -> sqlx::query::Query<'a, sqlx::Postgres, sqlx::postgres::PgArguments> {
8
+
sqlx::query!(
9
+
"INSERT INTO deleted_record (SELECT did, collection, rkey, rev, cid, live, data FROM record WHERE (did, collection, rkey) = ($1, $2, $3))",
10
+
did,
11
+
collection,
12
+
rkey,
13
+
)
14
+
}
15
+
16
+
pub fn delete_record<'a>(
17
+
did: &'a str,
18
+
collection: &'a str,
19
+
rkey: &'a str,
20
+
) -> sqlx::query::Query<'a, sqlx::Postgres, sqlx::postgres::PgArguments> {
21
+
sqlx::query!(
22
+
"DELETE FROM record WHERE (did, collection, rkey) = ($1, $2, $3)",
23
+
did,
24
+
collection,
25
+
rkey,
26
+
)
27
+
}
28
+
29
+
pub fn upsert_identity<'a>(
30
+
did: &'a str,
31
+
handle: &'a str,
32
+
status: &'a IdentityStatus,
33
+
is_active: bool,
34
+
) -> sqlx::query::Query<'a, sqlx::Postgres, sqlx::postgres::PgArguments> {
35
+
sqlx::query!(
36
+
"INSERT INTO identity (did, handle, active, status) VALUES ($1, $2, $3, $4) ON CONFLICT ON CONSTRAINT identity_pkey DO UPDATE SET (handle, active, status) = (EXCLUDED.handle, EXCLUDED.active, EXCLUDED.status)",
37
+
did,
38
+
handle,
39
+
is_active,
40
+
status as &IdentityStatus
41
+
)
42
+
}
+13
src/tap.rs
+13
src/tap.rs
···
1
+
mod channel;
2
+
mod client;
3
+
mod error;
4
+
mod types;
5
+
6
+
const USER_AGENT: &str = concat!(env!("CARGO_PKG_NAME"), "/", env!("CARGO_PKG_VERSION"));
7
+
8
+
pub type HttpClient = reqwest::Client;
9
+
10
+
pub use channel::TapChannel;
11
+
pub use client::TapClient;
12
+
pub use error::Error;
13
+
pub use types::*;
+313
src/tap/channel.rs
+313
src/tap/channel.rs
···
1
+
use core::fmt;
2
+
use std::{
3
+
collections::HashSet,
4
+
time::{Duration, SystemTime},
5
+
};
6
+
7
+
use futures_util::{SinkExt as _, StreamExt};
8
+
use serde::Serialize;
9
+
use tokio::{
10
+
net::TcpStream,
11
+
sync::{mpsc, watch},
12
+
};
13
+
use tokio_tungstenite::{
14
+
MaybeTlsStream, WebSocketStream,
15
+
tungstenite::{Bytes, ClientRequestBuilder, Message},
16
+
};
17
+
18
+
use crate::tap::{TapClient, TapEvent};
19
+
20
+
/// Maximum number of unanswered Ping messages to allow before the connection is
21
+
/// considered broken.
22
+
const MAX_INFLIGHT_PINGS: usize = 2;
23
+
24
+
const TIMEOUT: Duration = Duration::from_secs(30);
25
+
26
+
#[derive(Debug, thiserror::Error)]
27
+
#[error("Failed to enqueue acknowledgement for event #{0}")]
28
+
pub struct AckError(u64);
29
+
30
+
impl From<mpsc::error::SendError<Ack>> for AckError {
31
+
fn from(error: mpsc::error::SendError<Ack>) -> Self {
32
+
Self(error.0.0)
33
+
}
34
+
}
35
+
36
+
pub struct AckHandle {
37
+
id: u64,
38
+
tx: mpsc::Sender<Ack>,
39
+
}
40
+
41
+
impl AckHandle {
42
+
/// Acknowledge receipt of the associated event.
43
+
///
44
+
/// Success does *not* mean the Tap server has successfully received the
45
+
/// acknowledgement, only that the ack has be queued by the client.
46
+
pub async fn acknowledge(self) -> Result<(), AckError> {
47
+
self.tx.send(Ack::new(self.id)).await?;
48
+
Ok(())
49
+
}
50
+
}
51
+
52
+
#[derive(Debug)]
53
+
pub struct Ack(u64);
54
+
55
+
impl fmt::Display for Ack {
56
+
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
57
+
fmt::Display::fmt(&self.0, f)
58
+
}
59
+
}
60
+
61
+
impl Ack {
62
+
fn new(id: u64) -> Self {
63
+
Self(id)
64
+
}
65
+
}
66
+
67
+
/// Messages that are serialized and sent to the Tap server.
68
+
#[derive(Debug, Serialize)]
69
+
#[serde(tag = "type", rename_all = "snake_case")]
70
+
enum ClientMessage {
71
+
Ack { id: u64 },
72
+
}
73
+
74
+
impl From<&Ack> for ClientMessage {
75
+
fn from(&Ack(id): &Ack) -> Self {
76
+
Self::Ack { id }
77
+
}
78
+
}
79
+
80
+
#[derive(Debug)]
81
+
pub struct TapChannel {
82
+
rx: mpsc::Receiver<(TapEvent, AckHandle)>,
83
+
shutdown: watch::Sender<bool>,
84
+
}
85
+
86
+
impl TapChannel {
87
+
pub const DEFAULT_CAPACITY: usize = 128;
88
+
89
+
pub fn new(
90
+
tap: &TapClient,
91
+
capacity: usize,
92
+
) -> (
93
+
Self,
94
+
impl Future<Output = Result<Vec<Ack>, ChannelError>> + Send + 'static,
95
+
) {
96
+
let mut url = tap.url().clone();
97
+
url.set_path("/channel");
98
+
url.set_scheme(match url.scheme() {
99
+
"https" => "wss",
100
+
"http" => "ws",
101
+
_ => unreachable!("Tap::new should reject unknown schemes"),
102
+
})
103
+
.expect("'http' or 'https' is a valid URL scheme");
104
+
105
+
let uri = url
106
+
.as_str()
107
+
.parse()
108
+
.expect("Url has already been validated");
109
+
110
+
let mut builder = ClientRequestBuilder::new(uri);
111
+
for (header_name, header_value) in &tap.headers {
112
+
builder = builder.with_header(
113
+
header_name.to_string(),
114
+
header_value
115
+
.to_str()
116
+
.expect("Header value has already been validated"),
117
+
);
118
+
}
119
+
120
+
let (tx, rx) = mpsc::channel(capacity);
121
+
let (shutdown, shutdown_rx) = watch::channel(false);
122
+
let handle = channel_task(builder, tx, shutdown_rx, capacity);
123
+
124
+
(Self { rx, shutdown }, handle)
125
+
}
126
+
}
127
+
128
+
impl TapChannel {
129
+
pub async fn recv(&mut self) -> Option<(TapEvent, AckHandle)> {
130
+
self.rx.recv().await
131
+
}
132
+
}
133
+
134
+
impl Drop for TapChannel {
135
+
fn drop(&mut self) {
136
+
self.rx.close();
137
+
let _ = self.shutdown.send(true);
138
+
}
139
+
}
140
+
141
+
#[derive(Debug, thiserror::Error)]
142
+
pub enum ChannelError {
143
+
#[error("Client authorization failed")]
144
+
Authorization,
145
+
#[error("Failed to send pending Acks: {0:?}: {1}")]
146
+
FailedAcks(Vec<Ack>, tokio_tungstenite::tungstenite::Error),
147
+
}
148
+
149
+
async fn channel_task(
150
+
request_builder: ClientRequestBuilder,
151
+
event_tx: mpsc::Sender<(TapEvent, AckHandle)>,
152
+
mut shutdown_rx: watch::Receiver<bool>,
153
+
capacity: usize,
154
+
) -> Result<Vec<Ack>, ChannelError> {
155
+
#[derive(Debug)]
156
+
enum Action {
157
+
Message(Message),
158
+
Timeout,
159
+
Ack,
160
+
ClearAcks,
161
+
}
162
+
163
+
let mut pings: HashSet<Bytes> = HashSet::with_capacity(MAX_INFLIGHT_PINGS + 1);
164
+
let mut timeout = tokio::time::interval(TIMEOUT);
165
+
timeout.tick().await;
166
+
167
+
let (ack_tx, mut ack_rx) = mpsc::channel(capacity);
168
+
let mut acks: Vec<_> = Default::default();
169
+
170
+
'outer: loop {
171
+
let request = request_builder.clone();
172
+
let (mut socket, _) = match tokio_tungstenite::connect_async(request).await {
173
+
Ok(result) => result,
174
+
Err(tokio_tungstenite::tungstenite::Error::Http(error))
175
+
if error.status().is_client_error() =>
176
+
{
177
+
tracing::error!(?error, "failed to connect to Tap channel");
178
+
return Err(ChannelError::Authorization);
179
+
}
180
+
Err(error) => {
181
+
tracing::error!(?error);
182
+
183
+
// @TODO Reconnect delay
184
+
185
+
continue 'outer;
186
+
}
187
+
};
188
+
189
+
// Send any pending Acks.
190
+
if let Err(error) = send_acknowledgements(&mut acks, &mut socket).await {
191
+
tracing::error!(?error, "failed to send Ack");
192
+
continue;
193
+
}
194
+
195
+
loop {
196
+
let action = tokio::select! {
197
+
Some(Ok(message)) = socket.next() => Action::Message(message),
198
+
count = ack_rx.recv_many(&mut acks, 64) => match count {
199
+
0 => Action::ClearAcks,
200
+
_ => Action::Ack,
201
+
},
202
+
_ = timeout.tick() => Action::Timeout,
203
+
_ = shutdown_rx.wait_for(|v| *v) => Action::ClearAcks,
204
+
else => Action::ClearAcks,
205
+
};
206
+
207
+
match action {
208
+
Action::Message(message) => match message {
209
+
Message::Text(bytes) => {
210
+
let event = match serde_json::from_str::<TapEvent>(bytes.as_str()) {
211
+
Ok(event) => event,
212
+
Err(error) => {
213
+
tracing::error!(?error, bytes = %bytes.as_str(), "failed to deserialize event");
214
+
continue;
215
+
}
216
+
};
217
+
218
+
let ack = AckHandle {
219
+
id: event.id(),
220
+
tx: ack_tx.clone(),
221
+
};
222
+
223
+
if event_tx.send((event, ack)).await.is_err() {
224
+
tracing::error!("failed to dispatch event");
225
+
break 'outer;
226
+
}
227
+
}
228
+
Message::Binary(_) | Message::Frame(_) => {
229
+
tracing::error!("unexpected Binary or Frame message from server");
230
+
break;
231
+
}
232
+
Message::Ping(bytes) => {
233
+
if let Err(error) = socket.send(Message::Pong(bytes)).await {
234
+
tracing::error!(?error, "failed to send Pong");
235
+
continue 'outer;
236
+
}
237
+
}
238
+
Message::Pong(bytes) => {
239
+
tracing::trace!(?bytes, "received Pong from server");
240
+
if !pings.remove(&bytes) {
241
+
tracing::error!("unsolicited Pong");
242
+
break;
243
+
}
244
+
}
245
+
Message::Close(close_frame) => {
246
+
tracing::debug!(?close_frame, "received close frame");
247
+
break;
248
+
}
249
+
},
250
+
Action::Ack => {
251
+
if let Err(error) = send_acknowledgements(&mut acks, &mut socket).await {
252
+
tracing::error!(?error, "failed to send Ack");
253
+
break;
254
+
}
255
+
}
256
+
Action::Timeout => {
257
+
if pings.len() > MAX_INFLIGHT_PINGS {
258
+
tracing::error!("too many missed pings");
259
+
break;
260
+
}
261
+
262
+
let timestamp = SystemTime::now()
263
+
.duration_since(SystemTime::UNIX_EPOCH)
264
+
.expect("system time precedes UNIX epoch")
265
+
.as_micros();
266
+
267
+
let payload = format!("{timestamp}");
268
+
let payload: Bytes = payload.into();
269
+
pings.insert(payload.clone());
270
+
271
+
if socket.send(Message::Ping(payload)).await.is_err() {
272
+
tracing::error!("failed to send Ping to server");
273
+
break;
274
+
}
275
+
}
276
+
Action::ClearAcks => {
277
+
drop(ack_tx);
278
+
while let Some(ack) = ack_rx.recv().await {
279
+
acks.push(ack);
280
+
}
281
+
282
+
if let Err(error) = send_acknowledgements(&mut acks, &mut socket).await {
283
+
return Err(ChannelError::FailedAcks(acks, error));
284
+
}
285
+
286
+
break 'outer;
287
+
}
288
+
}
289
+
}
290
+
291
+
tracing::warn!("disconnected");
292
+
}
293
+
294
+
tracing::info!("complete");
295
+
Ok(acks)
296
+
}
297
+
298
+
async fn send_acknowledgements(
299
+
acks: &mut Vec<Ack>,
300
+
socket: &mut WebSocketStream<MaybeTlsStream<TcpStream>>,
301
+
) -> Result<usize, tokio_tungstenite::tungstenite::Error> {
302
+
let mut count = 0;
303
+
for ack in acks.drain(..) {
304
+
tracing::debug!(?ack, "sending ack");
305
+
let message = serde_json::to_string(&ClientMessage::from(&ack))
306
+
.expect("ClientMessage should be serializable");
307
+
308
+
socket.send(Message::text(message)).await?;
309
+
count += 1;
310
+
}
311
+
312
+
Ok(count)
313
+
}
+155
src/tap/client.rs
+155
src/tap/client.rs
···
1
+
use data_encoding::BASE64URL;
2
+
use reqwest::{
3
+
IntoUrl,
4
+
header::{self, HeaderMap, HeaderValue},
5
+
};
6
+
use serde_json::Value;
7
+
use url::Url;
8
+
9
+
use crate::tap::{
10
+
Error, HttpClient, RepoInfo, TapChannel,
11
+
channel::{Ack, ChannelError},
12
+
};
13
+
14
+
pub type Result<T> = core::result::Result<T, Error>;
15
+
16
+
#[derive(Clone)]
17
+
pub struct TapClient {
18
+
http: HttpClient,
19
+
url: Url,
20
+
pub(crate) headers: HeaderMap,
21
+
}
22
+
23
+
impl TapClient {
24
+
pub fn new<U: IntoUrl>(url: U, admin_password: Option<&str>) -> Result<Self> {
25
+
fn inner(url: Url, admin_password: Option<&str>) -> Result<TapClient> {
26
+
if !["http", "https"].contains(&url.scheme()) {
27
+
return Err(Error::UnsupportedScheme);
28
+
}
29
+
30
+
let mut headers = HeaderMap::new();
31
+
if let Some(password) = admin_password {
32
+
let token = format!("admin:{password}");
33
+
let encoded = BASE64URL.encode(token.as_bytes());
34
+
headers.append(
35
+
header::AUTHORIZATION,
36
+
HeaderValue::from_str(&format!("Basic {encoded}"))?,
37
+
);
38
+
}
39
+
40
+
let http = HttpClient::builder()
41
+
.default_headers(headers.clone())
42
+
.user_agent(crate::tap::USER_AGENT)
43
+
.build()?;
44
+
45
+
Ok(TapClient { http, url, headers })
46
+
}
47
+
48
+
inner(url.into_url()?, admin_password)
49
+
}
50
+
51
+
pub fn url(&self) -> &Url {
52
+
&self.url
53
+
}
54
+
}
55
+
56
+
impl TapClient {
57
+
/// Create a WebSocket channel to receive events.
58
+
pub fn channel(
59
+
&self,
60
+
) -> (
61
+
TapChannel,
62
+
impl Future<Output = core::result::Result<Vec<Ack>, ChannelError>> + Send + 'static,
63
+
) {
64
+
TapChannel::new(self, TapChannel::DEFAULT_CAPACITY)
65
+
}
66
+
67
+
/// Start tracking repos.
68
+
///
69
+
/// This will trigger backfill.
70
+
pub async fn add_repos(&self, dids: &[&str]) -> Result<()> {
71
+
#[derive(serde::Serialize)]
72
+
struct RequestBody<'a> {
73
+
dids: &'a [&'a str],
74
+
}
75
+
76
+
// An empty slice will trigger an internal service error in the Tap service.
77
+
if dids.is_empty() {
78
+
return Ok(());
79
+
}
80
+
81
+
let mut url = self.url.clone();
82
+
url.set_path("/repos/add");
83
+
84
+
let response = self
85
+
.http
86
+
.post(url)
87
+
.json(&RequestBody { dids })
88
+
.send()
89
+
.await?
90
+
.error_for_status()?;
91
+
92
+
let body = response.bytes().await?;
93
+
assert!(body.is_empty(), "expected an empty response body");
94
+
95
+
Ok(())
96
+
}
97
+
98
+
/// Stop tracking repos.
99
+
pub async fn remove_repos(&self, dids: &[&str]) -> Result<()> {
100
+
#[derive(serde::Serialize)]
101
+
struct RequestBody<'a> {
102
+
dids: &'a [&'a str],
103
+
}
104
+
105
+
let mut url = self.url.clone();
106
+
url.set_path("/repos/remove");
107
+
108
+
let response = self
109
+
.http
110
+
.post(url)
111
+
.json(&RequestBody { dids })
112
+
.send()
113
+
.await?
114
+
.error_for_status()?;
115
+
116
+
let body = response.bytes().await?;
117
+
assert!(body.is_empty(), "expected an empty response body");
118
+
119
+
Ok(())
120
+
}
121
+
122
+
/// Resolve a DID to its DID document.
123
+
pub async fn resolve_did(&self, did: &str) -> Result<Value> {
124
+
let mut url = self.url.clone();
125
+
url.set_path(&format!("/resolve/{did}"));
126
+
127
+
let response = self
128
+
.http
129
+
.get(url)
130
+
.send()
131
+
.await?
132
+
.error_for_status()?
133
+
.json()
134
+
.await?;
135
+
136
+
Ok(response)
137
+
}
138
+
139
+
/// Get info about a tracked repo.
140
+
pub async fn get_repo_info(&self, did: &str) -> Result<RepoInfo> {
141
+
let mut url = self.url.clone();
142
+
url.set_path(&format!("/info/{did}"));
143
+
144
+
let response = self
145
+
.http
146
+
.get(url)
147
+
.send()
148
+
.await?
149
+
.error_for_status()?
150
+
.json()
151
+
.await?;
152
+
153
+
Ok(response)
154
+
}
155
+
}
+9
src/tap/error.rs
+9
src/tap/error.rs
···
1
+
#[derive(Debug, thiserror::Error)]
2
+
pub enum Error {
3
+
#[error(transparent)]
4
+
Http(#[from] reqwest::Error),
5
+
#[error("Unsupported scheme")]
6
+
UnsupportedScheme,
7
+
#[error("Failed to construct a valid Authorization header: {0}")]
8
+
InvalidAuthorization(#[from] reqwest::header::InvalidHeaderValue),
9
+
}
+182
src/tap/types.rs
+182
src/tap/types.rs
···
1
+
use serde::{Deserialize, Serialize};
2
+
use serde_json::value::RawValue;
3
+
4
+
#[derive(Debug, Hash, Deserialize, Serialize)]
5
+
#[serde(rename_all = "lowercase")]
6
+
pub enum RecordAction {
7
+
Create,
8
+
Update,
9
+
Delete,
10
+
}
11
+
12
+
#[derive(Debug, Deserialize, Serialize)]
13
+
struct InnerRecordEvent {
14
+
did: String,
15
+
rev: String,
16
+
collection: String,
17
+
rkey: String,
18
+
action: RecordAction,
19
+
record: Option<Box<RawValue>>,
20
+
cid: Option<String>,
21
+
live: bool,
22
+
}
23
+
24
+
#[derive(Debug, Deserialize, Serialize)]
25
+
pub struct RecordEvent {
26
+
pub id: u64,
27
+
pub did: String,
28
+
pub rev: String,
29
+
pub collection: String,
30
+
pub rkey: String,
31
+
pub action: RecordAction,
32
+
pub record: Option<Box<RawValue>>,
33
+
pub cid: Option<String>,
34
+
pub live: bool,
35
+
}
36
+
37
+
#[derive(Debug, Deserialize, Serialize, sqlx::Type)]
38
+
#[serde(rename_all = "lowercase")]
39
+
#[sqlx(type_name = "identity_status", rename_all = "lowercase")]
40
+
pub enum IdentityStatus {
41
+
Active,
42
+
Takendown,
43
+
Suspended,
44
+
Deactivated,
45
+
Deleted,
46
+
}
47
+
48
+
#[derive(Debug, Deserialize, Serialize)]
49
+
struct InnerIdentityEvent {
50
+
did: String,
51
+
handle: String,
52
+
is_active: bool,
53
+
status: IdentityStatus,
54
+
}
55
+
56
+
#[derive(Debug, Deserialize, Serialize)]
57
+
pub struct IdentityEvent {
58
+
pub id: u64,
59
+
pub did: String,
60
+
pub handle: String,
61
+
pub is_active: bool,
62
+
pub status: IdentityStatus,
63
+
}
64
+
65
+
#[derive(Debug, Deserialize, Serialize)]
66
+
#[serde(rename_all = "snake_case")]
67
+
pub enum EventType {
68
+
Record,
69
+
Identity,
70
+
}
71
+
72
+
#[derive(Debug, Deserialize, Serialize)]
73
+
struct InnerEvent {
74
+
id: u64,
75
+
r#type: EventType,
76
+
#[serde(skip_serializing_if = "Option::is_none")]
77
+
record: Option<InnerRecordEvent>,
78
+
#[serde(skip_serializing_if = "Option::is_none")]
79
+
identity: Option<InnerIdentityEvent>,
80
+
}
81
+
82
+
#[derive(Debug, Deserialize, Serialize)]
83
+
#[serde(try_from = "InnerEvent")]
84
+
pub enum TapEvent {
85
+
Record(RecordEvent),
86
+
Identity(IdentityEvent),
87
+
}
88
+
89
+
impl TapEvent {
90
+
pub const fn id(&self) -> u64 {
91
+
match self {
92
+
Self::Record(record) => record.id,
93
+
Self::Identity(identity) => identity.id,
94
+
}
95
+
}
96
+
}
97
+
98
+
#[derive(Debug, thiserror::Error)]
99
+
enum EventError {
100
+
#[error("event with 'record' type should have 'record' property set")]
101
+
RecordEventMissingRecord,
102
+
#[error("event with 'record' type should not have 'identity' property set")]
103
+
RecordEventWithIdentity,
104
+
#[error("event with 'identity' type should have 'identity' property set")]
105
+
IdentityEventMissingIdentity,
106
+
#[error("event with 'identity' type should not have 'record' property set")]
107
+
IdentityEventWithRecord,
108
+
}
109
+
110
+
impl TryFrom<InnerEvent> for TapEvent {
111
+
type Error = EventError;
112
+
113
+
fn try_from(value: InnerEvent) -> Result<Self, Self::Error> {
114
+
match (value.r#type, value.record, value.identity) {
115
+
(EventType::Record, None, _) => Err(EventError::RecordEventMissingRecord),
116
+
(EventType::Record, _, Some(_)) => Err(EventError::RecordEventWithIdentity),
117
+
(EventType::Record, Some(record), None) => {
118
+
let InnerRecordEvent {
119
+
did,
120
+
rev,
121
+
collection,
122
+
rkey,
123
+
action,
124
+
record,
125
+
cid,
126
+
live,
127
+
} = record;
128
+
Ok(Self::Record(RecordEvent {
129
+
id: value.id,
130
+
did,
131
+
rev,
132
+
collection,
133
+
rkey,
134
+
action,
135
+
record,
136
+
cid,
137
+
live,
138
+
}))
139
+
}
140
+
(EventType::Identity, _, None) => Err(EventError::IdentityEventMissingIdentity),
141
+
(EventType::Identity, Some(_), _) => Err(EventError::IdentityEventWithRecord),
142
+
(EventType::Identity, None, Some(identity)) => {
143
+
let InnerIdentityEvent {
144
+
did,
145
+
handle,
146
+
is_active,
147
+
status,
148
+
} = identity;
149
+
Ok(Self::Identity(IdentityEvent {
150
+
id: value.id,
151
+
did,
152
+
handle,
153
+
is_active,
154
+
status,
155
+
}))
156
+
}
157
+
}
158
+
}
159
+
}
160
+
161
+
#[derive(Debug, Deserialize, Serialize)]
162
+
pub struct RepoInfo {
163
+
pub did: String,
164
+
pub handle: String,
165
+
pub state: String,
166
+
pub rev: String,
167
+
pub records: u64,
168
+
pub error: Option<String>,
169
+
pub retries: Option<u64>,
170
+
}
171
+
172
+
#[cfg(test)]
173
+
mod tests {
174
+
use super::*;
175
+
176
+
#[test]
177
+
fn deserialized_record_event() {
178
+
const SAMPLE: &str = r#"{"id":24431,"type":"record","record":{"live":false,"did":"did:plc:jlplwn5pi4dqrls7i6dx2me7","rev":"3m7xjcvqmch2k","collection":"sh.tangled.repo.issue.comment","rkey":"3lxy6urnngt22","action":"create","record":{"$type":"sh.tangled.repo.issue.comment","body":"x","commentId":66128,"createdAt":"2025-09-04T03:20:53Z","issue":"at://did:plc:qfpnj4og54vl56wngdriaxug/sh.tangled.repo.issue/3ljnffq4axj22","owner":"did:plc:jlplwn5pi4dqrls7i6dx2me7","repo":"at://did:plc:wshs7t2adsemcrrd4snkeqli/sh.tangled.repo/3liuighjy2h22"},"cid":"bafyreielwpdea6mnhgqz2r4yfyr5ne6v6h2ucncm46enukpqlclrned5ia"}}"#;
179
+
let event: TapEvent = serde_json::from_str(SAMPLE).unwrap();
180
+
assert!(matches!(event, TapEvent::Record(_)));
181
+
}
182
+
}
+19
src/util.rs
+19
src/util.rs
···
1
+
use std::ops;
2
+
3
+
use tokio::sync::watch;
4
+
5
+
#[derive(Debug, thiserror::Error)]
6
+
#[error("Shutdown signal received")]
7
+
pub struct Shutdown;
8
+
9
+
pub async fn with_shutdown<F: Future>(
10
+
f: F,
11
+
rx: &mut watch::Receiver<bool>,
12
+
) -> ops::ControlFlow<Shutdown, F::Output> {
13
+
use ops::ControlFlow::{Break, Continue};
14
+
15
+
tokio::select! {
16
+
result = f => Continue(result),
17
+
Ok(_) = rx.wait_for(|&v| v) => Break(Shutdown),
18
+
}
19
+
}