toolkit for mdBook [mirror of my GitHub repo] docs.tonywu.dev/mdbookkit/
permalinks rust-analyzer mdbook
0
fork

Configure Feed

Select the types of activity you want to include in your feed.

init

Tony Wu 7724443a

+3414
+17
.editorconfig
··· 1 + # http://editorconfig.org 2 + root = true 3 + 4 + [*] 5 + indent_style = space 6 + indent_size = 4 7 + end_of_line = lf 8 + charset = utf-8 9 + trim_trailing_whitespace = true 10 + insert_final_newline = true 11 + max_line_length = 88 12 + 13 + [*.{json,yaml,yml,toml,js,jsx,ts,tsx,mjs,mts,cjs,md,mdx,html,css,scss}] 14 + indent_size = 2 15 + 16 + [Makefile] 17 + indent_style = tab
+156
.gitignore
··· 1 + # Generated by Cargo 2 + # will have compiled files and executables 3 + debug/ 4 + target/ 5 + 6 + # Remove Cargo.lock from gitignore if creating an executable, leave it for libraries 7 + # More information here https://doc.rust-lang.org/cargo/guide/cargo-toml-vs-cargo-lock.html 8 + #Cargo.lock 9 + 10 + # These are backup files generated by rustfmt 11 + **/*.rs.bk 12 + 13 + # MSVC Windows builds of rustc generate these, which store debugging information 14 + *.pdb 15 + 16 + # RustRover 17 + # JetBrains specific template is maintained in a separate JetBrains.gitignore that can 18 + # be found at https://github.com/github/gitignore/blob/main/Global/JetBrains.gitignore 19 + # and can be added to the global gitignore or merged into this file. For a more nuclear 20 + # option (not recommended) you can uncomment the following to ignore the entire idea folder. 21 + #.idea/ 22 + 23 + # Logs 24 + logs 25 + *.log 26 + npm-debug.log* 27 + yarn-debug.log* 28 + yarn-error.log* 29 + lerna-debug.log* 30 + .pnpm-debug.log* 31 + 32 + # Diagnostic reports (https://nodejs.org/api/report.html) 33 + report.[0-9]*.[0-9]*.[0-9]*.[0-9]*.json 34 + 35 + # Runtime data 36 + pids 37 + *.pid 38 + *.seed 39 + *.pid.lock 40 + 41 + # Directory for instrumented libs generated by jscoverage/JSCover 42 + lib-cov 43 + 44 + # Coverage directory used by tools like istanbul 45 + coverage 46 + *.lcov 47 + 48 + # nyc test coverage 49 + .nyc_output 50 + 51 + # Grunt intermediate storage (https://gruntjs.com/creating-plugins#storing-task-files) 52 + .grunt 53 + 54 + # Bower dependency directory (https://bower.io/) 55 + bower_components 56 + 57 + # node-waf configuration 58 + .lock-wscript 59 + 60 + # Compiled binary addons (https://nodejs.org/api/addons.html) 61 + build/Release 62 + 63 + # Dependency directories 64 + node_modules/ 65 + jspm_packages/ 66 + 67 + # Snowpack dependency directory (https://snowpack.dev/) 68 + web_modules/ 69 + 70 + # TypeScript cache 71 + *.tsbuildinfo 72 + 73 + # Optional npm cache directory 74 + .npm 75 + 76 + # Optional eslint cache 77 + .eslintcache 78 + 79 + # Optional stylelint cache 80 + .stylelintcache 81 + 82 + # Microbundle cache 83 + .rpt2_cache/ 84 + .rts2_cache_cjs/ 85 + .rts2_cache_es/ 86 + .rts2_cache_umd/ 87 + 88 + # Optional REPL history 89 + .node_repl_history 90 + 91 + # Output of 'npm pack' 92 + *.tgz 93 + 94 + # Yarn Integrity file 95 + .yarn-integrity 96 + 97 + # dotenv environment variable files 98 + .env 99 + .env.development.local 100 + .env.test.local 101 + .env.production.local 102 + .env.local 103 + 104 + # parcel-bundler cache (https://parceljs.org/) 105 + .cache 106 + .parcel-cache 107 + 108 + # Next.js build output 109 + .next 110 + out 111 + 112 + # Nuxt.js build / generate output 113 + .nuxt 114 + dist 115 + 116 + # Gatsby files 117 + .cache/ 118 + # Comment in the public line in if your project uses Gatsby and not Next.js 119 + # https://nextjs.org/blog/next-9-1#public-directory-support 120 + # public 121 + 122 + # vuepress build output 123 + .vuepress/dist 124 + 125 + # vuepress v2.x temp and cache directory 126 + .temp 127 + .cache 128 + 129 + # Docusaurus cache and generated files 130 + .docusaurus 131 + 132 + # Serverless directories 133 + .serverless/ 134 + 135 + # FuseBox cache 136 + .fusebox/ 137 + 138 + # DynamoDB Local files 139 + .dynamodb/ 140 + 141 + # TernJS port file 142 + .tern-port 143 + 144 + # Stores VSCode versions used for testing VSCode extensions 145 + .vscode-test 146 + 147 + # yarn v2 148 + .yarn/cache 149 + .yarn/unplugged 150 + .yarn/build-state.yml 151 + .yarn/install-state.gz 152 + .pnp.* 153 + 154 + /vendor 155 + 156 + dist
+3
.vscode/settings.json
··· 1 + { 2 + "cSpell.words": ["cmark"] 3 + }
+1964
Cargo.lock
··· 1 + # This file is automatically @generated by Cargo. 2 + # It is not intended for manual editing. 3 + version = 4 4 + 5 + [[package]] 6 + name = "addr2line" 7 + version = "0.24.2" 8 + source = "registry+https://github.com/rust-lang/crates.io-index" 9 + checksum = "dfbe277e56a376000877090da837660b4427aad530e3028d44e0bffe4f89a1c1" 10 + dependencies = [ 11 + "gimli", 12 + ] 13 + 14 + [[package]] 15 + name = "adler2" 16 + version = "2.0.0" 17 + source = "registry+https://github.com/rust-lang/crates.io-index" 18 + checksum = "512761e0bb2578dd7380c6baaa0f4ce03e84f95e960231d1dec8bf4d7d6e2627" 19 + 20 + [[package]] 21 + name = "aho-corasick" 22 + version = "1.1.3" 23 + source = "registry+https://github.com/rust-lang/crates.io-index" 24 + checksum = "8e60d3430d3a69478ad0993f19238d2df97c507009a52b3c10addcd7f6bcb916" 25 + dependencies = [ 26 + "memchr", 27 + ] 28 + 29 + [[package]] 30 + name = "android-tzdata" 31 + version = "0.1.1" 32 + source = "registry+https://github.com/rust-lang/crates.io-index" 33 + checksum = "e999941b234f3131b00bc13c22d06e8c5ff726d1b6318ac7eb276997bbb4fef0" 34 + 35 + [[package]] 36 + name = "android_system_properties" 37 + version = "0.1.5" 38 + source = "registry+https://github.com/rust-lang/crates.io-index" 39 + checksum = "819e7219dbd41043ac279b19830f2efc897156490d7fd6ea916720117ee66311" 40 + dependencies = [ 41 + "libc", 42 + ] 43 + 44 + [[package]] 45 + name = "anstream" 46 + version = "0.6.18" 47 + source = "registry+https://github.com/rust-lang/crates.io-index" 48 + checksum = "8acc5369981196006228e28809f761875c0327210a891e941f4c683b3a99529b" 49 + dependencies = [ 50 + "anstyle", 51 + "anstyle-parse", 52 + "anstyle-query", 53 + "anstyle-wincon", 54 + "colorchoice", 55 + "is_terminal_polyfill", 56 + "utf8parse", 57 + ] 58 + 59 + [[package]] 60 + name = "anstyle" 61 + version = "1.0.10" 62 + source = "registry+https://github.com/rust-lang/crates.io-index" 63 + checksum = "55cc3b69f167a1ef2e161439aa98aed94e6028e5f9a59be9a6ffb47aef1651f9" 64 + 65 + [[package]] 66 + name = "anstyle-parse" 67 + version = "0.2.6" 68 + source = "registry+https://github.com/rust-lang/crates.io-index" 69 + checksum = "3b2d16507662817a6a20a9ea92df6652ee4f94f914589377d69f3b21bc5798a9" 70 + dependencies = [ 71 + "utf8parse", 72 + ] 73 + 74 + [[package]] 75 + name = "anstyle-query" 76 + version = "1.1.2" 77 + source = "registry+https://github.com/rust-lang/crates.io-index" 78 + checksum = "79947af37f4177cfead1110013d678905c37501914fba0efea834c3fe9a8d60c" 79 + dependencies = [ 80 + "windows-sys 0.59.0", 81 + ] 82 + 83 + [[package]] 84 + name = "anstyle-wincon" 85 + version = "3.0.7" 86 + source = "registry+https://github.com/rust-lang/crates.io-index" 87 + checksum = "ca3534e77181a9cc07539ad51f2141fe32f6c3ffd4df76db8ad92346b003ae4e" 88 + dependencies = [ 89 + "anstyle", 90 + "once_cell", 91 + "windows-sys 0.59.0", 92 + ] 93 + 94 + [[package]] 95 + name = "anyhow" 96 + version = "1.0.97" 97 + source = "registry+https://github.com/rust-lang/crates.io-index" 98 + checksum = "dcfed56ad506cb2c684a14971b8861fdc3baaaae314b9e5f9bb532cbe3ba7a4f" 99 + 100 + [[package]] 101 + name = "async-lsp" 102 + version = "0.2.2" 103 + source = "registry+https://github.com/rust-lang/crates.io-index" 104 + checksum = "6c1c85c4bb41706ad1f8338e39fa725a24bc642be41140a38d818c93b9ae91f5" 105 + dependencies = [ 106 + "futures", 107 + "lsp-types", 108 + "pin-project-lite", 109 + "rustix", 110 + "serde", 111 + "serde_json", 112 + "thiserror", 113 + "tokio", 114 + "tower-layer", 115 + "tower-service", 116 + "tracing", 117 + "waitpid-any", 118 + ] 119 + 120 + [[package]] 121 + name = "autocfg" 122 + version = "1.4.0" 123 + source = "registry+https://github.com/rust-lang/crates.io-index" 124 + checksum = "ace50bade8e6234aa140d9a2f552bbee1db4d353f69b8217bc503490fc1a9f26" 125 + 126 + [[package]] 127 + name = "backtrace" 128 + version = "0.3.74" 129 + source = "registry+https://github.com/rust-lang/crates.io-index" 130 + checksum = "8d82cb332cdfaed17ae235a638438ac4d4839913cc2af585c3c6746e8f8bee1a" 131 + dependencies = [ 132 + "addr2line", 133 + "cfg-if", 134 + "libc", 135 + "miniz_oxide", 136 + "object", 137 + "rustc-demangle", 138 + "windows-targets", 139 + ] 140 + 141 + [[package]] 142 + name = "bitflags" 143 + version = "1.3.2" 144 + source = "registry+https://github.com/rust-lang/crates.io-index" 145 + checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" 146 + 147 + [[package]] 148 + name = "bitflags" 149 + version = "2.9.0" 150 + source = "registry+https://github.com/rust-lang/crates.io-index" 151 + checksum = "5c8214115b7bf84099f1309324e63141d4c5d7cc26862f97a0a857dbefe165bd" 152 + 153 + [[package]] 154 + name = "block-buffer" 155 + version = "0.10.4" 156 + source = "registry+https://github.com/rust-lang/crates.io-index" 157 + checksum = "3078c7629b62d3f0439517fa394996acacc5cbc91c5a20d8c658e77abd503a71" 158 + dependencies = [ 159 + "generic-array", 160 + ] 161 + 162 + [[package]] 163 + name = "bstr" 164 + version = "1.11.3" 165 + source = "registry+https://github.com/rust-lang/crates.io-index" 166 + checksum = "531a9155a481e2ee699d4f98f43c0ca4ff8ee1bfd55c31e9e98fb29d2b176fe0" 167 + dependencies = [ 168 + "memchr", 169 + "regex-automata", 170 + "serde", 171 + ] 172 + 173 + [[package]] 174 + name = "bumpalo" 175 + version = "3.17.0" 176 + source = "registry+https://github.com/rust-lang/crates.io-index" 177 + checksum = "1628fb46dfa0b37568d12e5edd512553eccf6a22a78e8bde00bb4aed84d5bdbf" 178 + 179 + [[package]] 180 + name = "bytes" 181 + version = "1.10.1" 182 + source = "registry+https://github.com/rust-lang/crates.io-index" 183 + checksum = "d71b6127be86fdcfddb610f7182ac57211d4b18a3e9c82eb2d17662f2227ad6a" 184 + 185 + [[package]] 186 + name = "cargo_toml" 187 + version = "0.21.0" 188 + source = "registry+https://github.com/rust-lang/crates.io-index" 189 + checksum = "5fbd1fe9db3ebf71b89060adaf7b0504c2d6a425cf061313099547e382c2e472" 190 + dependencies = [ 191 + "serde", 192 + "toml 0.8.20", 193 + ] 194 + 195 + [[package]] 196 + name = "cc" 197 + version = "1.2.16" 198 + source = "registry+https://github.com/rust-lang/crates.io-index" 199 + checksum = "be714c154be609ec7f5dad223a33bf1482fff90472de28f7362806e6d4832b8c" 200 + dependencies = [ 201 + "shlex", 202 + ] 203 + 204 + [[package]] 205 + name = "cfg-if" 206 + version = "1.0.0" 207 + source = "registry+https://github.com/rust-lang/crates.io-index" 208 + checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" 209 + 210 + [[package]] 211 + name = "chrono" 212 + version = "0.4.40" 213 + source = "registry+https://github.com/rust-lang/crates.io-index" 214 + checksum = "1a7964611d71df112cb1730f2ee67324fcf4d0fc6606acbbe9bfe06df124637c" 215 + dependencies = [ 216 + "android-tzdata", 217 + "iana-time-zone", 218 + "num-traits", 219 + "windows-link", 220 + ] 221 + 222 + [[package]] 223 + name = "clap" 224 + version = "4.5.31" 225 + source = "registry+https://github.com/rust-lang/crates.io-index" 226 + checksum = "027bb0d98429ae334a8698531da7077bdf906419543a35a55c2cb1b66437d767" 227 + dependencies = [ 228 + "clap_builder", 229 + "clap_derive", 230 + ] 231 + 232 + [[package]] 233 + name = "clap_builder" 234 + version = "4.5.31" 235 + source = "registry+https://github.com/rust-lang/crates.io-index" 236 + checksum = "5589e0cba072e0f3d23791efac0fd8627b49c829c196a492e88168e6a669d863" 237 + dependencies = [ 238 + "anstream", 239 + "anstyle", 240 + "clap_lex", 241 + "strsim", 242 + "terminal_size", 243 + ] 244 + 245 + [[package]] 246 + name = "clap_complete" 247 + version = "4.5.46" 248 + source = "registry+https://github.com/rust-lang/crates.io-index" 249 + checksum = "f5c5508ea23c5366f77e53f5a0070e5a84e51687ec3ef9e0464c86dc8d13ce98" 250 + dependencies = [ 251 + "clap", 252 + ] 253 + 254 + [[package]] 255 + name = "clap_derive" 256 + version = "4.5.28" 257 + source = "registry+https://github.com/rust-lang/crates.io-index" 258 + checksum = "bf4ced95c6f4a675af3da73304b9ac4ed991640c36374e4b46795c49e17cf1ed" 259 + dependencies = [ 260 + "heck", 261 + "proc-macro2", 262 + "quote", 263 + "syn", 264 + ] 265 + 266 + [[package]] 267 + name = "clap_lex" 268 + version = "0.7.4" 269 + source = "registry+https://github.com/rust-lang/crates.io-index" 270 + checksum = "f46ad14479a25103f283c0f10005961cf086d8dc42205bb44c46ac563475dca6" 271 + 272 + [[package]] 273 + name = "colorchoice" 274 + version = "1.0.3" 275 + source = "registry+https://github.com/rust-lang/crates.io-index" 276 + checksum = "5b63caa9aa9397e2d9480a9b13673856c78d8ac123288526c37d7839f2a86990" 277 + 278 + [[package]] 279 + name = "console" 280 + version = "0.15.11" 281 + source = "registry+https://github.com/rust-lang/crates.io-index" 282 + checksum = "054ccb5b10f9f2cbf51eb355ca1d05c2d279ce1804688d0db74b4733a5aeafd8" 283 + dependencies = [ 284 + "encode_unicode", 285 + "libc", 286 + "once_cell", 287 + "windows-sys 0.59.0", 288 + ] 289 + 290 + [[package]] 291 + name = "core-foundation-sys" 292 + version = "0.8.7" 293 + source = "registry+https://github.com/rust-lang/crates.io-index" 294 + checksum = "773648b94d0e5d620f64f280777445740e61fe701025087ec8b57f45c791888b" 295 + 296 + [[package]] 297 + name = "cpufeatures" 298 + version = "0.2.17" 299 + source = "registry+https://github.com/rust-lang/crates.io-index" 300 + checksum = "59ed5838eebb26a2bb2e58f6d5b5316989ae9d08bab10e0e6d103e656d1b0280" 301 + dependencies = [ 302 + "libc", 303 + ] 304 + 305 + [[package]] 306 + name = "crypto-common" 307 + version = "0.1.6" 308 + source = "registry+https://github.com/rust-lang/crates.io-index" 309 + checksum = "1bfb12502f3fc46cca1bb51ac28df9d618d813cdc3d2f25b9fe775a34af26bb3" 310 + dependencies = [ 311 + "generic-array", 312 + "typenum", 313 + ] 314 + 315 + [[package]] 316 + name = "darling" 317 + version = "0.20.10" 318 + source = "registry+https://github.com/rust-lang/crates.io-index" 319 + checksum = "6f63b86c8a8826a49b8c21f08a2d07338eec8d900540f8630dc76284be802989" 320 + dependencies = [ 321 + "darling_core", 322 + "darling_macro", 323 + ] 324 + 325 + [[package]] 326 + name = "darling_core" 327 + version = "0.20.10" 328 + source = "registry+https://github.com/rust-lang/crates.io-index" 329 + checksum = "95133861a8032aaea082871032f5815eb9e98cef03fa916ab4500513994df9e5" 330 + dependencies = [ 331 + "fnv", 332 + "ident_case", 333 + "proc-macro2", 334 + "quote", 335 + "strsim", 336 + "syn", 337 + ] 338 + 339 + [[package]] 340 + name = "darling_macro" 341 + version = "0.20.10" 342 + source = "registry+https://github.com/rust-lang/crates.io-index" 343 + checksum = "d336a2a514f6ccccaa3e09b02d41d35330c07ddf03a62165fcec10bb561c7806" 344 + dependencies = [ 345 + "darling_core", 346 + "quote", 347 + "syn", 348 + ] 349 + 350 + [[package]] 351 + name = "dbus" 352 + version = "0.9.7" 353 + source = "registry+https://github.com/rust-lang/crates.io-index" 354 + checksum = "1bb21987b9fb1613058ba3843121dd18b163b254d8a6e797e144cbac14d96d1b" 355 + dependencies = [ 356 + "libc", 357 + "libdbus-sys", 358 + "winapi", 359 + ] 360 + 361 + [[package]] 362 + name = "derive_builder" 363 + version = "0.20.2" 364 + source = "registry+https://github.com/rust-lang/crates.io-index" 365 + checksum = "507dfb09ea8b7fa618fcf76e953f4f5e192547945816d5358edffe39f6f94947" 366 + dependencies = [ 367 + "derive_builder_macro", 368 + ] 369 + 370 + [[package]] 371 + name = "derive_builder_core" 372 + version = "0.20.2" 373 + source = "registry+https://github.com/rust-lang/crates.io-index" 374 + checksum = "2d5bcf7b024d6835cfb3d473887cd966994907effbe9227e8c8219824d06c4e8" 375 + dependencies = [ 376 + "darling", 377 + "proc-macro2", 378 + "quote", 379 + "syn", 380 + ] 381 + 382 + [[package]] 383 + name = "derive_builder_macro" 384 + version = "0.20.2" 385 + source = "registry+https://github.com/rust-lang/crates.io-index" 386 + checksum = "ab63b0e2bf4d5928aff72e83a7dace85d7bba5fe12dcc3c5a572d78caffd3f3c" 387 + dependencies = [ 388 + "derive_builder_core", 389 + "syn", 390 + ] 391 + 392 + [[package]] 393 + name = "digest" 394 + version = "0.10.7" 395 + source = "registry+https://github.com/rust-lang/crates.io-index" 396 + checksum = "9ed9a281f7bc9b7576e61468ba615a66a5c8cfdff42420a70aa82701a3b1e292" 397 + dependencies = [ 398 + "block-buffer", 399 + "crypto-common", 400 + ] 401 + 402 + [[package]] 403 + name = "displaydoc" 404 + version = "0.2.5" 405 + source = "registry+https://github.com/rust-lang/crates.io-index" 406 + checksum = "97369cbbc041bc366949bc74d34658d6cda5621039731c6310521892a3a20ae0" 407 + dependencies = [ 408 + "proc-macro2", 409 + "quote", 410 + "syn", 411 + ] 412 + 413 + [[package]] 414 + name = "encode_unicode" 415 + version = "1.0.0" 416 + source = "registry+https://github.com/rust-lang/crates.io-index" 417 + checksum = "34aa73646ffb006b8f5147f3dc182bd4bcb190227ce861fc4a4844bf8e3cb2c0" 418 + 419 + [[package]] 420 + name = "env_filter" 421 + version = "0.1.3" 422 + source = "registry+https://github.com/rust-lang/crates.io-index" 423 + checksum = "186e05a59d4c50738528153b83b0b0194d3a29507dfec16eccd4b342903397d0" 424 + dependencies = [ 425 + "log", 426 + "regex", 427 + ] 428 + 429 + [[package]] 430 + name = "env_logger" 431 + version = "0.11.6" 432 + source = "registry+https://github.com/rust-lang/crates.io-index" 433 + checksum = "dcaee3d8e3cfc3fd92428d477bc97fc29ec8716d180c0d74c643bb26166660e0" 434 + dependencies = [ 435 + "anstream", 436 + "anstyle", 437 + "env_filter", 438 + "humantime", 439 + "log", 440 + ] 441 + 442 + [[package]] 443 + name = "equivalent" 444 + version = "1.0.2" 445 + source = "registry+https://github.com/rust-lang/crates.io-index" 446 + checksum = "877a4ace8713b0bcf2a4e7eec82529c029f1d0619886d18145fea96c3ffe5c0f" 447 + 448 + [[package]] 449 + name = "errno" 450 + version = "0.3.10" 451 + source = "registry+https://github.com/rust-lang/crates.io-index" 452 + checksum = "33d852cb9b869c2a9b3df2f71a3074817f01e1844f839a144f5fcef059a4eb5d" 453 + dependencies = [ 454 + "libc", 455 + "windows-sys 0.59.0", 456 + ] 457 + 458 + [[package]] 459 + name = "fastrand" 460 + version = "2.3.0" 461 + source = "registry+https://github.com/rust-lang/crates.io-index" 462 + checksum = "37909eebbb50d72f9059c3b6d82c0463f2ff062c9e95845c43a6c9c0355411be" 463 + 464 + [[package]] 465 + name = "fnv" 466 + version = "1.0.7" 467 + source = "registry+https://github.com/rust-lang/crates.io-index" 468 + checksum = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1" 469 + 470 + [[package]] 471 + name = "form_urlencoded" 472 + version = "1.2.1" 473 + source = "registry+https://github.com/rust-lang/crates.io-index" 474 + checksum = "e13624c2627564efccf4934284bdd98cbaa14e79b0b5a141218e507b3a823456" 475 + dependencies = [ 476 + "percent-encoding", 477 + ] 478 + 479 + [[package]] 480 + name = "futures" 481 + version = "0.3.31" 482 + source = "registry+https://github.com/rust-lang/crates.io-index" 483 + checksum = "65bc07b1a8bc7c85c5f2e110c476c7389b4554ba72af57d8445ea63a576b0876" 484 + dependencies = [ 485 + "futures-channel", 486 + "futures-core", 487 + "futures-io", 488 + "futures-sink", 489 + "futures-task", 490 + "futures-util", 491 + ] 492 + 493 + [[package]] 494 + name = "futures-channel" 495 + version = "0.3.31" 496 + source = "registry+https://github.com/rust-lang/crates.io-index" 497 + checksum = "2dff15bf788c671c1934e366d07e30c1814a8ef514e1af724a602e8a2fbe1b10" 498 + dependencies = [ 499 + "futures-core", 500 + "futures-sink", 501 + ] 502 + 503 + [[package]] 504 + name = "futures-core" 505 + version = "0.3.31" 506 + source = "registry+https://github.com/rust-lang/crates.io-index" 507 + checksum = "05f29059c0c2090612e8d742178b0580d2dc940c837851ad723096f87af6663e" 508 + 509 + [[package]] 510 + name = "futures-io" 511 + version = "0.3.31" 512 + source = "registry+https://github.com/rust-lang/crates.io-index" 513 + checksum = "9e5c1b78ca4aae1ac06c48a526a655760685149f0d465d21f37abfe57ce075c6" 514 + 515 + [[package]] 516 + name = "futures-macro" 517 + version = "0.3.31" 518 + source = "registry+https://github.com/rust-lang/crates.io-index" 519 + checksum = "162ee34ebcb7c64a8abebc059ce0fee27c2262618d7b60ed8faf72fef13c3650" 520 + dependencies = [ 521 + "proc-macro2", 522 + "quote", 523 + "syn", 524 + ] 525 + 526 + [[package]] 527 + name = "futures-sink" 528 + version = "0.3.31" 529 + source = "registry+https://github.com/rust-lang/crates.io-index" 530 + checksum = "e575fab7d1e0dcb8d0c7bcf9a63ee213816ab51902e6d244a95819acacf1d4f7" 531 + 532 + [[package]] 533 + name = "futures-task" 534 + version = "0.3.31" 535 + source = "registry+https://github.com/rust-lang/crates.io-index" 536 + checksum = "f90f7dce0722e95104fcb095585910c0977252f286e354b5e3bd38902cd99988" 537 + 538 + [[package]] 539 + name = "futures-util" 540 + version = "0.3.31" 541 + source = "registry+https://github.com/rust-lang/crates.io-index" 542 + checksum = "9fa08315bb612088cc391249efdc3bc77536f16c91f6cf495e6fbe85b20a4a81" 543 + dependencies = [ 544 + "futures-channel", 545 + "futures-core", 546 + "futures-io", 547 + "futures-macro", 548 + "futures-sink", 549 + "futures-task", 550 + "memchr", 551 + "pin-project-lite", 552 + "pin-utils", 553 + "slab", 554 + ] 555 + 556 + [[package]] 557 + name = "generic-array" 558 + version = "0.14.7" 559 + source = "registry+https://github.com/rust-lang/crates.io-index" 560 + checksum = "85649ca51fd72272d7821adaf274ad91c288277713d9c18820d8499a7ff69e9a" 561 + dependencies = [ 562 + "typenum", 563 + "version_check", 564 + ] 565 + 566 + [[package]] 567 + name = "getopts" 568 + version = "0.2.21" 569 + source = "registry+https://github.com/rust-lang/crates.io-index" 570 + checksum = "14dbbfd5c71d70241ecf9e6f13737f7b5ce823821063188d7e46c41d371eebd5" 571 + dependencies = [ 572 + "unicode-width", 573 + ] 574 + 575 + [[package]] 576 + name = "getrandom" 577 + version = "0.3.1" 578 + source = "registry+https://github.com/rust-lang/crates.io-index" 579 + checksum = "43a49c392881ce6d5c3b8cb70f98717b7c07aabbdff06687b9030dbfbe2725f8" 580 + dependencies = [ 581 + "cfg-if", 582 + "libc", 583 + "wasi 0.13.3+wasi-0.2.2", 584 + "windows-targets", 585 + ] 586 + 587 + [[package]] 588 + name = "gimli" 589 + version = "0.31.1" 590 + source = "registry+https://github.com/rust-lang/crates.io-index" 591 + checksum = "07e28edb80900c19c28f1072f2e8aeca7fa06b23cd4169cefe1af5aa3260783f" 592 + 593 + [[package]] 594 + name = "handlebars" 595 + version = "6.3.1" 596 + source = "registry+https://github.com/rust-lang/crates.io-index" 597 + checksum = "d752747ddabc4c1a70dd28e72f2e3c218a816773e0d7faf67433f1acfa6cba7c" 598 + dependencies = [ 599 + "derive_builder", 600 + "log", 601 + "num-order", 602 + "pest", 603 + "pest_derive", 604 + "serde", 605 + "serde_json", 606 + "thiserror", 607 + ] 608 + 609 + [[package]] 610 + name = "hashbrown" 611 + version = "0.15.2" 612 + source = "registry+https://github.com/rust-lang/crates.io-index" 613 + checksum = "bf151400ff0baff5465007dd2f3e717f3fe502074ca563069ce3a6629d07b289" 614 + 615 + [[package]] 616 + name = "heck" 617 + version = "0.5.0" 618 + source = "registry+https://github.com/rust-lang/crates.io-index" 619 + checksum = "2304e00983f87ffb38b55b444b5e3b60a884b5d30c0fca7d82fe33449bbe55ea" 620 + 621 + [[package]] 622 + name = "hex" 623 + version = "0.4.3" 624 + source = "registry+https://github.com/rust-lang/crates.io-index" 625 + checksum = "7f24254aa9a54b5c858eaee2f5bccdb46aaf0e486a595ed5fd8f86ba55232a70" 626 + 627 + [[package]] 628 + name = "humantime" 629 + version = "2.1.0" 630 + source = "registry+https://github.com/rust-lang/crates.io-index" 631 + checksum = "9a3a5bfb195931eeb336b2a7b4d761daec841b97f947d34394601737a7bba5e4" 632 + 633 + [[package]] 634 + name = "iana-time-zone" 635 + version = "0.1.61" 636 + source = "registry+https://github.com/rust-lang/crates.io-index" 637 + checksum = "235e081f3925a06703c2d0117ea8b91f042756fd6e7a6e5d901e8ca1a996b220" 638 + dependencies = [ 639 + "android_system_properties", 640 + "core-foundation-sys", 641 + "iana-time-zone-haiku", 642 + "js-sys", 643 + "wasm-bindgen", 644 + "windows-core", 645 + ] 646 + 647 + [[package]] 648 + name = "iana-time-zone-haiku" 649 + version = "0.1.2" 650 + source = "registry+https://github.com/rust-lang/crates.io-index" 651 + checksum = "f31827a206f56af32e590ba56d5d2d085f558508192593743f16b2306495269f" 652 + dependencies = [ 653 + "cc", 654 + ] 655 + 656 + [[package]] 657 + name = "icu_collections" 658 + version = "1.5.0" 659 + source = "registry+https://github.com/rust-lang/crates.io-index" 660 + checksum = "db2fa452206ebee18c4b5c2274dbf1de17008e874b4dc4f0aea9d01ca79e4526" 661 + dependencies = [ 662 + "displaydoc", 663 + "yoke", 664 + "zerofrom", 665 + "zerovec", 666 + ] 667 + 668 + [[package]] 669 + name = "icu_locid" 670 + version = "1.5.0" 671 + source = "registry+https://github.com/rust-lang/crates.io-index" 672 + checksum = "13acbb8371917fc971be86fc8057c41a64b521c184808a698c02acc242dbf637" 673 + dependencies = [ 674 + "displaydoc", 675 + "litemap", 676 + "tinystr", 677 + "writeable", 678 + "zerovec", 679 + ] 680 + 681 + [[package]] 682 + name = "icu_locid_transform" 683 + version = "1.5.0" 684 + source = "registry+https://github.com/rust-lang/crates.io-index" 685 + checksum = "01d11ac35de8e40fdeda00d9e1e9d92525f3f9d887cdd7aa81d727596788b54e" 686 + dependencies = [ 687 + "displaydoc", 688 + "icu_locid", 689 + "icu_locid_transform_data", 690 + "icu_provider", 691 + "tinystr", 692 + "zerovec", 693 + ] 694 + 695 + [[package]] 696 + name = "icu_locid_transform_data" 697 + version = "1.5.0" 698 + source = "registry+https://github.com/rust-lang/crates.io-index" 699 + checksum = "fdc8ff3388f852bede6b579ad4e978ab004f139284d7b28715f773507b946f6e" 700 + 701 + [[package]] 702 + name = "icu_normalizer" 703 + version = "1.5.0" 704 + source = "registry+https://github.com/rust-lang/crates.io-index" 705 + checksum = "19ce3e0da2ec68599d193c93d088142efd7f9c5d6fc9b803774855747dc6a84f" 706 + dependencies = [ 707 + "displaydoc", 708 + "icu_collections", 709 + "icu_normalizer_data", 710 + "icu_properties", 711 + "icu_provider", 712 + "smallvec", 713 + "utf16_iter", 714 + "utf8_iter", 715 + "write16", 716 + "zerovec", 717 + ] 718 + 719 + [[package]] 720 + name = "icu_normalizer_data" 721 + version = "1.5.0" 722 + source = "registry+https://github.com/rust-lang/crates.io-index" 723 + checksum = "f8cafbf7aa791e9b22bec55a167906f9e1215fd475cd22adfcf660e03e989516" 724 + 725 + [[package]] 726 + name = "icu_properties" 727 + version = "1.5.1" 728 + source = "registry+https://github.com/rust-lang/crates.io-index" 729 + checksum = "93d6020766cfc6302c15dbbc9c8778c37e62c14427cb7f6e601d849e092aeef5" 730 + dependencies = [ 731 + "displaydoc", 732 + "icu_collections", 733 + "icu_locid_transform", 734 + "icu_properties_data", 735 + "icu_provider", 736 + "tinystr", 737 + "zerovec", 738 + ] 739 + 740 + [[package]] 741 + name = "icu_properties_data" 742 + version = "1.5.0" 743 + source = "registry+https://github.com/rust-lang/crates.io-index" 744 + checksum = "67a8effbc3dd3e4ba1afa8ad918d5684b8868b3b26500753effea8d2eed19569" 745 + 746 + [[package]] 747 + name = "icu_provider" 748 + version = "1.5.0" 749 + source = "registry+https://github.com/rust-lang/crates.io-index" 750 + checksum = "6ed421c8a8ef78d3e2dbc98a973be2f3770cb42b606e3ab18d6237c4dfde68d9" 751 + dependencies = [ 752 + "displaydoc", 753 + "icu_locid", 754 + "icu_provider_macros", 755 + "stable_deref_trait", 756 + "tinystr", 757 + "writeable", 758 + "yoke", 759 + "zerofrom", 760 + "zerovec", 761 + ] 762 + 763 + [[package]] 764 + name = "icu_provider_macros" 765 + version = "1.5.0" 766 + source = "registry+https://github.com/rust-lang/crates.io-index" 767 + checksum = "1ec89e9337638ecdc08744df490b221a7399bf8d164eb52a665454e60e075ad6" 768 + dependencies = [ 769 + "proc-macro2", 770 + "quote", 771 + "syn", 772 + ] 773 + 774 + [[package]] 775 + name = "ident_case" 776 + version = "1.0.1" 777 + source = "registry+https://github.com/rust-lang/crates.io-index" 778 + checksum = "b9e0384b61958566e926dc50660321d12159025e767c18e043daf26b70104c39" 779 + 780 + [[package]] 781 + name = "idna" 782 + version = "1.0.3" 783 + source = "registry+https://github.com/rust-lang/crates.io-index" 784 + checksum = "686f825264d630750a544639377bae737628043f20d38bbc029e8f29ea968a7e" 785 + dependencies = [ 786 + "idna_adapter", 787 + "smallvec", 788 + "utf8_iter", 789 + ] 790 + 791 + [[package]] 792 + name = "idna_adapter" 793 + version = "1.2.0" 794 + source = "registry+https://github.com/rust-lang/crates.io-index" 795 + checksum = "daca1df1c957320b2cf139ac61e7bd64fed304c5040df000a745aa1de3b4ef71" 796 + dependencies = [ 797 + "icu_normalizer", 798 + "icu_properties", 799 + ] 800 + 801 + [[package]] 802 + name = "indexmap" 803 + version = "2.7.1" 804 + source = "registry+https://github.com/rust-lang/crates.io-index" 805 + checksum = "8c9c992b02b5b4c94ea26e32fe5bccb7aa7d9f390ab5c1221ff895bc7ea8b652" 806 + dependencies = [ 807 + "equivalent", 808 + "hashbrown", 809 + ] 810 + 811 + [[package]] 812 + name = "insta" 813 + version = "1.42.2" 814 + source = "registry+https://github.com/rust-lang/crates.io-index" 815 + checksum = "50259abbaa67d11d2bcafc7ba1d094ed7a0c70e3ce893f0d0997f73558cb3084" 816 + dependencies = [ 817 + "console", 818 + "linked-hash-map", 819 + "once_cell", 820 + "pin-project", 821 + "serde", 822 + "similar", 823 + ] 824 + 825 + [[package]] 826 + name = "is_terminal_polyfill" 827 + version = "1.70.1" 828 + source = "registry+https://github.com/rust-lang/crates.io-index" 829 + checksum = "7943c866cc5cd64cbc25b2e01621d07fa8eb2a1a23160ee81ce38704e97b8ecf" 830 + 831 + [[package]] 832 + name = "itoa" 833 + version = "1.0.15" 834 + source = "registry+https://github.com/rust-lang/crates.io-index" 835 + checksum = "4a5f13b858c8d314ee3e8f639011f7ccefe71f97f96e50151fb991f267928e2c" 836 + 837 + [[package]] 838 + name = "js-sys" 839 + version = "0.3.77" 840 + source = "registry+https://github.com/rust-lang/crates.io-index" 841 + checksum = "1cfaf33c695fc6e08064efbc1f72ec937429614f25eef83af942d0e227c3a28f" 842 + dependencies = [ 843 + "once_cell", 844 + "wasm-bindgen", 845 + ] 846 + 847 + [[package]] 848 + name = "libc" 849 + version = "0.2.170" 850 + source = "registry+https://github.com/rust-lang/crates.io-index" 851 + checksum = "875b3680cb2f8f71bdcf9a30f38d48282f5d3c95cbf9b3fa57269bb5d5c06828" 852 + 853 + [[package]] 854 + name = "libdbus-sys" 855 + version = "0.2.5" 856 + source = "registry+https://github.com/rust-lang/crates.io-index" 857 + checksum = "06085512b750d640299b79be4bad3d2fa90a9c00b1fd9e1b46364f66f0485c72" 858 + dependencies = [ 859 + "cc", 860 + "pkg-config", 861 + ] 862 + 863 + [[package]] 864 + name = "linked-hash-map" 865 + version = "0.5.6" 866 + source = "registry+https://github.com/rust-lang/crates.io-index" 867 + checksum = "0717cef1bc8b636c6e1c1bbdefc09e6322da8a9321966e8928ef80d20f7f770f" 868 + 869 + [[package]] 870 + name = "linux-raw-sys" 871 + version = "0.9.2" 872 + source = "registry+https://github.com/rust-lang/crates.io-index" 873 + checksum = "6db9c683daf087dc577b7506e9695b3d556a9f3849903fa28186283afd6809e9" 874 + 875 + [[package]] 876 + name = "litemap" 877 + version = "0.7.5" 878 + source = "registry+https://github.com/rust-lang/crates.io-index" 879 + checksum = "23fb14cb19457329c82206317a5663005a4d404783dc74f4252769b0d5f42856" 880 + 881 + [[package]] 882 + name = "log" 883 + version = "0.4.26" 884 + source = "registry+https://github.com/rust-lang/crates.io-index" 885 + checksum = "30bde2b3dc3671ae49d8e2e9f044c7c005836e7a023ee57cffa25ab82764bb9e" 886 + 887 + [[package]] 888 + name = "lsp-types" 889 + version = "0.95.1" 890 + source = "registry+https://github.com/rust-lang/crates.io-index" 891 + checksum = "8e34d33a8e9b006cd3fc4fe69a921affa097bae4bb65f76271f4644f9a334365" 892 + dependencies = [ 893 + "bitflags 1.3.2", 894 + "serde", 895 + "serde_json", 896 + "serde_repr", 897 + "url", 898 + ] 899 + 900 + [[package]] 901 + name = "mdbook" 902 + version = "0.4.47" 903 + source = "registry+https://github.com/rust-lang/crates.io-index" 904 + checksum = "7e1a8fe3a4a01f28dab245c474cb7b95ccb4d3d2f17a5419a3d949f474c45e84" 905 + dependencies = [ 906 + "anyhow", 907 + "chrono", 908 + "clap", 909 + "clap_complete", 910 + "env_logger", 911 + "handlebars", 912 + "hex", 913 + "log", 914 + "memchr", 915 + "once_cell", 916 + "opener", 917 + "pulldown-cmark 0.10.3", 918 + "regex", 919 + "serde", 920 + "serde_json", 921 + "sha2", 922 + "shlex", 923 + "tempfile", 924 + "toml 0.5.11", 925 + "topological-sort", 926 + ] 927 + 928 + [[package]] 929 + name = "mdbook-rustdoc-link" 930 + version = "0.1.0" 931 + dependencies = [ 932 + "anyhow", 933 + "async-lsp", 934 + "cargo_toml", 935 + "clap", 936 + "env_logger", 937 + "insta", 938 + "log", 939 + "lsp-types", 940 + "mdbook", 941 + "proc-macro2", 942 + "pulldown-cmark 0.13.0", 943 + "pulldown-cmark-to-cmark", 944 + "quote", 945 + "serde", 946 + "serde_json", 947 + "syn", 948 + "tap", 949 + "tokio", 950 + "tokio-util", 951 + "toml 0.5.11", 952 + "tower", 953 + ] 954 + 955 + [[package]] 956 + name = "memchr" 957 + version = "2.7.4" 958 + source = "registry+https://github.com/rust-lang/crates.io-index" 959 + checksum = "78ca9ab1a0babb1e7d5695e3530886289c18cf2f87ec19a575a0abdce112e3a3" 960 + 961 + [[package]] 962 + name = "miniz_oxide" 963 + version = "0.8.5" 964 + source = "registry+https://github.com/rust-lang/crates.io-index" 965 + checksum = "8e3e04debbb59698c15bacbb6d93584a8c0ca9cc3213cb423d31f760d8843ce5" 966 + dependencies = [ 967 + "adler2", 968 + ] 969 + 970 + [[package]] 971 + name = "mio" 972 + version = "1.0.3" 973 + source = "registry+https://github.com/rust-lang/crates.io-index" 974 + checksum = "2886843bf800fba2e3377cff24abf6379b4c4d5c6681eaf9ea5b0d15090450bd" 975 + dependencies = [ 976 + "libc", 977 + "wasi 0.11.0+wasi-snapshot-preview1", 978 + "windows-sys 0.52.0", 979 + ] 980 + 981 + [[package]] 982 + name = "normpath" 983 + version = "1.3.0" 984 + source = "registry+https://github.com/rust-lang/crates.io-index" 985 + checksum = "c8911957c4b1549ac0dc74e30db9c8b0e66ddcd6d7acc33098f4c63a64a6d7ed" 986 + dependencies = [ 987 + "windows-sys 0.59.0", 988 + ] 989 + 990 + [[package]] 991 + name = "num-modular" 992 + version = "0.6.1" 993 + source = "registry+https://github.com/rust-lang/crates.io-index" 994 + checksum = "17bb261bf36fa7d83f4c294f834e91256769097b3cb505d44831e0a179ac647f" 995 + 996 + [[package]] 997 + name = "num-order" 998 + version = "1.2.0" 999 + source = "registry+https://github.com/rust-lang/crates.io-index" 1000 + checksum = "537b596b97c40fcf8056d153049eb22f481c17ebce72a513ec9286e4986d1bb6" 1001 + dependencies = [ 1002 + "num-modular", 1003 + ] 1004 + 1005 + [[package]] 1006 + name = "num-traits" 1007 + version = "0.2.19" 1008 + source = "registry+https://github.com/rust-lang/crates.io-index" 1009 + checksum = "071dfc062690e90b734c0b2273ce72ad0ffa95f0c74596bc250dcfd960262841" 1010 + dependencies = [ 1011 + "autocfg", 1012 + ] 1013 + 1014 + [[package]] 1015 + name = "object" 1016 + version = "0.36.7" 1017 + source = "registry+https://github.com/rust-lang/crates.io-index" 1018 + checksum = "62948e14d923ea95ea2c7c86c71013138b66525b86bdc08d2dcc262bdb497b87" 1019 + dependencies = [ 1020 + "memchr", 1021 + ] 1022 + 1023 + [[package]] 1024 + name = "once_cell" 1025 + version = "1.20.3" 1026 + source = "registry+https://github.com/rust-lang/crates.io-index" 1027 + checksum = "945462a4b81e43c4e3ba96bd7b49d834c6f61198356aa858733bc4acf3cbe62e" 1028 + 1029 + [[package]] 1030 + name = "opener" 1031 + version = "0.7.2" 1032 + source = "registry+https://github.com/rust-lang/crates.io-index" 1033 + checksum = "d0812e5e4df08da354c851a3376fead46db31c2214f849d3de356d774d057681" 1034 + dependencies = [ 1035 + "bstr", 1036 + "dbus", 1037 + "normpath", 1038 + "windows-sys 0.59.0", 1039 + ] 1040 + 1041 + [[package]] 1042 + name = "percent-encoding" 1043 + version = "2.3.1" 1044 + source = "registry+https://github.com/rust-lang/crates.io-index" 1045 + checksum = "e3148f5046208a5d56bcfc03053e3ca6334e51da8dfb19b6cdc8b306fae3283e" 1046 + 1047 + [[package]] 1048 + name = "pest" 1049 + version = "2.7.15" 1050 + source = "registry+https://github.com/rust-lang/crates.io-index" 1051 + checksum = "8b7cafe60d6cf8e62e1b9b2ea516a089c008945bb5a275416789e7db0bc199dc" 1052 + dependencies = [ 1053 + "memchr", 1054 + "thiserror", 1055 + "ucd-trie", 1056 + ] 1057 + 1058 + [[package]] 1059 + name = "pest_derive" 1060 + version = "2.7.15" 1061 + source = "registry+https://github.com/rust-lang/crates.io-index" 1062 + checksum = "816518421cfc6887a0d62bf441b6ffb4536fcc926395a69e1a85852d4363f57e" 1063 + dependencies = [ 1064 + "pest", 1065 + "pest_generator", 1066 + ] 1067 + 1068 + [[package]] 1069 + name = "pest_generator" 1070 + version = "2.7.15" 1071 + source = "registry+https://github.com/rust-lang/crates.io-index" 1072 + checksum = "7d1396fd3a870fc7838768d171b4616d5c91f6cc25e377b673d714567d99377b" 1073 + dependencies = [ 1074 + "pest", 1075 + "pest_meta", 1076 + "proc-macro2", 1077 + "quote", 1078 + "syn", 1079 + ] 1080 + 1081 + [[package]] 1082 + name = "pest_meta" 1083 + version = "2.7.15" 1084 + source = "registry+https://github.com/rust-lang/crates.io-index" 1085 + checksum = "e1e58089ea25d717bfd31fb534e4f3afcc2cc569c70de3e239778991ea3b7dea" 1086 + dependencies = [ 1087 + "once_cell", 1088 + "pest", 1089 + "sha2", 1090 + ] 1091 + 1092 + [[package]] 1093 + name = "pin-project" 1094 + version = "1.1.10" 1095 + source = "registry+https://github.com/rust-lang/crates.io-index" 1096 + checksum = "677f1add503faace112b9f1373e43e9e054bfdd22ff1a63c1bc485eaec6a6a8a" 1097 + dependencies = [ 1098 + "pin-project-internal", 1099 + ] 1100 + 1101 + [[package]] 1102 + name = "pin-project-internal" 1103 + version = "1.1.10" 1104 + source = "registry+https://github.com/rust-lang/crates.io-index" 1105 + checksum = "6e918e4ff8c4549eb882f14b3a4bc8c8bc93de829416eacf579f1207a8fbf861" 1106 + dependencies = [ 1107 + "proc-macro2", 1108 + "quote", 1109 + "syn", 1110 + ] 1111 + 1112 + [[package]] 1113 + name = "pin-project-lite" 1114 + version = "0.2.16" 1115 + source = "registry+https://github.com/rust-lang/crates.io-index" 1116 + checksum = "3b3cff922bd51709b605d9ead9aa71031d81447142d828eb4a6eba76fe619f9b" 1117 + 1118 + [[package]] 1119 + name = "pin-utils" 1120 + version = "0.1.0" 1121 + source = "registry+https://github.com/rust-lang/crates.io-index" 1122 + checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184" 1123 + 1124 + [[package]] 1125 + name = "pkg-config" 1126 + version = "0.3.32" 1127 + source = "registry+https://github.com/rust-lang/crates.io-index" 1128 + checksum = "7edddbd0b52d732b21ad9a5fab5c704c14cd949e5e9a1ec5929a24fded1b904c" 1129 + 1130 + [[package]] 1131 + name = "proc-macro2" 1132 + version = "1.0.94" 1133 + source = "registry+https://github.com/rust-lang/crates.io-index" 1134 + checksum = "a31971752e70b8b2686d7e46ec17fb38dad4051d94024c88df49b667caea9c84" 1135 + dependencies = [ 1136 + "unicode-ident", 1137 + ] 1138 + 1139 + [[package]] 1140 + name = "pulldown-cmark" 1141 + version = "0.10.3" 1142 + source = "registry+https://github.com/rust-lang/crates.io-index" 1143 + checksum = "76979bea66e7875e7509c4ec5300112b316af87fa7a252ca91c448b32dfe3993" 1144 + dependencies = [ 1145 + "bitflags 2.9.0", 1146 + "memchr", 1147 + "pulldown-cmark-escape 0.10.1", 1148 + "unicase", 1149 + ] 1150 + 1151 + [[package]] 1152 + name = "pulldown-cmark" 1153 + version = "0.13.0" 1154 + source = "registry+https://github.com/rust-lang/crates.io-index" 1155 + checksum = "1e8bbe1a966bd2f362681a44f6edce3c2310ac21e4d5067a6e7ec396297a6ea0" 1156 + dependencies = [ 1157 + "bitflags 2.9.0", 1158 + "getopts", 1159 + "memchr", 1160 + "pulldown-cmark-escape 0.11.0", 1161 + "unicase", 1162 + ] 1163 + 1164 + [[package]] 1165 + name = "pulldown-cmark-escape" 1166 + version = "0.10.1" 1167 + source = "registry+https://github.com/rust-lang/crates.io-index" 1168 + checksum = "bd348ff538bc9caeda7ee8cad2d1d48236a1f443c1fa3913c6a02fe0043b1dd3" 1169 + 1170 + [[package]] 1171 + name = "pulldown-cmark-escape" 1172 + version = "0.11.0" 1173 + source = "registry+https://github.com/rust-lang/crates.io-index" 1174 + checksum = "007d8adb5ddab6f8e3f491ac63566a7d5002cc7ed73901f72057943fa71ae1ae" 1175 + 1176 + [[package]] 1177 + name = "pulldown-cmark-to-cmark" 1178 + version = "21.0.0" 1179 + source = "registry+https://github.com/rust-lang/crates.io-index" 1180 + checksum = "e5b6a0769a491a08b31ea5c62494a8f144ee0987d86d670a8af4df1e1b7cde75" 1181 + dependencies = [ 1182 + "pulldown-cmark 0.13.0", 1183 + ] 1184 + 1185 + [[package]] 1186 + name = "quote" 1187 + version = "1.0.39" 1188 + source = "registry+https://github.com/rust-lang/crates.io-index" 1189 + checksum = "c1f1914ce909e1658d9907913b4b91947430c7d9be598b15a1912935b8c04801" 1190 + dependencies = [ 1191 + "proc-macro2", 1192 + ] 1193 + 1194 + [[package]] 1195 + name = "regex" 1196 + version = "1.11.1" 1197 + source = "registry+https://github.com/rust-lang/crates.io-index" 1198 + checksum = "b544ef1b4eac5dc2db33ea63606ae9ffcfac26c1416a2806ae0bf5f56b201191" 1199 + dependencies = [ 1200 + "aho-corasick", 1201 + "memchr", 1202 + "regex-automata", 1203 + "regex-syntax", 1204 + ] 1205 + 1206 + [[package]] 1207 + name = "regex-automata" 1208 + version = "0.4.9" 1209 + source = "registry+https://github.com/rust-lang/crates.io-index" 1210 + checksum = "809e8dc61f6de73b46c85f4c96486310fe304c434cfa43669d7b40f711150908" 1211 + dependencies = [ 1212 + "aho-corasick", 1213 + "memchr", 1214 + "regex-syntax", 1215 + ] 1216 + 1217 + [[package]] 1218 + name = "regex-syntax" 1219 + version = "0.8.5" 1220 + source = "registry+https://github.com/rust-lang/crates.io-index" 1221 + checksum = "2b15c43186be67a4fd63bee50d0303afffcef381492ebe2c5d87f324e1b8815c" 1222 + 1223 + [[package]] 1224 + name = "rustc-demangle" 1225 + version = "0.1.24" 1226 + source = "registry+https://github.com/rust-lang/crates.io-index" 1227 + checksum = "719b953e2095829ee67db738b3bfa9fa368c94900df327b3f07fe6e794d2fe1f" 1228 + 1229 + [[package]] 1230 + name = "rustix" 1231 + version = "1.0.1" 1232 + source = "registry+https://github.com/rust-lang/crates.io-index" 1233 + checksum = "dade4812df5c384711475be5fcd8c162555352945401aed22a35bffeab61f657" 1234 + dependencies = [ 1235 + "bitflags 2.9.0", 1236 + "errno", 1237 + "libc", 1238 + "linux-raw-sys", 1239 + "windows-sys 0.59.0", 1240 + ] 1241 + 1242 + [[package]] 1243 + name = "rustversion" 1244 + version = "1.0.20" 1245 + source = "registry+https://github.com/rust-lang/crates.io-index" 1246 + checksum = "eded382c5f5f786b989652c49544c4877d9f015cc22e145a5ea8ea66c2921cd2" 1247 + 1248 + [[package]] 1249 + name = "ryu" 1250 + version = "1.0.20" 1251 + source = "registry+https://github.com/rust-lang/crates.io-index" 1252 + checksum = "28d3b2b1366ec20994f1fd18c3c594f05c5dd4bc44d8bb0c1c632c8d6829481f" 1253 + 1254 + [[package]] 1255 + name = "serde" 1256 + version = "1.0.219" 1257 + source = "registry+https://github.com/rust-lang/crates.io-index" 1258 + checksum = "5f0e2c6ed6606019b4e29e69dbaba95b11854410e5347d525002456dbbb786b6" 1259 + dependencies = [ 1260 + "serde_derive", 1261 + ] 1262 + 1263 + [[package]] 1264 + name = "serde_derive" 1265 + version = "1.0.219" 1266 + source = "registry+https://github.com/rust-lang/crates.io-index" 1267 + checksum = "5b0276cf7f2c73365f7157c8123c21cd9a50fbbd844757af28ca1f5925fc2a00" 1268 + dependencies = [ 1269 + "proc-macro2", 1270 + "quote", 1271 + "syn", 1272 + ] 1273 + 1274 + [[package]] 1275 + name = "serde_json" 1276 + version = "1.0.140" 1277 + source = "registry+https://github.com/rust-lang/crates.io-index" 1278 + checksum = "20068b6e96dc6c9bd23e01df8827e6c7e1f2fddd43c21810382803c136b99373" 1279 + dependencies = [ 1280 + "itoa", 1281 + "memchr", 1282 + "ryu", 1283 + "serde", 1284 + ] 1285 + 1286 + [[package]] 1287 + name = "serde_repr" 1288 + version = "0.1.20" 1289 + source = "registry+https://github.com/rust-lang/crates.io-index" 1290 + checksum = "175ee3e80ae9982737ca543e96133087cbd9a485eecc3bc4de9c1a37b47ea59c" 1291 + dependencies = [ 1292 + "proc-macro2", 1293 + "quote", 1294 + "syn", 1295 + ] 1296 + 1297 + [[package]] 1298 + name = "serde_spanned" 1299 + version = "0.6.8" 1300 + source = "registry+https://github.com/rust-lang/crates.io-index" 1301 + checksum = "87607cb1398ed59d48732e575a4c28a7a8ebf2454b964fe3f224f2afc07909e1" 1302 + dependencies = [ 1303 + "serde", 1304 + ] 1305 + 1306 + [[package]] 1307 + name = "sha2" 1308 + version = "0.10.8" 1309 + source = "registry+https://github.com/rust-lang/crates.io-index" 1310 + checksum = "793db75ad2bcafc3ffa7c68b215fee268f537982cd901d132f89c6343f3a3dc8" 1311 + dependencies = [ 1312 + "cfg-if", 1313 + "cpufeatures", 1314 + "digest", 1315 + ] 1316 + 1317 + [[package]] 1318 + name = "shlex" 1319 + version = "1.3.0" 1320 + source = "registry+https://github.com/rust-lang/crates.io-index" 1321 + checksum = "0fda2ff0d084019ba4d7c6f371c95d8fd75ce3524c3cb8fb653a3023f6323e64" 1322 + 1323 + [[package]] 1324 + name = "signal-hook-registry" 1325 + version = "1.4.2" 1326 + source = "registry+https://github.com/rust-lang/crates.io-index" 1327 + checksum = "a9e9e0b4211b72e7b8b6e85c807d36c212bdb33ea8587f7569562a84df5465b1" 1328 + dependencies = [ 1329 + "libc", 1330 + ] 1331 + 1332 + [[package]] 1333 + name = "similar" 1334 + version = "2.7.0" 1335 + source = "registry+https://github.com/rust-lang/crates.io-index" 1336 + checksum = "bbbb5d9659141646ae647b42fe094daf6c6192d1620870b449d9557f748b2daa" 1337 + 1338 + [[package]] 1339 + name = "slab" 1340 + version = "0.4.9" 1341 + source = "registry+https://github.com/rust-lang/crates.io-index" 1342 + checksum = "8f92a496fb766b417c996b9c5e57daf2f7ad3b0bebe1ccfca4856390e3d3bb67" 1343 + dependencies = [ 1344 + "autocfg", 1345 + ] 1346 + 1347 + [[package]] 1348 + name = "smallvec" 1349 + version = "1.14.0" 1350 + source = "registry+https://github.com/rust-lang/crates.io-index" 1351 + checksum = "7fcf8323ef1faaee30a44a340193b1ac6814fd9b7b4e88e9d4519a3e4abe1cfd" 1352 + 1353 + [[package]] 1354 + name = "socket2" 1355 + version = "0.5.8" 1356 + source = "registry+https://github.com/rust-lang/crates.io-index" 1357 + checksum = "c970269d99b64e60ec3bd6ad27270092a5394c4e309314b18ae3fe575695fbe8" 1358 + dependencies = [ 1359 + "libc", 1360 + "windows-sys 0.52.0", 1361 + ] 1362 + 1363 + [[package]] 1364 + name = "stable_deref_trait" 1365 + version = "1.2.0" 1366 + source = "registry+https://github.com/rust-lang/crates.io-index" 1367 + checksum = "a8f112729512f8e442d81f95a8a7ddf2b7c6b8a1a6f509a95864142b30cab2d3" 1368 + 1369 + [[package]] 1370 + name = "strsim" 1371 + version = "0.11.1" 1372 + source = "registry+https://github.com/rust-lang/crates.io-index" 1373 + checksum = "7da8b5736845d9f2fcb837ea5d9e2628564b3b043a70948a3f0b778838c5fb4f" 1374 + 1375 + [[package]] 1376 + name = "syn" 1377 + version = "2.0.100" 1378 + source = "registry+https://github.com/rust-lang/crates.io-index" 1379 + checksum = "b09a44accad81e1ba1cd74a32461ba89dee89095ba17b32f5d03683b1b1fc2a0" 1380 + dependencies = [ 1381 + "proc-macro2", 1382 + "quote", 1383 + "unicode-ident", 1384 + ] 1385 + 1386 + [[package]] 1387 + name = "synstructure" 1388 + version = "0.13.1" 1389 + source = "registry+https://github.com/rust-lang/crates.io-index" 1390 + checksum = "c8af7666ab7b6390ab78131fb5b0fce11d6b7a6951602017c35fa82800708971" 1391 + dependencies = [ 1392 + "proc-macro2", 1393 + "quote", 1394 + "syn", 1395 + ] 1396 + 1397 + [[package]] 1398 + name = "tap" 1399 + version = "1.0.1" 1400 + source = "registry+https://github.com/rust-lang/crates.io-index" 1401 + checksum = "55937e1799185b12863d447f42597ed69d9928686b8d88a1df17376a097d8369" 1402 + 1403 + [[package]] 1404 + name = "tempfile" 1405 + version = "3.18.0" 1406 + source = "registry+https://github.com/rust-lang/crates.io-index" 1407 + checksum = "2c317e0a526ee6120d8dabad239c8dadca62b24b6f168914bbbc8e2fb1f0e567" 1408 + dependencies = [ 1409 + "cfg-if", 1410 + "fastrand", 1411 + "getrandom", 1412 + "once_cell", 1413 + "rustix", 1414 + "windows-sys 0.59.0", 1415 + ] 1416 + 1417 + [[package]] 1418 + name = "terminal_size" 1419 + version = "0.4.2" 1420 + source = "registry+https://github.com/rust-lang/crates.io-index" 1421 + checksum = "45c6481c4829e4cc63825e62c49186a34538b7b2750b73b266581ffb612fb5ed" 1422 + dependencies = [ 1423 + "rustix", 1424 + "windows-sys 0.59.0", 1425 + ] 1426 + 1427 + [[package]] 1428 + name = "thiserror" 1429 + version = "2.0.12" 1430 + source = "registry+https://github.com/rust-lang/crates.io-index" 1431 + checksum = "567b8a2dae586314f7be2a752ec7474332959c6460e02bde30d702a66d488708" 1432 + dependencies = [ 1433 + "thiserror-impl", 1434 + ] 1435 + 1436 + [[package]] 1437 + name = "thiserror-impl" 1438 + version = "2.0.12" 1439 + source = "registry+https://github.com/rust-lang/crates.io-index" 1440 + checksum = "7f7cf42b4507d8ea322120659672cf1b9dbb93f8f2d4ecfd6e51350ff5b17a1d" 1441 + dependencies = [ 1442 + "proc-macro2", 1443 + "quote", 1444 + "syn", 1445 + ] 1446 + 1447 + [[package]] 1448 + name = "tinystr" 1449 + version = "0.7.6" 1450 + source = "registry+https://github.com/rust-lang/crates.io-index" 1451 + checksum = "9117f5d4db391c1cf6927e7bea3db74b9a1c1add8f7eda9ffd5364f40f57b82f" 1452 + dependencies = [ 1453 + "displaydoc", 1454 + "zerovec", 1455 + ] 1456 + 1457 + [[package]] 1458 + name = "tokio" 1459 + version = "1.44.0" 1460 + source = "registry+https://github.com/rust-lang/crates.io-index" 1461 + checksum = "9975ea0f48b5aa3972bf2d888c238182458437cc2a19374b81b25cdf1023fb3a" 1462 + dependencies = [ 1463 + "backtrace", 1464 + "bytes", 1465 + "libc", 1466 + "mio", 1467 + "pin-project-lite", 1468 + "signal-hook-registry", 1469 + "socket2", 1470 + "tokio-macros", 1471 + "windows-sys 0.52.0", 1472 + ] 1473 + 1474 + [[package]] 1475 + name = "tokio-macros" 1476 + version = "2.5.0" 1477 + source = "registry+https://github.com/rust-lang/crates.io-index" 1478 + checksum = "6e06d43f1345a3bcd39f6a56dbb7dcab2ba47e68e8ac134855e7e2bdbaf8cab8" 1479 + dependencies = [ 1480 + "proc-macro2", 1481 + "quote", 1482 + "syn", 1483 + ] 1484 + 1485 + [[package]] 1486 + name = "tokio-util" 1487 + version = "0.7.13" 1488 + source = "registry+https://github.com/rust-lang/crates.io-index" 1489 + checksum = "d7fcaa8d55a2bdd6b83ace262b016eca0d79ee02818c5c1bcdf0305114081078" 1490 + dependencies = [ 1491 + "bytes", 1492 + "futures-core", 1493 + "futures-io", 1494 + "futures-sink", 1495 + "pin-project-lite", 1496 + "tokio", 1497 + ] 1498 + 1499 + [[package]] 1500 + name = "toml" 1501 + version = "0.5.11" 1502 + source = "registry+https://github.com/rust-lang/crates.io-index" 1503 + checksum = "f4f7f0dd8d50a853a531c426359045b1998f04219d88799810762cd4ad314234" 1504 + dependencies = [ 1505 + "serde", 1506 + ] 1507 + 1508 + [[package]] 1509 + name = "toml" 1510 + version = "0.8.20" 1511 + source = "registry+https://github.com/rust-lang/crates.io-index" 1512 + checksum = "cd87a5cdd6ffab733b2f74bc4fd7ee5fff6634124999ac278c35fc78c6120148" 1513 + dependencies = [ 1514 + "serde", 1515 + "serde_spanned", 1516 + "toml_datetime", 1517 + "toml_edit", 1518 + ] 1519 + 1520 + [[package]] 1521 + name = "toml_datetime" 1522 + version = "0.6.8" 1523 + source = "registry+https://github.com/rust-lang/crates.io-index" 1524 + checksum = "0dd7358ecb8fc2f8d014bf86f6f638ce72ba252a2c3a2572f2a795f1d23efb41" 1525 + dependencies = [ 1526 + "serde", 1527 + ] 1528 + 1529 + [[package]] 1530 + name = "toml_edit" 1531 + version = "0.22.24" 1532 + source = "registry+https://github.com/rust-lang/crates.io-index" 1533 + checksum = "17b4795ff5edd201c7cd6dca065ae59972ce77d1b80fa0a84d94950ece7d1474" 1534 + dependencies = [ 1535 + "indexmap", 1536 + "serde", 1537 + "serde_spanned", 1538 + "toml_datetime", 1539 + "winnow", 1540 + ] 1541 + 1542 + [[package]] 1543 + name = "topological-sort" 1544 + version = "0.2.2" 1545 + source = "registry+https://github.com/rust-lang/crates.io-index" 1546 + checksum = "ea68304e134ecd095ac6c3574494fc62b909f416c4fca77e440530221e549d3d" 1547 + 1548 + [[package]] 1549 + name = "tower" 1550 + version = "0.5.2" 1551 + source = "registry+https://github.com/rust-lang/crates.io-index" 1552 + checksum = "d039ad9159c98b70ecfd540b2573b97f7f52c3e8d9f8ad57a24b916a536975f9" 1553 + dependencies = [ 1554 + "tower-layer", 1555 + "tower-service", 1556 + ] 1557 + 1558 + [[package]] 1559 + name = "tower-layer" 1560 + version = "0.3.3" 1561 + source = "registry+https://github.com/rust-lang/crates.io-index" 1562 + checksum = "121c2a6cda46980bb0fcd1647ffaf6cd3fc79a013de288782836f6df9c48780e" 1563 + 1564 + [[package]] 1565 + name = "tower-service" 1566 + version = "0.3.3" 1567 + source = "registry+https://github.com/rust-lang/crates.io-index" 1568 + checksum = "8df9b6e13f2d32c91b9bd719c00d1958837bc7dec474d94952798cc8e69eeec3" 1569 + 1570 + [[package]] 1571 + name = "tracing" 1572 + version = "0.1.41" 1573 + source = "registry+https://github.com/rust-lang/crates.io-index" 1574 + checksum = "784e0ac535deb450455cbfa28a6f0df145ea1bb7ae51b821cf5e7927fdcfbdd0" 1575 + dependencies = [ 1576 + "pin-project-lite", 1577 + "tracing-attributes", 1578 + "tracing-core", 1579 + ] 1580 + 1581 + [[package]] 1582 + name = "tracing-attributes" 1583 + version = "0.1.28" 1584 + source = "registry+https://github.com/rust-lang/crates.io-index" 1585 + checksum = "395ae124c09f9e6918a2310af6038fba074bcf474ac352496d5910dd59a2226d" 1586 + dependencies = [ 1587 + "proc-macro2", 1588 + "quote", 1589 + "syn", 1590 + ] 1591 + 1592 + [[package]] 1593 + name = "tracing-core" 1594 + version = "0.1.33" 1595 + source = "registry+https://github.com/rust-lang/crates.io-index" 1596 + checksum = "e672c95779cf947c5311f83787af4fa8fffd12fb27e4993211a84bdfd9610f9c" 1597 + dependencies = [ 1598 + "once_cell", 1599 + ] 1600 + 1601 + [[package]] 1602 + name = "typenum" 1603 + version = "1.18.0" 1604 + source = "registry+https://github.com/rust-lang/crates.io-index" 1605 + checksum = "1dccffe3ce07af9386bfd29e80c0ab1a8205a2fc34e4bcd40364df902cfa8f3f" 1606 + 1607 + [[package]] 1608 + name = "ucd-trie" 1609 + version = "0.1.7" 1610 + source = "registry+https://github.com/rust-lang/crates.io-index" 1611 + checksum = "2896d95c02a80c6d6a5d6e953d479f5ddf2dfdb6a244441010e373ac0fb88971" 1612 + 1613 + [[package]] 1614 + name = "unicase" 1615 + version = "2.8.1" 1616 + source = "registry+https://github.com/rust-lang/crates.io-index" 1617 + checksum = "75b844d17643ee918803943289730bec8aac480150456169e647ed0b576ba539" 1618 + 1619 + [[package]] 1620 + name = "unicode-ident" 1621 + version = "1.0.18" 1622 + source = "registry+https://github.com/rust-lang/crates.io-index" 1623 + checksum = "5a5f39404a5da50712a4c1eecf25e90dd62b613502b7e925fd4e4d19b5c96512" 1624 + 1625 + [[package]] 1626 + name = "unicode-width" 1627 + version = "0.1.14" 1628 + source = "registry+https://github.com/rust-lang/crates.io-index" 1629 + checksum = "7dd6e30e90baa6f72411720665d41d89b9a3d039dc45b8faea1ddd07f617f6af" 1630 + 1631 + [[package]] 1632 + name = "url" 1633 + version = "2.5.4" 1634 + source = "registry+https://github.com/rust-lang/crates.io-index" 1635 + checksum = "32f8b686cadd1473f4bd0117a5d28d36b1ade384ea9b5069a1c40aefed7fda60" 1636 + dependencies = [ 1637 + "form_urlencoded", 1638 + "idna", 1639 + "percent-encoding", 1640 + "serde", 1641 + ] 1642 + 1643 + [[package]] 1644 + name = "utf16_iter" 1645 + version = "1.0.5" 1646 + source = "registry+https://github.com/rust-lang/crates.io-index" 1647 + checksum = "c8232dd3cdaed5356e0f716d285e4b40b932ac434100fe9b7e0e8e935b9e6246" 1648 + 1649 + [[package]] 1650 + name = "utf8_iter" 1651 + version = "1.0.4" 1652 + source = "registry+https://github.com/rust-lang/crates.io-index" 1653 + checksum = "b6c140620e7ffbb22c2dee59cafe6084a59b5ffc27a8859a5f0d494b5d52b6be" 1654 + 1655 + [[package]] 1656 + name = "utf8parse" 1657 + version = "0.2.2" 1658 + source = "registry+https://github.com/rust-lang/crates.io-index" 1659 + checksum = "06abde3611657adf66d383f00b093d7faecc7fa57071cce2578660c9f1010821" 1660 + 1661 + [[package]] 1662 + name = "version_check" 1663 + version = "0.9.5" 1664 + source = "registry+https://github.com/rust-lang/crates.io-index" 1665 + checksum = "0b928f33d975fc6ad9f86c8f283853ad26bdd5b10b7f1542aa2fa15e2289105a" 1666 + 1667 + [[package]] 1668 + name = "waitpid-any" 1669 + version = "0.3.0" 1670 + source = "registry+https://github.com/rust-lang/crates.io-index" 1671 + checksum = "18aa3ce681e189f125c4c1e1388c03285e2fd434ef52c7203084012ac29c5e4a" 1672 + dependencies = [ 1673 + "rustix", 1674 + "windows-sys 0.59.0", 1675 + ] 1676 + 1677 + [[package]] 1678 + name = "wasi" 1679 + version = "0.11.0+wasi-snapshot-preview1" 1680 + source = "registry+https://github.com/rust-lang/crates.io-index" 1681 + checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423" 1682 + 1683 + [[package]] 1684 + name = "wasi" 1685 + version = "0.13.3+wasi-0.2.2" 1686 + source = "registry+https://github.com/rust-lang/crates.io-index" 1687 + checksum = "26816d2e1a4a36a2940b96c5296ce403917633dff8f3440e9b236ed6f6bacad2" 1688 + dependencies = [ 1689 + "wit-bindgen-rt", 1690 + ] 1691 + 1692 + [[package]] 1693 + name = "wasm-bindgen" 1694 + version = "0.2.100" 1695 + source = "registry+https://github.com/rust-lang/crates.io-index" 1696 + checksum = "1edc8929d7499fc4e8f0be2262a241556cfc54a0bea223790e71446f2aab1ef5" 1697 + dependencies = [ 1698 + "cfg-if", 1699 + "once_cell", 1700 + "rustversion", 1701 + "wasm-bindgen-macro", 1702 + ] 1703 + 1704 + [[package]] 1705 + name = "wasm-bindgen-backend" 1706 + version = "0.2.100" 1707 + source = "registry+https://github.com/rust-lang/crates.io-index" 1708 + checksum = "2f0a0651a5c2bc21487bde11ee802ccaf4c51935d0d3d42a6101f98161700bc6" 1709 + dependencies = [ 1710 + "bumpalo", 1711 + "log", 1712 + "proc-macro2", 1713 + "quote", 1714 + "syn", 1715 + "wasm-bindgen-shared", 1716 + ] 1717 + 1718 + [[package]] 1719 + name = "wasm-bindgen-macro" 1720 + version = "0.2.100" 1721 + source = "registry+https://github.com/rust-lang/crates.io-index" 1722 + checksum = "7fe63fc6d09ed3792bd0897b314f53de8e16568c2b3f7982f468c0bf9bd0b407" 1723 + dependencies = [ 1724 + "quote", 1725 + "wasm-bindgen-macro-support", 1726 + ] 1727 + 1728 + [[package]] 1729 + name = "wasm-bindgen-macro-support" 1730 + version = "0.2.100" 1731 + source = "registry+https://github.com/rust-lang/crates.io-index" 1732 + checksum = "8ae87ea40c9f689fc23f209965b6fb8a99ad69aeeb0231408be24920604395de" 1733 + dependencies = [ 1734 + "proc-macro2", 1735 + "quote", 1736 + "syn", 1737 + "wasm-bindgen-backend", 1738 + "wasm-bindgen-shared", 1739 + ] 1740 + 1741 + [[package]] 1742 + name = "wasm-bindgen-shared" 1743 + version = "0.2.100" 1744 + source = "registry+https://github.com/rust-lang/crates.io-index" 1745 + checksum = "1a05d73b933a847d6cccdda8f838a22ff101ad9bf93e33684f39c1f5f0eece3d" 1746 + dependencies = [ 1747 + "unicode-ident", 1748 + ] 1749 + 1750 + [[package]] 1751 + name = "winapi" 1752 + version = "0.3.9" 1753 + source = "registry+https://github.com/rust-lang/crates.io-index" 1754 + checksum = "5c839a674fcd7a98952e593242ea400abe93992746761e38641405d28b00f419" 1755 + dependencies = [ 1756 + "winapi-i686-pc-windows-gnu", 1757 + "winapi-x86_64-pc-windows-gnu", 1758 + ] 1759 + 1760 + [[package]] 1761 + name = "winapi-i686-pc-windows-gnu" 1762 + version = "0.4.0" 1763 + source = "registry+https://github.com/rust-lang/crates.io-index" 1764 + checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6" 1765 + 1766 + [[package]] 1767 + name = "winapi-x86_64-pc-windows-gnu" 1768 + version = "0.4.0" 1769 + source = "registry+https://github.com/rust-lang/crates.io-index" 1770 + checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" 1771 + 1772 + [[package]] 1773 + name = "windows-core" 1774 + version = "0.52.0" 1775 + source = "registry+https://github.com/rust-lang/crates.io-index" 1776 + checksum = "33ab640c8d7e35bf8ba19b884ba838ceb4fba93a4e8c65a9059d08afcfc683d9" 1777 + dependencies = [ 1778 + "windows-targets", 1779 + ] 1780 + 1781 + [[package]] 1782 + name = "windows-link" 1783 + version = "0.1.0" 1784 + source = "registry+https://github.com/rust-lang/crates.io-index" 1785 + checksum = "6dccfd733ce2b1753b03b6d3c65edf020262ea35e20ccdf3e288043e6dd620e3" 1786 + 1787 + [[package]] 1788 + name = "windows-sys" 1789 + version = "0.52.0" 1790 + source = "registry+https://github.com/rust-lang/crates.io-index" 1791 + checksum = "282be5f36a8ce781fad8c8ae18fa3f9beff57ec1b52cb3de0789201425d9a33d" 1792 + dependencies = [ 1793 + "windows-targets", 1794 + ] 1795 + 1796 + [[package]] 1797 + name = "windows-sys" 1798 + version = "0.59.0" 1799 + source = "registry+https://github.com/rust-lang/crates.io-index" 1800 + checksum = "1e38bc4d79ed67fd075bcc251a1c39b32a1776bbe92e5bef1f0bf1f8c531853b" 1801 + dependencies = [ 1802 + "windows-targets", 1803 + ] 1804 + 1805 + [[package]] 1806 + name = "windows-targets" 1807 + version = "0.52.6" 1808 + source = "registry+https://github.com/rust-lang/crates.io-index" 1809 + checksum = "9b724f72796e036ab90c1021d4780d4d3d648aca59e491e6b98e725b84e99973" 1810 + dependencies = [ 1811 + "windows_aarch64_gnullvm", 1812 + "windows_aarch64_msvc", 1813 + "windows_i686_gnu", 1814 + "windows_i686_gnullvm", 1815 + "windows_i686_msvc", 1816 + "windows_x86_64_gnu", 1817 + "windows_x86_64_gnullvm", 1818 + "windows_x86_64_msvc", 1819 + ] 1820 + 1821 + [[package]] 1822 + name = "windows_aarch64_gnullvm" 1823 + version = "0.52.6" 1824 + source = "registry+https://github.com/rust-lang/crates.io-index" 1825 + checksum = "32a4622180e7a0ec044bb555404c800bc9fd9ec262ec147edd5989ccd0c02cd3" 1826 + 1827 + [[package]] 1828 + name = "windows_aarch64_msvc" 1829 + version = "0.52.6" 1830 + source = "registry+https://github.com/rust-lang/crates.io-index" 1831 + checksum = "09ec2a7bb152e2252b53fa7803150007879548bc709c039df7627cabbd05d469" 1832 + 1833 + [[package]] 1834 + name = "windows_i686_gnu" 1835 + version = "0.52.6" 1836 + source = "registry+https://github.com/rust-lang/crates.io-index" 1837 + checksum = "8e9b5ad5ab802e97eb8e295ac6720e509ee4c243f69d781394014ebfe8bbfa0b" 1838 + 1839 + [[package]] 1840 + name = "windows_i686_gnullvm" 1841 + version = "0.52.6" 1842 + source = "registry+https://github.com/rust-lang/crates.io-index" 1843 + checksum = "0eee52d38c090b3caa76c563b86c3a4bd71ef1a819287c19d586d7334ae8ed66" 1844 + 1845 + [[package]] 1846 + name = "windows_i686_msvc" 1847 + version = "0.52.6" 1848 + source = "registry+https://github.com/rust-lang/crates.io-index" 1849 + checksum = "240948bc05c5e7c6dabba28bf89d89ffce3e303022809e73deaefe4f6ec56c66" 1850 + 1851 + [[package]] 1852 + name = "windows_x86_64_gnu" 1853 + version = "0.52.6" 1854 + source = "registry+https://github.com/rust-lang/crates.io-index" 1855 + checksum = "147a5c80aabfbf0c7d901cb5895d1de30ef2907eb21fbbab29ca94c5b08b1a78" 1856 + 1857 + [[package]] 1858 + name = "windows_x86_64_gnullvm" 1859 + version = "0.52.6" 1860 + source = "registry+https://github.com/rust-lang/crates.io-index" 1861 + checksum = "24d5b23dc417412679681396f2b49f3de8c1473deb516bd34410872eff51ed0d" 1862 + 1863 + [[package]] 1864 + name = "windows_x86_64_msvc" 1865 + version = "0.52.6" 1866 + source = "registry+https://github.com/rust-lang/crates.io-index" 1867 + checksum = "589f6da84c646204747d1270a2a5661ea66ed1cced2631d546fdfb155959f9ec" 1868 + 1869 + [[package]] 1870 + name = "winnow" 1871 + version = "0.7.3" 1872 + source = "registry+https://github.com/rust-lang/crates.io-index" 1873 + checksum = "0e7f4ea97f6f78012141bcdb6a216b2609f0979ada50b20ca5b52dde2eac2bb1" 1874 + dependencies = [ 1875 + "memchr", 1876 + ] 1877 + 1878 + [[package]] 1879 + name = "wit-bindgen-rt" 1880 + version = "0.33.0" 1881 + source = "registry+https://github.com/rust-lang/crates.io-index" 1882 + checksum = "3268f3d866458b787f390cf61f4bbb563b922d091359f9608842999eaee3943c" 1883 + dependencies = [ 1884 + "bitflags 2.9.0", 1885 + ] 1886 + 1887 + [[package]] 1888 + name = "write16" 1889 + version = "1.0.0" 1890 + source = "registry+https://github.com/rust-lang/crates.io-index" 1891 + checksum = "d1890f4022759daae28ed4fe62859b1236caebfc61ede2f63ed4e695f3f6d936" 1892 + 1893 + [[package]] 1894 + name = "writeable" 1895 + version = "0.5.5" 1896 + source = "registry+https://github.com/rust-lang/crates.io-index" 1897 + checksum = "1e9df38ee2d2c3c5948ea468a8406ff0db0b29ae1ffde1bcf20ef305bcc95c51" 1898 + 1899 + [[package]] 1900 + name = "yoke" 1901 + version = "0.7.5" 1902 + source = "registry+https://github.com/rust-lang/crates.io-index" 1903 + checksum = "120e6aef9aa629e3d4f52dc8cc43a015c7724194c97dfaf45180d2daf2b77f40" 1904 + dependencies = [ 1905 + "serde", 1906 + "stable_deref_trait", 1907 + "yoke-derive", 1908 + "zerofrom", 1909 + ] 1910 + 1911 + [[package]] 1912 + name = "yoke-derive" 1913 + version = "0.7.5" 1914 + source = "registry+https://github.com/rust-lang/crates.io-index" 1915 + checksum = "2380878cad4ac9aac1e2435f3eb4020e8374b5f13c296cb75b4620ff8e229154" 1916 + dependencies = [ 1917 + "proc-macro2", 1918 + "quote", 1919 + "syn", 1920 + "synstructure", 1921 + ] 1922 + 1923 + [[package]] 1924 + name = "zerofrom" 1925 + version = "0.1.6" 1926 + source = "registry+https://github.com/rust-lang/crates.io-index" 1927 + checksum = "50cc42e0333e05660c3587f3bf9d0478688e15d870fab3346451ce7f8c9fbea5" 1928 + dependencies = [ 1929 + "zerofrom-derive", 1930 + ] 1931 + 1932 + [[package]] 1933 + name = "zerofrom-derive" 1934 + version = "0.1.6" 1935 + source = "registry+https://github.com/rust-lang/crates.io-index" 1936 + checksum = "d71e5d6e06ab090c67b5e44993ec16b72dcbaabc526db883a360057678b48502" 1937 + dependencies = [ 1938 + "proc-macro2", 1939 + "quote", 1940 + "syn", 1941 + "synstructure", 1942 + ] 1943 + 1944 + [[package]] 1945 + name = "zerovec" 1946 + version = "0.10.4" 1947 + source = "registry+https://github.com/rust-lang/crates.io-index" 1948 + checksum = "aa2b893d79df23bfb12d5461018d408ea19dfafe76c2c7ef6d4eba614f8ff079" 1949 + dependencies = [ 1950 + "yoke", 1951 + "zerofrom", 1952 + "zerovec-derive", 1953 + ] 1954 + 1955 + [[package]] 1956 + name = "zerovec-derive" 1957 + version = "0.10.3" 1958 + source = "registry+https://github.com/rust-lang/crates.io-index" 1959 + checksum = "6eafa6dfb17584ea3e2bd6e76e0cc15ad7af12b09abdd1ca55961bed9b1063c6" 1960 + dependencies = [ 1961 + "proc-macro2", 1962 + "quote", 1963 + "syn", 1964 + ]
+30
Cargo.toml
··· 1 + [workspace.package] 2 + authors = ["Tony Wu <tonywu6@protonmail.com>"] 3 + edition = "2021" 4 + license = "MIT OR Apache-2.0" 5 + publish = false 6 + repository = "https://github.com/tonywu6/bookmd" 7 + 8 + [profile.dev.package] 9 + insta.opt-level = 3 10 + similar.opt-level = 3 11 + 12 + [workspace] 13 + default-members = ["crates/*"] 14 + members = ["crates/*"] 15 + resolver = "2" 16 + 17 + [workspace.dependencies] 18 + anyhow = "1.0.95" 19 + clap = { version = "4.5.31", features = ["derive"] } 20 + env_logger = "0.11.6" 21 + insta = { version = "1.40.0", features = ["yaml"] } 22 + log = "0.4.26" 23 + mdbook = { version = "0.4.46", default-features = false } 24 + pulldown-cmark = "0.13.0" 25 + pulldown-cmark-to-cmark = "21.0.0" 26 + serde = { version = "1", features = ["derive"] } 27 + serde_json = "1.0.139" 28 + tap = "1.0.1" 29 + tokio = { version = "1", features = ["macros"] } 30 + toml = "0.5"
+201
LICENSE-APACHE.md
··· 1 + Apache License 2 + Version 2.0, January 2004 3 + http://www.apache.org/licenses/ 4 + 5 + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION 6 + 7 + 1. Definitions. 8 + 9 + "License" shall mean the terms and conditions for use, reproduction, 10 + and distribution as defined by Sections 1 through 9 of this document. 11 + 12 + "Licensor" shall mean the copyright owner or entity authorized by 13 + the copyright owner that is granting the License. 14 + 15 + "Legal Entity" shall mean the union of the acting entity and all 16 + other entities that control, are controlled by, or are under common 17 + control with that entity. For the purposes of this definition, 18 + "control" means (i) the power, direct or indirect, to cause the 19 + direction or management of such entity, whether by contract or 20 + otherwise, or (ii) ownership of fifty percent (50%) or more of the 21 + outstanding shares, or (iii) beneficial ownership of such entity. 22 + 23 + "You" (or "Your") shall mean an individual or Legal Entity 24 + exercising permissions granted by this License. 25 + 26 + "Source" form shall mean the preferred form for making modifications, 27 + including but not limited to software source code, documentation 28 + source, and configuration files. 29 + 30 + "Object" form shall mean any form resulting from mechanical 31 + transformation or translation of a Source form, including but 32 + not limited to compiled object code, generated documentation, 33 + and conversions to other media types. 34 + 35 + "Work" shall mean the work of authorship, whether in Source or 36 + Object form, made available under the License, as indicated by a 37 + copyright notice that is included in or attached to the work 38 + (an example is provided in the Appendix below). 39 + 40 + "Derivative Works" shall mean any work, whether in Source or Object 41 + form, that is based on (or derived from) the Work and for which the 42 + editorial revisions, annotations, elaborations, or other modifications 43 + represent, as a whole, an original work of authorship. For the purposes 44 + of this License, Derivative Works shall not include works that remain 45 + separable from, or merely link (or bind by name) to the interfaces of, 46 + the Work and Derivative Works thereof. 47 + 48 + "Contribution" shall mean any work of authorship, including 49 + the original version of the Work and any modifications or additions 50 + to that Work or Derivative Works thereof, that is intentionally 51 + submitted to Licensor for inclusion in the Work by the copyright owner 52 + or by an individual or Legal Entity authorized to submit on behalf of 53 + the copyright owner. For the purposes of this definition, "submitted" 54 + means any form of electronic, verbal, or written communication sent 55 + to the Licensor or its representatives, including but not limited to 56 + communication on electronic mailing lists, source code control systems, 57 + and issue tracking systems that are managed by, or on behalf of, the 58 + Licensor for the purpose of discussing and improving the Work, but 59 + excluding communication that is conspicuously marked or otherwise 60 + designated in writing by the copyright owner as "Not a Contribution." 61 + 62 + "Contributor" shall mean Licensor and any individual or Legal Entity 63 + on behalf of whom a Contribution has been received by Licensor and 64 + subsequently incorporated within the Work. 65 + 66 + 2. Grant of Copyright License. Subject to the terms and conditions of 67 + this License, each Contributor hereby grants to You a perpetual, 68 + worldwide, non-exclusive, no-charge, royalty-free, irrevocable 69 + copyright license to reproduce, prepare Derivative Works of, 70 + publicly display, publicly perform, sublicense, and distribute the 71 + Work and such Derivative Works in Source or Object form. 72 + 73 + 3. Grant of Patent License. Subject to the terms and conditions of 74 + this License, each Contributor hereby grants to You a perpetual, 75 + worldwide, non-exclusive, no-charge, royalty-free, irrevocable 76 + (except as stated in this section) patent license to make, have made, 77 + use, offer to sell, sell, import, and otherwise transfer the Work, 78 + where such license applies only to those patent claims licensable 79 + by such Contributor that are necessarily infringed by their 80 + Contribution(s) alone or by combination of their Contribution(s) 81 + with the Work to which such Contribution(s) was submitted. If You 82 + institute patent litigation against any entity (including a 83 + cross-claim or counterclaim in a lawsuit) alleging that the Work 84 + or a Contribution incorporated within the Work constitutes direct 85 + or contributory patent infringement, then any patent licenses 86 + granted to You under this License for that Work shall terminate 87 + as of the date such litigation is filed. 88 + 89 + 4. Redistribution. You may reproduce and distribute copies of the 90 + Work or Derivative Works thereof in any medium, with or without 91 + modifications, and in Source or Object form, provided that You 92 + meet the following conditions: 93 + 94 + (a) You must give any other recipients of the Work or 95 + Derivative Works a copy of this License; and 96 + 97 + (b) You must cause any modified files to carry prominent notices 98 + stating that You changed the files; and 99 + 100 + (c) You must retain, in the Source form of any Derivative Works 101 + that You distribute, all copyright, patent, trademark, and 102 + attribution notices from the Source form of the Work, 103 + excluding those notices that do not pertain to any part of 104 + the Derivative Works; and 105 + 106 + (d) If the Work includes a "NOTICE" text file as part of its 107 + distribution, then any Derivative Works that You distribute must 108 + include a readable copy of the attribution notices contained 109 + within such NOTICE file, excluding those notices that do not 110 + pertain to any part of the Derivative Works, in at least one 111 + of the following places: within a NOTICE text file distributed 112 + as part of the Derivative Works; within the Source form or 113 + documentation, if provided along with the Derivative Works; or, 114 + within a display generated by the Derivative Works, if and 115 + wherever such third-party notices normally appear. The contents 116 + of the NOTICE file are for informational purposes only and 117 + do not modify the License. You may add Your own attribution 118 + notices within Derivative Works that You distribute, alongside 119 + or as an addendum to the NOTICE text from the Work, provided 120 + that such additional attribution notices cannot be construed 121 + as modifying the License. 122 + 123 + You may add Your own copyright statement to Your modifications and 124 + may provide additional or different license terms and conditions 125 + for use, reproduction, or distribution of Your modifications, or 126 + for any such Derivative Works as a whole, provided Your use, 127 + reproduction, and distribution of the Work otherwise complies with 128 + the conditions stated in this License. 129 + 130 + 5. Submission of Contributions. Unless You explicitly state otherwise, 131 + any Contribution intentionally submitted for inclusion in the Work 132 + by You to the Licensor shall be under the terms and conditions of 133 + this License, without any additional terms or conditions. 134 + Notwithstanding the above, nothing herein shall supersede or modify 135 + the terms of any separate license agreement you may have executed 136 + with Licensor regarding such Contributions. 137 + 138 + 6. Trademarks. This License does not grant permission to use the trade 139 + names, trademarks, service marks, or product names of the Licensor, 140 + except as required for reasonable and customary use in describing the 141 + origin of the Work and reproducing the content of the NOTICE file. 142 + 143 + 7. Disclaimer of Warranty. Unless required by applicable law or 144 + agreed to in writing, Licensor provides the Work (and each 145 + Contributor provides its Contributions) on an "AS IS" BASIS, 146 + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or 147 + implied, including, without limitation, any warranties or conditions 148 + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A 149 + PARTICULAR PURPOSE. You are solely responsible for determining the 150 + appropriateness of using or redistributing the Work and assume any 151 + risks associated with Your exercise of permissions under this License. 152 + 153 + 8. Limitation of Liability. In no event and under no legal theory, 154 + whether in tort (including negligence), contract, or otherwise, 155 + unless required by applicable law (such as deliberate and grossly 156 + negligent acts) or agreed to in writing, shall any Contributor be 157 + liable to You for damages, including any direct, indirect, special, 158 + incidental, or consequential damages of any character arising as a 159 + result of this License or out of the use or inability to use the 160 + Work (including but not limited to damages for loss of goodwill, 161 + work stoppage, computer failure or malfunction, or any and all 162 + other commercial damages or losses), even if such Contributor 163 + has been advised of the possibility of such damages. 164 + 165 + 9. Accepting Warranty or Additional Liability. While redistributing 166 + the Work or Derivative Works thereof, You may choose to offer, 167 + and charge a fee for, acceptance of support, warranty, indemnity, 168 + or other liability obligations and/or rights consistent with this 169 + License. However, in accepting such obligations, You may act only 170 + on Your own behalf and on Your sole responsibility, not on behalf 171 + of any other Contributor, and only if You agree to indemnify, 172 + defend, and hold each Contributor harmless for any liability 173 + incurred by, or claims asserted against, such Contributor by reason 174 + of your accepting any such warranty or additional liability. 175 + 176 + END OF TERMS AND CONDITIONS 177 + 178 + APPENDIX: How to apply the Apache License to your work. 179 + 180 + To apply the Apache License to your work, attach the following 181 + boilerplate notice, with the fields enclosed by brackets "[]" 182 + replaced with your own identifying information. (Don't include 183 + the brackets!) The text should be enclosed in the appropriate 184 + comment syntax for the file format. We also recommend that a 185 + file or class name and description of purpose be included on the 186 + same "printed page" as the copyright notice for easier 187 + identification within third-party archives. 188 + 189 + Copyright [yyyy] [name of copyright owner] 190 + 191 + Licensed under the Apache License, Version 2.0 (the "License"); 192 + you may not use this file except in compliance with the License. 193 + You may obtain a copy of the License at 194 + 195 + http://www.apache.org/licenses/LICENSE-2.0 196 + 197 + Unless required by applicable law or agreed to in writing, software 198 + distributed under the License is distributed on an "AS IS" BASIS, 199 + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 200 + See the License for the specific language governing permissions and 201 + limitations under the License.
+23
LICENSE-MIT.md
··· 1 + Permission is hereby granted, free of charge, to any 2 + person obtaining a copy of this software and associated 3 + documentation files (the "Software"), to deal in the 4 + Software without restriction, including without 5 + limitation the rights to use, copy, modify, merge, 6 + publish, distribute, sublicense, and/or sell copies of 7 + the Software, and to permit persons to whom the Software 8 + is furnished to do so, subject to the following 9 + conditions: 10 + 11 + The above copyright notice and this permission notice 12 + shall be included in all copies or substantial portions 13 + of the Software. 14 + 15 + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF 16 + ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED 17 + TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A 18 + PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT 19 + SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY 20 + CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION 21 + OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR 22 + IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 23 + DEALINGS IN THE SOFTWARE.
+2
TODO.md
··· 1 + - [ ] jupytext 2 + - [ ] local links
+39
crates/rustdoc-link/Cargo.toml
··· 1 + [package] 2 + name = "mdbook-rustdoc-link" 3 + version = "0.1.0" 4 + 5 + authors.workspace = true 6 + edition.workspace = true 7 + license.workspace = true 8 + publish.workspace = true 9 + repository.workspace = true 10 + 11 + [dependencies] 12 + anyhow = { workspace = true } 13 + async-lsp = "0.2.2" 14 + cargo_toml = "0.21.0" 15 + clap = { workspace = true } 16 + env_logger = { workspace = true } 17 + log = { workspace = true } 18 + lsp-types = "0.95.0" 19 + mdbook = { workspace = true } 20 + proc-macro2 = { version = "1.0.94", features = ["span-locations"] } 21 + pulldown-cmark = { workspace = true } 22 + pulldown-cmark-to-cmark = { workspace = true } 23 + quote = "1.0.39" 24 + serde = { workspace = true } 25 + serde_json = { workspace = true } 26 + syn = "2.0.99" 27 + tap = { workspace = true } 28 + tokio = { workspace = true, features = [ 29 + "macros", 30 + "rt-multi-thread", 31 + "process", 32 + "time", 33 + ] } 34 + tokio-util = { version = "0.7.13", features = ["compat"] } 35 + toml = { workspace = true } 36 + tower = "0.5.2" 37 + 38 + [dev-dependencies] 39 + insta = { workspace = true }
+361
crates/rustdoc-link/src/client.rs
··· 1 + use std::{ 2 + collections::HashMap, 3 + ops::ControlFlow, 4 + path::{Path, PathBuf}, 5 + process::Stdio, 6 + sync::{Arc, RwLock}, 7 + task::Poll, 8 + time::Duration, 9 + }; 10 + 11 + use anyhow::{anyhow, bail, Context, Result}; 12 + use async_lsp::{ 13 + concurrency::ConcurrencyLayer, panic::CatchUnwindLayer, router::Router, tracing::TracingLayer, 14 + LanguageServer, MainLoop, ServerSocket, 15 + }; 16 + use cargo_toml::{Manifest, Product}; 17 + use lsp_types::{ 18 + notification::{Progress, PublishDiagnostics, ShowMessage}, 19 + request::Request, 20 + ClientCapabilities, DidCloseTextDocumentParams, DidOpenTextDocumentParams, 21 + GeneralClientCapabilities, InitializeParams, InitializedParams, NumberOrString, Position, 22 + PositionEncodingKind, ProgressParams, ProgressParamsValue, TextDocumentIdentifier, 23 + TextDocumentItem, TextDocumentPositionParams, Url, WindowClientCapabilities, WorkDoneProgress, 24 + WorkspaceFolder, 25 + }; 26 + use serde::{Deserialize, Serialize}; 27 + use serde_json::json; 28 + use tokio::{ 29 + process::Command, 30 + sync::{mpsc, OwnedSemaphorePermit, Semaphore}, 31 + task::JoinHandle, 32 + time::timeout, 33 + }; 34 + use tokio_util::compat::{TokioAsyncReadCompatExt, TokioAsyncWriteCompatExt}; 35 + use tower::ServiceBuilder; 36 + 37 + use crate::{sync::Subsample, BuildOptions}; 38 + 39 + #[derive(Debug, Clone)] 40 + pub struct Client { 41 + pub server: ServerSocket, 42 + pub config: Environment, 43 + stabilizer: Subsample<()>, 44 + documents: DocumentLock, 45 + } 46 + 47 + impl Client { 48 + pub async fn spawn(options: BuildOptions) -> Result<(Self, DisposeClient)> { 49 + let config = Environment::new(options)?; 50 + 51 + let (tx, rx) = mpsc::channel(16); 52 + 53 + let stabilizer = Subsample::new(rx, Duration::from_secs(1)); 54 + 55 + let (background, mut server) = MainLoop::new_client(move |_| { 56 + struct State { 57 + tx: mpsc::Sender<Poll<()>>, 58 + } 59 + 60 + let state = State { tx }; 61 + 62 + let mut router = Router::new(state); 63 + 64 + router 65 + .notification::<Progress>(|state, progress| { 66 + log::debug!("{progress:#?}"); 67 + 68 + match indexing_progress(&progress) { 69 + None => log::debug!("{progress:#?}"), 70 + Some(WorkDoneProgress::Begin(begin)) => { 71 + log::info!( 72 + "{} {}", 73 + begin.title, 74 + begin.message.as_deref().unwrap_or_default() 75 + ); 76 + let tx = state.tx.clone(); 77 + tokio::spawn(async move { tx.send(Poll::Pending).await.ok() }); 78 + } 79 + Some(WorkDoneProgress::End(end)) => { 80 + log::info!("{}", end.message.as_deref().unwrap_or("Done")); 81 + let tx = state.tx.clone(); 82 + tokio::spawn(async move { tx.send(Poll::Ready(())).await.ok() }); 83 + } 84 + Some(WorkDoneProgress::Report(report)) => { 85 + if let Some(message) = &report.message { 86 + log::info!("{message}"); 87 + } 88 + } 89 + } 90 + 91 + ControlFlow::Continue(()) 92 + }) 93 + .notification::<PublishDiagnostics>(|_, diagnostics| { 94 + log::debug!("{diagnostics:#?}"); 95 + ControlFlow::Continue(()) 96 + }) 97 + .notification::<ShowMessage>(|_, message| { 98 + log::debug!("{message:#?}"); 99 + ControlFlow::Continue(()) 100 + }) 101 + .event(|_, _: StopEvent| ControlFlow::Break(Ok(()))); 102 + 103 + ServiceBuilder::new() 104 + .layer(TracingLayer::default()) 105 + .layer(CatchUnwindLayer::default()) 106 + .layer(ConcurrencyLayer::default()) 107 + .service(router) 108 + }); 109 + 110 + let proc = Command::new("rust-analyzer") 111 + .current_dir(&config.root_dir) 112 + .stdin(Stdio::piped()) 113 + .stdout(Stdio::piped()) 114 + .stderr(Stdio::inherit()) 115 + .kill_on_drop(true) 116 + .spawn() 117 + .context("failed to spawn rust-analyzer")?; 118 + 119 + let background = tokio::spawn(async move { 120 + let mut proc = proc; 121 + let stdout = proc.stdout.take().unwrap(); 122 + let stdin = proc.stdin.take().unwrap(); 123 + background 124 + .run_buffered(stdout.compat(), stdin.compat_write()) 125 + .await 126 + .unwrap(); 127 + }); 128 + 129 + let root_uri = Url::from_directory_path(&config.root_dir).unwrap(); 130 + 131 + let init = server 132 + .initialize(InitializeParams { 133 + workspace_folders: Some(vec![WorkspaceFolder { 134 + uri: root_uri.clone(), 135 + name: "root".into(), 136 + }]), 137 + capabilities: ClientCapabilities { 138 + experimental: Some(json! {{ 139 + "localDocs": true, 140 + }}), 141 + window: Some(WindowClientCapabilities { 142 + work_done_progress: Some(true), 143 + ..Default::default() 144 + }), 145 + general: Some(GeneralClientCapabilities { 146 + position_encodings: Some(vec![PositionEncodingKind::UTF8]), 147 + ..Default::default() 148 + }), 149 + ..Default::default() 150 + }, 151 + ..Default::default() 152 + }) 153 + .await?; 154 + 155 + log::debug!("{init:#?}"); 156 + 157 + if init.capabilities.position_encoding != Some(PositionEncodingKind::UTF8) { 158 + bail!("this rust-analyzer does not support utf-8 positions") 159 + } 160 + 161 + server.initialized(InitializedParams {})?; 162 + 163 + let documents = DocumentLock::default(); 164 + 165 + let client = Self { 166 + server, 167 + config, 168 + stabilizer, 169 + documents, 170 + }; 171 + 172 + Ok((client, DisposeClient(background))) 173 + } 174 + 175 + pub async fn open(&self, uri: Url, text: String) -> Result<OpenDocument> { 176 + let document = self.documents.open(self.server.clone(), uri, text).await?; 177 + timeout(Duration::from_secs(60), self.stabilizer.wait()) 178 + .await 179 + .context("timed out waiting for rust-analyzer to open document")?; 180 + Ok(document) 181 + } 182 + } 183 + 184 + #[derive(Debug, Clone)] 185 + pub struct Environment { 186 + pub root_dir: PathBuf, 187 + pub entrypoint: Url, 188 + pub build_opts: BuildOptions, 189 + } 190 + 191 + impl Environment { 192 + fn new(build_opts: BuildOptions) -> Result<Self> { 193 + let root_dir = build_opts 194 + .manifest_dir 195 + .clone() 196 + .map(Ok) 197 + .unwrap_or_else(std::env::current_dir)? 198 + .canonicalize()?; 199 + 200 + let entrypoint = find_entrypoint(&root_dir)?; 201 + 202 + Ok(Self { 203 + root_dir, 204 + entrypoint, 205 + build_opts, 206 + }) 207 + } 208 + } 209 + 210 + pub fn find_entrypoint<P: AsRef<Path>>(from_dir: P) -> Result<Url> { 211 + let dir = from_dir.as_ref().canonicalize()?; 212 + 213 + let path = { 214 + let mut dir = dir.as_path(); 215 + loop { 216 + let path = dir.join("Cargo.toml"); 217 + if path.exists() { 218 + break path; 219 + } 220 + dir = match dir.parent() { 221 + Some(dir) => dir, 222 + None => { 223 + return Err(anyhow!(from_dir.as_ref().display().to_string())) 224 + .context("failed to find a Cargo.toml"); 225 + } 226 + }; 227 + } 228 + }; 229 + 230 + let manifest = { 231 + let mut manifest = Manifest::from_path(&path)?; 232 + manifest.complete_from_path(&path)?; 233 + manifest 234 + }; 235 + 236 + let root_url = Url::from_file_path(&path).unwrap(); 237 + 238 + if let Some(Product { 239 + path: Some(lib), .. 240 + }) = manifest.lib 241 + { 242 + Ok(root_url.join(&lib)?) 243 + } else if let Some(bin) = manifest.bin.iter().find_map(|bin| bin.path.as_ref()) { 244 + Ok(root_url.join(bin)?) 245 + } else { 246 + Err(anyhow!("{}", path.display())).context("Cargo.toml does not have a lib or bin target") 247 + } 248 + } 249 + 250 + struct StopEvent; 251 + 252 + #[must_use] 253 + pub struct DisposeClient(JoinHandle<()>); 254 + 255 + impl DisposeClient { 256 + pub async fn of(self, client: Client) -> Result<()> { 257 + let Client { mut server, .. } = client; 258 + server.shutdown(()).await?; 259 + server.exit(())?; 260 + server.emit(StopEvent)?; 261 + self.0.await?; 262 + Ok(()) 263 + } 264 + } 265 + 266 + #[derive(Debug, Default, Clone)] 267 + struct DocumentLock { 268 + opened: Arc<RwLock<DocumentMap>>, 269 + } 270 + 271 + type DocumentMap = HashMap<Url, (Arc<Semaphore>, i32)>; 272 + 273 + impl DocumentLock { 274 + pub async fn open( 275 + &self, 276 + mut sock: ServerSocket, 277 + uri: Url, 278 + text: String, 279 + ) -> Result<OpenDocument> { 280 + let (sema, version) = { 281 + let mut lock = self.opened.write().unwrap(); 282 + let (sema, version) = lock 283 + .entry(uri.clone()) 284 + .or_insert_with(|| (Arc::new(Semaphore::new(1)), 0)); 285 + *version += 1; 286 + (sema.clone(), *version) 287 + }; 288 + 289 + let _permit = sema.acquire_owned().await?; 290 + 291 + sock.did_open(DidOpenTextDocumentParams { 292 + text_document: TextDocumentItem { 293 + language_id: "rust".into(), 294 + uri: uri.clone(), 295 + text, 296 + version, 297 + }, 298 + })?; 299 + 300 + let closing = Some(DidCloseTextDocumentParams { 301 + text_document: TextDocumentIdentifier { uri }, 302 + }); 303 + 304 + Ok(OpenDocument { 305 + sock, 306 + closing, 307 + _permit, 308 + }) 309 + } 310 + } 311 + 312 + #[derive(Debug)] 313 + #[must_use = "bind this to a variable or document will be immediately closed"] 314 + pub struct OpenDocument { 315 + sock: ServerSocket, 316 + closing: Option<DidCloseTextDocumentParams>, 317 + _permit: OwnedSemaphorePermit, 318 + } 319 + 320 + impl Drop for OpenDocument { 321 + fn drop(&mut self) { 322 + self.sock.did_close(self.closing.take().unwrap()).ok(); 323 + } 324 + } 325 + 326 + pub enum ExternalDocs {} 327 + 328 + impl Request for ExternalDocs { 329 + const METHOD: &'static str = "experimental/externalDocs"; 330 + type Params = TextDocumentPositionParams; 331 + type Result = Option<ExternalDocLinks>; 332 + } 333 + 334 + #[derive(Debug, Deserialize, Serialize)] 335 + pub struct ExternalDocLinks { 336 + pub web: Option<Url>, 337 + pub local: Option<Url>, 338 + } 339 + 340 + pub fn document_position(uri: Url, position: Position) -> TextDocumentPositionParams { 341 + TextDocumentPositionParams { 342 + text_document: TextDocumentIdentifier { uri }, 343 + position, 344 + } 345 + } 346 + 347 + fn indexing_progress(progress: &ProgressParams) -> Option<&WorkDoneProgress> { 348 + if let ProgressParams { 349 + token: NumberOrString::String(token), 350 + value: ProgressParamsValue::WorkDone(progress), 351 + } = progress 352 + { 353 + if token == "rustAnalyzer/Indexing" { 354 + Some(progress) 355 + } else { 356 + None 357 + } 358 + } else { 359 + None 360 + } 361 + }
+65
crates/rustdoc-link/src/item.rs
··· 1 + use syn::{ 2 + parse::{Parse, ParseStream}, 3 + spanned::Spanned, 4 + Error, Expr, ExprCall, ExprMacro, ExprPath, Ident, Macro, Path, Result, 5 + }; 6 + use tap::Pipe; 7 + 8 + pub enum ItemName { 9 + Path { path: Path }, 10 + Call { path: Path }, 11 + Macro { mac: Macro }, 12 + } 13 + 14 + impl Parse for ItemName { 15 + fn parse(input: ParseStream) -> Result<Self> { 16 + let expr = Expr::parse(input)?; 17 + match expr { 18 + Expr::Path(ExprPath { 19 + path, qself: None, .. 20 + }) => Ok(Self::Path { path }), 21 + 22 + Expr::Call(ExprCall { func, .. }) => match *func { 23 + Expr::Path(ExprPath { 24 + path, qself: None, .. 25 + }) => Ok(Self::Call { path }), 26 + func => Error::new(func.span(), "expected a path").pipe(Err), 27 + }, 28 + 29 + Expr::Macro(ExprMacro { mac, .. }) => Ok(Self::Macro { mac }), 30 + 31 + expr => Error::new(expr.span(), "expected a path, call, or macro").pipe(Err), 32 + } 33 + } 34 + } 35 + 36 + impl ItemName { 37 + pub fn ident(&self) -> &Ident { 38 + let path = match &self { 39 + Self::Path { path } => path, 40 + Self::Call { path, .. } => path, 41 + Self::Macro { mac } => &mac.path, 42 + }; 43 + &path 44 + .segments 45 + .last() 46 + .expect("path should not be empty") 47 + .ident 48 + } 49 + } 50 + 51 + #[cfg(test)] 52 + const _: () = { 53 + use proc_macro2::TokenStream; 54 + use quote::{quote, ToTokens}; 55 + 56 + impl ToTokens for ItemName { 57 + fn to_tokens(&self, tokens: &mut TokenStream) { 58 + match self { 59 + Self::Path { path } => path.to_tokens(tokens), 60 + Self::Call { path, .. } => quote! { #path () }.to_tokens(tokens), 61 + Self::Macro { mac } => mac.to_tokens(tokens), 62 + } 63 + } 64 + } 65 + };
+321
crates/rustdoc-link/src/main.rs
··· 1 + use std::{ 2 + collections::{HashMap, HashSet}, 3 + io::{Read, Write}, 4 + path::PathBuf, 5 + }; 6 + 7 + use anyhow::Result; 8 + use lsp_types::Position; 9 + use mdbook::{book::Book, preprocess::PreprocessorContext, BookItem}; 10 + use serde::Deserialize; 11 + use tap::{Pipe, Tap, TapFallible, TapOptional}; 12 + use tokio::task::JoinSet; 13 + 14 + use crate::{ 15 + client::{document_position, Client, ExternalDocLinks, ExternalDocs}, 16 + item::ItemName, 17 + markdown::{markdown_parser, Pages}, 18 + }; 19 + 20 + mod client; 21 + mod item; 22 + mod markdown; 23 + mod sync; 24 + 25 + #[derive(clap::Parser, Deserialize, Debug, Default, Clone)] 26 + #[serde(rename_all = "kebab-case")] 27 + struct BuildOptions { 28 + #[arg(long)] 29 + #[serde(default)] 30 + manifest_dir: Option<PathBuf>, 31 + #[arg(long)] 32 + #[serde(default)] 33 + pub smart_punctuation: bool, 34 + #[arg(long)] 35 + #[serde(default)] 36 + pub prefer_local_links: bool, 37 + } 38 + 39 + #[derive(clap::Parser, Debug, Clone)] 40 + struct Command { 41 + #[command(subcommand)] 42 + command: Option<Commands>, 43 + } 44 + 45 + #[derive(clap::Subcommand, Debug, Clone)] 46 + enum Commands { 47 + Supports { renderer: String }, 48 + Markdown(BuildOptions), 49 + } 50 + 51 + #[tokio::main] 52 + async fn main() -> Result<()> { 53 + use clap::Parser; 54 + env_logger::init(); 55 + match Command::parse().command { 56 + Some(Commands::Supports { .. }) => Ok(()), 57 + Some(Commands::Markdown(options)) => markdown(options).await, 58 + None => mdbook().await, 59 + } 60 + } 61 + 62 + async fn mdbook() -> Result<()> { 63 + let (context, mut book): (PreprocessorContext, Book) = Vec::new() 64 + .pipe(|mut buf| std::io::stdin().read_to_end(&mut buf).and(Ok(buf)))? 65 + .pipe(String::from_utf8)? 66 + .pipe_as_ref(serde_json::from_str)?; 67 + 68 + let options = { 69 + let mut options = if let Some(config) = context.config.get_preprocessor(preprocessor_name()) 70 + { 71 + BuildOptions::deserialize(toml::Value::Table(config.clone()))? 72 + } else { 73 + Default::default() 74 + }; 75 + if let Some(path) = options.manifest_dir { 76 + options.manifest_dir = Some(context.root.join(path)) 77 + } else { 78 + options.manifest_dir = Some(context.root) 79 + } 80 + options.smart_punctuation = context 81 + .config 82 + .get_deserialized_opt::<bool, _>("output.html.smart-punctuation") 83 + .unwrap_or_default() 84 + .unwrap_or(true); 85 + options 86 + }; 87 + 88 + let (mut client, dispose) = Client::spawn(options).await?; 89 + 90 + let (pages, items) = book.iter().fold( 91 + (Pages::default(), HashSet::new()), 92 + |(mut pages, mut items), item| { 93 + let BookItem::Chapter(ch) = item else { 94 + return (pages, items); 95 + }; 96 + let Some(key) = &ch.source_path else { 97 + return (pages, items); 98 + }; 99 + let stream = markdown_parser(&ch.content, client.config.build_opts.smart_punctuation); 100 + items.extend(pages.read(key.clone(), stream)); 101 + (pages, items) 102 + }, 103 + ); 104 + 105 + let links = client.resolve(items.into_iter().collect()).await?; 106 + 107 + let mut result = book 108 + .iter() 109 + .filter_map(|item| { 110 + let BookItem::Chapter(ch) = item else { 111 + return None; 112 + }; 113 + let Some(key) = &ch.source_path else { 114 + return None; 115 + }; 116 + pages 117 + .emit(key, |k| links.get(k)) 118 + .tap_err(|e| log::warn!("{e:?}")) 119 + .ok() 120 + .map(|output| (key.clone(), output)) 121 + }) 122 + .collect::<HashMap<_, _>>(); 123 + 124 + book.for_each_mut(|item| { 125 + let BookItem::Chapter(ch) = item else { return }; 126 + let Some(key) = &ch.source_path else { return }; 127 + if let Some(output) = result.remove(key) { 128 + ch.content = output; 129 + } 130 + }); 131 + 132 + dispose.of(client).await?; 133 + 134 + serde_json::to_string(&book)?.pipe(|out| std::io::stdout().write_all(out.as_bytes()))?; 135 + 136 + Ok(()) 137 + } 138 + 139 + async fn markdown(options: BuildOptions) -> Result<()> { 140 + let (mut client, dispose) = Client::spawn(options).await?; 141 + 142 + let mut pages = Pages::default(); 143 + 144 + let stream = Vec::new() 145 + .pipe(|mut buf| std::io::stdin().read_to_end(&mut buf).and(Ok(buf)))? 146 + .pipe(String::from_utf8)?; 147 + 148 + let stream = markdown_parser(&stream, client.config.build_opts.smart_punctuation); 149 + 150 + let items = pages.read((), stream); 151 + 152 + let links = client.resolve(items.into_iter().collect()).await?; 153 + 154 + let output = pages.emit(&(), |k| links.get(k))?; 155 + 156 + std::io::stdout().write_all(output.as_bytes())?; 157 + 158 + dispose.of(client).await?; 159 + 160 + Ok(()) 161 + } 162 + 163 + impl Client { 164 + async fn resolve(&mut self, request: Vec<String>) -> Result<ItemLinks> { 165 + let src = std::fs::read_to_string(self.config.entrypoint.path())?; 166 + 167 + let request = ItemRequestBatch::new(&src, request); 168 + 169 + let mut links = HashMap::new(); 170 + 171 + let local = self.config.build_opts.prefer_local_links; 172 + 173 + if request.request.is_empty() { 174 + return Ok(ItemLinks { links, local }); 175 + } 176 + 177 + let _document = self 178 + .open(self.config.entrypoint.clone(), request.context) 179 + .await?; 180 + 181 + let mut tasks = JoinSet::new(); 182 + 183 + for ItemRequest { 184 + path, 185 + hash, 186 + position, 187 + } in &request.request 188 + { 189 + if links.contains_key(path) { 190 + continue; 191 + } 192 + 193 + let server = self.server.clone(); 194 + let uri = self.config.entrypoint.clone(); 195 + let pos = *position; 196 + let path = path.clone(); 197 + let hash = hash.clone(); 198 + 199 + tasks.spawn(async move { 200 + let ExternalDocLinks { web, local } = server 201 + .request::<ExternalDocs>(document_position(uri, pos)) 202 + .await 203 + .tap_err(|err| log::warn!("{err:#?}")) 204 + .unwrap_or_default()?; 205 + 206 + let (web, local) = if let Some(hash) = hash.as_deref() { 207 + let web = web.tap_some_mut(|u| u.set_fragment(Some(hash))); 208 + let local = local.tap_some_mut(|u| u.set_fragment(Some(hash))); 209 + (web, local) 210 + } else { 211 + (web, local) 212 + }; 213 + 214 + if web.is_none() && local.is_none() { 215 + None 216 + } else { 217 + let links = ExternalDocLinks { web, local }; 218 + let key = if let Some(hash) = hash { 219 + format!("{path}#{hash}") 220 + } else { 221 + path 222 + }; 223 + Some((key, links)) 224 + } 225 + }); 226 + } 227 + 228 + while let Some(res) = tasks.join_next().await { 229 + if let Ok(Some((key, resolved))) = res { 230 + links.insert(key, resolved); 231 + }; 232 + } 233 + 234 + Ok(ItemLinks { links, local }) 235 + } 236 + } 237 + 238 + #[derive(Debug)] 239 + struct ItemRequestBatch { 240 + context: String, 241 + request: Vec<ItemRequest>, 242 + } 243 + 244 + #[derive(Debug)] 245 + struct ItemRequest { 246 + path: String, 247 + hash: Option<String>, 248 + position: Position, 249 + } 250 + 251 + impl ItemRequestBatch { 252 + fn new(source: &str, items: Vec<String>) -> Self { 253 + use syn::parse::{Parse, Parser}; 254 + 255 + let source = format!("{source}\nfn __6c0db446e2fa428eb93e3c71945e9654() {{\n"); 256 + 257 + let mut request = vec![]; 258 + let mut line = source.chars().filter(|&c| c == '\n').count(); 259 + 260 + let context = HashSet::<String>::from_iter(items) 261 + .into_iter() 262 + .filter_map(|name| { 263 + let mut name = name.split('#'); 264 + let path = name.next().unwrap(); 265 + let item = ItemName::parse.parse_str(path).ok()?; 266 + let position = item.ident().span().start(); 267 + if position.line == 1 { 268 + let path = path.to_owned(); 269 + let hash = name.next().map(ToOwned::to_owned); 270 + Some((path, hash, position.column)) 271 + } else { 272 + None 273 + } 274 + }) 275 + .fold(source, |mut output, (path, hash, column)| { 276 + use std::fmt::Write; 277 + let _ = writeln!(output, "{path};"); 278 + let position = Position::new(line as _, column as _); 279 + request.push(ItemRequest { 280 + path, 281 + hash, 282 + position, 283 + }); 284 + line += 1; 285 + output 286 + }); 287 + 288 + let context = context.tap_mut(|c| c.push('}')); 289 + 290 + Self { context, request } 291 + } 292 + } 293 + 294 + struct ItemLinks { 295 + links: HashMap<String, client::ExternalDocLinks>, 296 + local: bool, 297 + } 298 + 299 + impl ItemLinks { 300 + fn get(&self, key: &str) -> Option<&str> { 301 + self.links 302 + .get(key) 303 + .and_then(|links| { 304 + if self.local { 305 + links.local.as_ref() 306 + } else { 307 + links.web.as_ref() 308 + } 309 + }) 310 + .map(|u| u.as_str()) 311 + } 312 + } 313 + 314 + fn preprocessor_name() -> &'static str { 315 + let name = env!("CARGO_PKG_NAME"); 316 + if let Some(idx) = name.find('-') { 317 + &name[idx + 1..] 318 + } else { 319 + name 320 + } 321 + }
+171
crates/rustdoc-link/src/markdown.rs
··· 1 + use std::{ 2 + borrow::Borrow, 3 + collections::{HashMap, HashSet}, 4 + fmt::Debug, 5 + hash::Hash, 6 + }; 7 + 8 + use anyhow::{Context, Result}; 9 + use pulldown_cmark::{ 10 + BrokenLink, BrokenLinkCallback, CowStr, Event, LinkType, Options, Parser, Tag, TagEnd, 11 + }; 12 + use pulldown_cmark_to_cmark::cmark; 13 + use tap::Pipe; 14 + 15 + #[derive(Debug, Default)] 16 + pub struct Pages<'a, K> { 17 + pages: HashMap<K, Vec<Event<'a>>>, 18 + } 19 + 20 + impl<'a, K: Eq + Hash> Pages<'a, K> { 21 + pub fn read<S>(&mut self, key: K, stream: S) -> HashSet<String> 22 + where 23 + S: Iterator<Item = Event<'a>>, 24 + { 25 + let mut items = HashSet::new(); 26 + let buffer = stream 27 + .inspect(|event| { 28 + if let Event::Start(Tag::Link { dest_url, .. }) = &event { 29 + items.insert(dest_url.to_string()); 30 + } 31 + }) 32 + .collect::<Vec<_>>(); 33 + self.pages.insert(key, buffer); 34 + items 35 + } 36 + 37 + pub fn emit<Q, L>(&self, key: &Q, mut links: L) -> Result<String> 38 + where 39 + K: Borrow<Q>, 40 + Q: Eq + Hash + Debug + ?Sized, 41 + L: FnMut(&str) -> Option<&'a str>, 42 + { 43 + let buffer = self 44 + .pages 45 + .get(key) 46 + .with_context(|| format!("no such document {key:?}"))?; 47 + 48 + enum Suffix<'a> { 49 + Collapsed, 50 + Shortcut, 51 + Reference(CowStr<'a>), 52 + } 53 + 54 + impl Suffix<'_> { 55 + // how is this 'static ? 56 + fn as_str(&self) -> CowStr<'static> { 57 + match self { 58 + Self::Collapsed => "][]".into(), 59 + Self::Shortcut => "]".into(), 60 + Self::Reference(id) => format!("][{id}]").into(), 61 + } 62 + } 63 + } 64 + 65 + let stream = buffer 66 + .iter() 67 + .cloned() 68 + .scan(Option::<Suffix>::None, |suffix, mut event| { 69 + if let Event::Start(Tag::Link { 70 + dest_url, 71 + id, 72 + link_type, 73 + .. 74 + }) = &mut event 75 + { 76 + if let Some(found) = links(dest_url) { 77 + *dest_url = found.to_owned().into(); 78 + Some(event) 79 + } else if matches!( 80 + link_type, 81 + LinkType::CollapsedUnknown 82 + | LinkType::ReferenceUnknown 83 + | LinkType::ShortcutUnknown 84 + ) { 85 + // don't emit unresolved "broken" links as links 86 + *suffix = match link_type { 87 + LinkType::ShortcutUnknown => Some(Suffix::Shortcut), 88 + LinkType::CollapsedUnknown => Some(Suffix::Collapsed), 89 + LinkType::ReferenceUnknown => Some(Suffix::Reference(id.clone())), 90 + _ => unreachable!(), 91 + }; 92 + Some(Event::Text(CowStr::Borrowed("["))) 93 + } else { 94 + Some(event) 95 + } 96 + } else if matches!(event, Event::End(TagEnd::Link)) { 97 + if let Some(suffix) = suffix.take() { 98 + // a link was dropped, patch corresponding TagEnd::Link 99 + Some(Event::Text(suffix.as_str())) 100 + } else { 101 + Some(event) 102 + } 103 + } else { 104 + Some(event) 105 + } 106 + .pipe(Some) 107 + }) 108 + .flatten(); 109 + 110 + String::new() 111 + .pipe(|mut wr| cmark(stream, &mut wr).and(Ok(wr)))? 112 + .pipe(Ok) 113 + } 114 + } 115 + 116 + pub fn markdown_parser(text: &str, smart_punctuation: bool) -> MarkdownStream<'_> { 117 + Parser::new_with_broken_link_callback(text, options(smart_punctuation), Some(BrokenLinks)) 118 + } 119 + 120 + pub type MarkdownStream<'a> = Parser<'a, BrokenLinks>; 121 + 122 + pub struct BrokenLinks; 123 + 124 + impl<'input> BrokenLinkCallback<'input> for BrokenLinks { 125 + fn handle_broken_link( 126 + &mut self, 127 + link: BrokenLink<'input>, 128 + ) -> Option<(CowStr<'input>, CowStr<'input>)> { 129 + let inner = if let CowStr::Borrowed(inner) = link.reference { 130 + let parse = markdown_parser(inner, false); 131 + 132 + let inner = parse 133 + .filter_map(|event| match event { 134 + Event::Text(inner) => Some(inner), 135 + Event::Code(inner) => Some(inner), 136 + _ => None, 137 + }) 138 + .collect::<Vec<_>>(); 139 + 140 + if inner.len() == 1 { 141 + inner.into_iter().next().unwrap() 142 + } else { 143 + inner 144 + .iter() 145 + .map(ToString::to_string) 146 + .collect::<Box<str>>() 147 + .pipe(CowStr::Boxed) 148 + } 149 + } else { 150 + link.reference.clone() 151 + }; 152 + if inner.is_empty() { 153 + None 154 + } else { 155 + Some((inner, link.reference)) 156 + } 157 + } 158 + } 159 + 160 + fn options(smart_punctuation: bool) -> Options { 161 + let mut opts = Options::empty(); 162 + opts.insert(Options::ENABLE_TABLES); 163 + opts.insert(Options::ENABLE_FOOTNOTES); 164 + opts.insert(Options::ENABLE_STRIKETHROUGH); 165 + opts.insert(Options::ENABLE_TASKLISTS); 166 + opts.insert(Options::ENABLE_HEADING_ATTRIBUTES); 167 + if smart_punctuation { 168 + opts.insert(Options::ENABLE_SMART_PUNCTUATION); 169 + } 170 + opts 171 + }
+61
crates/rustdoc-link/src/sync.rs
··· 1 + use std::{ 2 + sync::{Arc, RwLock}, 3 + task::Poll, 4 + time::Duration, 5 + }; 6 + 7 + use tokio::{ 8 + sync::{mpsc, Notify}, 9 + task::JoinHandle, 10 + time::sleep, 11 + }; 12 + 13 + #[derive(Debug, Clone)] 14 + pub struct Subsample<T> { 15 + state: Arc<RwLock<Poll<T>>>, 16 + event: Arc<Notify>, 17 + } 18 + 19 + impl<T: Clone + Send + Sync + 'static> Subsample<T> { 20 + pub fn new(mut rx: mpsc::Receiver<Poll<T>>, wait: Duration) -> Self { 21 + let state = Arc::new(RwLock::new(Poll::Pending)); 22 + let event = Arc::new(Notify::new()); 23 + 24 + tokio::spawn({ 25 + let state = state.clone(); 26 + let event = event.clone(); 27 + async move { 28 + let mut abort: Option<JoinHandle<()>> = None; 29 + while let Some(value) = rx.recv().await { 30 + if let Some(abort) = abort.take() { 31 + abort.abort(); 32 + } 33 + if value.is_ready() { 34 + let event = event.clone(); 35 + let state = state.clone(); 36 + abort = Some(tokio::spawn(async move { 37 + sleep(wait).await; 38 + *state.write().unwrap() = value; 39 + event.notify_waiters(); 40 + })); 41 + } else { 42 + *state.write().unwrap() = value; 43 + } 44 + } 45 + } 46 + }); 47 + 48 + Self { event, state } 49 + } 50 + 51 + pub async fn wait(&self) -> T { 52 + loop { 53 + { 54 + if let Poll::Ready(value) = self.state.read().unwrap().clone() { 55 + return value; 56 + } 57 + } 58 + self.event.notified().await; 59 + } 60 + } 61 + }