alamin655 commited on
Commit
2b85095
2 Parent(s): fd62456 991f3f5

Merge branch 'neon-mmd:rolling' into hf-rolling

Browse files
Cargo.lock CHANGED
@@ -4,17 +4,17 @@ version = 3
4
 
5
  [[package]]
6
  name = "actix-codec"
7
- version = "0.5.1"
8
  source = "registry+https://github.com/rust-lang/crates.io-index"
9
- checksum = "617a8268e3537fe1d8c9ead925fca49ef6400927ee7bc26750e90ecee14ce4b8"
10
  dependencies = [
11
- "bitflags 1.3.2",
12
  "bytes 1.5.0",
13
  "futures-core",
14
  "futures-sink",
15
  "memchr",
16
  "pin-project-lite",
17
- "tokio 1.35.1",
18
  "tokio-util",
19
  "tracing",
20
  ]
@@ -44,7 +44,7 @@ dependencies = [
44
  "actix-service",
45
  "actix-utils",
46
  "actix-web",
47
- "bitflags 2.4.1",
48
  "bytes 1.5.0",
49
  "derive_more",
50
  "futures-core",
@@ -71,24 +71,24 @@ dependencies = [
71
 
72
  [[package]]
73
  name = "actix-http"
74
- version = "3.5.1"
75
  source = "registry+https://github.com/rust-lang/crates.io-index"
76
- checksum = "129d4c88e98860e1758c5de288d1632b07970a16d59bdf7b8d66053d582bb71f"
77
  dependencies = [
78
  "actix-codec",
79
  "actix-rt",
80
  "actix-service",
81
  "actix-utils",
82
- "ahash 0.8.7",
83
- "base64 0.21.5",
84
- "bitflags 2.4.1",
85
  "brotli",
86
  "bytes 1.5.0",
87
  "bytestring",
88
  "derive_more",
89
  "encoding_rs",
90
  "futures-core",
91
- "http 0.2.11",
92
  "httparse",
93
  "httpdate",
94
  "itoa 1.0.10",
@@ -100,7 +100,7 @@ dependencies = [
100
  "rand 0.8.5",
101
  "sha1",
102
  "smallvec 1.13.1",
103
- "tokio 1.35.1",
104
  "tokio-util",
105
  "tracing",
106
  ]
@@ -112,7 +112,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
112
  checksum = "e01ed3140b2f8d422c68afa1ed2e85d996ea619c988ac834d255db32138655cb"
113
  dependencies = [
114
  "quote 1.0.35",
115
- "syn 2.0.48",
116
  ]
117
 
118
  [[package]]
@@ -122,7 +122,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
122
  checksum = "d22475596539443685426b6bdadb926ad0ecaefdfc5fb05e5e3441f15463c511"
123
  dependencies = [
124
  "bytestring",
125
- "http 0.2.11",
126
  "regex",
127
  "serde",
128
  "tracing",
@@ -135,7 +135,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
135
  checksum = "28f32d40287d3f402ae0028a9d54bef51af15c8769492826a69d28f81893151d"
136
  dependencies = [
137
  "futures-core",
138
- "tokio 1.35.1",
139
  ]
140
 
141
  [[package]]
@@ -149,9 +149,9 @@ dependencies = [
149
  "actix-utils",
150
  "futures-core",
151
  "futures-util",
152
- "mio 0.8.10",
153
  "socket2",
154
- "tokio 1.35.1",
155
  "tracing",
156
  ]
157
 
@@ -178,9 +178,9 @@ dependencies = [
178
 
179
  [[package]]
180
  name = "actix-web"
181
- version = "4.4.1"
182
  source = "registry+https://github.com/rust-lang/crates.io-index"
183
- checksum = "e43428f3bf11dee6d166b00ec2df4e3aa8cc1606aaa0b7433c146852e2f4e03b"
184
  dependencies = [
185
  "actix-codec",
186
  "actix-http",
@@ -191,7 +191,7 @@ dependencies = [
191
  "actix-service",
192
  "actix-utils",
193
  "actix-web-codegen",
194
- "ahash 0.8.7",
195
  "bytes 1.5.0",
196
  "bytestring",
197
  "cfg-if 1.0.0",
@@ -212,7 +212,7 @@ dependencies = [
212
  "serde_urlencoded 0.7.1",
213
  "smallvec 1.13.1",
214
  "socket2",
215
- "time 0.3.31",
216
  "url 2.5.0",
217
  ]
218
 
@@ -225,7 +225,7 @@ dependencies = [
225
  "actix-router",
226
  "proc-macro2 1.0.78",
227
  "quote 1.0.35",
228
- "syn 2.0.48",
229
  ]
230
 
231
  [[package]]
@@ -255,20 +255,9 @@ dependencies = [
255
 
256
  [[package]]
257
  name = "ahash"
258
- version = "0.7.7"
259
- source = "registry+https://github.com/rust-lang/crates.io-index"
260
- checksum = "5a824f2aa7e75a0c98c5a504fceb80649e9c35265d44525b5f94de4771a395cd"
261
- dependencies = [
262
- "getrandom",
263
- "once_cell",
264
- "version_check",
265
- ]
266
-
267
- [[package]]
268
- name = "ahash"
269
- version = "0.8.7"
270
  source = "registry+https://github.com/rust-lang/crates.io-index"
271
- checksum = "77c3a9648d43b9cd48db467b3f87fdd6e146bcc88ab0180006cef2179fe11d01"
272
  dependencies = [
273
  "cfg-if 1.0.0",
274
  "getrandom",
@@ -318,21 +307,21 @@ checksum = "4b46cbb362ab8752921c97e041f5e366ee6297bd428a31275b9fcf1e380f7299"
318
 
319
  [[package]]
320
  name = "anstyle"
321
- version = "1.0.4"
322
  source = "registry+https://github.com/rust-lang/crates.io-index"
323
- checksum = "7079075b41f533b8c61d2a4d073c4676e1f8b249ff94a393b0595db304e0dd87"
324
 
325
  [[package]]
326
  name = "anyhow"
327
- version = "1.0.77"
328
  source = "registry+https://github.com/rust-lang/crates.io-index"
329
- checksum = "c9d19de80eff169429ac1e9f48fffb163916b448a44e8e046186232046d9e1f9"
330
 
331
  [[package]]
332
  name = "arc-swap"
333
- version = "1.6.0"
334
  source = "registry+https://github.com/rust-lang/crates.io-index"
335
- checksum = "bddcadddf5e9015d310179a59bb28c4d4b9920ad0f11e8e14dbadf654890c9a6"
336
 
337
  [[package]]
338
  name = "arrayref"
@@ -348,16 +337,16 @@ checksum = "96d30a06541fbafbc7f82ed10c06164cfbd2c401138f6addd8404629c4b16711"
348
 
349
  [[package]]
350
  name = "async-compression"
351
- version = "0.4.5"
352
  source = "registry+https://github.com/rust-lang/crates.io-index"
353
- checksum = "bc2d0cfb2a7388d34f590e76686704c494ed7aaceed62ee1ba35cbf363abc2a5"
354
  dependencies = [
355
  "brotli",
356
  "flate2",
357
  "futures-core",
358
  "memchr",
359
  "pin-project-lite",
360
- "tokio 1.35.1",
361
  ]
362
 
363
  [[package]]
@@ -368,13 +357,13 @@ checksum = "9338790e78aa95a416786ec8389546c4b6a1dfc3dc36071ed9518a9413a542eb"
368
 
369
  [[package]]
370
  name = "async-trait"
371
- version = "0.1.76"
372
  source = "registry+https://github.com/rust-lang/crates.io-index"
373
- checksum = "531b97fb4cd3dfdce92c35dedbfdc1f0b9d8091c8ca943d6dae340ef5012d514"
374
  dependencies = [
375
  "proc-macro2 1.0.78",
376
  "quote 1.0.35",
377
- "syn 2.0.48",
378
  ]
379
 
380
  [[package]]
@@ -418,9 +407,9 @@ dependencies = [
418
 
419
  [[package]]
420
  name = "base64"
421
- version = "0.21.5"
422
  source = "registry+https://github.com/rust-lang/crates.io-index"
423
- checksum = "35636a1494ede3b646cc98f74f8e62c773a38a659ebc777a2cf26b9b74171df9"
424
 
425
  [[package]]
426
  name = "bit-set"
@@ -445,9 +434,9 @@ checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a"
445
 
446
  [[package]]
447
  name = "bitflags"
448
- version = "2.4.1"
449
  source = "registry+https://github.com/rust-lang/crates.io-index"
450
- checksum = "327762f6e5a765692301e5bb513e0d9fef63be86bbc14528052b1cd3e6f03e07"
451
 
452
  [[package]]
453
  name = "blake3"
@@ -494,9 +483,9 @@ dependencies = [
494
 
495
  [[package]]
496
  name = "bstr"
497
- version = "1.9.0"
498
  source = "registry+https://github.com/rust-lang/crates.io-index"
499
- checksum = "c48f0051a4b4c5e0b6d365cd04af53aeaa209e3cc15ec2cdb69e73cc87fbd0dc"
500
  dependencies = [
501
  "memchr",
502
  "serde",
@@ -504,9 +493,9 @@ dependencies = [
504
 
505
  [[package]]
506
  name = "bumpalo"
507
- version = "3.14.0"
508
  source = "registry+https://github.com/rust-lang/crates.io-index"
509
- checksum = "7f30e7476521f6f8af1a1c4c0b8cc94f0bee37d91763d0ca2665f299b6cd8aec"
510
 
511
  [[package]]
512
  name = "bytecount"
@@ -557,9 +546,9 @@ dependencies = [
557
 
558
  [[package]]
559
  name = "cargo-platform"
560
- version = "0.1.6"
561
  source = "registry+https://github.com/rust-lang/crates.io-index"
562
- checksum = "ceed8ef69d8518a5dda55c07425450b58a4e1946f4951eab6d7191ee86c2443d"
563
  dependencies = [
564
  "serde",
565
  ]
@@ -572,7 +561,7 @@ checksum = "4acbb09d9ee8e23699b9634375c72795d095bf268439da88562cf9b501f181fa"
572
  dependencies = [
573
  "camino",
574
  "cargo-platform",
575
- "semver 1.0.20",
576
  "serde",
577
  "serde_json",
578
  ]
@@ -585,12 +574,9 @@ checksum = "37b2a672a2cb129a2e41c10b1224bb368f9f37a2b16b612598138befd7b37eb5"
585
 
586
  [[package]]
587
  name = "cc"
588
- version = "1.0.83"
589
  source = "registry+https://github.com/rust-lang/crates.io-index"
590
- checksum = "f1174fb0b6ec23863f8b971027804a42614e347eafb0a95bf0b12cdae21fc4d0"
591
- dependencies = [
592
- "libc",
593
- ]
594
 
595
  [[package]]
596
  name = "cfg-if"
@@ -639,9 +625,9 @@ dependencies = [
639
 
640
  [[package]]
641
  name = "ciborium"
642
- version = "0.2.1"
643
  source = "registry+https://github.com/rust-lang/crates.io-index"
644
- checksum = "effd91f6c78e5a4ace8a5d3c0b6bfaec9e2baaef55f3efc00e45fb2e477ee926"
645
  dependencies = [
646
  "ciborium-io",
647
  "ciborium-ll",
@@ -650,15 +636,15 @@ dependencies = [
650
 
651
  [[package]]
652
  name = "ciborium-io"
653
- version = "0.2.1"
654
  source = "registry+https://github.com/rust-lang/crates.io-index"
655
- checksum = "cdf919175532b369853f5d5e20b26b43112613fd6fe7aee757e35f7a44642656"
656
 
657
  [[package]]
658
  name = "ciborium-ll"
659
- version = "0.2.1"
660
  source = "registry+https://github.com/rust-lang/crates.io-index"
661
- checksum = "defaa24ecc093c77630e6c15e17c51f5e187bf35ee514f4e2d67baaa96dae22b"
662
  dependencies = [
663
  "ciborium-io",
664
  "half",
@@ -677,18 +663,18 @@ dependencies = [
677
 
678
  [[package]]
679
  name = "clap"
680
- version = "4.4.12"
681
  source = "registry+https://github.com/rust-lang/crates.io-index"
682
- checksum = "dcfab8ba68f3668e89f6ff60f5b205cea56aa7b769451a59f34b8682f51c056d"
683
  dependencies = [
684
  "clap_builder",
685
  ]
686
 
687
  [[package]]
688
  name = "clap_builder"
689
- version = "4.4.12"
690
  source = "registry+https://github.com/rust-lang/crates.io-index"
691
- checksum = "fb7fb5e4e979aec3be7791562fcba452f94ad85e954da024396433e0e25a79e9"
692
  dependencies = [
693
  "anstyle",
694
  "clap_lex",
@@ -696,9 +682,9 @@ dependencies = [
696
 
697
  [[package]]
698
  name = "clap_lex"
699
- version = "0.6.0"
700
  source = "registry+https://github.com/rust-lang/crates.io-index"
701
- checksum = "702fc72eb24e5a1e48ce58027a675bc24edd52096d5397d4aea7c6dd9eca0bd1"
702
 
703
  [[package]]
704
  name = "cloudabi"
@@ -719,7 +705,7 @@ dependencies = [
719
  "futures-core",
720
  "memchr",
721
  "pin-project-lite",
722
- "tokio 1.35.1",
723
  "tokio-util",
724
  ]
725
 
@@ -772,7 +758,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
772
  checksum = "e859cd57d0710d9e06c381b550c06e76992472a8c6d527aecd2fc673dcc231fb"
773
  dependencies = [
774
  "percent-encoding 2.3.1",
775
- "time 0.3.31",
776
  "version_check",
777
  ]
778
 
@@ -812,18 +798,18 @@ checksum = "06ea2b9bc92be3c2baa9334a323ebca2d6f074ff852cd1d7b11064035cd3868f"
812
 
813
  [[package]]
814
  name = "cpufeatures"
815
- version = "0.2.11"
816
  source = "registry+https://github.com/rust-lang/crates.io-index"
817
- checksum = "ce420fe07aecd3e67c5f910618fe65e94158f6dcc0adf44e00d69ce2bdfe0fd0"
818
  dependencies = [
819
  "libc",
820
  ]
821
 
822
  [[package]]
823
  name = "crc32fast"
824
- version = "1.3.2"
825
  source = "registry+https://github.com/rust-lang/crates.io-index"
826
- checksum = "b540bd8bc810d3885c6ea91e2018302f68baba2129ab3e88f32389ee9370880d"
827
  dependencies = [
828
  "cfg-if 1.0.0",
829
  ]
@@ -864,12 +850,11 @@ dependencies = [
864
 
865
  [[package]]
866
  name = "crossbeam-channel"
867
- version = "0.5.10"
868
  source = "registry+https://github.com/rust-lang/crates.io-index"
869
- checksum = "82a9b73a36529d9c47029b9fb3a6f0ea3cc916a261195352ba19e770fc1748b2"
870
  dependencies = [
871
- "cfg-if 1.0.0",
872
- "crossbeam-utils 0.8.18",
873
  ]
874
 
875
  [[package]]
@@ -922,12 +907,15 @@ dependencies = [
922
 
923
  [[package]]
924
  name = "crossbeam-utils"
925
- version = "0.8.18"
926
  source = "registry+https://github.com/rust-lang/crates.io-index"
927
- checksum = "c3a430a770ebd84726f584a90ee7f020d28db52c6d02138900f22341f866d39c"
928
- dependencies = [
929
- "cfg-if 1.0.0",
930
- ]
 
 
 
931
 
932
  [[package]]
933
  name = "crypto-common"
@@ -982,7 +970,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
982
  checksum = "13b588ba4ac1a99f7f2964d24b3d896ddc6bf847ee3855dbd4366f058cfcd331"
983
  dependencies = [
984
  "quote 1.0.35",
985
- "syn 2.0.48",
986
  ]
987
 
988
  [[package]]
@@ -1006,9 +994,9 @@ checksum = "7e962a19be5cfc3f3bf6dd8f61eb50107f356ad6270fbb3ed41476571db78be5"
1006
 
1007
  [[package]]
1008
  name = "deranged"
1009
- version = "0.3.10"
1010
  source = "registry+https://github.com/rust-lang/crates.io-index"
1011
- checksum = "8eb30d70a07a3b04884d2677f06bec33509dc67ca60d92949e5535352d3191dc"
1012
  dependencies = [
1013
  "powerfmt",
1014
  ]
@@ -1081,9 +1069,9 @@ checksum = "3a68a4904193147e0a8dec3314640e6db742afd5f6e634f428a6af230d9b3591"
1081
 
1082
  [[package]]
1083
  name = "either"
1084
- version = "1.9.0"
1085
  source = "registry+https://github.com/rust-lang/crates.io-index"
1086
- checksum = "a26ae43d7bcc3b814de94796a5e736d4029efb0ee900c12e2d54c993ad1a1e07"
1087
 
1088
  [[package]]
1089
  name = "encoding_rs"
@@ -1105,9 +1093,9 @@ dependencies = [
1105
 
1106
  [[package]]
1107
  name = "env_logger"
1108
- version = "0.11.1"
1109
  source = "registry+https://github.com/rust-lang/crates.io-index"
1110
- checksum = "05e7cf40684ae96ade6232ed84582f40ce0a66efcd43a5117aef610534f8e0b8"
1111
  dependencies = [
1112
  "env_filter",
1113
  "log",
@@ -1347,7 +1335,7 @@ checksum = "87750cf4b7a4c0625b1529e4c543c2182106e4dedc60a2a6455e00d212c489ac"
1347
  dependencies = [
1348
  "proc-macro2 1.0.78",
1349
  "quote 1.0.35",
1350
- "syn 2.0.48",
1351
  ]
1352
 
1353
  [[package]]
@@ -1364,9 +1352,9 @@ checksum = "38d84fa142264698cdce1a9f9172cf383a0c82de1bddcf3092901442c4097004"
1364
 
1365
  [[package]]
1366
  name = "futures-timer"
1367
- version = "3.0.2"
1368
  source = "registry+https://github.com/rust-lang/crates.io-index"
1369
- checksum = "e64b03909df88034c26dc1547e8970b91f98bdb65165d6a4e9110d94263dbb2c"
1370
 
1371
  [[package]]
1372
  name = "futures-util"
@@ -1416,9 +1404,9 @@ dependencies = [
1416
 
1417
  [[package]]
1418
  name = "getrandom"
1419
- version = "0.2.11"
1420
  source = "registry+https://github.com/rust-lang/crates.io-index"
1421
- checksum = "fe9006bed769170c11f845cf00c7c1e9092aeb3f268e007c3e760ac68008070f"
1422
  dependencies = [
1423
  "cfg-if 1.0.0",
1424
  "libc",
@@ -1439,9 +1427,9 @@ checksum = "d2fabcfbdc87f4758337ca535fb41a6d701b65693ce38287d856d1674551ec9b"
1439
 
1440
  [[package]]
1441
  name = "governor"
1442
- version = "0.6.0"
1443
  source = "registry+https://github.com/rust-lang/crates.io-index"
1444
- checksum = "821239e5672ff23e2a7060901fa622950bbd80b649cdaadd78d1c1767ed14eb4"
1445
  dependencies = [
1446
  "cfg-if 1.0.0",
1447
  "dashmap",
@@ -1450,9 +1438,11 @@ dependencies = [
1450
  "no-std-compat",
1451
  "nonzero_ext",
1452
  "parking_lot 0.12.1",
 
1453
  "quanta",
1454
  "rand 0.8.5",
1455
  "smallvec 1.13.1",
 
1456
  ]
1457
 
1458
  [[package]]
@@ -1475,28 +1465,32 @@ dependencies = [
1475
 
1476
  [[package]]
1477
  name = "h2"
1478
- version = "0.3.22"
1479
  source = "registry+https://github.com/rust-lang/crates.io-index"
1480
- checksum = "4d6250322ef6e60f93f9a2162799302cd6f68f79f6e5d85c8c16f14d1d958178"
1481
  dependencies = [
1482
  "bytes 1.5.0",
1483
  "fnv",
1484
  "futures-core",
1485
  "futures-sink",
1486
  "futures-util",
1487
- "http 0.2.11",
1488
- "indexmap 2.1.0",
1489
  "slab",
1490
- "tokio 1.35.1",
1491
  "tokio-util",
1492
  "tracing",
1493
  ]
1494
 
1495
  [[package]]
1496
  name = "half"
1497
- version = "1.8.2"
1498
  source = "registry+https://github.com/rust-lang/crates.io-index"
1499
- checksum = "eabb4a44450da02c90444cf74558da904edde8fb4e9035a9a6a4e15445af0bd7"
 
 
 
 
1500
 
1501
  [[package]]
1502
  name = "hashbrown"
@@ -1510,7 +1504,7 @@ version = "0.13.2"
1510
  source = "registry+https://github.com/rust-lang/crates.io-index"
1511
  checksum = "43a3c133739dddd0d2990f9a4bdf8eb4b21ef50e4851ca85ab661199821d510e"
1512
  dependencies = [
1513
- "ahash 0.8.7",
1514
  "bumpalo",
1515
  ]
1516
 
@@ -1522,9 +1516,9 @@ checksum = "290f1a1d9242c78d09ce40a5e87e7554ee637af1351968159f4952f028f75604"
1522
 
1523
  [[package]]
1524
  name = "hermit-abi"
1525
- version = "0.3.3"
1526
  source = "registry+https://github.com/rust-lang/crates.io-index"
1527
- checksum = "d77f7ec81a6d05a3abb01ab6eb7590f6083d08449fe5a1c8b1e620283546ccb7"
1528
 
1529
  [[package]]
1530
  name = "home"
@@ -1576,9 +1570,9 @@ dependencies = [
1576
 
1577
  [[package]]
1578
  name = "http"
1579
- version = "0.2.11"
1580
  source = "registry+https://github.com/rust-lang/crates.io-index"
1581
- checksum = "8947b1a6fad4393052c7ba1f4cd97bed3e953a95c79c92ad9b051a04611d9fbb"
1582
  dependencies = [
1583
  "bytes 1.5.0",
1584
  "fnv",
@@ -1604,7 +1598,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
1604
  checksum = "7ceab25649e9960c0311ea418d17bee82c0dcec1bd053b5f9a66e265a693bed2"
1605
  dependencies = [
1606
  "bytes 1.5.0",
1607
- "http 0.2.11",
1608
  "pin-project-lite",
1609
  ]
1610
 
@@ -1666,15 +1660,15 @@ dependencies = [
1666
  "futures-channel",
1667
  "futures-core",
1668
  "futures-util",
1669
- "h2 0.3.22",
1670
- "http 0.2.11",
1671
  "http-body 0.4.6",
1672
  "httparse",
1673
  "httpdate",
1674
  "itoa 1.0.10",
1675
  "pin-project-lite",
1676
  "socket2",
1677
- "tokio 1.35.1",
1678
  "tower-service",
1679
  "tracing",
1680
  "want 0.3.1",
@@ -1687,10 +1681,10 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
1687
  checksum = "ec3efd23720e2049821a693cbc7e65ea87c72f1c58ff2f9522ff332b1491e590"
1688
  dependencies = [
1689
  "futures-util",
1690
- "http 0.2.11",
1691
  "hyper 0.14.28",
1692
  "rustls",
1693
- "tokio 1.35.1",
1694
  "tokio-rustls",
1695
  ]
1696
 
@@ -1751,9 +1745,9 @@ dependencies = [
1751
 
1752
  [[package]]
1753
  name = "indexmap"
1754
- version = "2.1.0"
1755
  source = "registry+https://github.com/rust-lang/crates.io-index"
1756
- checksum = "d530e1a18b1cb4c484e6e34556a0d948706958449fca0cab753d649f2bce3d1f"
1757
  dependencies = [
1758
  "equivalent",
1759
  "hashbrown 0.14.3",
@@ -1785,12 +1779,12 @@ checksum = "8f518f335dce6725a761382244631d86cf0ccb2863413590b31338feb467f9c3"
1785
 
1786
  [[package]]
1787
  name = "is-terminal"
1788
- version = "0.4.10"
1789
  source = "registry+https://github.com/rust-lang/crates.io-index"
1790
- checksum = "0bad00257d07be169d870ab665980b06cdb366d792ad690bf2e76876dc503455"
1791
  dependencies = [
1792
  "hermit-abi",
1793
- "rustix",
1794
  "windows-sys 0.52.0",
1795
  ]
1796
 
@@ -1817,9 +1811,9 @@ checksum = "b1a46d1a171d865aa5f83f92695765caa047a9b4cbae2cbf37dbd613a793fd4c"
1817
 
1818
  [[package]]
1819
  name = "js-sys"
1820
- version = "0.3.66"
1821
  source = "registry+https://github.com/rust-lang/crates.io-index"
1822
- checksum = "cee9c64da59eae3b50095c18d3e74f8b73c0b86d2792824ff01bbce68ba229ca"
1823
  dependencies = [
1824
  "wasm-bindgen",
1825
  ]
@@ -1864,16 +1858,17 @@ dependencies = [
1864
 
1865
  [[package]]
1866
  name = "lightningcss"
1867
- version = "1.0.0-alpha.52"
1868
  source = "registry+https://github.com/rust-lang/crates.io-index"
1869
- checksum = "771a62dedf5ec563bbfea9760f6c6a6bc546e67355eba0cd7d00c0dc34b11d90"
1870
  dependencies = [
1871
- "ahash 0.7.7",
1872
- "bitflags 2.4.1",
1873
  "const-str",
1874
  "cssparser 0.33.0",
1875
  "cssparser-color",
1876
  "data-encoding",
 
1877
  "itertools",
1878
  "lazy_static",
1879
  "parcel_selectors",
@@ -1884,9 +1879,9 @@ dependencies = [
1884
 
1885
  [[package]]
1886
  name = "linux-raw-sys"
1887
- version = "0.4.12"
1888
  source = "registry+https://github.com/rust-lang/crates.io-index"
1889
- checksum = "c4cd1a83af159aa67994778be9070f0ae1bd732942279cabb14f86f986a21456"
1890
 
1891
  [[package]]
1892
  name = "local-channel"
@@ -1941,9 +1936,9 @@ dependencies = [
1941
 
1942
  [[package]]
1943
  name = "luajit-src"
1944
- version = "210.5.3+29b0b28"
1945
  source = "registry+https://github.com/rust-lang/crates.io-index"
1946
- checksum = "0c2bb89013916ce5c949f01a1fbd6d435a58e1d980767a791d755911211d792d"
1947
  dependencies = [
1948
  "cc",
1949
  "which",
@@ -1955,15 +1950,6 @@ version = "0.1.1"
1955
  source = "registry+https://github.com/rust-lang/crates.io-index"
1956
  checksum = "c41e0c4fef86961ac6d6f8a82609f55f31b05e4fce149ac5710e439df7619ba4"
1957
 
1958
- [[package]]
1959
- name = "mach2"
1960
- version = "0.4.2"
1961
- source = "registry+https://github.com/rust-lang/crates.io-index"
1962
- checksum = "19b955cdeb2a02b9117f121ce63aa52d08ade45de53e48fe6a38b39c10f6f709"
1963
- dependencies = [
1964
- "libc",
1965
- ]
1966
-
1967
  [[package]]
1968
  name = "markup5ever"
1969
  version = "0.8.1"
@@ -2073,12 +2059,12 @@ dependencies = [
2073
 
2074
  [[package]]
2075
  name = "mini-moka"
2076
- version = "0.10.2"
2077
  source = "registry+https://github.com/rust-lang/crates.io-index"
2078
- checksum = "23e0b72e7c9042467008b10279fc732326bd605459ae03bda88825909dd19b56"
2079
  dependencies = [
2080
  "crossbeam-channel",
2081
- "crossbeam-utils 0.8.18",
2082
  "dashmap",
2083
  "skeptic",
2084
  "smallvec 1.13.1",
@@ -2099,22 +2085,18 @@ dependencies = [
2099
 
2100
  [[package]]
2101
  name = "miniz_oxide"
2102
- version = "0.7.1"
2103
  source = "registry+https://github.com/rust-lang/crates.io-index"
2104
- checksum = "e7810e0be55b428ada41041c41f32c9f1a42817901b4ccf45fa3d4b6561e74c7"
2105
  dependencies = [
2106
  "adler",
2107
  ]
2108
 
2109
  [[package]]
2110
  name = "mintex"
2111
- version = "0.1.2"
2112
  source = "registry+https://github.com/rust-lang/crates.io-index"
2113
- checksum = "fd7c5ba1c3b5a23418d7bbf98c71c3d4946a0125002129231da8d6b723d559cb"
2114
- dependencies = [
2115
- "once_cell",
2116
- "sys-info",
2117
- ]
2118
 
2119
  [[package]]
2120
  name = "mio"
@@ -2137,9 +2119,9 @@ dependencies = [
2137
 
2138
  [[package]]
2139
  name = "mio"
2140
- version = "0.8.10"
2141
  source = "registry+https://github.com/rust-lang/crates.io-index"
2142
- checksum = "8f3d0b296e374a4e6f3c7b0a1f5a51d748a0d34c85e7dc48fc3fa9a87657fe09"
2143
  dependencies = [
2144
  "libc",
2145
  "log",
@@ -2161,9 +2143,9 @@ dependencies = [
2161
 
2162
  [[package]]
2163
  name = "mlua"
2164
- version = "0.9.2"
2165
  source = "registry+https://github.com/rust-lang/crates.io-index"
2166
- checksum = "7c81f8ac20188feb5461a73eabb22a34dd09d6d58513535eb587e46bff6ba250"
2167
  dependencies = [
2168
  "bstr",
2169
  "mlua-sys",
@@ -2174,9 +2156,9 @@ dependencies = [
2174
 
2175
  [[package]]
2176
  name = "mlua-sys"
2177
- version = "0.4.0"
2178
  source = "registry+https://github.com/rust-lang/crates.io-index"
2179
- checksum = "fc29228347d6bdc9e613dc95c69df2817f755434ee0f7f3b27b57755fe238b7f"
2180
  dependencies = [
2181
  "cc",
2182
  "cfg-if 1.0.0",
@@ -2238,11 +2220,17 @@ version = "0.3.0"
2238
  source = "registry+https://github.com/rust-lang/crates.io-index"
2239
  checksum = "38bf9645c8b145698bb0b18a4637dcacbc421ea49bef2317e4fd8065a387cf21"
2240
 
 
 
 
 
 
 
2241
  [[package]]
2242
  name = "num-traits"
2243
- version = "0.2.17"
2244
  source = "registry+https://github.com/rust-lang/crates.io-index"
2245
- checksum = "39e3200413f237f41ab11ad6d161bc7239c84dcb631773ccd7de3dfe4b5c267c"
2246
  dependencies = [
2247
  "autocfg 1.1.0",
2248
  ]
@@ -2280,17 +2268,17 @@ checksum = "0ab1bc2a289d34bd04a330323ac98a1b4bc82c9d9fcb1e66b63caa84da26b575"
2280
 
2281
  [[package]]
2282
  name = "opaque-debug"
2283
- version = "0.3.0"
2284
  source = "registry+https://github.com/rust-lang/crates.io-index"
2285
- checksum = "624a8340c38c1b80fd549087862da4ba43e08858af025b236e509b6649fc13d5"
2286
 
2287
  [[package]]
2288
  name = "openssl"
2289
- version = "0.10.62"
2290
  source = "registry+https://github.com/rust-lang/crates.io-index"
2291
- checksum = "8cde4d2d9200ad5909f8dac647e29482e07c3a35de8a13fce7c9c7747ad9f671"
2292
  dependencies = [
2293
- "bitflags 2.4.1",
2294
  "cfg-if 1.0.0",
2295
  "foreign-types",
2296
  "libc",
@@ -2307,7 +2295,7 @@ checksum = "a948666b637a0f465e8564c73e89d4dde00d72d4d473cc972f390fc3dcee7d9c"
2307
  dependencies = [
2308
  "proc-macro2 1.0.78",
2309
  "quote 1.0.35",
2310
- "syn 2.0.48",
2311
  ]
2312
 
2313
  [[package]]
@@ -2318,9 +2306,9 @@ checksum = "ff011a302c396a5197692431fc1948019154afc178baf7d8e37367442a4601cf"
2318
 
2319
  [[package]]
2320
  name = "openssl-sys"
2321
- version = "0.9.98"
2322
  source = "registry+https://github.com/rust-lang/crates.io-index"
2323
- checksum = "c1665caf8ab2dc9aef43d1c0023bd904633a6a05cb30b0ad59bec2ae986e57a7"
2324
  dependencies = [
2325
  "cc",
2326
  "libc",
@@ -2334,7 +2322,7 @@ version = "0.26.4"
2334
  source = "registry+https://github.com/rust-lang/crates.io-index"
2335
  checksum = "05d74befe2d076330d9a58bf9ca2da424568724ab278adf15fb5718253133887"
2336
  dependencies = [
2337
- "bitflags 2.4.1",
2338
  "cssparser 0.33.0",
2339
  "fxhash",
2340
  "log",
@@ -2518,7 +2506,7 @@ dependencies = [
2518
  "phf_shared 0.11.2",
2519
  "proc-macro2 1.0.78",
2520
  "quote 1.0.35",
2521
- "syn 2.0.48",
2522
  ]
2523
 
2524
  [[package]]
@@ -2550,22 +2538,22 @@ dependencies = [
2550
 
2551
  [[package]]
2552
  name = "pin-project"
2553
- version = "1.1.3"
2554
  source = "registry+https://github.com/rust-lang/crates.io-index"
2555
- checksum = "fda4ed1c6c173e3fc7a83629421152e01d7b1f9b7f65fb301e490e8cfc656422"
2556
  dependencies = [
2557
  "pin-project-internal",
2558
  ]
2559
 
2560
  [[package]]
2561
  name = "pin-project-internal"
2562
- version = "1.1.3"
2563
  source = "registry+https://github.com/rust-lang/crates.io-index"
2564
- checksum = "4359fd9c9171ec6e8c62926d6faaf553a8dc3f64e1507e76da7911b4f6a04405"
2565
  dependencies = [
2566
  "proc-macro2 1.0.78",
2567
  "quote 1.0.35",
2568
- "syn 2.0.48",
2569
  ]
2570
 
2571
  [[package]]
@@ -2582,9 +2570,9 @@ checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184"
2582
 
2583
  [[package]]
2584
  name = "pkg-config"
2585
- version = "0.3.28"
2586
  source = "registry+https://github.com/rust-lang/crates.io-index"
2587
- checksum = "69d3587f8a9e599cc7ec2c00e331f71c4e69a5f9a4b8a6efd5b07466b9736f9a"
2588
 
2589
  [[package]]
2590
  name = "poly1305"
@@ -2597,6 +2585,12 @@ dependencies = [
2597
  "universal-hash",
2598
  ]
2599
 
 
 
 
 
 
 
2600
  [[package]]
2601
  name = "powerfmt"
2602
  version = "0.2.0"
@@ -2669,24 +2663,23 @@ dependencies = [
2669
 
2670
  [[package]]
2671
  name = "pulldown-cmark"
2672
- version = "0.9.3"
2673
  source = "registry+https://github.com/rust-lang/crates.io-index"
2674
- checksum = "77a1a2f1f0a7ecff9c31abbe177637be0e97a0aef46cf8738ece09327985d998"
2675
  dependencies = [
2676
- "bitflags 1.3.2",
2677
  "memchr",
2678
  "unicase",
2679
  ]
2680
 
2681
  [[package]]
2682
  name = "quanta"
2683
- version = "0.11.1"
2684
  source = "registry+https://github.com/rust-lang/crates.io-index"
2685
- checksum = "a17e662a7a8291a865152364c20c7abc5e60486ab2001e8ec10b24862de0b9ab"
2686
  dependencies = [
2687
- "crossbeam-utils 0.8.18",
2688
  "libc",
2689
- "mach2",
2690
  "once_cell",
2691
  "raw-cpuid",
2692
  "wasi 0.11.0+wasi-snapshot-preview1",
@@ -2850,11 +2843,11 @@ dependencies = [
2850
 
2851
  [[package]]
2852
  name = "raw-cpuid"
2853
- version = "10.7.0"
2854
  source = "registry+https://github.com/rust-lang/crates.io-index"
2855
- checksum = "6c297679cb867470fa8c9f67dbba74a78d78e3e98d7cf2b08d6d71540f797332"
2856
  dependencies = [
2857
- "bitflags 1.3.2",
2858
  ]
2859
 
2860
  [[package]]
@@ -2882,7 +2875,7 @@ dependencies = [
2882
  "percent-encoding 2.3.1",
2883
  "pin-project-lite",
2884
  "ryu",
2885
- "tokio 1.35.1",
2886
  "tokio-retry",
2887
  "tokio-util",
2888
  "url 2.5.0",
@@ -2905,9 +2898,9 @@ dependencies = [
2905
 
2906
  [[package]]
2907
  name = "regex"
2908
- version = "1.10.2"
2909
  source = "registry+https://github.com/rust-lang/crates.io-index"
2910
- checksum = "380b951a9c5e80ddfd6136919eef32310721aa4aacd4889a8d39124b026ab343"
2911
  dependencies = [
2912
  "aho-corasick 1.1.2",
2913
  "memchr",
@@ -2917,9 +2910,9 @@ dependencies = [
2917
 
2918
  [[package]]
2919
  name = "regex-automata"
2920
- version = "0.4.3"
2921
  source = "registry+https://github.com/rust-lang/crates.io-index"
2922
- checksum = "5f804c7828047e88b2d32e2d7fe5a105da8ee3264f01902f796c8e067dc2483f"
2923
  dependencies = [
2924
  "aho-corasick 1.1.2",
2925
  "memchr",
@@ -2968,18 +2961,18 @@ dependencies = [
2968
 
2969
  [[package]]
2970
  name = "reqwest"
2971
- version = "0.11.24"
2972
  source = "registry+https://github.com/rust-lang/crates.io-index"
2973
- checksum = "c6920094eb85afde5e4a138be3f2de8bbdf28000f0029e72c45025a56b042251"
2974
  dependencies = [
2975
  "async-compression",
2976
- "base64 0.21.5",
2977
  "bytes 1.5.0",
2978
  "encoding_rs",
2979
  "futures-core",
2980
  "futures-util",
2981
- "h2 0.3.22",
2982
- "http 0.2.11",
2983
  "http-body 0.4.6",
2984
  "hyper 0.14.28",
2985
  "hyper-rustls",
@@ -2997,7 +2990,7 @@ dependencies = [
2997
  "serde_urlencoded 0.7.1",
2998
  "sync_wrapper",
2999
  "system-configuration",
3000
- "tokio 1.35.1",
3001
  "tokio-rustls",
3002
  "tokio-util",
3003
  "tower-service",
@@ -3011,16 +3004,17 @@ dependencies = [
3011
 
3012
  [[package]]
3013
  name = "ring"
3014
- version = "0.17.7"
3015
  source = "registry+https://github.com/rust-lang/crates.io-index"
3016
- checksum = "688c63d65483050968b2a8937f7995f443e27041a0f7700aa59b0822aedebb74"
3017
  dependencies = [
3018
  "cc",
 
3019
  "getrandom",
3020
  "libc",
3021
  "spin",
3022
  "untrusted",
3023
- "windows-sys 0.48.0",
3024
  ]
3025
 
3026
  [[package]]
@@ -3050,7 +3044,7 @@ version = "0.4.0"
3050
  source = "registry+https://github.com/rust-lang/crates.io-index"
3051
  checksum = "bfa0f585226d2e68097d4f95d113b15b83a82e819ab25717ec0590d9584ef366"
3052
  dependencies = [
3053
- "semver 1.0.20",
3054
  ]
3055
 
3056
  [[package]]
@@ -3059,7 +3053,7 @@ version = "0.38.31"
3059
  source = "registry+https://github.com/rust-lang/crates.io-index"
3060
  checksum = "6ea3e1a662af26cd7a3ba09c0297a31af215563ecf42817c98df621387f4e949"
3061
  dependencies = [
3062
- "bitflags 2.4.1",
3063
  "errno",
3064
  "libc",
3065
  "linux-raw-sys",
@@ -3084,7 +3078,7 @@ version = "1.0.4"
3084
  source = "registry+https://github.com/rust-lang/crates.io-index"
3085
  checksum = "1c74cae0a4cf6ccbbf5f359f08efdf8ee7e1dc532573bf0db71968cb56b1448c"
3086
  dependencies = [
3087
- "base64 0.21.5",
3088
  ]
3089
 
3090
  [[package]]
@@ -3111,9 +3105,9 @@ dependencies = [
3111
 
3112
  [[package]]
3113
  name = "ryu"
3114
- version = "1.0.16"
3115
  source = "registry+https://github.com/rust-lang/crates.io-index"
3116
- checksum = "f98d2aa92eebf49b69786be48e4477826b256916e84a57ff2a4f21923b48eb4c"
3117
 
3118
  [[package]]
3119
  name = "same-file"
@@ -3145,7 +3139,7 @@ version = "0.18.1"
3145
  source = "registry+https://github.com/rust-lang/crates.io-index"
3146
  checksum = "585480e3719b311b78a573db1c9d9c4c1f8010c2dee4cc59c2efe58ea4dbc3e1"
3147
  dependencies = [
3148
- "ahash 0.8.7",
3149
  "cssparser 0.31.2",
3150
  "ego-tree",
3151
  "html5ever 0.26.0",
@@ -3203,7 +3197,7 @@ version = "0.25.0"
3203
  source = "registry+https://github.com/rust-lang/crates.io-index"
3204
  checksum = "4eb30575f3638fc8f6815f448d50cb1a2e255b0897985c8c59f4d37b72a07b06"
3205
  dependencies = [
3206
- "bitflags 2.4.1",
3207
  "cssparser 0.31.2",
3208
  "derive_more",
3209
  "fxhash",
@@ -3227,9 +3221,9 @@ dependencies = [
3227
 
3228
  [[package]]
3229
  name = "semver"
3230
- version = "1.0.20"
3231
  source = "registry+https://github.com/rust-lang/crates.io-index"
3232
- checksum = "836fa6a3e1e547f9a2c4040802ec865b5d85f4014efe00555d7090a3dcaa1090"
3233
  dependencies = [
3234
  "serde",
3235
  ]
@@ -3242,29 +3236,29 @@ checksum = "388a1df253eca08550bef6c72392cfe7c30914bf41df5269b68cbd6ff8f570a3"
3242
 
3243
  [[package]]
3244
  name = "serde"
3245
- version = "1.0.196"
3246
  source = "registry+https://github.com/rust-lang/crates.io-index"
3247
- checksum = "870026e60fa08c69f064aa766c10f10b1d62db9ccd4d0abb206472bee0ce3b32"
3248
  dependencies = [
3249
  "serde_derive",
3250
  ]
3251
 
3252
  [[package]]
3253
  name = "serde_derive"
3254
- version = "1.0.196"
3255
  source = "registry+https://github.com/rust-lang/crates.io-index"
3256
- checksum = "33c85360c95e7d137454dc81d9a4ed2b8efd8fbe19cee57357b32b9771fccb67"
3257
  dependencies = [
3258
  "proc-macro2 1.0.78",
3259
  "quote 1.0.35",
3260
- "syn 2.0.48",
3261
  ]
3262
 
3263
  [[package]]
3264
  name = "serde_json"
3265
- version = "1.0.109"
3266
  source = "registry+https://github.com/rust-lang/crates.io-index"
3267
- checksum = "cb0652c533506ad7a2e353cce269330d6afd8bdfb6d75e0ace5b35aacbd7b9e9"
3268
  dependencies = [
3269
  "itoa 1.0.10",
3270
  "ryu",
@@ -3380,12 +3374,12 @@ dependencies = [
3380
 
3381
  [[package]]
3382
  name = "socket2"
3383
- version = "0.5.5"
3384
  source = "registry+https://github.com/rust-lang/crates.io-index"
3385
- checksum = "7b5fac59a5cb5dd637972e5fca70daf0523c9067fcdc4842f053dae04a18f8e9"
3386
  dependencies = [
3387
  "libc",
3388
- "windows-sys 0.48.0",
3389
  ]
3390
 
3391
  [[package]]
@@ -3394,6 +3388,15 @@ version = "0.9.8"
3394
  source = "registry+https://github.com/rust-lang/crates.io-index"
3395
  checksum = "6980e8d7511241f8acf4aebddbb1ff938df5eebe98691418c4468d0b72a96a67"
3396
 
 
 
 
 
 
 
 
 
 
3397
  [[package]]
3398
  name = "stable_deref_trait"
3399
  version = "1.2.0"
@@ -3499,9 +3502,9 @@ dependencies = [
3499
 
3500
  [[package]]
3501
  name = "syn"
3502
- version = "2.0.48"
3503
  source = "registry+https://github.com/rust-lang/crates.io-index"
3504
- checksum = "0f3531638e407dfc0814761abb7c00a5b54992b849452a0646b7f65c9f770f3f"
3505
  dependencies = [
3506
  "proc-macro2 1.0.78",
3507
  "quote 1.0.35",
@@ -3526,32 +3529,22 @@ dependencies = [
3526
  "unicode-xid 0.2.4",
3527
  ]
3528
 
3529
- [[package]]
3530
- name = "sys-info"
3531
- version = "0.9.1"
3532
- source = "registry+https://github.com/rust-lang/crates.io-index"
3533
- checksum = "0b3a0d0aba8bf96a0e1ddfdc352fc53b3df7f39318c71854910c3c4b024ae52c"
3534
- dependencies = [
3535
- "cc",
3536
- "libc",
3537
- ]
3538
-
3539
  [[package]]
3540
  name = "system-configuration"
3541
- version = "0.5.1"
3542
  source = "registry+https://github.com/rust-lang/crates.io-index"
3543
- checksum = "ba3a3adc5c275d719af8cb4272ea1c4a6d668a777f37e115f6d11ddbc1c8e0e7"
3544
  dependencies = [
3545
- "bitflags 1.3.2",
3546
  "core-foundation",
3547
  "system-configuration-sys",
3548
  ]
3549
 
3550
  [[package]]
3551
  name = "system-configuration-sys"
3552
- version = "0.5.0"
3553
  source = "registry+https://github.com/rust-lang/crates.io-index"
3554
- checksum = "a75fb188eb626b924683e3b95e3a48e63551fcfb51949de2f06a9d91dbee93c9"
3555
  dependencies = [
3556
  "core-foundation-sys",
3557
  "libc",
@@ -3605,12 +3598,13 @@ dependencies = [
3605
 
3606
  [[package]]
3607
  name = "time"
3608
- version = "0.3.31"
3609
  source = "registry+https://github.com/rust-lang/crates.io-index"
3610
- checksum = "f657ba42c3f86e7680e53c8cd3af8abbe56b5491790b46e22e19c0d57463583e"
3611
  dependencies = [
3612
  "deranged",
3613
  "itoa 1.0.10",
 
3614
  "powerfmt",
3615
  "serde",
3616
  "time-core",
@@ -3625,10 +3619,11 @@ checksum = "ef927ca75afb808a4d64dd374f00a2adf8d0fcff8e7b184af886c3c87ec4a3f3"
3625
 
3626
  [[package]]
3627
  name = "time-macros"
3628
- version = "0.2.16"
3629
  source = "registry+https://github.com/rust-lang/crates.io-index"
3630
- checksum = "26197e33420244aeb70c3e8c78376ca46571bc4e701e4791c2cd9f57dcb3a43f"
3631
  dependencies = [
 
3632
  "time-core",
3633
  ]
3634
 
@@ -3678,14 +3673,14 @@ dependencies = [
3678
 
3679
  [[package]]
3680
  name = "tokio"
3681
- version = "1.35.1"
3682
  source = "registry+https://github.com/rust-lang/crates.io-index"
3683
- checksum = "c89b4efa943be685f629b149f53829423f8f5531ea21249408e8e2f8671ec104"
3684
  dependencies = [
3685
  "backtrace",
3686
  "bytes 1.5.0",
3687
  "libc",
3688
- "mio 0.8.10",
3689
  "num_cpus",
3690
  "parking_lot 0.12.1",
3691
  "pin-project-lite",
@@ -3745,7 +3740,7 @@ checksum = "5b8a1e28f2deaa14e508979454cb3a223b10b938b45af148bc0986de36f1923b"
3745
  dependencies = [
3746
  "proc-macro2 1.0.78",
3747
  "quote 1.0.35",
3748
- "syn 2.0.48",
3749
  ]
3750
 
3751
  [[package]]
@@ -3775,7 +3770,7 @@ checksum = "7f57eb36ecbe0fc510036adff84824dd3c24bb781e21bfa67b69d556aa85214f"
3775
  dependencies = [
3776
  "pin-project",
3777
  "rand 0.8.5",
3778
- "tokio 1.35.1",
3779
  ]
3780
 
3781
  [[package]]
@@ -3785,7 +3780,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
3785
  checksum = "c28327cf380ac148141087fbfb9de9d7bd4e84ab5d2c28fbc911d753de8a7081"
3786
  dependencies = [
3787
  "rustls",
3788
- "tokio 1.35.1",
3789
  ]
3790
 
3791
  [[package]]
@@ -3851,7 +3846,7 @@ dependencies = [
3851
  "futures-core",
3852
  "futures-sink",
3853
  "pin-project-lite",
3854
- "tokio 1.35.1",
3855
  "tracing",
3856
  ]
3857
 
@@ -3928,9 +3923,9 @@ dependencies = [
3928
 
3929
  [[package]]
3930
  name = "unicode-bidi"
3931
- version = "0.3.14"
3932
  source = "registry+https://github.com/rust-lang/crates.io-index"
3933
- checksum = "6f2528f27a9eb2b21e69c95319b30bd0efd85d09c379741b0f78ea1d86be2416"
3934
 
3935
  [[package]]
3936
  name = "unicode-ident"
@@ -3940,9 +3935,9 @@ checksum = "3354b9ac3fae1ff6755cb6db53683adb661634f67557942dea4facebec0fee4b"
3940
 
3941
  [[package]]
3942
  name = "unicode-normalization"
3943
- version = "0.1.22"
3944
  source = "registry+https://github.com/rust-lang/crates.io-index"
3945
- checksum = "5c5713f0fc4b5db668a2ac63cdb7bb4469d8c9fed047b1d0292cc7b0ce2ba921"
3946
  dependencies = [
3947
  "tinyvec",
3948
  ]
@@ -4038,9 +4033,9 @@ checksum = "49874b5167b65d7193b8aba1567f5c7d93d001cafc34600cee003eda787e483f"
4038
 
4039
  [[package]]
4040
  name = "walkdir"
4041
- version = "2.4.0"
4042
  source = "registry+https://github.com/rust-lang/crates.io-index"
4043
- checksum = "d71d857dc86794ca4c280d616f7da00d2dbfd8cd788846559a6813e6aa4b54ee"
4044
  dependencies = [
4045
  "same-file",
4046
  "winapi-util",
@@ -4080,9 +4075,9 @@ checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423"
4080
 
4081
  [[package]]
4082
  name = "wasm-bindgen"
4083
- version = "0.2.89"
4084
  source = "registry+https://github.com/rust-lang/crates.io-index"
4085
- checksum = "0ed0d4f68a3015cc185aff4db9506a015f4b96f95303897bfa23f846db54064e"
4086
  dependencies = [
4087
  "cfg-if 1.0.0",
4088
  "wasm-bindgen-macro",
@@ -4090,24 +4085,24 @@ dependencies = [
4090
 
4091
  [[package]]
4092
  name = "wasm-bindgen-backend"
4093
- version = "0.2.89"
4094
  source = "registry+https://github.com/rust-lang/crates.io-index"
4095
- checksum = "1b56f625e64f3a1084ded111c4d5f477df9f8c92df113852fa5a374dbda78826"
4096
  dependencies = [
4097
  "bumpalo",
4098
  "log",
4099
  "once_cell",
4100
  "proc-macro2 1.0.78",
4101
  "quote 1.0.35",
4102
- "syn 2.0.48",
4103
  "wasm-bindgen-shared",
4104
  ]
4105
 
4106
  [[package]]
4107
  name = "wasm-bindgen-futures"
4108
- version = "0.4.39"
4109
  source = "registry+https://github.com/rust-lang/crates.io-index"
4110
- checksum = "ac36a15a220124ac510204aec1c3e5db8a22ab06fd6706d881dc6149f8ed9a12"
4111
  dependencies = [
4112
  "cfg-if 1.0.0",
4113
  "js-sys",
@@ -4117,9 +4112,9 @@ dependencies = [
4117
 
4118
  [[package]]
4119
  name = "wasm-bindgen-macro"
4120
- version = "0.2.89"
4121
  source = "registry+https://github.com/rust-lang/crates.io-index"
4122
- checksum = "0162dbf37223cd2afce98f3d0785506dcb8d266223983e4b5b525859e6e182b2"
4123
  dependencies = [
4124
  "quote 1.0.35",
4125
  "wasm-bindgen-macro-support",
@@ -4127,28 +4122,28 @@ dependencies = [
4127
 
4128
  [[package]]
4129
  name = "wasm-bindgen-macro-support"
4130
- version = "0.2.89"
4131
  source = "registry+https://github.com/rust-lang/crates.io-index"
4132
- checksum = "f0eb82fcb7930ae6219a7ecfd55b217f5f0893484b7a13022ebb2b2bf20b5283"
4133
  dependencies = [
4134
  "proc-macro2 1.0.78",
4135
  "quote 1.0.35",
4136
- "syn 2.0.48",
4137
  "wasm-bindgen-backend",
4138
  "wasm-bindgen-shared",
4139
  ]
4140
 
4141
  [[package]]
4142
  name = "wasm-bindgen-shared"
4143
- version = "0.2.89"
4144
  source = "registry+https://github.com/rust-lang/crates.io-index"
4145
- checksum = "7ab9b36309365056cd639da3134bf87fa8f3d86008abf99e612384a6eecd459f"
4146
 
4147
  [[package]]
4148
  name = "web-sys"
4149
- version = "0.3.66"
4150
  source = "registry+https://github.com/rust-lang/crates.io-index"
4151
- checksum = "50c24a44ec86bb68fbecd1b3efed7e85ea5621b39b35ef2766b66cd984f8010f"
4152
  dependencies = [
4153
  "js-sys",
4154
  "wasm-bindgen",
@@ -4156,23 +4151,23 @@ dependencies = [
4156
 
4157
  [[package]]
4158
  name = "webpki-roots"
4159
- version = "0.25.3"
4160
  source = "registry+https://github.com/rust-lang/crates.io-index"
4161
- checksum = "1778a42e8b3b90bff8d0f5032bf22250792889a5cdc752aa0020c84abe3aaf10"
4162
 
4163
  [[package]]
4164
  name = "websurfx"
4165
- version = "1.9.20"
4166
  dependencies = [
4167
  "actix-cors",
4168
  "actix-files",
4169
  "actix-governor",
4170
  "actix-web",
 
4171
  "async-once-cell",
4172
  "async-trait",
4173
- "base64 0.21.5",
4174
  "blake3",
4175
- "brotli",
4176
  "cfg-if 1.0.0",
4177
  "chacha20",
4178
  "chacha20poly1305",
@@ -4191,27 +4186,27 @@ dependencies = [
4191
  "mlua",
4192
  "redis",
4193
  "regex",
4194
- "reqwest 0.11.24",
4195
  "rusty-hook",
4196
  "scraper",
4197
  "serde",
4198
  "serde_json",
4199
  "smallvec 1.13.1",
4200
  "tempfile",
4201
- "tokio 1.35.1",
4202
  ]
4203
 
4204
  [[package]]
4205
  name = "which"
4206
- version = "5.0.0"
4207
  source = "registry+https://github.com/rust-lang/crates.io-index"
4208
- checksum = "9bf3ea8596f3a0dd5980b46430f2058dfe2c36a27ccfbb1845d6fbfcd9ba6e14"
4209
  dependencies = [
4210
  "either",
4211
  "home",
4212
  "once_cell",
4213
  "rustix",
4214
- "windows-sys 0.48.0",
4215
  ]
4216
 
4217
  [[package]]
@@ -4272,7 +4267,7 @@ version = "0.52.0"
4272
  source = "registry+https://github.com/rust-lang/crates.io-index"
4273
  checksum = "282be5f36a8ce781fad8c8ae18fa3f9beff57ec1b52cb3de0789201425d9a33d"
4274
  dependencies = [
4275
- "windows-targets 0.52.0",
4276
  ]
4277
 
4278
  [[package]]
@@ -4292,17 +4287,17 @@ dependencies = [
4292
 
4293
  [[package]]
4294
  name = "windows-targets"
4295
- version = "0.52.0"
4296
  source = "registry+https://github.com/rust-lang/crates.io-index"
4297
- checksum = "8a18201040b24831fbb9e4eb208f8892e1f50a37feb53cc7ff887feb8f50e7cd"
4298
  dependencies = [
4299
- "windows_aarch64_gnullvm 0.52.0",
4300
- "windows_aarch64_msvc 0.52.0",
4301
- "windows_i686_gnu 0.52.0",
4302
- "windows_i686_msvc 0.52.0",
4303
- "windows_x86_64_gnu 0.52.0",
4304
- "windows_x86_64_gnullvm 0.52.0",
4305
- "windows_x86_64_msvc 0.52.0",
4306
  ]
4307
 
4308
  [[package]]
@@ -4313,9 +4308,9 @@ checksum = "2b38e32f0abccf9987a4e3079dfb67dcd799fb61361e53e2882c3cbaf0d905d8"
4313
 
4314
  [[package]]
4315
  name = "windows_aarch64_gnullvm"
4316
- version = "0.52.0"
4317
  source = "registry+https://github.com/rust-lang/crates.io-index"
4318
- checksum = "cb7764e35d4db8a7921e09562a0304bf2f93e0a51bfccee0bd0bb0b666b015ea"
4319
 
4320
  [[package]]
4321
  name = "windows_aarch64_msvc"
@@ -4325,9 +4320,9 @@ checksum = "dc35310971f3b2dbbf3f0690a219f40e2d9afcf64f9ab7cc1be722937c26b4bc"
4325
 
4326
  [[package]]
4327
  name = "windows_aarch64_msvc"
4328
- version = "0.52.0"
4329
  source = "registry+https://github.com/rust-lang/crates.io-index"
4330
- checksum = "bbaa0368d4f1d2aaefc55b6fcfee13f41544ddf36801e793edbbfd7d7df075ef"
4331
 
4332
  [[package]]
4333
  name = "windows_i686_gnu"
@@ -4337,9 +4332,9 @@ checksum = "a75915e7def60c94dcef72200b9a8e58e5091744960da64ec734a6c6e9b3743e"
4337
 
4338
  [[package]]
4339
  name = "windows_i686_gnu"
4340
- version = "0.52.0"
4341
  source = "registry+https://github.com/rust-lang/crates.io-index"
4342
- checksum = "a28637cb1fa3560a16915793afb20081aba2c92ee8af57b4d5f28e4b3e7df313"
4343
 
4344
  [[package]]
4345
  name = "windows_i686_msvc"
@@ -4349,9 +4344,9 @@ checksum = "8f55c233f70c4b27f66c523580f78f1004e8b5a8b659e05a4eb49d4166cca406"
4349
 
4350
  [[package]]
4351
  name = "windows_i686_msvc"
4352
- version = "0.52.0"
4353
  source = "registry+https://github.com/rust-lang/crates.io-index"
4354
- checksum = "ffe5e8e31046ce6230cc7215707b816e339ff4d4d67c65dffa206fd0f7aa7b9a"
4355
 
4356
  [[package]]
4357
  name = "windows_x86_64_gnu"
@@ -4361,9 +4356,9 @@ checksum = "53d40abd2583d23e4718fddf1ebec84dbff8381c07cae67ff7768bbf19c6718e"
4361
 
4362
  [[package]]
4363
  name = "windows_x86_64_gnu"
4364
- version = "0.52.0"
4365
  source = "registry+https://github.com/rust-lang/crates.io-index"
4366
- checksum = "3d6fa32db2bc4a2f5abeacf2b69f7992cd09dca97498da74a151a3132c26befd"
4367
 
4368
  [[package]]
4369
  name = "windows_x86_64_gnullvm"
@@ -4373,9 +4368,9 @@ checksum = "0b7b52767868a23d5bab768e390dc5f5c55825b6d30b86c844ff2dc7414044cc"
4373
 
4374
  [[package]]
4375
  name = "windows_x86_64_gnullvm"
4376
- version = "0.52.0"
4377
  source = "registry+https://github.com/rust-lang/crates.io-index"
4378
- checksum = "1a657e1e9d3f514745a572a6846d3c7aa7dbe1658c056ed9c3344c4109a6949e"
4379
 
4380
  [[package]]
4381
  name = "windows_x86_64_msvc"
@@ -4385,9 +4380,9 @@ checksum = "ed94fce61571a4006852b7389a063ab983c02eb1bb37b47f8272ce92d06d9538"
4385
 
4386
  [[package]]
4387
  name = "windows_x86_64_msvc"
4388
- version = "0.52.0"
4389
  source = "registry+https://github.com/rust-lang/crates.io-index"
4390
- checksum = "dff9641d1cd4be8d1a070daf9e3773c5f67e78b4d9d42263020c057706765c04"
4391
 
4392
  [[package]]
4393
  name = "winreg"
@@ -4435,7 +4430,7 @@ checksum = "9ce1b18ccd8e73a9321186f97e46f9f04b778851177567b1975109d26a08d2a6"
4435
  dependencies = [
4436
  "proc-macro2 1.0.78",
4437
  "quote 1.0.35",
4438
- "syn 2.0.48",
4439
  ]
4440
 
4441
  [[package]]
 
4
 
5
  [[package]]
6
  name = "actix-codec"
7
+ version = "0.5.2"
8
  source = "registry+https://github.com/rust-lang/crates.io-index"
9
+ checksum = "5f7b0a21988c1bf877cf4759ef5ddaac04c1c9fe808c9142ecb78ba97d97a28a"
10
  dependencies = [
11
+ "bitflags 2.4.2",
12
  "bytes 1.5.0",
13
  "futures-core",
14
  "futures-sink",
15
  "memchr",
16
  "pin-project-lite",
17
+ "tokio 1.36.0",
18
  "tokio-util",
19
  "tracing",
20
  ]
 
44
  "actix-service",
45
  "actix-utils",
46
  "actix-web",
47
+ "bitflags 2.4.2",
48
  "bytes 1.5.0",
49
  "derive_more",
50
  "futures-core",
 
71
 
72
  [[package]]
73
  name = "actix-http"
74
+ version = "3.6.0"
75
  source = "registry+https://github.com/rust-lang/crates.io-index"
76
+ checksum = "d223b13fd481fc0d1f83bb12659ae774d9e3601814c68a0bc539731698cca743"
77
  dependencies = [
78
  "actix-codec",
79
  "actix-rt",
80
  "actix-service",
81
  "actix-utils",
82
+ "ahash",
83
+ "base64 0.21.7",
84
+ "bitflags 2.4.2",
85
  "brotli",
86
  "bytes 1.5.0",
87
  "bytestring",
88
  "derive_more",
89
  "encoding_rs",
90
  "futures-core",
91
+ "http 0.2.12",
92
  "httparse",
93
  "httpdate",
94
  "itoa 1.0.10",
 
100
  "rand 0.8.5",
101
  "sha1",
102
  "smallvec 1.13.1",
103
+ "tokio 1.36.0",
104
  "tokio-util",
105
  "tracing",
106
  ]
 
112
  checksum = "e01ed3140b2f8d422c68afa1ed2e85d996ea619c988ac834d255db32138655cb"
113
  dependencies = [
114
  "quote 1.0.35",
115
+ "syn 2.0.52",
116
  ]
117
 
118
  [[package]]
 
122
  checksum = "d22475596539443685426b6bdadb926ad0ecaefdfc5fb05e5e3441f15463c511"
123
  dependencies = [
124
  "bytestring",
125
+ "http 0.2.12",
126
  "regex",
127
  "serde",
128
  "tracing",
 
135
  checksum = "28f32d40287d3f402ae0028a9d54bef51af15c8769492826a69d28f81893151d"
136
  dependencies = [
137
  "futures-core",
138
+ "tokio 1.36.0",
139
  ]
140
 
141
  [[package]]
 
149
  "actix-utils",
150
  "futures-core",
151
  "futures-util",
152
+ "mio 0.8.11",
153
  "socket2",
154
+ "tokio 1.36.0",
155
  "tracing",
156
  ]
157
 
 
178
 
179
  [[package]]
180
  name = "actix-web"
181
+ version = "4.5.1"
182
  source = "registry+https://github.com/rust-lang/crates.io-index"
183
+ checksum = "43a6556ddebb638c2358714d853257ed226ece6023ef9364f23f0c70737ea984"
184
  dependencies = [
185
  "actix-codec",
186
  "actix-http",
 
191
  "actix-service",
192
  "actix-utils",
193
  "actix-web-codegen",
194
+ "ahash",
195
  "bytes 1.5.0",
196
  "bytestring",
197
  "cfg-if 1.0.0",
 
212
  "serde_urlencoded 0.7.1",
213
  "smallvec 1.13.1",
214
  "socket2",
215
+ "time 0.3.34",
216
  "url 2.5.0",
217
  ]
218
 
 
225
  "actix-router",
226
  "proc-macro2 1.0.78",
227
  "quote 1.0.35",
228
+ "syn 2.0.52",
229
  ]
230
 
231
  [[package]]
 
255
 
256
  [[package]]
257
  name = "ahash"
258
+ version = "0.8.11"
 
 
 
 
 
 
 
 
 
 
 
259
  source = "registry+https://github.com/rust-lang/crates.io-index"
260
+ checksum = "e89da841a80418a9b391ebaea17f5c112ffaaa96f621d2c285b5174da76b9011"
261
  dependencies = [
262
  "cfg-if 1.0.0",
263
  "getrandom",
 
307
 
308
  [[package]]
309
  name = "anstyle"
310
+ version = "1.0.6"
311
  source = "registry+https://github.com/rust-lang/crates.io-index"
312
+ checksum = "8901269c6307e8d93993578286ac0edf7f195079ffff5ebdeea6a59ffb7e36bc"
313
 
314
  [[package]]
315
  name = "anyhow"
316
+ version = "1.0.80"
317
  source = "registry+https://github.com/rust-lang/crates.io-index"
318
+ checksum = "5ad32ce52e4161730f7098c077cd2ed6229b5804ccf99e5366be1ab72a98b4e1"
319
 
320
  [[package]]
321
  name = "arc-swap"
322
+ version = "1.7.0"
323
  source = "registry+https://github.com/rust-lang/crates.io-index"
324
+ checksum = "7b3d0060af21e8d11a926981cc00c6c1541aa91dd64b9f881985c3da1094425f"
325
 
326
  [[package]]
327
  name = "arrayref"
 
337
 
338
  [[package]]
339
  name = "async-compression"
340
+ version = "0.4.6"
341
  source = "registry+https://github.com/rust-lang/crates.io-index"
342
+ checksum = "a116f46a969224200a0a97f29cfd4c50e7534e4b4826bd23ea2c3c533039c82c"
343
  dependencies = [
344
  "brotli",
345
  "flate2",
346
  "futures-core",
347
  "memchr",
348
  "pin-project-lite",
349
+ "tokio 1.36.0",
350
  ]
351
 
352
  [[package]]
 
357
 
358
  [[package]]
359
  name = "async-trait"
360
+ version = "0.1.77"
361
  source = "registry+https://github.com/rust-lang/crates.io-index"
362
+ checksum = "c980ee35e870bd1a4d2c8294d4c04d0499e67bca1e4b5cefcc693c2fa00caea9"
363
  dependencies = [
364
  "proc-macro2 1.0.78",
365
  "quote 1.0.35",
366
+ "syn 2.0.52",
367
  ]
368
 
369
  [[package]]
 
407
 
408
  [[package]]
409
  name = "base64"
410
+ version = "0.21.7"
411
  source = "registry+https://github.com/rust-lang/crates.io-index"
412
+ checksum = "9d297deb1925b89f2ccc13d7635fa0714f12c87adce1c75356b39ca9b7178567"
413
 
414
  [[package]]
415
  name = "bit-set"
 
434
 
435
  [[package]]
436
  name = "bitflags"
437
+ version = "2.4.2"
438
  source = "registry+https://github.com/rust-lang/crates.io-index"
439
+ checksum = "ed570934406eb16438a4e976b1b4500774099c13b8cb96eec99f620f05090ddf"
440
 
441
  [[package]]
442
  name = "blake3"
 
483
 
484
  [[package]]
485
  name = "bstr"
486
+ version = "1.9.1"
487
  source = "registry+https://github.com/rust-lang/crates.io-index"
488
+ checksum = "05efc5cfd9110c8416e471df0e96702d58690178e206e61b7173706673c93706"
489
  dependencies = [
490
  "memchr",
491
  "serde",
 
493
 
494
  [[package]]
495
  name = "bumpalo"
496
+ version = "3.15.4"
497
  source = "registry+https://github.com/rust-lang/crates.io-index"
498
+ checksum = "7ff69b9dd49fd426c69a0db9fc04dd934cdb6645ff000864d98f7e2af8830eaa"
499
 
500
  [[package]]
501
  name = "bytecount"
 
546
 
547
  [[package]]
548
  name = "cargo-platform"
549
+ version = "0.1.7"
550
  source = "registry+https://github.com/rust-lang/crates.io-index"
551
+ checksum = "694c8807f2ae16faecc43dc17d74b3eb042482789fd0eb64b39a2e04e087053f"
552
  dependencies = [
553
  "serde",
554
  ]
 
561
  dependencies = [
562
  "camino",
563
  "cargo-platform",
564
+ "semver 1.0.22",
565
  "serde",
566
  "serde_json",
567
  ]
 
574
 
575
  [[package]]
576
  name = "cc"
577
+ version = "1.0.90"
578
  source = "registry+https://github.com/rust-lang/crates.io-index"
579
+ checksum = "8cd6604a82acf3039f1144f54b8eb34e91ffba622051189e71b781822d5ee1f5"
 
 
 
580
 
581
  [[package]]
582
  name = "cfg-if"
 
625
 
626
  [[package]]
627
  name = "ciborium"
628
+ version = "0.2.2"
629
  source = "registry+https://github.com/rust-lang/crates.io-index"
630
+ checksum = "42e69ffd6f0917f5c029256a24d0161db17cea3997d185db0d35926308770f0e"
631
  dependencies = [
632
  "ciborium-io",
633
  "ciborium-ll",
 
636
 
637
  [[package]]
638
  name = "ciborium-io"
639
+ version = "0.2.2"
640
  source = "registry+https://github.com/rust-lang/crates.io-index"
641
+ checksum = "05afea1e0a06c9be33d539b876f1ce3692f4afea2cb41f740e7743225ed1c757"
642
 
643
  [[package]]
644
  name = "ciborium-ll"
645
+ version = "0.2.2"
646
  source = "registry+https://github.com/rust-lang/crates.io-index"
647
+ checksum = "57663b653d948a338bfb3eeba9bb2fd5fcfaecb9e199e87e1eda4d9e8b240fd9"
648
  dependencies = [
649
  "ciborium-io",
650
  "half",
 
663
 
664
  [[package]]
665
  name = "clap"
666
+ version = "4.5.2"
667
  source = "registry+https://github.com/rust-lang/crates.io-index"
668
+ checksum = "b230ab84b0ffdf890d5a10abdbc8b83ae1c4918275daea1ab8801f71536b2651"
669
  dependencies = [
670
  "clap_builder",
671
  ]
672
 
673
  [[package]]
674
  name = "clap_builder"
675
+ version = "4.5.2"
676
  source = "registry+https://github.com/rust-lang/crates.io-index"
677
+ checksum = "ae129e2e766ae0ec03484e609954119f123cc1fe650337e155d03b022f24f7b4"
678
  dependencies = [
679
  "anstyle",
680
  "clap_lex",
 
682
 
683
  [[package]]
684
  name = "clap_lex"
685
+ version = "0.7.0"
686
  source = "registry+https://github.com/rust-lang/crates.io-index"
687
+ checksum = "98cc8fbded0c607b7ba9dd60cd98df59af97e84d24e49c8557331cfc26d301ce"
688
 
689
  [[package]]
690
  name = "cloudabi"
 
705
  "futures-core",
706
  "memchr",
707
  "pin-project-lite",
708
+ "tokio 1.36.0",
709
  "tokio-util",
710
  ]
711
 
 
758
  checksum = "e859cd57d0710d9e06c381b550c06e76992472a8c6d527aecd2fc673dcc231fb"
759
  dependencies = [
760
  "percent-encoding 2.3.1",
761
+ "time 0.3.34",
762
  "version_check",
763
  ]
764
 
 
798
 
799
  [[package]]
800
  name = "cpufeatures"
801
+ version = "0.2.12"
802
  source = "registry+https://github.com/rust-lang/crates.io-index"
803
+ checksum = "53fe5e26ff1b7aef8bca9c6080520cfb8d9333c7568e1829cef191a9723e5504"
804
  dependencies = [
805
  "libc",
806
  ]
807
 
808
  [[package]]
809
  name = "crc32fast"
810
+ version = "1.4.0"
811
  source = "registry+https://github.com/rust-lang/crates.io-index"
812
+ checksum = "b3855a8a784b474f333699ef2bbca9db2c4a1f6d9088a90a2d25b1eb53111eaa"
813
  dependencies = [
814
  "cfg-if 1.0.0",
815
  ]
 
850
 
851
  [[package]]
852
  name = "crossbeam-channel"
853
+ version = "0.5.12"
854
  source = "registry+https://github.com/rust-lang/crates.io-index"
855
+ checksum = "ab3db02a9c5b5121e1e42fbdb1aeb65f5e02624cc58c43f2884c6ccac0b82f95"
856
  dependencies = [
857
+ "crossbeam-utils 0.8.19",
 
858
  ]
859
 
860
  [[package]]
 
907
 
908
  [[package]]
909
  name = "crossbeam-utils"
910
+ version = "0.8.19"
911
  source = "registry+https://github.com/rust-lang/crates.io-index"
912
+ checksum = "248e3bacc7dc6baa3b21e405ee045c3047101a49145e7e9eca583ab4c2ca5345"
913
+
914
+ [[package]]
915
+ name = "crunchy"
916
+ version = "0.2.2"
917
+ source = "registry+https://github.com/rust-lang/crates.io-index"
918
+ checksum = "7a81dae078cea95a014a339291cec439d2f232ebe854a9d672b796c6afafa9b7"
919
 
920
  [[package]]
921
  name = "crypto-common"
 
970
  checksum = "13b588ba4ac1a99f7f2964d24b3d896ddc6bf847ee3855dbd4366f058cfcd331"
971
  dependencies = [
972
  "quote 1.0.35",
973
+ "syn 2.0.52",
974
  ]
975
 
976
  [[package]]
 
994
 
995
  [[package]]
996
  name = "deranged"
997
+ version = "0.3.11"
998
  source = "registry+https://github.com/rust-lang/crates.io-index"
999
+ checksum = "b42b6fa04a440b495c8b04d0e71b707c585f83cb9cb28cf8cd0d976c315e31b4"
1000
  dependencies = [
1001
  "powerfmt",
1002
  ]
 
1069
 
1070
  [[package]]
1071
  name = "either"
1072
+ version = "1.10.0"
1073
  source = "registry+https://github.com/rust-lang/crates.io-index"
1074
+ checksum = "11157ac094ffbdde99aa67b23417ebdd801842852b500e395a45a9c0aac03e4a"
1075
 
1076
  [[package]]
1077
  name = "encoding_rs"
 
1093
 
1094
  [[package]]
1095
  name = "env_logger"
1096
+ version = "0.11.3"
1097
  source = "registry+https://github.com/rust-lang/crates.io-index"
1098
+ checksum = "38b35839ba51819680ba087cd351788c9a3c476841207e0b8cee0b04722343b9"
1099
  dependencies = [
1100
  "env_filter",
1101
  "log",
 
1335
  dependencies = [
1336
  "proc-macro2 1.0.78",
1337
  "quote 1.0.35",
1338
+ "syn 2.0.52",
1339
  ]
1340
 
1341
  [[package]]
 
1352
 
1353
  [[package]]
1354
  name = "futures-timer"
1355
+ version = "3.0.3"
1356
  source = "registry+https://github.com/rust-lang/crates.io-index"
1357
+ checksum = "f288b0a4f20f9a56b5d1da57e2227c661b7b16168e2f72365f57b63326e29b24"
1358
 
1359
  [[package]]
1360
  name = "futures-util"
 
1404
 
1405
  [[package]]
1406
  name = "getrandom"
1407
+ version = "0.2.12"
1408
  source = "registry+https://github.com/rust-lang/crates.io-index"
1409
+ checksum = "190092ea657667030ac6a35e305e62fc4dd69fd98ac98631e5d3a2b1575a12b5"
1410
  dependencies = [
1411
  "cfg-if 1.0.0",
1412
  "libc",
 
1427
 
1428
  [[package]]
1429
  name = "governor"
1430
+ version = "0.6.3"
1431
  source = "registry+https://github.com/rust-lang/crates.io-index"
1432
+ checksum = "68a7f542ee6b35af73b06abc0dad1c1bae89964e4e253bc4b587b91c9637867b"
1433
  dependencies = [
1434
  "cfg-if 1.0.0",
1435
  "dashmap",
 
1438
  "no-std-compat",
1439
  "nonzero_ext",
1440
  "parking_lot 0.12.1",
1441
+ "portable-atomic",
1442
  "quanta",
1443
  "rand 0.8.5",
1444
  "smallvec 1.13.1",
1445
+ "spinning_top",
1446
  ]
1447
 
1448
  [[package]]
 
1465
 
1466
  [[package]]
1467
  name = "h2"
1468
+ version = "0.3.24"
1469
  source = "registry+https://github.com/rust-lang/crates.io-index"
1470
+ checksum = "bb2c4422095b67ee78da96fbb51a4cc413b3b25883c7717ff7ca1ab31022c9c9"
1471
  dependencies = [
1472
  "bytes 1.5.0",
1473
  "fnv",
1474
  "futures-core",
1475
  "futures-sink",
1476
  "futures-util",
1477
+ "http 0.2.12",
1478
+ "indexmap 2.2.5",
1479
  "slab",
1480
+ "tokio 1.36.0",
1481
  "tokio-util",
1482
  "tracing",
1483
  ]
1484
 
1485
  [[package]]
1486
  name = "half"
1487
+ version = "2.4.0"
1488
  source = "registry+https://github.com/rust-lang/crates.io-index"
1489
+ checksum = "b5eceaaeec696539ddaf7b333340f1af35a5aa87ae3e4f3ead0532f72affab2e"
1490
+ dependencies = [
1491
+ "cfg-if 1.0.0",
1492
+ "crunchy",
1493
+ ]
1494
 
1495
  [[package]]
1496
  name = "hashbrown"
 
1504
  source = "registry+https://github.com/rust-lang/crates.io-index"
1505
  checksum = "43a3c133739dddd0d2990f9a4bdf8eb4b21ef50e4851ca85ab661199821d510e"
1506
  dependencies = [
1507
+ "ahash",
1508
  "bumpalo",
1509
  ]
1510
 
 
1516
 
1517
  [[package]]
1518
  name = "hermit-abi"
1519
+ version = "0.3.9"
1520
  source = "registry+https://github.com/rust-lang/crates.io-index"
1521
+ checksum = "d231dfb89cfffdbc30e7fc41579ed6066ad03abda9e567ccafae602b97ec5024"
1522
 
1523
  [[package]]
1524
  name = "home"
 
1570
 
1571
  [[package]]
1572
  name = "http"
1573
+ version = "0.2.12"
1574
  source = "registry+https://github.com/rust-lang/crates.io-index"
1575
+ checksum = "601cbb57e577e2f5ef5be8e7b83f0f63994f25aa94d673e54a92d5c516d101f1"
1576
  dependencies = [
1577
  "bytes 1.5.0",
1578
  "fnv",
 
1598
  checksum = "7ceab25649e9960c0311ea418d17bee82c0dcec1bd053b5f9a66e265a693bed2"
1599
  dependencies = [
1600
  "bytes 1.5.0",
1601
+ "http 0.2.12",
1602
  "pin-project-lite",
1603
  ]
1604
 
 
1660
  "futures-channel",
1661
  "futures-core",
1662
  "futures-util",
1663
+ "h2 0.3.24",
1664
+ "http 0.2.12",
1665
  "http-body 0.4.6",
1666
  "httparse",
1667
  "httpdate",
1668
  "itoa 1.0.10",
1669
  "pin-project-lite",
1670
  "socket2",
1671
+ "tokio 1.36.0",
1672
  "tower-service",
1673
  "tracing",
1674
  "want 0.3.1",
 
1681
  checksum = "ec3efd23720e2049821a693cbc7e65ea87c72f1c58ff2f9522ff332b1491e590"
1682
  dependencies = [
1683
  "futures-util",
1684
+ "http 0.2.12",
1685
  "hyper 0.14.28",
1686
  "rustls",
1687
+ "tokio 1.36.0",
1688
  "tokio-rustls",
1689
  ]
1690
 
 
1745
 
1746
  [[package]]
1747
  name = "indexmap"
1748
+ version = "2.2.5"
1749
  source = "registry+https://github.com/rust-lang/crates.io-index"
1750
+ checksum = "7b0b929d511467233429c45a44ac1dcaa21ba0f5ba11e4879e6ed28ddb4f9df4"
1751
  dependencies = [
1752
  "equivalent",
1753
  "hashbrown 0.14.3",
 
1779
 
1780
  [[package]]
1781
  name = "is-terminal"
1782
+ version = "0.4.12"
1783
  source = "registry+https://github.com/rust-lang/crates.io-index"
1784
+ checksum = "f23ff5ef2b80d608d61efee834934d862cd92461afc0560dedf493e4c033738b"
1785
  dependencies = [
1786
  "hermit-abi",
1787
+ "libc",
1788
  "windows-sys 0.52.0",
1789
  ]
1790
 
 
1811
 
1812
  [[package]]
1813
  name = "js-sys"
1814
+ version = "0.3.69"
1815
  source = "registry+https://github.com/rust-lang/crates.io-index"
1816
+ checksum = "29c15563dc2726973df627357ce0c9ddddbea194836909d655df6a75d2cf296d"
1817
  dependencies = [
1818
  "wasm-bindgen",
1819
  ]
 
1858
 
1859
  [[package]]
1860
  name = "lightningcss"
1861
+ version = "1.0.0-alpha.54"
1862
  source = "registry+https://github.com/rust-lang/crates.io-index"
1863
+ checksum = "07d306844e5af1753490c420c0d6ae3d814b00725092d106332762827ca8f0fe"
1864
  dependencies = [
1865
+ "ahash",
1866
+ "bitflags 2.4.2",
1867
  "const-str",
1868
  "cssparser 0.33.0",
1869
  "cssparser-color",
1870
  "data-encoding",
1871
+ "getrandom",
1872
  "itertools",
1873
  "lazy_static",
1874
  "parcel_selectors",
 
1879
 
1880
  [[package]]
1881
  name = "linux-raw-sys"
1882
+ version = "0.4.13"
1883
  source = "registry+https://github.com/rust-lang/crates.io-index"
1884
+ checksum = "01cda141df6706de531b6c46c3a33ecca755538219bd484262fa09410c13539c"
1885
 
1886
  [[package]]
1887
  name = "local-channel"
 
1936
 
1937
  [[package]]
1938
  name = "luajit-src"
1939
+ version = "210.5.6+9cc2e42"
1940
  source = "registry+https://github.com/rust-lang/crates.io-index"
1941
+ checksum = "23b365d859c9ffc187f48bb3e25ec80c3b40cf3f68f53544f4adeaee70554157"
1942
  dependencies = [
1943
  "cc",
1944
  "which",
 
1950
  source = "registry+https://github.com/rust-lang/crates.io-index"
1951
  checksum = "c41e0c4fef86961ac6d6f8a82609f55f31b05e4fce149ac5710e439df7619ba4"
1952
 
 
 
 
 
 
 
 
 
 
1953
  [[package]]
1954
  name = "markup5ever"
1955
  version = "0.8.1"
 
2059
 
2060
  [[package]]
2061
  name = "mini-moka"
2062
+ version = "0.10.3"
2063
  source = "registry+https://github.com/rust-lang/crates.io-index"
2064
+ checksum = "c325dfab65f261f386debee8b0969da215b3fa0037e74c8a1234db7ba986d803"
2065
  dependencies = [
2066
  "crossbeam-channel",
2067
+ "crossbeam-utils 0.8.19",
2068
  "dashmap",
2069
  "skeptic",
2070
  "smallvec 1.13.1",
 
2085
 
2086
  [[package]]
2087
  name = "miniz_oxide"
2088
+ version = "0.7.2"
2089
  source = "registry+https://github.com/rust-lang/crates.io-index"
2090
+ checksum = "9d811f3e15f28568be3407c8e7fdb6514c1cda3cb30683f15b6a1a1dc4ea14a7"
2091
  dependencies = [
2092
  "adler",
2093
  ]
2094
 
2095
  [[package]]
2096
  name = "mintex"
2097
+ version = "0.1.3"
2098
  source = "registry+https://github.com/rust-lang/crates.io-index"
2099
+ checksum = "9bec4598fddb13cc7b528819e697852653252b760f1228b7642679bf2ff2cd07"
 
 
 
 
2100
 
2101
  [[package]]
2102
  name = "mio"
 
2119
 
2120
  [[package]]
2121
  name = "mio"
2122
+ version = "0.8.11"
2123
  source = "registry+https://github.com/rust-lang/crates.io-index"
2124
+ checksum = "a4a650543ca06a924e8b371db273b2756685faae30f8487da1b56505a8f78b0c"
2125
  dependencies = [
2126
  "libc",
2127
  "log",
 
2143
 
2144
  [[package]]
2145
  name = "mlua"
2146
+ version = "0.9.6"
2147
  source = "registry+https://github.com/rust-lang/crates.io-index"
2148
+ checksum = "868d02cb5eb97761bbf6bd6922c1c7a88b8ea252bbf43bd8350a0bf8497a1fc0"
2149
  dependencies = [
2150
  "bstr",
2151
  "mlua-sys",
 
2156
 
2157
  [[package]]
2158
  name = "mlua-sys"
2159
+ version = "0.5.1"
2160
  source = "registry+https://github.com/rust-lang/crates.io-index"
2161
+ checksum = "2847b42764435201d8cbee1f517edb79c4cca4181877b90047587c89e1b7bce4"
2162
  dependencies = [
2163
  "cc",
2164
  "cfg-if 1.0.0",
 
2220
  source = "registry+https://github.com/rust-lang/crates.io-index"
2221
  checksum = "38bf9645c8b145698bb0b18a4637dcacbc421ea49bef2317e4fd8065a387cf21"
2222
 
2223
+ [[package]]
2224
+ name = "num-conv"
2225
+ version = "0.1.0"
2226
+ source = "registry+https://github.com/rust-lang/crates.io-index"
2227
+ checksum = "51d515d32fb182ee37cda2ccdcb92950d6a3c2893aa280e540671c2cd0f3b1d9"
2228
+
2229
  [[package]]
2230
  name = "num-traits"
2231
+ version = "0.2.18"
2232
  source = "registry+https://github.com/rust-lang/crates.io-index"
2233
+ checksum = "da0df0e5185db44f69b44f26786fe401b6c293d1907744beaa7fa62b2e5a517a"
2234
  dependencies = [
2235
  "autocfg 1.1.0",
2236
  ]
 
2268
 
2269
  [[package]]
2270
  name = "opaque-debug"
2271
+ version = "0.3.1"
2272
  source = "registry+https://github.com/rust-lang/crates.io-index"
2273
+ checksum = "c08d65885ee38876c4f86fa503fb49d7b507c2b62552df7c70b2fce627e06381"
2274
 
2275
  [[package]]
2276
  name = "openssl"
2277
+ version = "0.10.64"
2278
  source = "registry+https://github.com/rust-lang/crates.io-index"
2279
+ checksum = "95a0481286a310808298130d22dd1fef0fa571e05a8f44ec801801e84b216b1f"
2280
  dependencies = [
2281
+ "bitflags 2.4.2",
2282
  "cfg-if 1.0.0",
2283
  "foreign-types",
2284
  "libc",
 
2295
  dependencies = [
2296
  "proc-macro2 1.0.78",
2297
  "quote 1.0.35",
2298
+ "syn 2.0.52",
2299
  ]
2300
 
2301
  [[package]]
 
2306
 
2307
  [[package]]
2308
  name = "openssl-sys"
2309
+ version = "0.9.101"
2310
  source = "registry+https://github.com/rust-lang/crates.io-index"
2311
+ checksum = "dda2b0f344e78efc2facf7d195d098df0dd72151b26ab98da807afc26c198dff"
2312
  dependencies = [
2313
  "cc",
2314
  "libc",
 
2322
  source = "registry+https://github.com/rust-lang/crates.io-index"
2323
  checksum = "05d74befe2d076330d9a58bf9ca2da424568724ab278adf15fb5718253133887"
2324
  dependencies = [
2325
+ "bitflags 2.4.2",
2326
  "cssparser 0.33.0",
2327
  "fxhash",
2328
  "log",
 
2506
  "phf_shared 0.11.2",
2507
  "proc-macro2 1.0.78",
2508
  "quote 1.0.35",
2509
+ "syn 2.0.52",
2510
  ]
2511
 
2512
  [[package]]
 
2538
 
2539
  [[package]]
2540
  name = "pin-project"
2541
+ version = "1.1.5"
2542
  source = "registry+https://github.com/rust-lang/crates.io-index"
2543
+ checksum = "b6bf43b791c5b9e34c3d182969b4abb522f9343702850a2e57f460d00d09b4b3"
2544
  dependencies = [
2545
  "pin-project-internal",
2546
  ]
2547
 
2548
  [[package]]
2549
  name = "pin-project-internal"
2550
+ version = "1.1.5"
2551
  source = "registry+https://github.com/rust-lang/crates.io-index"
2552
+ checksum = "2f38a4412a78282e09a2cf38d195ea5420d15ba0602cb375210efbc877243965"
2553
  dependencies = [
2554
  "proc-macro2 1.0.78",
2555
  "quote 1.0.35",
2556
+ "syn 2.0.52",
2557
  ]
2558
 
2559
  [[package]]
 
2570
 
2571
  [[package]]
2572
  name = "pkg-config"
2573
+ version = "0.3.30"
2574
  source = "registry+https://github.com/rust-lang/crates.io-index"
2575
+ checksum = "d231b230927b5e4ad203db57bbcbee2802f6bce620b1e4a9024a07d94e2907ec"
2576
 
2577
  [[package]]
2578
  name = "poly1305"
 
2585
  "universal-hash",
2586
  ]
2587
 
2588
+ [[package]]
2589
+ name = "portable-atomic"
2590
+ version = "1.6.0"
2591
+ source = "registry+https://github.com/rust-lang/crates.io-index"
2592
+ checksum = "7170ef9988bc169ba16dd36a7fa041e5c4cbeb6a35b76d4c03daded371eae7c0"
2593
+
2594
  [[package]]
2595
  name = "powerfmt"
2596
  version = "0.2.0"
 
2663
 
2664
  [[package]]
2665
  name = "pulldown-cmark"
2666
+ version = "0.9.6"
2667
  source = "registry+https://github.com/rust-lang/crates.io-index"
2668
+ checksum = "57206b407293d2bcd3af849ce869d52068623f19e1b5ff8e8778e3309439682b"
2669
  dependencies = [
2670
+ "bitflags 2.4.2",
2671
  "memchr",
2672
  "unicase",
2673
  ]
2674
 
2675
  [[package]]
2676
  name = "quanta"
2677
+ version = "0.12.2"
2678
  source = "registry+https://github.com/rust-lang/crates.io-index"
2679
+ checksum = "9ca0b7bac0b97248c40bb77288fc52029cf1459c0461ea1b05ee32ccf011de2c"
2680
  dependencies = [
2681
+ "crossbeam-utils 0.8.19",
2682
  "libc",
 
2683
  "once_cell",
2684
  "raw-cpuid",
2685
  "wasi 0.11.0+wasi-snapshot-preview1",
 
2843
 
2844
  [[package]]
2845
  name = "raw-cpuid"
2846
+ version = "11.0.1"
2847
  source = "registry+https://github.com/rust-lang/crates.io-index"
2848
+ checksum = "9d86a7c4638d42c44551f4791a20e687dbb4c3de1f33c43dd71e355cd429def1"
2849
  dependencies = [
2850
+ "bitflags 2.4.2",
2851
  ]
2852
 
2853
  [[package]]
 
2875
  "percent-encoding 2.3.1",
2876
  "pin-project-lite",
2877
  "ryu",
2878
+ "tokio 1.36.0",
2879
  "tokio-retry",
2880
  "tokio-util",
2881
  "url 2.5.0",
 
2898
 
2899
  [[package]]
2900
  name = "regex"
2901
+ version = "1.10.3"
2902
  source = "registry+https://github.com/rust-lang/crates.io-index"
2903
+ checksum = "b62dbe01f0b06f9d8dc7d49e05a0785f153b00b2c227856282f671e0318c9b15"
2904
  dependencies = [
2905
  "aho-corasick 1.1.2",
2906
  "memchr",
 
2910
 
2911
  [[package]]
2912
  name = "regex-automata"
2913
+ version = "0.4.6"
2914
  source = "registry+https://github.com/rust-lang/crates.io-index"
2915
+ checksum = "86b83b8b9847f9bf95ef68afb0b8e6cdb80f498442f5179a29fad448fcc1eaea"
2916
  dependencies = [
2917
  "aho-corasick 1.1.2",
2918
  "memchr",
 
2961
 
2962
  [[package]]
2963
  name = "reqwest"
2964
+ version = "0.11.25"
2965
  source = "registry+https://github.com/rust-lang/crates.io-index"
2966
+ checksum = "0eea5a9eb898d3783f17c6407670e3592fd174cb81a10e51d4c37f49450b9946"
2967
  dependencies = [
2968
  "async-compression",
2969
+ "base64 0.21.7",
2970
  "bytes 1.5.0",
2971
  "encoding_rs",
2972
  "futures-core",
2973
  "futures-util",
2974
+ "h2 0.3.24",
2975
+ "http 0.2.12",
2976
  "http-body 0.4.6",
2977
  "hyper 0.14.28",
2978
  "hyper-rustls",
 
2990
  "serde_urlencoded 0.7.1",
2991
  "sync_wrapper",
2992
  "system-configuration",
2993
+ "tokio 1.36.0",
2994
  "tokio-rustls",
2995
  "tokio-util",
2996
  "tower-service",
 
3004
 
3005
  [[package]]
3006
  name = "ring"
3007
+ version = "0.17.8"
3008
  source = "registry+https://github.com/rust-lang/crates.io-index"
3009
+ checksum = "c17fa4cb658e3583423e915b9f3acc01cceaee1860e33d59ebae66adc3a2dc0d"
3010
  dependencies = [
3011
  "cc",
3012
+ "cfg-if 1.0.0",
3013
  "getrandom",
3014
  "libc",
3015
  "spin",
3016
  "untrusted",
3017
+ "windows-sys 0.52.0",
3018
  ]
3019
 
3020
  [[package]]
 
3044
  source = "registry+https://github.com/rust-lang/crates.io-index"
3045
  checksum = "bfa0f585226d2e68097d4f95d113b15b83a82e819ab25717ec0590d9584ef366"
3046
  dependencies = [
3047
+ "semver 1.0.22",
3048
  ]
3049
 
3050
  [[package]]
 
3053
  source = "registry+https://github.com/rust-lang/crates.io-index"
3054
  checksum = "6ea3e1a662af26cd7a3ba09c0297a31af215563ecf42817c98df621387f4e949"
3055
  dependencies = [
3056
+ "bitflags 2.4.2",
3057
  "errno",
3058
  "libc",
3059
  "linux-raw-sys",
 
3078
  source = "registry+https://github.com/rust-lang/crates.io-index"
3079
  checksum = "1c74cae0a4cf6ccbbf5f359f08efdf8ee7e1dc532573bf0db71968cb56b1448c"
3080
  dependencies = [
3081
+ "base64 0.21.7",
3082
  ]
3083
 
3084
  [[package]]
 
3105
 
3106
  [[package]]
3107
  name = "ryu"
3108
+ version = "1.0.17"
3109
  source = "registry+https://github.com/rust-lang/crates.io-index"
3110
+ checksum = "e86697c916019a8588c99b5fac3cead74ec0b4b819707a682fd4d23fa0ce1ba1"
3111
 
3112
  [[package]]
3113
  name = "same-file"
 
3139
  source = "registry+https://github.com/rust-lang/crates.io-index"
3140
  checksum = "585480e3719b311b78a573db1c9d9c4c1f8010c2dee4cc59c2efe58ea4dbc3e1"
3141
  dependencies = [
3142
+ "ahash",
3143
  "cssparser 0.31.2",
3144
  "ego-tree",
3145
  "html5ever 0.26.0",
 
3197
  source = "registry+https://github.com/rust-lang/crates.io-index"
3198
  checksum = "4eb30575f3638fc8f6815f448d50cb1a2e255b0897985c8c59f4d37b72a07b06"
3199
  dependencies = [
3200
+ "bitflags 2.4.2",
3201
  "cssparser 0.31.2",
3202
  "derive_more",
3203
  "fxhash",
 
3221
 
3222
  [[package]]
3223
  name = "semver"
3224
+ version = "1.0.22"
3225
  source = "registry+https://github.com/rust-lang/crates.io-index"
3226
+ checksum = "92d43fe69e652f3df9bdc2b85b2854a0825b86e4fb76bc44d945137d053639ca"
3227
  dependencies = [
3228
  "serde",
3229
  ]
 
3236
 
3237
  [[package]]
3238
  name = "serde"
3239
+ version = "1.0.197"
3240
  source = "registry+https://github.com/rust-lang/crates.io-index"
3241
+ checksum = "3fb1c873e1b9b056a4dc4c0c198b24c3ffa059243875552b2bd0933b1aee4ce2"
3242
  dependencies = [
3243
  "serde_derive",
3244
  ]
3245
 
3246
  [[package]]
3247
  name = "serde_derive"
3248
+ version = "1.0.197"
3249
  source = "registry+https://github.com/rust-lang/crates.io-index"
3250
+ checksum = "7eb0b34b42edc17f6b7cac84a52a1c5f0e1bb2227e997ca9011ea3dd34e8610b"
3251
  dependencies = [
3252
  "proc-macro2 1.0.78",
3253
  "quote 1.0.35",
3254
+ "syn 2.0.52",
3255
  ]
3256
 
3257
  [[package]]
3258
  name = "serde_json"
3259
+ version = "1.0.114"
3260
  source = "registry+https://github.com/rust-lang/crates.io-index"
3261
+ checksum = "c5f09b1bd632ef549eaa9f60a1f8de742bdbc698e6cee2095fc84dde5f549ae0"
3262
  dependencies = [
3263
  "itoa 1.0.10",
3264
  "ryu",
 
3374
 
3375
  [[package]]
3376
  name = "socket2"
3377
+ version = "0.5.6"
3378
  source = "registry+https://github.com/rust-lang/crates.io-index"
3379
+ checksum = "05ffd9c0a93b7543e062e759284fcf5f5e3b098501104bfbdde4d404db792871"
3380
  dependencies = [
3381
  "libc",
3382
+ "windows-sys 0.52.0",
3383
  ]
3384
 
3385
  [[package]]
 
3388
  source = "registry+https://github.com/rust-lang/crates.io-index"
3389
  checksum = "6980e8d7511241f8acf4aebddbb1ff938df5eebe98691418c4468d0b72a96a67"
3390
 
3391
+ [[package]]
3392
+ name = "spinning_top"
3393
+ version = "0.3.0"
3394
+ source = "registry+https://github.com/rust-lang/crates.io-index"
3395
+ checksum = "d96d2d1d716fb500937168cc09353ffdc7a012be8475ac7308e1bdf0e3923300"
3396
+ dependencies = [
3397
+ "lock_api 0.4.11",
3398
+ ]
3399
+
3400
  [[package]]
3401
  name = "stable_deref_trait"
3402
  version = "1.2.0"
 
3502
 
3503
  [[package]]
3504
  name = "syn"
3505
+ version = "2.0.52"
3506
  source = "registry+https://github.com/rust-lang/crates.io-index"
3507
+ checksum = "b699d15b36d1f02c3e7c69f8ffef53de37aefae075d8488d4ba1a7788d574a07"
3508
  dependencies = [
3509
  "proc-macro2 1.0.78",
3510
  "quote 1.0.35",
 
3529
  "unicode-xid 0.2.4",
3530
  ]
3531
 
 
 
 
 
 
 
 
 
 
 
3532
  [[package]]
3533
  name = "system-configuration"
3534
+ version = "0.6.0"
3535
  source = "registry+https://github.com/rust-lang/crates.io-index"
3536
+ checksum = "658bc6ee10a9b4fcf576e9b0819d95ec16f4d2c02d39fd83ac1c8789785c4a42"
3537
  dependencies = [
3538
+ "bitflags 2.4.2",
3539
  "core-foundation",
3540
  "system-configuration-sys",
3541
  ]
3542
 
3543
  [[package]]
3544
  name = "system-configuration-sys"
3545
+ version = "0.6.0"
3546
  source = "registry+https://github.com/rust-lang/crates.io-index"
3547
+ checksum = "8e1d1b10ced5ca923a1fcb8d03e96b8d3268065d724548c0211415ff6ac6bac4"
3548
  dependencies = [
3549
  "core-foundation-sys",
3550
  "libc",
 
3598
 
3599
  [[package]]
3600
  name = "time"
3601
+ version = "0.3.34"
3602
  source = "registry+https://github.com/rust-lang/crates.io-index"
3603
+ checksum = "c8248b6521bb14bc45b4067159b9b6ad792e2d6d754d6c41fb50e29fefe38749"
3604
  dependencies = [
3605
  "deranged",
3606
  "itoa 1.0.10",
3607
+ "num-conv",
3608
  "powerfmt",
3609
  "serde",
3610
  "time-core",
 
3619
 
3620
  [[package]]
3621
  name = "time-macros"
3622
+ version = "0.2.17"
3623
  source = "registry+https://github.com/rust-lang/crates.io-index"
3624
+ checksum = "7ba3a3ef41e6672a2f0f001392bb5dcd3ff0a9992d618ca761a11c3121547774"
3625
  dependencies = [
3626
+ "num-conv",
3627
  "time-core",
3628
  ]
3629
 
 
3673
 
3674
  [[package]]
3675
  name = "tokio"
3676
+ version = "1.36.0"
3677
  source = "registry+https://github.com/rust-lang/crates.io-index"
3678
+ checksum = "61285f6515fa018fb2d1e46eb21223fff441ee8db5d0f1435e8ab4f5cdb80931"
3679
  dependencies = [
3680
  "backtrace",
3681
  "bytes 1.5.0",
3682
  "libc",
3683
+ "mio 0.8.11",
3684
  "num_cpus",
3685
  "parking_lot 0.12.1",
3686
  "pin-project-lite",
 
3740
  dependencies = [
3741
  "proc-macro2 1.0.78",
3742
  "quote 1.0.35",
3743
+ "syn 2.0.52",
3744
  ]
3745
 
3746
  [[package]]
 
3770
  dependencies = [
3771
  "pin-project",
3772
  "rand 0.8.5",
3773
+ "tokio 1.36.0",
3774
  ]
3775
 
3776
  [[package]]
 
3780
  checksum = "c28327cf380ac148141087fbfb9de9d7bd4e84ab5d2c28fbc911d753de8a7081"
3781
  dependencies = [
3782
  "rustls",
3783
+ "tokio 1.36.0",
3784
  ]
3785
 
3786
  [[package]]
 
3846
  "futures-core",
3847
  "futures-sink",
3848
  "pin-project-lite",
3849
+ "tokio 1.36.0",
3850
  "tracing",
3851
  ]
3852
 
 
3923
 
3924
  [[package]]
3925
  name = "unicode-bidi"
3926
+ version = "0.3.15"
3927
  source = "registry+https://github.com/rust-lang/crates.io-index"
3928
+ checksum = "08f95100a766bf4f8f28f90d77e0a5461bbdb219042e7679bebe79004fed8d75"
3929
 
3930
  [[package]]
3931
  name = "unicode-ident"
 
3935
 
3936
  [[package]]
3937
  name = "unicode-normalization"
3938
+ version = "0.1.23"
3939
  source = "registry+https://github.com/rust-lang/crates.io-index"
3940
+ checksum = "a56d1686db2308d901306f92a263857ef59ea39678a5458e7cb17f01415101f5"
3941
  dependencies = [
3942
  "tinyvec",
3943
  ]
 
4033
 
4034
  [[package]]
4035
  name = "walkdir"
4036
+ version = "2.5.0"
4037
  source = "registry+https://github.com/rust-lang/crates.io-index"
4038
+ checksum = "29790946404f91d9c5d06f9874efddea1dc06c5efe94541a7d6863108e3a5e4b"
4039
  dependencies = [
4040
  "same-file",
4041
  "winapi-util",
 
4075
 
4076
  [[package]]
4077
  name = "wasm-bindgen"
4078
+ version = "0.2.92"
4079
  source = "registry+https://github.com/rust-lang/crates.io-index"
4080
+ checksum = "4be2531df63900aeb2bca0daaaddec08491ee64ceecbee5076636a3b026795a8"
4081
  dependencies = [
4082
  "cfg-if 1.0.0",
4083
  "wasm-bindgen-macro",
 
4085
 
4086
  [[package]]
4087
  name = "wasm-bindgen-backend"
4088
+ version = "0.2.92"
4089
  source = "registry+https://github.com/rust-lang/crates.io-index"
4090
+ checksum = "614d787b966d3989fa7bb98a654e369c762374fd3213d212cfc0251257e747da"
4091
  dependencies = [
4092
  "bumpalo",
4093
  "log",
4094
  "once_cell",
4095
  "proc-macro2 1.0.78",
4096
  "quote 1.0.35",
4097
+ "syn 2.0.52",
4098
  "wasm-bindgen-shared",
4099
  ]
4100
 
4101
  [[package]]
4102
  name = "wasm-bindgen-futures"
4103
+ version = "0.4.42"
4104
  source = "registry+https://github.com/rust-lang/crates.io-index"
4105
+ checksum = "76bc14366121efc8dbb487ab05bcc9d346b3b5ec0eaa76e46594cabbe51762c0"
4106
  dependencies = [
4107
  "cfg-if 1.0.0",
4108
  "js-sys",
 
4112
 
4113
  [[package]]
4114
  name = "wasm-bindgen-macro"
4115
+ version = "0.2.92"
4116
  source = "registry+https://github.com/rust-lang/crates.io-index"
4117
+ checksum = "a1f8823de937b71b9460c0c34e25f3da88250760bec0ebac694b49997550d726"
4118
  dependencies = [
4119
  "quote 1.0.35",
4120
  "wasm-bindgen-macro-support",
 
4122
 
4123
  [[package]]
4124
  name = "wasm-bindgen-macro-support"
4125
+ version = "0.2.92"
4126
  source = "registry+https://github.com/rust-lang/crates.io-index"
4127
+ checksum = "e94f17b526d0a461a191c78ea52bbce64071ed5c04c9ffe424dcb38f74171bb7"
4128
  dependencies = [
4129
  "proc-macro2 1.0.78",
4130
  "quote 1.0.35",
4131
+ "syn 2.0.52",
4132
  "wasm-bindgen-backend",
4133
  "wasm-bindgen-shared",
4134
  ]
4135
 
4136
  [[package]]
4137
  name = "wasm-bindgen-shared"
4138
+ version = "0.2.92"
4139
  source = "registry+https://github.com/rust-lang/crates.io-index"
4140
+ checksum = "af190c94f2773fdb3729c55b007a722abb5384da03bc0986df4c289bf5567e96"
4141
 
4142
  [[package]]
4143
  name = "web-sys"
4144
+ version = "0.3.69"
4145
  source = "registry+https://github.com/rust-lang/crates.io-index"
4146
+ checksum = "77afa9a11836342370f4817622a2f0f418b134426d91a82dfb48f532d2ec13ef"
4147
  dependencies = [
4148
  "js-sys",
4149
  "wasm-bindgen",
 
4151
 
4152
  [[package]]
4153
  name = "webpki-roots"
4154
+ version = "0.25.4"
4155
  source = "registry+https://github.com/rust-lang/crates.io-index"
4156
+ checksum = "5f20c57d8d7db6d3b86154206ae5d8fba62dd39573114de97c2cb0578251f8e1"
4157
 
4158
  [[package]]
4159
  name = "websurfx"
4160
+ version = "1.10.9"
4161
  dependencies = [
4162
  "actix-cors",
4163
  "actix-files",
4164
  "actix-governor",
4165
  "actix-web",
4166
+ "async-compression",
4167
  "async-once-cell",
4168
  "async-trait",
4169
+ "base64 0.21.7",
4170
  "blake3",
 
4171
  "cfg-if 1.0.0",
4172
  "chacha20",
4173
  "chacha20poly1305",
 
4186
  "mlua",
4187
  "redis",
4188
  "regex",
4189
+ "reqwest 0.11.25",
4190
  "rusty-hook",
4191
  "scraper",
4192
  "serde",
4193
  "serde_json",
4194
  "smallvec 1.13.1",
4195
  "tempfile",
4196
+ "tokio 1.36.0",
4197
  ]
4198
 
4199
  [[package]]
4200
  name = "which"
4201
+ version = "6.0.0"
4202
  source = "registry+https://github.com/rust-lang/crates.io-index"
4203
+ checksum = "7fa5e0c10bf77f44aac573e498d1a82d5fbd5e91f6fc0a99e7be4b38e85e101c"
4204
  dependencies = [
4205
  "either",
4206
  "home",
4207
  "once_cell",
4208
  "rustix",
4209
+ "windows-sys 0.52.0",
4210
  ]
4211
 
4212
  [[package]]
 
4267
  source = "registry+https://github.com/rust-lang/crates.io-index"
4268
  checksum = "282be5f36a8ce781fad8c8ae18fa3f9beff57ec1b52cb3de0789201425d9a33d"
4269
  dependencies = [
4270
+ "windows-targets 0.52.4",
4271
  ]
4272
 
4273
  [[package]]
 
4287
 
4288
  [[package]]
4289
  name = "windows-targets"
4290
+ version = "0.52.4"
4291
  source = "registry+https://github.com/rust-lang/crates.io-index"
4292
+ checksum = "7dd37b7e5ab9018759f893a1952c9420d060016fc19a472b4bb20d1bdd694d1b"
4293
  dependencies = [
4294
+ "windows_aarch64_gnullvm 0.52.4",
4295
+ "windows_aarch64_msvc 0.52.4",
4296
+ "windows_i686_gnu 0.52.4",
4297
+ "windows_i686_msvc 0.52.4",
4298
+ "windows_x86_64_gnu 0.52.4",
4299
+ "windows_x86_64_gnullvm 0.52.4",
4300
+ "windows_x86_64_msvc 0.52.4",
4301
  ]
4302
 
4303
  [[package]]
 
4308
 
4309
  [[package]]
4310
  name = "windows_aarch64_gnullvm"
4311
+ version = "0.52.4"
4312
  source = "registry+https://github.com/rust-lang/crates.io-index"
4313
+ checksum = "bcf46cf4c365c6f2d1cc93ce535f2c8b244591df96ceee75d8e83deb70a9cac9"
4314
 
4315
  [[package]]
4316
  name = "windows_aarch64_msvc"
 
4320
 
4321
  [[package]]
4322
  name = "windows_aarch64_msvc"
4323
+ version = "0.52.4"
4324
  source = "registry+https://github.com/rust-lang/crates.io-index"
4325
+ checksum = "da9f259dd3bcf6990b55bffd094c4f7235817ba4ceebde8e6d11cd0c5633b675"
4326
 
4327
  [[package]]
4328
  name = "windows_i686_gnu"
 
4332
 
4333
  [[package]]
4334
  name = "windows_i686_gnu"
4335
+ version = "0.52.4"
4336
  source = "registry+https://github.com/rust-lang/crates.io-index"
4337
+ checksum = "b474d8268f99e0995f25b9f095bc7434632601028cf86590aea5c8a5cb7801d3"
4338
 
4339
  [[package]]
4340
  name = "windows_i686_msvc"
 
4344
 
4345
  [[package]]
4346
  name = "windows_i686_msvc"
4347
+ version = "0.52.4"
4348
  source = "registry+https://github.com/rust-lang/crates.io-index"
4349
+ checksum = "1515e9a29e5bed743cb4415a9ecf5dfca648ce85ee42e15873c3cd8610ff8e02"
4350
 
4351
  [[package]]
4352
  name = "windows_x86_64_gnu"
 
4356
 
4357
  [[package]]
4358
  name = "windows_x86_64_gnu"
4359
+ version = "0.52.4"
4360
  source = "registry+https://github.com/rust-lang/crates.io-index"
4361
+ checksum = "5eee091590e89cc02ad514ffe3ead9eb6b660aedca2183455434b93546371a03"
4362
 
4363
  [[package]]
4364
  name = "windows_x86_64_gnullvm"
 
4368
 
4369
  [[package]]
4370
  name = "windows_x86_64_gnullvm"
4371
+ version = "0.52.4"
4372
  source = "registry+https://github.com/rust-lang/crates.io-index"
4373
+ checksum = "77ca79f2451b49fa9e2af39f0747fe999fcda4f5e241b2898624dca97a1f2177"
4374
 
4375
  [[package]]
4376
  name = "windows_x86_64_msvc"
 
4380
 
4381
  [[package]]
4382
  name = "windows_x86_64_msvc"
4383
+ version = "0.52.4"
4384
  source = "registry+https://github.com/rust-lang/crates.io-index"
4385
+ checksum = "32b752e52a2da0ddfbdbcc6fceadfeede4c939ed16d13e648833a61dfb611ed8"
4386
 
4387
  [[package]]
4388
  name = "winreg"
 
4430
  dependencies = [
4431
  "proc-macro2 1.0.78",
4432
  "quote 1.0.35",
4433
+ "syn 2.0.52",
4434
  ]
4435
 
4436
  [[package]]
Cargo.toml CHANGED
@@ -1,6 +1,6 @@
1
  [package]
2
  name = "websurfx"
3
- version = "1.9.20"
4
  edition = "2021"
5
  description = "An open-source alternative to Searx that provides clean, ad-free, and organic results with incredible speed while keeping privacy and security in mind."
6
  repository = "https://github.com/neon-mmd/websurfx"
@@ -14,7 +14,7 @@ path = "src/bin/websurfx.rs"
14
 
15
  [dependencies]
16
  reqwest = {version="0.11.24", default-features=false, features=["rustls-tls","brotli", "gzip"]}
17
- tokio = {version="1.32.0",features=["rt-multi-thread","macros"], default-features = false}
18
  serde = {version="1.0.196", default-features=false, features=["derive"]}
19
  serde_json = {version="1.0.109", default-features=false}
20
  maud = {version="0.25.0", default-features=false, features=["actix-web"]}
@@ -32,13 +32,13 @@ error-stack = {version="0.4.0", default-features=false, features=["std"]}
32
  async-trait = {version="0.1.76", default-features=false}
33
  regex = {version="1.9.4", features=["perf"], default-features = false}
34
  smallvec = {version="1.13.1", features=["union", "serde"], default-features=false}
35
- futures = {version="0.3.28", default-features=false}
36
- dhat = {version="0.3.3", optional = true, default-features=false}
37
  mimalloc = { version = "0.1.38", default-features = false }
38
  async-once-cell = {version="0.5.3", default-features=false}
39
  actix-governor = {version="0.5.0", default-features=false}
40
  mini-moka = { version="0.10", optional = true, default-features=false, features=["sync"]}
41
- brotli = { version = "3.4.0", default-features = false, features=["std"], optional=true}
42
  chacha20poly1305={version="0.10.1", default-features=false, features=["alloc","getrandom"], optional=true}
43
  chacha20 = {version="0.9.1", default-features=false, optional=true}
44
  base64 = {version="0.21.5", default-features=false, features=["std"], optional=true}
@@ -84,7 +84,7 @@ default = ["memory-cache"]
84
  dhat-heap = ["dep:dhat"]
85
  memory-cache = ["dep:mini-moka"]
86
  redis-cache = ["dep:redis","dep:base64"]
87
- compress-cache-results = ["dep:brotli","dep:cfg-if"]
88
  encrypt-cache-results = ["dep:chacha20poly1305","dep:chacha20"]
89
  cec-cache-results = ["compress-cache-results","encrypt-cache-results"]
90
 
 
1
  [package]
2
  name = "websurfx"
3
+ version = "1.10.9"
4
  edition = "2021"
5
  description = "An open-source alternative to Searx that provides clean, ad-free, and organic results with incredible speed while keeping privacy and security in mind."
6
  repository = "https://github.com/neon-mmd/websurfx"
 
14
 
15
  [dependencies]
16
  reqwest = {version="0.11.24", default-features=false, features=["rustls-tls","brotli", "gzip"]}
17
+ tokio = {version="1.32.0",features=["rt-multi-thread","macros", "fs", "io-util"], default-features = false}
18
  serde = {version="1.0.196", default-features=false, features=["derive"]}
19
  serde_json = {version="1.0.109", default-features=false}
20
  maud = {version="0.25.0", default-features=false, features=["actix-web"]}
 
32
  async-trait = {version="0.1.76", default-features=false}
33
  regex = {version="1.9.4", features=["perf"], default-features = false}
34
  smallvec = {version="1.13.1", features=["union", "serde"], default-features=false}
35
+ futures = {version="0.3.30", default-features=false, features=["alloc"]}
36
+ dhat = {version="0.3.2", optional = true, default-features=false}
37
  mimalloc = { version = "0.1.38", default-features = false }
38
  async-once-cell = {version="0.5.3", default-features=false}
39
  actix-governor = {version="0.5.0", default-features=false}
40
  mini-moka = { version="0.10", optional = true, default-features=false, features=["sync"]}
41
+ async-compression = { version = "0.4.6", default-features = false, features=["brotli","tokio"], optional=true}
42
  chacha20poly1305={version="0.10.1", default-features=false, features=["alloc","getrandom"], optional=true}
43
  chacha20 = {version="0.9.1", default-features=false, optional=true}
44
  base64 = {version="0.21.5", default-features=false, features=["std"], optional=true}
 
84
  dhat-heap = ["dep:dhat"]
85
  memory-cache = ["dep:mini-moka"]
86
  redis-cache = ["dep:redis","dep:base64"]
87
+ compress-cache-results = ["dep:async-compression","dep:cfg-if"]
88
  encrypt-cache-results = ["dep:chacha20poly1305","dep:chacha20"]
89
  cec-cache-results = ["compress-cache-results","encrypt-cache-results"]
90
 
src/bin/websurfx.rs CHANGED
@@ -5,7 +5,7 @@
5
  #[cfg(not(feature = "dhat-heap"))]
6
  use mimalloc::MiMalloc;
7
 
8
- use std::net::TcpListener;
9
  use websurfx::{cache::cacher::create_cache, config::parser::Config, run};
10
 
11
  /// A dhat heap memory profiler
@@ -17,6 +17,9 @@ static ALLOC: dhat::Alloc = dhat::Alloc;
17
  #[global_allocator]
18
  static GLOBAL: MiMalloc = MiMalloc;
19
 
 
 
 
20
  /// The function that launches the main server and registers all the routes of the website.
21
  ///
22
  /// # Error
@@ -29,10 +32,10 @@ async fn main() -> std::io::Result<()> {
29
  #[cfg(feature = "dhat-heap")]
30
  let _profiler = dhat::Profiler::new_heap();
31
 
32
- // Initialize the parsed config file.
33
- let config = Config::parse(false).unwrap();
34
 
35
- let cache = create_cache(&config).await;
36
 
37
  log::info!(
38
  "started server on port {} and IP {}",
@@ -45,7 +48,7 @@ async fn main() -> std::io::Result<()> {
45
  config.port,
46
  );
47
 
48
- let listener = TcpListener::bind((config.binding_ip.clone(), config.port))?;
49
 
50
  run(listener, config, cache)?.await
51
  }
 
5
  #[cfg(not(feature = "dhat-heap"))]
6
  use mimalloc::MiMalloc;
7
 
8
+ use std::{net::TcpListener, sync::OnceLock};
9
  use websurfx::{cache::cacher::create_cache, config::parser::Config, run};
10
 
11
  /// A dhat heap memory profiler
 
17
  #[global_allocator]
18
  static GLOBAL: MiMalloc = MiMalloc;
19
 
20
+ /// A static constant for holding the parsed config.
21
+ static CONFIG: OnceLock<Config> = OnceLock::new();
22
+
23
  /// The function that launches the main server and registers all the routes of the website.
24
  ///
25
  /// # Error
 
32
  #[cfg(feature = "dhat-heap")]
33
  let _profiler = dhat::Profiler::new_heap();
34
 
35
+ // Initialize the parsed config globally.
36
+ let config = CONFIG.get_or_init(|| Config::parse(false).unwrap());
37
 
38
+ let cache = create_cache(config).await;
39
 
40
  log::info!(
41
  "started server on port {} and IP {}",
 
48
  config.port,
49
  );
50
 
51
+ let listener = TcpListener::bind((config.binding_ip.as_str(), config.port))?;
52
 
53
  run(listener, config, cache)?.await
54
  }
src/cache/cacher.rs CHANGED
@@ -93,7 +93,7 @@ pub trait Cacher: Send + Sync {
93
  feature = "encrypt-cache-results",
94
  feature = "cec-cache-results"
95
  ))]
96
- fn encrypt_or_decrypt_results(
97
  &mut self,
98
  mut bytes: Vec<u8>,
99
  encrypt: bool,
@@ -137,11 +137,19 @@ pub trait Cacher: Send + Sync {
137
  /// Returns the compressed bytes on success otherwise it returns a CacheError
138
  /// on failure.
139
  #[cfg(any(feature = "compress-cache-results", feature = "cec-cache-results"))]
140
- fn compress_results(&mut self, mut bytes: Vec<u8>) -> Result<Vec<u8>, Report<CacheError>> {
141
- use std::io::Write;
142
- let mut writer = brotli::CompressorWriter::new(Vec::new(), 4096, 11, 22);
 
 
 
143
  writer
144
  .write_all(&bytes)
 
 
 
 
 
145
  .map_err(|_| CacheError::CompressionError)?;
146
  bytes = writer.into_inner();
147
  Ok(bytes)
@@ -159,17 +167,17 @@ pub trait Cacher: Send + Sync {
159
  /// Returns the compressed and encrypted bytes on success otherwise it returns a CacheError
160
  /// on failure.
161
  #[cfg(feature = "cec-cache-results")]
162
- fn compress_encrypt_compress_results(
163
  &mut self,
164
  mut bytes: Vec<u8>,
165
  ) -> Result<Vec<u8>, Report<CacheError>> {
166
  // compress first
167
- bytes = self.compress_results(bytes)?;
168
  // encrypt
169
- bytes = self.encrypt_or_decrypt_results(bytes, true)?;
170
 
171
  // compress again;
172
- bytes = self.compress_results(bytes)?;
173
 
174
  Ok(bytes)
175
  }
@@ -187,11 +195,11 @@ pub trait Cacher: Send + Sync {
187
  /// on failure.
188
 
189
  #[cfg(any(feature = "compress-cache-results", feature = "cec-cache-results"))]
190
- fn decompress_results(&mut self, bytes: &[u8]) -> Result<Vec<u8>, Report<CacheError>> {
191
  cfg_if::cfg_if! {
192
  if #[cfg(feature = "compress-cache-results")]
193
  {
194
- decompress_util(bytes)
195
 
196
  }
197
  else if #[cfg(feature = "cec-cache-results")]
@@ -199,7 +207,7 @@ pub trait Cacher: Send + Sync {
199
  let decompressed = decompress_util(bytes)?;
200
  let decrypted = self.encrypt_or_decrypt_results(decompressed, false)?;
201
 
202
- decompress_util(&decrypted)
203
 
204
  }
205
  }
@@ -216,7 +224,7 @@ pub trait Cacher: Send + Sync {
216
  /// # Error
217
  /// Returns a Vec of compressed or encrypted bytes on success otherwise it returns a CacheError
218
  /// on failure.
219
- fn pre_process_search_results(
220
  &mut self,
221
  search_results: &SearchResults,
222
  ) -> Result<Vec<u8>, Report<CacheError>> {
@@ -224,19 +232,20 @@ pub trait Cacher: Send + Sync {
224
  let mut bytes: Vec<u8> = search_results.try_into()?;
225
  #[cfg(feature = "compress-cache-results")]
226
  {
227
- let compressed = self.compress_results(bytes)?;
228
  bytes = compressed;
229
  }
230
 
231
  #[cfg(feature = "encrypt-cache-results")]
232
  {
233
- let encrypted = self.encrypt_or_decrypt_results(bytes, true)?;
234
  bytes = encrypted;
235
  }
236
 
237
  #[cfg(feature = "cec-cache-results")]
238
  {
239
- let compressed_encrypted_compressed = self.compress_encrypt_compress_results(bytes)?;
 
240
  bytes = compressed_encrypted_compressed;
241
  }
242
 
@@ -256,25 +265,25 @@ pub trait Cacher: Send + Sync {
256
  /// on failure.
257
 
258
  #[allow(unused_mut)] // needs to be mutable when any of the features is enabled
259
- fn post_process_search_results(
260
  &mut self,
261
  mut bytes: Vec<u8>,
262
  ) -> Result<SearchResults, Report<CacheError>> {
263
  #[cfg(feature = "compress-cache-results")]
264
  {
265
- let decompressed = self.decompress_results(&bytes)?;
266
  bytes = decompressed
267
  }
268
 
269
  #[cfg(feature = "encrypt-cache-results")]
270
  {
271
- let decrypted = self.encrypt_or_decrypt_results(bytes, false)?;
272
  bytes = decrypted
273
  }
274
 
275
  #[cfg(feature = "cec-cache-results")]
276
  {
277
- let decompressed_decrypted = self.decompress_results(&bytes)?;
278
  bytes = decompressed_decrypted;
279
  }
280
 
@@ -295,16 +304,19 @@ pub trait Cacher: Send + Sync {
295
  /// on failure.
296
 
297
  #[cfg(any(feature = "compress-cache-results", feature = "cec-cache-results"))]
298
- fn decompress_util(input: &[u8]) -> Result<Vec<u8>, Report<CacheError>> {
299
- use std::io::Write;
300
- let mut writer = brotli::DecompressorWriter::new(Vec::new(), 4096);
301
 
302
  writer
303
  .write_all(input)
 
304
  .map_err(|_| CacheError::CompressionError)?;
305
- let bytes = writer
306
- .into_inner()
 
307
  .map_err(|_| CacheError::CompressionError)?;
 
308
  Ok(bytes)
309
  }
310
 
@@ -329,7 +341,7 @@ impl Cacher for RedisCache {
329
  let bytes = base64::engine::general_purpose::STANDARD_NO_PAD
330
  .decode(base64_string)
331
  .map_err(|_| CacheError::Base64DecodingOrEncodingError)?;
332
- self.post_process_search_results(bytes)
333
  }
334
 
335
  async fn cache_results(
@@ -345,7 +357,7 @@ impl Cacher for RedisCache {
345
  let mut bytes = Vec::with_capacity(search_results_len);
346
 
347
  for result in search_results {
348
- let processed = self.pre_process_search_results(result)?;
349
  bytes.push(processed);
350
  }
351
 
@@ -405,7 +417,7 @@ impl Cacher for InMemoryCache {
405
  async fn cached_results(&mut self, url: &str) -> Result<SearchResults, Report<CacheError>> {
406
  let hashed_url_string = self.hash_url(url);
407
  match self.cache.get(&hashed_url_string) {
408
- Some(res) => self.post_process_search_results(res),
409
  None => Err(Report::new(CacheError::MissingValue)),
410
  }
411
  }
@@ -417,7 +429,7 @@ impl Cacher for InMemoryCache {
417
  ) -> Result<(), Report<CacheError>> {
418
  for (url, search_result) in urls.iter().zip(search_results.iter()) {
419
  let hashed_url_string = self.hash_url(url);
420
- let bytes = self.pre_process_search_results(search_result)?;
421
  self.cache.insert(hashed_url_string, bytes);
422
  }
423
 
 
93
  feature = "encrypt-cache-results",
94
  feature = "cec-cache-results"
95
  ))]
96
+ async fn encrypt_or_decrypt_results(
97
  &mut self,
98
  mut bytes: Vec<u8>,
99
  encrypt: bool,
 
137
  /// Returns the compressed bytes on success otherwise it returns a CacheError
138
  /// on failure.
139
  #[cfg(any(feature = "compress-cache-results", feature = "cec-cache-results"))]
140
+ async fn compress_results(
141
+ &mut self,
142
+ mut bytes: Vec<u8>,
143
+ ) -> Result<Vec<u8>, Report<CacheError>> {
144
+ use tokio::io::AsyncWriteExt;
145
+ let mut writer = async_compression::tokio::write::BrotliEncoder::new(Vec::new());
146
  writer
147
  .write_all(&bytes)
148
+ .await
149
+ .map_err(|_| CacheError::CompressionError)?;
150
+ writer
151
+ .shutdown()
152
+ .await
153
  .map_err(|_| CacheError::CompressionError)?;
154
  bytes = writer.into_inner();
155
  Ok(bytes)
 
167
  /// Returns the compressed and encrypted bytes on success otherwise it returns a CacheError
168
  /// on failure.
169
  #[cfg(feature = "cec-cache-results")]
170
+ async fn compress_encrypt_compress_results(
171
  &mut self,
172
  mut bytes: Vec<u8>,
173
  ) -> Result<Vec<u8>, Report<CacheError>> {
174
  // compress first
175
+ bytes = self.compress_results(bytes).await?;
176
  // encrypt
177
+ bytes = self.encrypt_or_decrypt_results(bytes, true).await?;
178
 
179
  // compress again;
180
+ bytes = self.compress_results(bytes).await?;
181
 
182
  Ok(bytes)
183
  }
 
195
  /// on failure.
196
 
197
  #[cfg(any(feature = "compress-cache-results", feature = "cec-cache-results"))]
198
+ async fn decompress_results(&mut self, bytes: &[u8]) -> Result<Vec<u8>, Report<CacheError>> {
199
  cfg_if::cfg_if! {
200
  if #[cfg(feature = "compress-cache-results")]
201
  {
202
+ decompress_util(bytes).await
203
 
204
  }
205
  else if #[cfg(feature = "cec-cache-results")]
 
207
  let decompressed = decompress_util(bytes)?;
208
  let decrypted = self.encrypt_or_decrypt_results(decompressed, false)?;
209
 
210
+ decompress_util(&decrypted).await
211
 
212
  }
213
  }
 
224
  /// # Error
225
  /// Returns a Vec of compressed or encrypted bytes on success otherwise it returns a CacheError
226
  /// on failure.
227
+ async fn pre_process_search_results(
228
  &mut self,
229
  search_results: &SearchResults,
230
  ) -> Result<Vec<u8>, Report<CacheError>> {
 
232
  let mut bytes: Vec<u8> = search_results.try_into()?;
233
  #[cfg(feature = "compress-cache-results")]
234
  {
235
+ let compressed = self.compress_results(bytes).await?;
236
  bytes = compressed;
237
  }
238
 
239
  #[cfg(feature = "encrypt-cache-results")]
240
  {
241
+ let encrypted = self.encrypt_or_decrypt_results(bytes, true).await?;
242
  bytes = encrypted;
243
  }
244
 
245
  #[cfg(feature = "cec-cache-results")]
246
  {
247
+ let compressed_encrypted_compressed =
248
+ self.compress_encrypt_compress_results(bytes).await?;
249
  bytes = compressed_encrypted_compressed;
250
  }
251
 
 
265
  /// on failure.
266
 
267
  #[allow(unused_mut)] // needs to be mutable when any of the features is enabled
268
+ async fn post_process_search_results(
269
  &mut self,
270
  mut bytes: Vec<u8>,
271
  ) -> Result<SearchResults, Report<CacheError>> {
272
  #[cfg(feature = "compress-cache-results")]
273
  {
274
+ let decompressed = self.decompress_results(&bytes).await?;
275
  bytes = decompressed
276
  }
277
 
278
  #[cfg(feature = "encrypt-cache-results")]
279
  {
280
+ let decrypted = self.encrypt_or_decrypt_results(bytes, false).await?;
281
  bytes = decrypted
282
  }
283
 
284
  #[cfg(feature = "cec-cache-results")]
285
  {
286
+ let decompressed_decrypted = self.decompress_results(&bytes).await?;
287
  bytes = decompressed_decrypted;
288
  }
289
 
 
304
  /// on failure.
305
 
306
  #[cfg(any(feature = "compress-cache-results", feature = "cec-cache-results"))]
307
+ async fn decompress_util(input: &[u8]) -> Result<Vec<u8>, Report<CacheError>> {
308
+ use tokio::io::AsyncWriteExt;
309
+ let mut writer = async_compression::tokio::write::BrotliDecoder::new(Vec::new());
310
 
311
  writer
312
  .write_all(input)
313
+ .await
314
  .map_err(|_| CacheError::CompressionError)?;
315
+ writer
316
+ .shutdown()
317
+ .await
318
  .map_err(|_| CacheError::CompressionError)?;
319
+ let bytes = writer.into_inner();
320
  Ok(bytes)
321
  }
322
 
 
341
  let bytes = base64::engine::general_purpose::STANDARD_NO_PAD
342
  .decode(base64_string)
343
  .map_err(|_| CacheError::Base64DecodingOrEncodingError)?;
344
+ self.post_process_search_results(bytes).await
345
  }
346
 
347
  async fn cache_results(
 
357
  let mut bytes = Vec::with_capacity(search_results_len);
358
 
359
  for result in search_results {
360
+ let processed = self.pre_process_search_results(result).await?;
361
  bytes.push(processed);
362
  }
363
 
 
417
  async fn cached_results(&mut self, url: &str) -> Result<SearchResults, Report<CacheError>> {
418
  let hashed_url_string = self.hash_url(url);
419
  match self.cache.get(&hashed_url_string) {
420
+ Some(res) => self.post_process_search_results(res).await,
421
  None => Err(Report::new(CacheError::MissingValue)),
422
  }
423
  }
 
429
  ) -> Result<(), Report<CacheError>> {
430
  for (url, search_result) in urls.iter().zip(search_results.iter()) {
431
  let hashed_url_string = self.hash_url(url);
432
+ let bytes = self.pre_process_search_results(search_result).await?;
433
  self.cache.insert(hashed_url_string, bytes);
434
  }
435
 
src/cache/redis_cacher.rs CHANGED
@@ -1,15 +1,16 @@
1
  //! This module provides the functionality to cache the aggregated results fetched and aggregated
2
  //! from the upstream search engines in a json format.
3
 
 
4
  use error_stack::Report;
5
- use futures::future::try_join_all;
6
  use redis::{aio::ConnectionManager, AsyncCommands, Client, RedisError};
7
 
8
- use super::error::CacheError;
 
9
 
10
  /// A named struct which stores the redis Connection url address to which the client will
11
  /// connect to.
12
- #[derive(Clone)]
13
  pub struct RedisCache {
14
  /// It stores a pool of connections ready to be used.
15
  connection_pool: Vec<ConnectionManager>,
@@ -20,6 +21,8 @@ pub struct RedisCache {
20
  current_connection: u8,
21
  /// It stores the max TTL for keys.
22
  cache_ttl: u16,
 
 
23
  }
24
 
25
  impl RedisCache {
@@ -30,6 +33,8 @@ impl RedisCache {
30
  /// * `redis_connection_url` - It takes the redis Connection url address.
31
  /// * `pool_size` - It takes the size of the connection pool (in other words the number of
32
  /// connections that should be stored in the pool).
 
 
33
  ///
34
  /// # Error
35
  ///
@@ -41,18 +46,28 @@ impl RedisCache {
41
  cache_ttl: u16,
42
  ) -> Result<Self, Box<dyn std::error::Error>> {
43
  let client = Client::open(redis_connection_url)?;
44
- let mut tasks: Vec<_> = Vec::new();
45
 
46
  for _ in 0..pool_size {
47
- tasks.push(client.get_connection_manager());
 
 
 
 
 
 
 
 
48
  }
49
 
50
  let redis_cache = RedisCache {
51
- connection_pool: try_join_all(tasks).await?,
52
  pool_size,
53
  current_connection: Default::default(),
54
  cache_ttl,
 
55
  };
 
56
  Ok(redis_cache)
57
  }
58
 
@@ -122,13 +137,14 @@ impl RedisCache {
122
  keys: impl Iterator<Item = String>,
123
  ) -> Result<(), Report<CacheError>> {
124
  self.current_connection = Default::default();
125
- let mut pipeline = redis::Pipeline::with_capacity(3);
126
 
127
  for (key, json_result) in keys.zip(json_results) {
128
- pipeline.set_ex(key, json_result, self.cache_ttl.into());
 
129
  }
130
 
131
- let mut result: Result<(), RedisError> = pipeline
 
132
  .query_async(&mut self.connection_pool[self.current_connection as usize])
133
  .await;
134
 
@@ -149,7 +165,8 @@ impl RedisCache {
149
  CacheError::PoolExhaustionWithConnectionDropError,
150
  ));
151
  }
152
- result = pipeline
 
153
  .query_async(
154
  &mut self.connection_pool[self.current_connection as usize],
155
  )
 
1
  //! This module provides the functionality to cache the aggregated results fetched and aggregated
2
  //! from the upstream search engines in a json format.
3
 
4
+ use super::error::CacheError;
5
  use error_stack::Report;
6
+ use futures::stream::FuturesUnordered;
7
  use redis::{aio::ConnectionManager, AsyncCommands, Client, RedisError};
8
 
9
+ /// A constant holding the redis pipeline size.
10
+ const REDIS_PIPELINE_SIZE: usize = 3;
11
 
12
  /// A named struct which stores the redis Connection url address to which the client will
13
  /// connect to.
 
14
  pub struct RedisCache {
15
  /// It stores a pool of connections ready to be used.
16
  connection_pool: Vec<ConnectionManager>,
 
21
  current_connection: u8,
22
  /// It stores the max TTL for keys.
23
  cache_ttl: u16,
24
+ /// It stores the redis pipeline struct of size 3.
25
+ pipeline: redis::Pipeline,
26
  }
27
 
28
  impl RedisCache {
 
33
  /// * `redis_connection_url` - It takes the redis Connection url address.
34
  /// * `pool_size` - It takes the size of the connection pool (in other words the number of
35
  /// connections that should be stored in the pool).
36
+ /// * `cache_ttl` - It takes the the time to live for cached results to live in the redis
37
+ /// server.
38
  ///
39
  /// # Error
40
  ///
 
46
  cache_ttl: u16,
47
  ) -> Result<Self, Box<dyn std::error::Error>> {
48
  let client = Client::open(redis_connection_url)?;
49
+ let tasks: FuturesUnordered<_> = FuturesUnordered::new();
50
 
51
  for _ in 0..pool_size {
52
+ let client_partially_cloned = client.clone();
53
+ tasks.push(tokio::spawn(async move {
54
+ client_partially_cloned.get_connection_manager().await
55
+ }));
56
+ }
57
+
58
+ let mut outputs = Vec::new();
59
+ for task in tasks {
60
+ outputs.push(task.await??);
61
  }
62
 
63
  let redis_cache = RedisCache {
64
+ connection_pool: outputs,
65
  pool_size,
66
  current_connection: Default::default(),
67
  cache_ttl,
68
+ pipeline: redis::Pipeline::with_capacity(REDIS_PIPELINE_SIZE),
69
  };
70
+
71
  Ok(redis_cache)
72
  }
73
 
 
137
  keys: impl Iterator<Item = String>,
138
  ) -> Result<(), Report<CacheError>> {
139
  self.current_connection = Default::default();
 
140
 
141
  for (key, json_result) in keys.zip(json_results) {
142
+ self.pipeline
143
+ .set_ex(key, json_result, self.cache_ttl.into());
144
  }
145
 
146
+ let mut result: Result<(), RedisError> = self
147
+ .pipeline
148
  .query_async(&mut self.connection_pool[self.current_connection as usize])
149
  .await;
150
 
 
165
  CacheError::PoolExhaustionWithConnectionDropError,
166
  ));
167
  }
168
+ result = self
169
+ .pipeline
170
  .query_async(
171
  &mut self.connection_pool[self.current_connection as usize],
172
  )
src/config/parser.rs CHANGED
@@ -9,7 +9,6 @@ use mlua::Lua;
9
  use std::{collections::HashMap, fs, thread::available_parallelism};
10
 
11
  /// A named struct which stores the parsed config file options.
12
- #[derive(Clone)]
13
  pub struct Config {
14
  /// It stores the parsed port number option on which the server should launch.
15
  pub port: u16,
 
9
  use std::{collections::HashMap, fs, thread::available_parallelism};
10
 
11
  /// A named struct which stores the parsed config file options.
 
12
  pub struct Config {
13
  /// It stores the parsed port number option on which the server should launch.
14
  pub port: u16,
src/engines/bing.rs CHANGED
@@ -48,7 +48,7 @@ impl SearchEngine for Bing {
48
  user_agent: &str,
49
  client: &Client,
50
  _safe_search: u8,
51
- ) -> Result<HashMap<String, SearchResult>, EngineError> {
52
  // Bing uses `start results from this number` convention
53
  // So, for 10 results per page, page 0 starts at 1, page 1
54
  // starts at 11, and so on.
 
48
  user_agent: &str,
49
  client: &Client,
50
  _safe_search: u8,
51
+ ) -> Result<Vec<(String, SearchResult)>, EngineError> {
52
  // Bing uses `start results from this number` convention
53
  // So, for 10 results per page, page 0 starts at 1, page 1
54
  // starts at 11, and so on.
src/engines/brave.rs CHANGED
@@ -44,7 +44,7 @@ impl SearchEngine for Brave {
44
  user_agent: &str,
45
  client: &Client,
46
  safe_search: u8,
47
- ) -> Result<HashMap<String, SearchResult>, EngineError> {
48
  let url = format!("https://search.brave.com/search?q={query}&offset={page}");
49
 
50
  let safe_search_level = match safe_search {
 
44
  user_agent: &str,
45
  client: &Client,
46
  safe_search: u8,
47
+ ) -> Result<Vec<(String, SearchResult)>, EngineError> {
48
  let url = format!("https://search.brave.com/search?q={query}&offset={page}");
49
 
50
  let safe_search_level = match safe_search {
src/engines/duckduckgo.rs CHANGED
@@ -47,7 +47,7 @@ impl SearchEngine for DuckDuckGo {
47
  user_agent: &str,
48
  client: &Client,
49
  _safe_search: u8,
50
- ) -> Result<HashMap<String, SearchResult>, EngineError> {
51
  // Page number can be missing or empty string and so appropriate handling is required
52
  // so that upstream server recieves valid page number.
53
  let url: String = match page {
 
47
  user_agent: &str,
48
  client: &Client,
49
  _safe_search: u8,
50
+ ) -> Result<Vec<(String, SearchResult)>, EngineError> {
51
  // Page number can be missing or empty string and so appropriate handling is required
52
  // so that upstream server recieves valid page number.
53
  let url: String = match page {
src/engines/librex.rs CHANGED
@@ -62,7 +62,7 @@ impl SearchEngine for LibreX {
62
  user_agent: &str,
63
  client: &Client,
64
  _safe_search: u8,
65
- ) -> Result<HashMap<String, SearchResult>, EngineError> {
66
  // Page number can be missing or empty string and so appropriate handling is required
67
  // so that upstream server recieves valid page number.
68
  let url: String = format!(
 
62
  user_agent: &str,
63
  client: &Client,
64
  _safe_search: u8,
65
+ ) -> Result<Vec<(String, SearchResult)>, EngineError> {
66
  // Page number can be missing or empty string and so appropriate handling is required
67
  // so that upstream server recieves valid page number.
68
  let url: String = format!(
src/engines/mojeek.rs CHANGED
@@ -47,7 +47,7 @@ impl SearchEngine for Mojeek {
47
  user_agent: &str,
48
  client: &Client,
49
  safe_search: u8,
50
- ) -> Result<HashMap<String, SearchResult>, EngineError> {
51
  // Mojeek uses `start results from this number` convention
52
  // So, for 10 results per page, page 0 starts at 1, page 1
53
  // starts at 11, and so on.
@@ -72,8 +72,23 @@ impl SearchEngine for Mojeek {
72
  "Yep",
73
  "You",
74
  ];
 
75
  let qss = search_engines.join("%2C");
76
- let safe = if safe_search == 0 { "0" } else { "1" };
 
 
 
 
 
 
 
 
 
 
 
 
 
 
77
 
78
  // Mojeek detects automated requests, these are preferences that are
79
  // able to circumvent the countermeasure. Some of these are
@@ -89,7 +104,7 @@ impl SearchEngine for Mojeek {
89
  ("hp", "minimal"),
90
  ("lb", "en"),
91
  ("qss", &qss),
92
- ("safe", safe),
93
  ];
94
 
95
  let mut query_params_string = String::new();
 
47
  user_agent: &str,
48
  client: &Client,
49
  safe_search: u8,
50
+ ) -> Result<Vec<(String, SearchResult)>, EngineError> {
51
  // Mojeek uses `start results from this number` convention
52
  // So, for 10 results per page, page 0 starts at 1, page 1
53
  // starts at 11, and so on.
 
72
  "Yep",
73
  "You",
74
  ];
75
+
76
  let qss = search_engines.join("%2C");
77
+
78
+ // A branchless condition to check whether the `safe_search` parameter has the
79
+ // value 0 or not. If it is zero then it sets the value 0 otherwise it sets
80
+ // the value to 1 for all other values of `safe_search`
81
+ //
82
+ // Moreover, the below branchless code is equivalent to the following code below:
83
+ //
84
+ // ```rust
85
+ // let safe = if safe_search == 0 { 0 } else { 1 }.to_string();
86
+ // ```
87
+ //
88
+ // For more information on branchless programming. See:
89
+ //
90
+ // * https://piped.video/watch?v=bVJ-mWWL7cE
91
+ let safe = u8::from(safe_search != 0).to_string();
92
 
93
  // Mojeek detects automated requests, these are preferences that are
94
  // able to circumvent the countermeasure. Some of these are
 
104
  ("hp", "minimal"),
105
  ("lb", "en"),
106
  ("qss", &qss),
107
+ ("safe", &safe),
108
  ];
109
 
110
  let mut query_params_string = String::new();
src/engines/search_result_parser.rs CHANGED
@@ -1,5 +1,4 @@
1
  //! This modules provides helper functionalities for parsing a html document into internal SearchResult.
2
- use std::collections::HashMap;
3
 
4
  use crate::models::{aggregation_models::SearchResult, engine_models::EngineError};
5
  use error_stack::{Report, Result};
@@ -47,7 +46,7 @@ impl SearchResultParser {
47
  &self,
48
  document: &Html,
49
  builder: impl Fn(&ElementRef<'_>, &ElementRef<'_>, &ElementRef<'_>) -> Option<SearchResult>,
50
- ) -> Result<HashMap<String, SearchResult>, EngineError> {
51
  let res = document
52
  .select(&self.results)
53
  .filter_map(|result| {
 
1
  //! This modules provides helper functionalities for parsing a html document into internal SearchResult.
 
2
 
3
  use crate::models::{aggregation_models::SearchResult, engine_models::EngineError};
4
  use error_stack::{Report, Result};
 
46
  &self,
47
  document: &Html,
48
  builder: impl Fn(&ElementRef<'_>, &ElementRef<'_>, &ElementRef<'_>) -> Option<SearchResult>,
49
+ ) -> Result<Vec<(String, SearchResult)>, EngineError> {
50
  let res = document
51
  .select(&self.results)
52
  .filter_map(|result| {
src/engines/searx.rs CHANGED
@@ -43,12 +43,21 @@ impl SearchEngine for Searx {
43
  user_agent: &str,
44
  client: &Client,
45
  mut safe_search: u8,
46
- ) -> Result<HashMap<String, SearchResult>, EngineError> {
47
- // Page number can be missing or empty string and so appropriate handling is required
48
- // so that upstream server recieves valid page number.
49
- if safe_search == 3 {
50
- safe_search = 2;
51
- };
 
 
 
 
 
 
 
 
 
52
 
53
  let url: String = format!(
54
  "https://searx.be/search?q={query}&pageno={}&safesearch={safe_search}",
 
43
  user_agent: &str,
44
  client: &Client,
45
  mut safe_search: u8,
46
+ ) -> Result<Vec<(String, SearchResult)>, EngineError> {
47
+ // A branchless condition to check whether the `safe_search` parameter has the
48
+ // value greater than equal to three or not. If it is, then it modifies the
49
+ // `safesearch` parameters value to 2.
50
+ //
51
+ // Moreover, the below branchless code is equivalent to the following code below:
52
+ //
53
+ // ```rust
54
+ // safe_search = u8::from(safe_search == 3) * 2;
55
+ // ```
56
+ //
57
+ // For more information on branchless programming. See:
58
+ //
59
+ // * https://piped.video/watch?v=bVJ-mWWL7cE
60
+ safe_search = u8::from(safe_search >= 3) * 2;
61
 
62
  let url: String = format!(
63
  "https://searx.be/search?q={query}&pageno={}&safesearch={safe_search}",
src/engines/startpage.rs CHANGED
@@ -47,7 +47,7 @@ impl SearchEngine for Startpage {
47
  user_agent: &str,
48
  client: &Client,
49
  _safe_search: u8,
50
- ) -> Result<HashMap<String, SearchResult>, EngineError> {
51
  // Page number can be missing or empty string and so appropriate handling is required
52
  // so that upstream server recieves valid page number.
53
  let url: String = format!(
 
47
  user_agent: &str,
48
  client: &Client,
49
  _safe_search: u8,
50
+ ) -> Result<Vec<(String, SearchResult)>, EngineError> {
51
  // Page number can be missing or empty string and so appropriate handling is required
52
  // so that upstream server recieves valid page number.
53
  let url: String = format!(
src/lib.rs CHANGED
@@ -14,7 +14,7 @@ pub mod results;
14
  pub mod server;
15
  pub mod templates;
16
 
17
- use std::net::TcpListener;
18
 
19
  use crate::server::router;
20
 
@@ -31,6 +31,9 @@ use cache::cacher::{Cacher, SharedCache};
31
  use config::parser::Config;
32
  use handler::{file_path, FileType};
33
 
 
 
 
34
  /// Runs the web server on the provided TCP listener and returns a `Server` instance.
35
  ///
36
  /// # Arguments
@@ -44,27 +47,29 @@ use handler::{file_path, FileType};
44
  /// # Example
45
  ///
46
  /// ```rust
47
- /// use std::net::TcpListener;
48
  /// use websurfx::{config::parser::Config, run, cache::cacher::create_cache};
49
  ///
 
 
 
50
  /// #[tokio::main]
51
  /// async fn main(){
52
- /// let config = Config::parse(true).unwrap();
 
53
  /// let listener = TcpListener::bind("127.0.0.1:8080").expect("Failed to bind address");
54
- /// let cache = create_cache(&config).await;
55
- /// let server = run(listener,config,cache).expect("Failed to start server");
56
  /// }
57
  /// ```
58
  pub fn run(
59
  listener: TcpListener,
60
- config: Config,
61
  cache: impl Cacher + 'static,
62
  ) -> std::io::Result<Server> {
63
  let public_folder_path: &str = file_path(FileType::Theme)?;
64
 
65
- let cloned_config_threads_opt: u8 = config.threads;
66
-
67
- let cache = web::Data::new(SharedCache::new(cache));
68
 
69
  let server = HttpServer::new(move || {
70
  let cors: Cors = Cors::default()
@@ -81,8 +86,8 @@ pub fn run(
81
  // Compress the responses provided by the server for the client requests.
82
  .wrap(Compress::default())
83
  .wrap(Logger::default()) // added logging middleware for logging.
84
- .app_data(web::Data::new(config.clone()))
85
- .app_data(cache.clone())
86
  .wrap(cors)
87
  .wrap(Governor::new(
88
  &GovernorConfigBuilder::default()
@@ -107,7 +112,7 @@ pub fn run(
107
  .service(router::settings) // settings page
108
  .default_service(web::route().to(router::not_found)) // error page
109
  })
110
- .workers(cloned_config_threads_opt as usize)
111
  // Start server on 127.0.0.1 with the user provided port number. for example 127.0.0.1:8080.
112
  .listen(listener)?
113
  .run();
 
14
  pub mod server;
15
  pub mod templates;
16
 
17
+ use std::{net::TcpListener, sync::OnceLock};
18
 
19
  use crate::server::router;
20
 
 
31
  use config::parser::Config;
32
  use handler::{file_path, FileType};
33
 
34
+ /// A static constant for holding the cache struct.
35
+ static SHARED_CACHE: OnceLock<SharedCache> = OnceLock::new();
36
+
37
  /// Runs the web server on the provided TCP listener and returns a `Server` instance.
38
  ///
39
  /// # Arguments
 
47
  /// # Example
48
  ///
49
  /// ```rust
50
+ /// use std::{net::TcpListener, sync::OnceLock};
51
  /// use websurfx::{config::parser::Config, run, cache::cacher::create_cache};
52
  ///
53
+ /// /// A static constant for holding the parsed config.
54
+ /// static CONFIG: OnceLock<Config> = OnceLock::new();
55
+ ///
56
  /// #[tokio::main]
57
  /// async fn main(){
58
+ /// // Initialize the parsed config globally.
59
+ /// let config = CONFIG.get_or_init(|| Config::parse(true).unwrap());
60
  /// let listener = TcpListener::bind("127.0.0.1:8080").expect("Failed to bind address");
61
+ /// let cache = create_cache(config).await;
62
+ /// let server = run(listener,&config,cache).expect("Failed to start server");
63
  /// }
64
  /// ```
65
  pub fn run(
66
  listener: TcpListener,
67
+ config: &'static Config,
68
  cache: impl Cacher + 'static,
69
  ) -> std::io::Result<Server> {
70
  let public_folder_path: &str = file_path(FileType::Theme)?;
71
 
72
+ let cache = SHARED_CACHE.get_or_init(|| SharedCache::new(cache));
 
 
73
 
74
  let server = HttpServer::new(move || {
75
  let cors: Cors = Cors::default()
 
86
  // Compress the responses provided by the server for the client requests.
87
  .wrap(Compress::default())
88
  .wrap(Logger::default()) // added logging middleware for logging.
89
+ .app_data(web::Data::new(config))
90
+ .app_data(web::Data::new(cache))
91
  .wrap(cors)
92
  .wrap(Governor::new(
93
  &GovernorConfigBuilder::default()
 
112
  .service(router::settings) // settings page
113
  .default_service(web::route().to(router::not_found)) // error page
114
  })
115
+ .workers(config.threads as usize)
116
  // Start server on 127.0.0.1 with the user provided port number. for example 127.0.0.1:8080.
117
  .listen(listener)?
118
  .run();
src/models/aggregation_models.rs CHANGED
@@ -154,8 +154,8 @@ impl SearchResults {
154
  }
155
 
156
  /// A setter function that sets the filtered to true.
157
- pub fn set_filtered(&mut self) {
158
- self.filtered = true;
159
  }
160
 
161
  /// A getter function that gets the value of `engine_errors_info`.
 
154
  }
155
 
156
  /// A setter function that sets the filtered to true.
157
+ pub fn set_filtered(&mut self, filtered: bool) {
158
+ self.filtered = filtered;
159
  }
160
 
161
  /// A getter function that gets the value of `engine_errors_info`.
src/models/engine_models.rs CHANGED
@@ -4,7 +4,7 @@
4
  use super::aggregation_models::SearchResult;
5
  use error_stack::{Report, Result, ResultExt};
6
  use reqwest::Client;
7
- use std::{collections::HashMap, fmt};
8
 
9
  /// A custom error type used for handle engine associated errors.
10
  #[derive(Debug)]
@@ -147,7 +147,7 @@ pub trait SearchEngine: Sync + Send {
147
  user_agent: &str,
148
  client: &Client,
149
  safe_search: u8,
150
- ) -> Result<HashMap<String, SearchResult>, EngineError>;
151
  }
152
 
153
  /// A named struct which stores the engine struct with the name of the associated engine.
 
4
  use super::aggregation_models::SearchResult;
5
  use error_stack::{Report, Result, ResultExt};
6
  use reqwest::Client;
7
+ use std::fmt;
8
 
9
  /// A custom error type used for handle engine associated errors.
10
  #[derive(Debug)]
 
147
  user_agent: &str,
148
  client: &Client,
149
  safe_search: u8,
150
+ ) -> Result<Vec<(String, SearchResult)>, EngineError>;
151
  }
152
 
153
  /// A named struct which stores the engine struct with the name of the associated engine.
src/models/parser_models.rs CHANGED
@@ -10,7 +10,7 @@
10
  /// order to allow the deserializing the json back to struct in aggregate function in
11
  /// aggregator.rs and create a new struct out of it and then serialize it back to json and pass
12
  /// it to the template files.
13
- #[derive(Clone, Default)]
14
  pub struct Style {
15
  /// It stores the parsed theme option used to set a theme for the website.
16
  pub theme: String,
@@ -40,7 +40,6 @@ impl Style {
40
  }
41
 
42
  /// Configuration options for the aggregator.
43
- #[derive(Clone)]
44
  pub struct AggregatorConfig {
45
  /// It stores the option to whether enable or disable random delays between
46
  /// requests.
@@ -48,7 +47,6 @@ pub struct AggregatorConfig {
48
  }
49
 
50
  /// Configuration options for the rate limiter middleware.
51
- #[derive(Clone)]
52
  pub struct RateLimiter {
53
  /// The number of request that are allowed within a provided time limit.
54
  pub number_of_requests: u8,
 
10
  /// order to allow the deserializing the json back to struct in aggregate function in
11
  /// aggregator.rs and create a new struct out of it and then serialize it back to json and pass
12
  /// it to the template files.
13
+ #[derive(Default)]
14
  pub struct Style {
15
  /// It stores the parsed theme option used to set a theme for the website.
16
  pub theme: String,
 
40
  }
41
 
42
  /// Configuration options for the aggregator.
 
43
  pub struct AggregatorConfig {
44
  /// It stores the option to whether enable or disable random delays between
45
  /// requests.
 
47
  }
48
 
49
  /// Configuration options for the rate limiter middleware.
 
50
  pub struct RateLimiter {
51
  /// The number of request that are allowed within a provided time limit.
52
  pub number_of_requests: u8,
src/results/aggregator.rs CHANGED
@@ -9,22 +9,25 @@ use crate::models::{
9
  engine_models::{EngineError, EngineHandler},
10
  };
11
  use error_stack::Report;
 
12
  use regex::Regex;
13
  use reqwest::{Client, ClientBuilder};
 
14
  use std::time::{SystemTime, UNIX_EPOCH};
15
- use std::{
16
- collections::HashMap,
17
- io::{BufReader, Read},
 
18
  time::Duration,
19
  };
20
- use std::{fs::File, io::BufRead};
21
- use tokio::task::JoinHandle;
22
 
23
  /// A constant for holding the prebuilt Client globally in the app.
24
  static CLIENT: std::sync::OnceLock<Client> = std::sync::OnceLock::new();
25
 
26
  /// Aliases for long type annotations
27
- type FutureVec = Vec<JoinHandle<Result<HashMap<String, SearchResult>, Report<EngineError>>>>;
 
 
28
 
29
  /// The function aggregates the scraped results from the user-selected upstream search engines.
30
  /// These engines can be chosen either from the user interface (UI) or from the configuration file.
@@ -37,7 +40,7 @@ type FutureVec = Vec<JoinHandle<Result<HashMap<String, SearchResult>, Report<Eng
37
  ///
38
  /// Additionally, the function eliminates duplicate results. If two results are identified as coming from
39
  /// multiple engines, their names are combined to indicate that the results were fetched from these upstream
40
- /// engines. After this, all the data in the `HashMap` is removed and placed into a struct that contains all
41
  /// the aggregated results in a vector. Furthermore, the query used is also added to the struct. This step is
42
  /// necessary to ensure that the search bar in the search remains populated even when searched from the query URL.
43
  ///
@@ -94,15 +97,22 @@ pub async fn aggregate(
94
  let mut names: Vec<&str> = Vec::with_capacity(0);
95
 
96
  // create tasks for upstream result fetching
97
- let mut tasks: FutureVec = FutureVec::new();
98
 
 
99
  for engine_handler in upstream_search_engines {
100
- let (name, search_engine) = engine_handler.to_owned().into_name_engine();
101
  names.push(name);
102
- let query: String = query.to_owned();
103
  tasks.push(tokio::spawn(async move {
104
  search_engine
105
- .results(&query, page, user_agent, client, safe_search)
 
 
 
 
 
 
106
  .await
107
  }));
108
  }
@@ -117,7 +127,7 @@ pub async fn aggregate(
117
  }
118
 
119
  // aggregate search results, removing duplicates and handling errors the upstream engines returned
120
- let mut result_map: HashMap<String, SearchResult> = HashMap::new();
121
  let mut engine_errors_info: Vec<EngineErrorInfo> = Vec::new();
122
 
123
  let mut handle_error = |error: &Report<EngineError>, engine_name: &'static str| {
@@ -134,51 +144,45 @@ pub async fn aggregate(
134
 
135
  if result_map.is_empty() {
136
  match response {
137
- Ok(results) => {
138
- result_map = results.clone();
139
- }
140
- Err(error) => {
141
- handle_error(&error, engine);
142
- }
143
- }
144
  continue;
145
  }
146
 
147
  match response {
148
  Ok(result) => {
149
  result.into_iter().for_each(|(key, value)| {
150
- result_map
151
- .entry(key)
152
- .and_modify(|result| {
153
- result.add_engines(engine);
154
- })
155
- .or_insert_with(|| -> SearchResult { value });
156
  });
157
  }
158
- Err(error) => {
159
- handle_error(&error, engine);
160
- }
161
- }
162
  }
163
 
164
  if safe_search >= 3 {
165
- let mut blacklist_map: HashMap<String, SearchResult> = HashMap::new();
166
  filter_with_lists(
167
  &mut result_map,
168
  &mut blacklist_map,
169
  file_path(FileType::BlockList)?,
170
- )?;
 
171
 
172
  filter_with_lists(
173
  &mut blacklist_map,
174
  &mut result_map,
175
  file_path(FileType::AllowList)?,
176
- )?;
 
177
 
178
  drop(blacklist_map);
179
  }
180
 
181
- let results: Vec<SearchResult> = result_map.into_values().collect();
182
 
183
  Ok(SearchResults::new(results, &engine_errors_info))
184
  }
@@ -187,35 +191,41 @@ pub async fn aggregate(
187
  ///
188
  /// # Arguments
189
  ///
190
- /// * `map_to_be_filtered` - A mutable reference to a `HashMap` of search results to filter, where the filtered results will be removed from.
191
- /// * `resultant_map` - A mutable reference to a `HashMap` to hold the filtered results.
192
  /// * `file_path` - A `&str` representing the path to a file containing regex patterns to use for filtering.
193
  ///
194
  /// # Errors
195
  ///
196
  /// Returns an error if the file at `file_path` cannot be opened or read, or if a regex pattern is invalid.
197
- pub fn filter_with_lists(
198
- map_to_be_filtered: &mut HashMap<String, SearchResult>,
199
- resultant_map: &mut HashMap<String, SearchResult>,
200
  file_path: &str,
201
  ) -> Result<(), Box<dyn std::error::Error>> {
202
- let mut reader = BufReader::new(File::open(file_path)?);
 
203
 
204
- for line in reader.by_ref().lines() {
205
- let re = Regex::new(line?.trim())?;
206
 
 
 
207
  // Iterate over each search result in the map and check if it matches the regex pattern
208
- for (url, search_result) in map_to_be_filtered.clone().into_iter() {
209
- if re.is_match(&url.to_lowercase())
210
- || re.is_match(&search_result.title.to_lowercase())
211
- || re.is_match(&search_result.description.to_lowercase())
 
 
212
  {
213
- // If the search result matches the regex pattern, move it from the original map to the resultant map
214
- resultant_map.insert(
215
- url.to_owned(),
216
- map_to_be_filtered.remove(&url.to_owned()).unwrap(),
217
- );
218
- }
 
219
  }
220
  }
221
 
@@ -226,15 +236,14 @@ pub fn filter_with_lists(
226
  mod tests {
227
  use super::*;
228
  use smallvec::smallvec;
229
- use std::collections::HashMap;
230
  use std::io::Write;
231
  use tempfile::NamedTempFile;
232
 
233
- #[test]
234
- fn test_filter_with_lists() -> Result<(), Box<dyn std::error::Error>> {
235
  // Create a map of search results to filter
236
- let mut map_to_be_filtered = HashMap::new();
237
- map_to_be_filtered.insert(
238
  "https://www.example.com".to_owned(),
239
  SearchResult {
240
  title: "Example Domain".to_owned(),
@@ -243,15 +252,15 @@ mod tests {
243
  .to_owned(),
244
  engine: smallvec!["Google".to_owned(), "Bing".to_owned()],
245
  },
246
- );
247
- map_to_be_filtered.insert(
248
  "https://www.rust-lang.org/".to_owned(),
249
  SearchResult {
250
  title: "Rust Programming Language".to_owned(),
251
  url: "https://www.rust-lang.org/".to_owned(),
252
  description: "A systems programming language that runs blazingly fast, prevents segfaults, and guarantees thread safety.".to_owned(),
253
  engine: smallvec!["Google".to_owned(), "DuckDuckGo".to_owned()],
254
- },
255
  );
256
 
257
  // Create a temporary file with regex patterns
@@ -260,25 +269,30 @@ mod tests {
260
  writeln!(file, "rust")?;
261
  file.flush()?;
262
 
263
- let mut resultant_map = HashMap::new();
264
  filter_with_lists(
265
  &mut map_to_be_filtered,
266
  &mut resultant_map,
267
  file.path().to_str().unwrap(),
268
- )?;
 
269
 
270
  assert_eq!(resultant_map.len(), 2);
271
- assert!(resultant_map.contains_key("https://www.example.com"));
272
- assert!(resultant_map.contains_key("https://www.rust-lang.org/"));
 
 
 
 
273
  assert_eq!(map_to_be_filtered.len(), 0);
274
 
275
  Ok(())
276
  }
277
 
278
- #[test]
279
- fn test_filter_with_lists_wildcard() -> Result<(), Box<dyn std::error::Error>> {
280
- let mut map_to_be_filtered = HashMap::new();
281
- map_to_be_filtered.insert(
282
  "https://www.example.com".to_owned(),
283
  SearchResult {
284
  title: "Example Domain".to_owned(),
@@ -287,8 +301,8 @@ mod tests {
287
  .to_owned(),
288
  engine: smallvec!["Google".to_owned(), "Bing".to_owned()],
289
  },
290
- );
291
- map_to_be_filtered.insert(
292
  "https://www.rust-lang.org/".to_owned(),
293
  SearchResult {
294
  title: "Rust Programming Language".to_owned(),
@@ -296,34 +310,39 @@ mod tests {
296
  description: "A systems programming language that runs blazingly fast, prevents segfaults, and guarantees thread safety.".to_owned(),
297
  engine: smallvec!["Google".to_owned(), "DuckDuckGo".to_owned()],
298
  },
299
- );
300
 
301
  // Create a temporary file with a regex pattern containing a wildcard
302
  let mut file = NamedTempFile::new()?;
303
  writeln!(file, "ex.*le")?;
304
  file.flush()?;
305
 
306
- let mut resultant_map = HashMap::new();
307
 
308
  filter_with_lists(
309
  &mut map_to_be_filtered,
310
  &mut resultant_map,
311
  file.path().to_str().unwrap(),
312
- )?;
 
313
 
314
  assert_eq!(resultant_map.len(), 1);
315
- assert!(resultant_map.contains_key("https://www.example.com"));
 
 
316
  assert_eq!(map_to_be_filtered.len(), 1);
317
- assert!(map_to_be_filtered.contains_key("https://www.rust-lang.org/"));
 
 
318
 
319
  Ok(())
320
  }
321
 
322
- #[test]
323
- fn test_filter_with_lists_file_not_found() {
324
- let mut map_to_be_filtered = HashMap::new();
325
 
326
- let mut resultant_map = HashMap::new();
327
 
328
  // Call the `filter_with_lists` function with a non-existent file path
329
  let result = filter_with_lists(
@@ -332,13 +351,13 @@ mod tests {
332
  "non-existent-file.txt",
333
  );
334
 
335
- assert!(result.is_err());
336
  }
337
 
338
- #[test]
339
- fn test_filter_with_lists_invalid_regex() {
340
- let mut map_to_be_filtered = HashMap::new();
341
- map_to_be_filtered.insert(
342
  "https://www.example.com".to_owned(),
343
  SearchResult {
344
  title: "Example Domain".to_owned(),
@@ -347,9 +366,9 @@ mod tests {
347
  .to_owned(),
348
  engine: smallvec!["Google".to_owned(), "Bing".to_owned()],
349
  },
350
- );
351
 
352
- let mut resultant_map = HashMap::new();
353
 
354
  // Create a temporary file with an invalid regex pattern
355
  let mut file = NamedTempFile::new().unwrap();
@@ -362,6 +381,6 @@ mod tests {
362
  file.path().to_str().unwrap(),
363
  );
364
 
365
- assert!(result.is_err());
366
  }
367
  }
 
9
  engine_models::{EngineError, EngineHandler},
10
  };
11
  use error_stack::Report;
12
+ use futures::stream::FuturesUnordered;
13
  use regex::Regex;
14
  use reqwest::{Client, ClientBuilder};
15
+ use std::sync::Arc;
16
  use std::time::{SystemTime, UNIX_EPOCH};
17
+ use tokio::{
18
+ fs::File,
19
+ io::{AsyncBufReadExt, BufReader},
20
+ task::JoinHandle,
21
  time::Duration,
22
  };
 
 
23
 
24
  /// A constant for holding the prebuilt Client globally in the app.
25
  static CLIENT: std::sync::OnceLock<Client> = std::sync::OnceLock::new();
26
 
27
  /// Aliases for long type annotations
28
+
29
+ type FutureVec =
30
+ FuturesUnordered<JoinHandle<Result<Vec<(String, SearchResult)>, Report<EngineError>>>>;
31
 
32
  /// The function aggregates the scraped results from the user-selected upstream search engines.
33
  /// These engines can be chosen either from the user interface (UI) or from the configuration file.
 
40
  ///
41
  /// Additionally, the function eliminates duplicate results. If two results are identified as coming from
42
  /// multiple engines, their names are combined to indicate that the results were fetched from these upstream
43
+ /// engines. After this, all the data in the `Vec` is removed and placed into a struct that contains all
44
  /// the aggregated results in a vector. Furthermore, the query used is also added to the struct. This step is
45
  /// necessary to ensure that the search bar in the search remains populated even when searched from the query URL.
46
  ///
 
97
  let mut names: Vec<&str> = Vec::with_capacity(0);
98
 
99
  // create tasks for upstream result fetching
100
+ let tasks: FutureVec = FutureVec::new();
101
 
102
+ let query: Arc<String> = Arc::new(query.to_string());
103
  for engine_handler in upstream_search_engines {
104
+ let (name, search_engine) = engine_handler.clone().into_name_engine();
105
  names.push(name);
106
+ let query_partially_cloned = query.clone();
107
  tasks.push(tokio::spawn(async move {
108
  search_engine
109
+ .results(
110
+ &query_partially_cloned,
111
+ page,
112
+ user_agent,
113
+ client,
114
+ safe_search,
115
+ )
116
  .await
117
  }));
118
  }
 
127
  }
128
 
129
  // aggregate search results, removing duplicates and handling errors the upstream engines returned
130
+ let mut result_map: Vec<(String, SearchResult)> = Vec::new();
131
  let mut engine_errors_info: Vec<EngineErrorInfo> = Vec::new();
132
 
133
  let mut handle_error = |error: &Report<EngineError>, engine_name: &'static str| {
 
144
 
145
  if result_map.is_empty() {
146
  match response {
147
+ Ok(results) => result_map = results,
148
+ Err(error) => handle_error(&error, engine),
149
+ };
 
 
 
 
150
  continue;
151
  }
152
 
153
  match response {
154
  Ok(result) => {
155
  result.into_iter().for_each(|(key, value)| {
156
+ match result_map.iter().find(|(key_s, _)| key_s == &key) {
157
+ Some(value) => value.1.to_owned().add_engines(engine),
158
+ None => result_map.push((key, value)),
159
+ };
 
 
160
  });
161
  }
162
+ Err(error) => handle_error(&error, engine),
163
+ };
 
 
164
  }
165
 
166
  if safe_search >= 3 {
167
+ let mut blacklist_map: Vec<(String, SearchResult)> = Vec::new();
168
  filter_with_lists(
169
  &mut result_map,
170
  &mut blacklist_map,
171
  file_path(FileType::BlockList)?,
172
+ )
173
+ .await?;
174
 
175
  filter_with_lists(
176
  &mut blacklist_map,
177
  &mut result_map,
178
  file_path(FileType::AllowList)?,
179
+ )
180
+ .await?;
181
 
182
  drop(blacklist_map);
183
  }
184
 
185
+ let results: Vec<SearchResult> = result_map.iter().map(|(_, value)| value.clone()).collect();
186
 
187
  Ok(SearchResults::new(results, &engine_errors_info))
188
  }
 
191
  ///
192
  /// # Arguments
193
  ///
194
+ /// * `map_to_be_filtered` - A mutable reference to a `Vec` of search results to filter, where the filtered results will be removed from.
195
+ /// * `resultant_map` - A mutable reference to a `Vec` to hold the filtered results.
196
  /// * `file_path` - A `&str` representing the path to a file containing regex patterns to use for filtering.
197
  ///
198
  /// # Errors
199
  ///
200
  /// Returns an error if the file at `file_path` cannot be opened or read, or if a regex pattern is invalid.
201
+ pub async fn filter_with_lists(
202
+ map_to_be_filtered: &mut Vec<(String, SearchResult)>,
203
+ resultant_map: &mut Vec<(String, SearchResult)>,
204
  file_path: &str,
205
  ) -> Result<(), Box<dyn std::error::Error>> {
206
+ let reader = BufReader::new(File::open(file_path).await?);
207
+ let mut lines = reader.lines();
208
 
209
+ while let Some(line) = lines.next_line().await? {
210
+ let re = Regex::new(line.trim())?;
211
 
212
+ let mut length = map_to_be_filtered.len();
213
+ let mut idx: usize = Default::default();
214
  // Iterate over each search result in the map and check if it matches the regex pattern
215
+ while idx < length {
216
+ let ele = &map_to_be_filtered[idx];
217
+ let ele_inner = &ele.1;
218
+ match re.is_match(&ele.0.to_lowercase())
219
+ || re.is_match(&ele_inner.title.to_lowercase())
220
+ || re.is_match(&ele_inner.description.to_lowercase())
221
  {
222
+ true => {
223
+ // If the search result matches the regex pattern, move it from the original map to the resultant map
224
+ resultant_map.push(map_to_be_filtered.swap_remove(idx));
225
+ length -= 1;
226
+ }
227
+ false => idx += 1,
228
+ };
229
  }
230
  }
231
 
 
236
  mod tests {
237
  use super::*;
238
  use smallvec::smallvec;
 
239
  use std::io::Write;
240
  use tempfile::NamedTempFile;
241
 
242
+ #[tokio::test]
243
+ async fn test_filter_with_lists() -> Result<(), Box<dyn std::error::Error>> {
244
  // Create a map of search results to filter
245
+ let mut map_to_be_filtered = Vec::new();
246
+ map_to_be_filtered.push((
247
  "https://www.example.com".to_owned(),
248
  SearchResult {
249
  title: "Example Domain".to_owned(),
 
252
  .to_owned(),
253
  engine: smallvec!["Google".to_owned(), "Bing".to_owned()],
254
  },
255
+ ));
256
+ map_to_be_filtered.push((
257
  "https://www.rust-lang.org/".to_owned(),
258
  SearchResult {
259
  title: "Rust Programming Language".to_owned(),
260
  url: "https://www.rust-lang.org/".to_owned(),
261
  description: "A systems programming language that runs blazingly fast, prevents segfaults, and guarantees thread safety.".to_owned(),
262
  engine: smallvec!["Google".to_owned(), "DuckDuckGo".to_owned()],
263
+ },)
264
  );
265
 
266
  // Create a temporary file with regex patterns
 
269
  writeln!(file, "rust")?;
270
  file.flush()?;
271
 
272
+ let mut resultant_map = Vec::new();
273
  filter_with_lists(
274
  &mut map_to_be_filtered,
275
  &mut resultant_map,
276
  file.path().to_str().unwrap(),
277
+ )
278
+ .await?;
279
 
280
  assert_eq!(resultant_map.len(), 2);
281
+ assert!(resultant_map
282
+ .iter()
283
+ .any(|(key, _)| key == "https://www.example.com"));
284
+ assert!(resultant_map
285
+ .iter()
286
+ .any(|(key, _)| key == "https://www.rust-lang.org/"));
287
  assert_eq!(map_to_be_filtered.len(), 0);
288
 
289
  Ok(())
290
  }
291
 
292
+ #[tokio::test]
293
+ async fn test_filter_with_lists_wildcard() -> Result<(), Box<dyn std::error::Error>> {
294
+ let mut map_to_be_filtered = Vec::new();
295
+ map_to_be_filtered.push((
296
  "https://www.example.com".to_owned(),
297
  SearchResult {
298
  title: "Example Domain".to_owned(),
 
301
  .to_owned(),
302
  engine: smallvec!["Google".to_owned(), "Bing".to_owned()],
303
  },
304
+ ));
305
+ map_to_be_filtered.push((
306
  "https://www.rust-lang.org/".to_owned(),
307
  SearchResult {
308
  title: "Rust Programming Language".to_owned(),
 
310
  description: "A systems programming language that runs blazingly fast, prevents segfaults, and guarantees thread safety.".to_owned(),
311
  engine: smallvec!["Google".to_owned(), "DuckDuckGo".to_owned()],
312
  },
313
+ ));
314
 
315
  // Create a temporary file with a regex pattern containing a wildcard
316
  let mut file = NamedTempFile::new()?;
317
  writeln!(file, "ex.*le")?;
318
  file.flush()?;
319
 
320
+ let mut resultant_map = Vec::new();
321
 
322
  filter_with_lists(
323
  &mut map_to_be_filtered,
324
  &mut resultant_map,
325
  file.path().to_str().unwrap(),
326
+ )
327
+ .await?;
328
 
329
  assert_eq!(resultant_map.len(), 1);
330
+ assert!(resultant_map
331
+ .iter()
332
+ .any(|(key, _)| key == "https://www.example.com"));
333
  assert_eq!(map_to_be_filtered.len(), 1);
334
+ assert!(map_to_be_filtered
335
+ .iter()
336
+ .any(|(key, _)| key == "https://www.rust-lang.org/"));
337
 
338
  Ok(())
339
  }
340
 
341
+ #[tokio::test]
342
+ async fn test_filter_with_lists_file_not_found() {
343
+ let mut map_to_be_filtered = Vec::new();
344
 
345
+ let mut resultant_map = Vec::new();
346
 
347
  // Call the `filter_with_lists` function with a non-existent file path
348
  let result = filter_with_lists(
 
351
  "non-existent-file.txt",
352
  );
353
 
354
+ assert!(result.await.is_err());
355
  }
356
 
357
+ #[tokio::test]
358
+ async fn test_filter_with_lists_invalid_regex() {
359
+ let mut map_to_be_filtered = Vec::new();
360
+ map_to_be_filtered.push((
361
  "https://www.example.com".to_owned(),
362
  SearchResult {
363
  title: "Example Domain".to_owned(),
 
366
  .to_owned(),
367
  engine: smallvec!["Google".to_owned(), "Bing".to_owned()],
368
  },
369
+ ));
370
 
371
+ let mut resultant_map = Vec::new();
372
 
373
  // Create a temporary file with an invalid regex pattern
374
  let mut file = NamedTempFile::new().unwrap();
 
381
  file.path().to_str().unwrap(),
382
  );
383
 
384
+ assert!(result.await.is_err());
385
  }
386
  }
src/server/router.rs CHANGED
@@ -7,11 +7,13 @@ use crate::{
7
  handler::{file_path, FileType},
8
  };
9
  use actix_web::{get, http::header::ContentType, web, HttpRequest, HttpResponse};
10
- use std::fs::read_to_string;
11
 
12
  /// Handles the route of index page or main page of the `websurfx` meta search engine website.
13
  #[get("/")]
14
- pub async fn index(config: web::Data<Config>) -> Result<HttpResponse, Box<dyn std::error::Error>> {
 
 
15
  Ok(HttpResponse::Ok().content_type(ContentType::html()).body(
16
  crate::templates::views::index::index(
17
  &config.style.colorscheme,
@@ -25,7 +27,7 @@ pub async fn index(config: web::Data<Config>) -> Result<HttpResponse, Box<dyn st
25
  /// Handles the route of any other accessed route/page which is not provided by the
26
  /// website essentially the 404 error page.
27
  pub async fn not_found(
28
- config: web::Data<Config>,
29
  ) -> Result<HttpResponse, Box<dyn std::error::Error>> {
30
  Ok(HttpResponse::Ok().content_type(ContentType::html()).body(
31
  crate::templates::views::not_found::not_found(
@@ -41,7 +43,7 @@ pub async fn not_found(
41
  #[get("/robots.txt")]
42
  pub async fn robots_data(_req: HttpRequest) -> Result<HttpResponse, Box<dyn std::error::Error>> {
43
  let page_content: String =
44
- read_to_string(format!("{}/robots.txt", file_path(FileType::Theme)?))?;
45
  Ok(HttpResponse::Ok()
46
  .content_type(ContentType::plaintext())
47
  .body(page_content))
@@ -49,7 +51,9 @@ pub async fn robots_data(_req: HttpRequest) -> Result<HttpResponse, Box<dyn std:
49
 
50
  /// Handles the route of about page of the `websurfx` meta search engine website.
51
  #[get("/about")]
52
- pub async fn about(config: web::Data<Config>) -> Result<HttpResponse, Box<dyn std::error::Error>> {
 
 
53
  Ok(HttpResponse::Ok().content_type(ContentType::html()).body(
54
  crate::templates::views::about::about(
55
  &config.style.colorscheme,
@@ -63,7 +67,7 @@ pub async fn about(config: web::Data<Config>) -> Result<HttpResponse, Box<dyn st
63
  /// Handles the route of settings page of the `websurfx` meta search engine website.
64
  #[get("/settings")]
65
  pub async fn settings(
66
- config: web::Data<Config>,
67
  ) -> Result<HttpResponse, Box<dyn std::error::Error>> {
68
  Ok(HttpResponse::Ok().content_type(ContentType::html()).body(
69
  crate::templates::views::settings::settings(
 
7
  handler::{file_path, FileType},
8
  };
9
  use actix_web::{get, http::header::ContentType, web, HttpRequest, HttpResponse};
10
+ use tokio::fs::read_to_string;
11
 
12
  /// Handles the route of index page or main page of the `websurfx` meta search engine website.
13
  #[get("/")]
14
+ pub async fn index(
15
+ config: web::Data<&'static Config>,
16
+ ) -> Result<HttpResponse, Box<dyn std::error::Error>> {
17
  Ok(HttpResponse::Ok().content_type(ContentType::html()).body(
18
  crate::templates::views::index::index(
19
  &config.style.colorscheme,
 
27
  /// Handles the route of any other accessed route/page which is not provided by the
28
  /// website essentially the 404 error page.
29
  pub async fn not_found(
30
+ config: web::Data<&'static Config>,
31
  ) -> Result<HttpResponse, Box<dyn std::error::Error>> {
32
  Ok(HttpResponse::Ok().content_type(ContentType::html()).body(
33
  crate::templates::views::not_found::not_found(
 
43
  #[get("/robots.txt")]
44
  pub async fn robots_data(_req: HttpRequest) -> Result<HttpResponse, Box<dyn std::error::Error>> {
45
  let page_content: String =
46
+ read_to_string(format!("{}/robots.txt", file_path(FileType::Theme)?)).await?;
47
  Ok(HttpResponse::Ok()
48
  .content_type(ContentType::plaintext())
49
  .body(page_content))
 
51
 
52
  /// Handles the route of about page of the `websurfx` meta search engine website.
53
  #[get("/about")]
54
+ pub async fn about(
55
+ config: web::Data<&'static Config>,
56
+ ) -> Result<HttpResponse, Box<dyn std::error::Error>> {
57
  Ok(HttpResponse::Ok().content_type(ContentType::html()).body(
58
  crate::templates::views::about::about(
59
  &config.style.colorscheme,
 
67
  /// Handles the route of settings page of the `websurfx` meta search engine website.
68
  #[get("/settings")]
69
  pub async fn settings(
70
+ config: web::Data<&'static Config>,
71
  ) -> Result<HttpResponse, Box<dyn std::error::Error>> {
72
  Ok(HttpResponse::Ok().content_type(ContentType::html()).body(
73
  crate::templates::views::settings::settings(
src/server/routes/search.rs CHANGED
@@ -13,12 +13,12 @@ use crate::{
13
  };
14
  use actix_web::{get, http::header::ContentType, web, HttpRequest, HttpResponse};
15
  use regex::Regex;
16
- use std::{
17
- borrow::Cow,
18
  fs::File,
19
- io::{BufRead, BufReader, Read},
 
20
  };
21
- use tokio::join;
22
 
23
  /// Handles the route of search page of the `websurfx` meta search engine website and it takes
24
  /// two search url parameters `q` and `page` where `page` parameter is optional.
@@ -37,8 +37,8 @@ use tokio::join;
37
  #[get("/search")]
38
  pub async fn search(
39
  req: HttpRequest,
40
- config: web::Data<Config>,
41
- cache: web::Data<SharedCache>,
42
  ) -> Result<HttpResponse, Box<dyn std::error::Error>> {
43
  use std::sync::Arc;
44
  let params = web::Query::<SearchParams>::from_query(req.query_string())?;
@@ -70,8 +70,8 @@ pub async fn search(
70
  });
71
 
72
  search_settings.safe_search_level = get_safesearch_level(
73
- &Some(search_settings.safe_search_level),
74
- &params.safesearch,
75
  config.safe_search,
76
  );
77
 
@@ -158,8 +158,8 @@ pub async fn search(
158
  /// It returns the `SearchResults` struct if the search results could be successfully fetched from
159
  /// the cache or from the upstream search engines otherwise it returns an appropriate error.
160
  async fn results(
161
- config: &Config,
162
- cache: &web::Data<SharedCache>,
163
  query: &str,
164
  page: u32,
165
  search_settings: &server_models::Cookie<'_>,
@@ -188,7 +188,7 @@ async fn results(
188
  let mut results: SearchResults = SearchResults::default();
189
 
190
  let flag: bool =
191
- !is_match_from_filter_list(file_path(FileType::BlockList)?, query)?;
192
  // Return early when query contains disallowed words,
193
  if flag {
194
  results.set_disallowed();
@@ -225,12 +225,12 @@ async fn results(
225
  search_results
226
  }
227
  };
228
- if results.engine_errors_info().is_empty()
229
- && results.results().is_empty()
230
- && !results.no_engines_selected()
231
- {
232
- results.set_filtered();
233
- }
234
  cache
235
  .cache_results(&[results.clone()], &[cache_key.clone()])
236
  .await?;
@@ -252,13 +252,14 @@ async fn results(
252
  ///
253
  /// Returns a bool indicating whether the results were found in the list or not on success
254
  /// otherwise returns a standard error type on a failure.
255
- fn is_match_from_filter_list(
256
  file_path: &str,
257
  query: &str,
258
  ) -> Result<bool, Box<dyn std::error::Error>> {
259
- let mut reader = BufReader::new(File::open(file_path)?);
260
- for line in reader.by_ref().lines() {
261
- let re = Regex::new(&line?)?;
 
262
  if re.is_match(query) {
263
  return Ok(true);
264
  }
@@ -267,24 +268,95 @@ fn is_match_from_filter_list(
267
  Ok(false)
268
  }
269
 
270
- /// A helper function to modify the safe search level based on the url params.
271
- /// The `safe_search` is the one in the user's cookie or
272
- /// the default set by the server config if the cookie was missing.
273
  ///
274
  /// # Argurments
275
  ///
276
- /// * `url_level` - Safe search level from the url.
277
- /// * `safe_search` - User's cookie, or the safe search level set by the server
278
- /// * `config_level` - Safe search level to fall back to
279
- fn get_safesearch_level(cookie_level: &Option<u8>, url_level: &Option<u8>, config_level: u8) -> u8 {
280
- match url_level {
281
- Some(url_level) => {
282
- if *url_level >= 3 {
283
- config_level
284
- } else {
285
- *url_level
286
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
287
  }
288
- None => cookie_level.unwrap_or(config_level),
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
289
  }
290
  }
 
13
  };
14
  use actix_web::{get, http::header::ContentType, web, HttpRequest, HttpResponse};
15
  use regex::Regex;
16
+ use std::borrow::Cow;
17
+ use tokio::{
18
  fs::File,
19
+ io::{AsyncBufReadExt, BufReader},
20
+ join,
21
  };
 
22
 
23
  /// Handles the route of search page of the `websurfx` meta search engine website and it takes
24
  /// two search url parameters `q` and `page` where `page` parameter is optional.
 
37
  #[get("/search")]
38
  pub async fn search(
39
  req: HttpRequest,
40
+ config: web::Data<&'static Config>,
41
+ cache: web::Data<&'static SharedCache>,
42
  ) -> Result<HttpResponse, Box<dyn std::error::Error>> {
43
  use std::sync::Arc;
44
  let params = web::Query::<SearchParams>::from_query(req.query_string())?;
 
70
  });
71
 
72
  search_settings.safe_search_level = get_safesearch_level(
73
+ params.safesearch,
74
+ search_settings.safe_search_level,
75
  config.safe_search,
76
  );
77
 
 
158
  /// It returns the `SearchResults` struct if the search results could be successfully fetched from
159
  /// the cache or from the upstream search engines otherwise it returns an appropriate error.
160
  async fn results(
161
+ config: &'static Config,
162
+ cache: &'static SharedCache,
163
  query: &str,
164
  page: u32,
165
  search_settings: &server_models::Cookie<'_>,
 
188
  let mut results: SearchResults = SearchResults::default();
189
 
190
  let flag: bool =
191
+ !is_match_from_filter_list(file_path(FileType::BlockList)?, query).await?;
192
  // Return early when query contains disallowed words,
193
  if flag {
194
  results.set_disallowed();
 
225
  search_results
226
  }
227
  };
228
+ let (engine_errors_info, results_empty_check, no_engines_selected) = (
229
+ results.engine_errors_info().is_empty(),
230
+ results.results().is_empty(),
231
+ results.no_engines_selected(),
232
+ );
233
+ results.set_filtered(engine_errors_info & results_empty_check & !no_engines_selected);
234
  cache
235
  .cache_results(&[results.clone()], &[cache_key.clone()])
236
  .await?;
 
252
  ///
253
  /// Returns a bool indicating whether the results were found in the list or not on success
254
  /// otherwise returns a standard error type on a failure.
255
+ async fn is_match_from_filter_list(
256
  file_path: &str,
257
  query: &str,
258
  ) -> Result<bool, Box<dyn std::error::Error>> {
259
+ let reader = BufReader::new(File::open(file_path).await?);
260
+ let mut lines = reader.lines();
261
+ while let Some(line) = lines.next_line().await? {
262
+ let re = Regex::new(&line)?;
263
  if re.is_match(query) {
264
  return Ok(true);
265
  }
 
268
  Ok(false)
269
  }
270
 
271
+ /// A helper function to choose the safe search level value based on the URL parameters,
272
+ /// cookie value and config value.
 
273
  ///
274
  /// # Argurments
275
  ///
276
+ /// * `safe_search_level_from_url` - Safe search level from the URL parameters.
277
+ /// * `cookie_safe_search_level` - Safe search level value from the cookie.
278
+ /// * `config_safe_search_level` - Safe search level value from the config file.
279
+ ///
280
+ /// # Returns
281
+ ///
282
+ /// Returns an appropriate safe search level value based on the safe search level values
283
+ /// from the URL parameters, cookie and the config file.
284
+ fn get_safesearch_level(
285
+ safe_search_level_from_url: Option<u8>,
286
+ cookie_safe_search_level: u8,
287
+ config_safe_search_level: u8,
288
+ ) -> u8 {
289
+ (u8::from(safe_search_level_from_url.is_some())
290
+ * ((u8::from(config_safe_search_level >= 3) * config_safe_search_level)
291
+ + (u8::from(config_safe_search_level < 3) * safe_search_level_from_url.unwrap_or(0))))
292
+ + (u8::from(safe_search_level_from_url.is_none())
293
+ * ((u8::from(config_safe_search_level >= 3) * config_safe_search_level)
294
+ + (u8::from(config_safe_search_level < 3) * cookie_safe_search_level)))
295
+ }
296
+
297
+ #[cfg(test)]
298
+ mod tests {
299
+ use std::time::{SystemTime, UNIX_EPOCH};
300
+
301
+ /// A helper function which creates a random mock safe search level value.
302
+ ///
303
+ /// # Returns
304
+ ///
305
+ /// Returns an optional u8 value.
306
+ fn mock_safe_search_level_value() -> Option<u8> {
307
+ let nanos = SystemTime::now()
308
+ .duration_since(UNIX_EPOCH)
309
+ .unwrap_or_default()
310
+ .subsec_nanos() as f32;
311
+ let delay = ((nanos / 1_0000_0000 as f32).floor() as i8) - 1;
312
+
313
+ match delay {
314
+ -1 => None,
315
+ some_num => Some(if some_num > 4 { some_num - 4 } else { some_num } as u8),
316
  }
317
+ }
318
+
319
+ #[test]
320
+ /// A test function to test whether the output of the branchless and branched code
321
+ /// for the code to choose the appropriate safe search level is same or not.
322
+ fn get_safesearch_level_branched_branchless_code_test() {
323
+ // Get mock values for the safe search level values for URL parameters, cookie
324
+ // and config.
325
+ let safe_search_level_from_url = mock_safe_search_level_value();
326
+ let cookie_safe_search_level = mock_safe_search_level_value().unwrap_or(0);
327
+ let config_safe_search_level = mock_safe_search_level_value().unwrap_or(0);
328
+
329
+ // Branched code
330
+ let safe_search_level_value_from_branched_code = match safe_search_level_from_url {
331
+ Some(safe_search_level_from_url_parsed) => {
332
+ if config_safe_search_level >= 3 {
333
+ config_safe_search_level
334
+ } else {
335
+ safe_search_level_from_url_parsed
336
+ }
337
+ }
338
+ None => {
339
+ if config_safe_search_level >= 3 {
340
+ config_safe_search_level
341
+ } else {
342
+ cookie_safe_search_level
343
+ }
344
+ }
345
+ };
346
+
347
+ // branchless code
348
+ let safe_search_level_value_from_branchless_code =
349
+ (u8::from(safe_search_level_from_url.is_some())
350
+ * ((u8::from(config_safe_search_level >= 3) * config_safe_search_level)
351
+ + (u8::from(config_safe_search_level < 3)
352
+ * safe_search_level_from_url.unwrap_or(0))))
353
+ + (u8::from(safe_search_level_from_url.is_none())
354
+ * ((u8::from(config_safe_search_level >= 3) * config_safe_search_level)
355
+ + (u8::from(config_safe_search_level < 3) * cookie_safe_search_level)));
356
+
357
+ assert_eq!(
358
+ safe_search_level_value_from_branched_code,
359
+ safe_search_level_value_from_branchless_code
360
+ );
361
  }
362
  }
src/templates/partials/settings_tabs/engines.rs CHANGED
@@ -55,7 +55,7 @@ pub fn engines(engine_names: &HashMap<String, bool>) -> Markup {
55
  input type="checkbox" class="engine" checked;
56
  span class="slider round"{}
57
  }
58
- (format!("{}{}",engine_name[..1].to_uppercase().to_owned(), engine_name[1..].to_owned()))
59
  }
60
  }
61
  @else {
@@ -64,7 +64,7 @@ pub fn engines(engine_names: &HashMap<String, bool>) -> Markup {
64
  input type="checkbox" class="engine";
65
  span class="slider round"{}
66
  }
67
- (format!("{}{}",engine_name[..1].to_uppercase().to_owned(), engine_name[1..].to_owned()))
68
  }
69
  }
70
  }
 
55
  input type="checkbox" class="engine" checked;
56
  span class="slider round"{}
57
  }
58
+ (format!("{}{}",&engine_name[..1].to_uppercase(), &engine_name[1..]))
59
  }
60
  }
61
  @else {
 
64
  input type="checkbox" class="engine";
65
  span class="slider round"{}
66
  }
67
+ (format!("{}{}",&engine_name[..1], &engine_name[1..]))
68
  }
69
  }
70
  }
src/templates/partials/settings_tabs/user_interface.rs CHANGED
@@ -36,7 +36,7 @@ fn style_option_list(
36
  }
37
 
38
  if style_type == "animations" {
39
- style_option_names.push(("".to_owned(), "none".to_owned()))
40
  }
41
 
42
  Ok(style_option_names)
@@ -83,9 +83,11 @@ pub fn user_interface(
83
  "Select the animation for your theme to be used in user interface"
84
  }
85
  select name="animations"{
 
 
86
  // Sets the user selected animation name from the config file as the first option in the selection list.
87
- option value=(animation.as_ref().unwrap_or(&"".to_owned())){(animation.as_ref().unwrap_or(&"".to_owned()).replace('-'," "))}
88
- @for (k,v) in style_option_list("animations", animation.as_ref().unwrap_or(&"".to_owned()))?{
89
  option value=(k){(v)}
90
  }
91
  }
 
36
  }
37
 
38
  if style_type == "animations" {
39
+ style_option_names.push((String::default(), "none".to_owned()))
40
  }
41
 
42
  Ok(style_option_names)
 
83
  "Select the animation for your theme to be used in user interface"
84
  }
85
  select name="animations"{
86
+ @let default_animation = &String::default();
87
+ @let animation = animation.as_ref().unwrap_or(default_animation);
88
  // Sets the user selected animation name from the config file as the first option in the selection list.
89
+ option value=(animation){(animation.replace('-'," "))}
90
+ @for (k,v) in style_option_list("animations", animation)?{
91
  option value=(k){(v)}
92
  }
93
  }
src/templates/views/search.rs CHANGED
@@ -38,7 +38,7 @@ pub fn search(
38
  small{(result.url)}
39
  p{(PreEscaped(&result.description))}
40
  .upstream_engines{
41
- @for name in result.clone().engine{
42
  span{(name)}
43
  }
44
  }
 
38
  small{(result.url)}
39
  p{(PreEscaped(&result.description))}
40
  .upstream_engines{
41
+ @for name in &result.engine {
42
  span{(name)}
43
  }
44
  }
tests/index.rs CHANGED
@@ -1,14 +1,17 @@
1
- use std::net::TcpListener;
2
 
3
  use websurfx::{config::parser::Config, run, templates::views};
4
 
 
 
 
5
  // Starts a new instance of the HTTP server, bound to a random available port
6
  async fn spawn_app() -> String {
7
  // Binding to port 0 will trigger the OS to assign a port for us.
8
  let listener = TcpListener::bind("127.0.0.1:0").expect("Failed to bind random port");
9
  let port = listener.local_addr().unwrap().port();
10
- let config = Config::parse(false).unwrap();
11
- let cache = websurfx::cache::cacher::create_cache(&config).await;
12
  let server = run(listener, config, cache).expect("Failed to bind address");
13
 
14
  tokio::spawn(server);
 
1
+ use std::{net::TcpListener, sync::OnceLock};
2
 
3
  use websurfx::{config::parser::Config, run, templates::views};
4
 
5
+ /// A static constant for holding the parsed config.
6
+ static CONFIG: OnceLock<Config> = OnceLock::new();
7
+
8
  // Starts a new instance of the HTTP server, bound to a random available port
9
  async fn spawn_app() -> String {
10
  // Binding to port 0 will trigger the OS to assign a port for us.
11
  let listener = TcpListener::bind("127.0.0.1:0").expect("Failed to bind random port");
12
  let port = listener.local_addr().unwrap().port();
13
+ let config = CONFIG.get_or_init(|| Config::parse(false).unwrap());
14
+ let cache = websurfx::cache::cacher::create_cache(config).await;
15
  let server = run(listener, config, cache).expect("Failed to bind address");
16
 
17
  tokio::spawn(server);