diff --git a/Cargo.lock b/Cargo.lock index add27db..d82e369 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -40,6 +40,12 @@ dependencies = [ "memchr", ] +[[package]] +name = "allocator-api2" +version = "0.2.21" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "683d7910e743518b0e34f1186f92494becacb047c7b6bf616c96772180fef923" + [[package]] name = "android_system_properties" version = "0.1.5" @@ -99,6 +105,21 @@ dependencies = [ "windows-sys 0.61.2", ] +[[package]] +name = "arc-swap" +version = "1.8.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9ded5f9a03ac8f24d1b8a25101ee812cd32cdc8c50a4c50237de2c4915850e73" +dependencies = [ + "rustversion", +] + +[[package]] +name = "atomic-waker" +version = "1.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1505bd5d3d116872e7271a6d4e16d81d0c8570876c8de68093a09ac269d8aac0" + [[package]] name = "autocfg" version = "1.5.0" @@ -129,6 +150,12 @@ dependencies = [ "backtrace", ] +[[package]] +name = "base64" +version = "0.22.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "72b3254f16251a8381aa12e40e3c4d2f0199f8c6508fbecb9d91f575e0fbb8c6" + [[package]] name = "bitflags" version = "1.3.2" @@ -157,6 +184,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "63044e1ae8e69f3b5a92c736ca6269b8d12fa7efe39bf34ddb06d102cf0e2cab" dependencies = [ "memchr", + "regex-automata", "serde", ] @@ -172,6 +200,12 @@ version = "1.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1fd0f2584146f6f2ef48085050886acf353beff7305ebd1ae69500e27c67f64b" +[[package]] +name = "bytes" +version = "1.11.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b35204fbdc0b3f4446b89fc1ac2cf84a8a68971995d0bf2e925ec7cd960f9cb3" + [[package]] name = "cc" version = "1.2.55" @@ -188,6 +222,12 @@ version = "1.0.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9330f8b2ff13f34540b44e946ef35111825727b38d33286ef986142615121801" +[[package]] +name = "cfg_aliases" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "613afe47fcd5fac7ccf1db93babcb082c5994d996f20b8b159f2ad1658eb5724" + [[package]] name = "chrono" version = "0.4.43" @@ -261,6 +301,12 @@ version = "0.7.7" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c3e64b0cc0439b12df2fa678eae89a1c56a529fd067a9115f7827f1fffd22b32" +[[package]] +name = "clru" +version = "0.6.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cbd0f76e066e64fdc5631e3bb46381254deab9ef1158292f27c8c57e3bf3fe59" + [[package]] name = "colorchoice" version = "1.0.4" @@ -300,6 +346,16 @@ dependencies = [ "tiny-keccak", ] +[[package]] +name = "core-foundation" +version = "0.9.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "91e195e091a93c46f7102ec7818a2aa394e1e1771c3ab4825963fa03e45afb8f" +dependencies = [ + "core-foundation-sys", + "libc", +] + [[package]] name = "core-foundation-sys" version = "0.8.7" @@ -315,6 +371,15 @@ dependencies = [ "libc", ] +[[package]] +name = "crc32fast" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9481c1c90cbf2ac953f07c8d4a58aa3945c425b7185c9154d67a65e4230da511" +dependencies = [ + "cfg-if", +] + [[package]] name = "crossbeam-deque" version = "0.8.6" @@ -349,7 +414,7 @@ dependencies = [ "bitflags 1.3.2", "crossterm_winapi", "libc", - "mio", + "mio 0.8.11", "parking_lot", "signal-hook", "signal-hook-mio", @@ -402,6 +467,8 @@ name = "diecut-core" version = "0.1.0" dependencies = [ "console", + "dirs", + "gix", "globset", "indicatif", "inquire", @@ -410,6 +477,7 @@ dependencies = [ "rhai", "serde", "serde_json", + "sha2", "tempfile", "tera", "thiserror", @@ -427,6 +495,44 @@ dependencies = [ "crypto-common", ] +[[package]] +name = "dirs" +version = "6.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c3e8aa94d75141228480295a7d0e7feb620b1a5ad9f12bc40be62411e38cce4e" +dependencies = [ + "dirs-sys", +] + +[[package]] +name = "dirs-sys" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e01a3366d27ee9890022452ee61b2b63a67e6f13f58900b651ff5665f0bb1fab" +dependencies = [ + "libc", + "option-ext", + "redox_users", + "windows-sys 0.61.2", +] + +[[package]] +name = "displaydoc" +version = "0.2.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "97369cbbc041bc366949bc74d34658d6cda5621039731c6310521892a3a20ae0" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "dunce" +version = "1.0.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "92773504d58c093f6de2459af4af33faa518c13451eb8f2b5698ed3d36e7c813" + [[package]] name = "dyn-clone" version = "1.0.20" @@ -439,6 +545,15 @@ version = "1.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "34aa73646ffb006b8f5147f3dc182bd4bcb190227ce861fc4a4844bf8e3cb2c0" +[[package]] +name = "encoding_rs" +version = "0.8.35" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "75030f3c4f45dafd7586dd6780965a8c7e8e285a5ecb86713e63a79c5b2766f3" +dependencies = [ + "cfg-if", +] + [[package]] name = "equivalent" version = "1.0.2" @@ -455,18 +570,114 @@ dependencies = [ "windows-sys 0.61.2", ] +[[package]] +name = "faster-hex" +version = "0.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7223ae2d2f179b803433d9c830478527e92b8117eab39460edae7f1614d9fb73" +dependencies = [ + "heapless", + "serde", +] + [[package]] name = "fastrand" version = "2.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "37909eebbb50d72f9059c3b6d82c0463f2ff062c9e95845c43a6c9c0355411be" +[[package]] +name = "filetime" +version = "0.2.27" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f98844151eee8917efc50bd9e8318cb963ae8b297431495d3f758616ea5c57db" +dependencies = [ + "cfg-if", + "libc", + "libredox", +] + [[package]] name = "find-msvc-tools" version = "0.1.9" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5baebc0774151f905a1a2cc41989300b1e6fbb29aff0ceffa1064fdd3088d582" +[[package]] +name = "flate2" +version = "1.1.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "843fba2746e448b37e26a819579957415c8cef339bf08564fe8b7ddbd959573c" +dependencies = [ + "miniz_oxide", + "zlib-rs", +] + +[[package]] +name = "fnv" +version = "1.0.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1" + +[[package]] +name = "form_urlencoded" +version = "1.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cb4cb245038516f5f85277875cdaa4f7d2c9a0fa0468de06ed190163b1581fcf" +dependencies = [ + "percent-encoding", +] + +[[package]] +name = "futures-channel" +version = "0.3.31" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2dff15bf788c671c1934e366d07e30c1814a8ef514e1af724a602e8a2fbe1b10" +dependencies = [ + "futures-core", + "futures-sink", +] + +[[package]] +name = "futures-core" +version = "0.3.31" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "05f29059c0c2090612e8d742178b0580d2dc940c837851ad723096f87af6663e" + +[[package]] +name = "futures-io" +version = "0.3.31" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9e5c1b78ca4aae1ac06c48a526a655760685149f0d465d21f37abfe57ce075c6" + +[[package]] +name = "futures-sink" +version = "0.3.31" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e575fab7d1e0dcb8d0c7bcf9a63ee213816ab51902e6d244a95819acacf1d4f7" + +[[package]] +name = "futures-task" +version = "0.3.31" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f90f7dce0722e95104fcb095585910c0977252f286e354b5e3bd38902cd99988" + +[[package]] +name = "futures-util" +version = "0.3.31" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9fa08315bb612088cc391249efdc3bc77536f16c91f6cf495e6fbe85b20a4a81" +dependencies = [ + "futures-core", + "futures-io", + "futures-sink", + "futures-task", + "memchr", + "pin-project-lite", + "pin-utils", + "slab", +] + [[package]] name = "fuzzy-matcher" version = "0.3.7" @@ -502,8 +713,10 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ff2abc00be7fca6ebc474524697ae276ad847ad0a6b3faa4bcb027e9a4614ad0" dependencies = [ "cfg-if", + "js-sys", "libc", "wasi", + "wasm-bindgen", ] [[package]] @@ -513,9 +726,11 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "899def5c37c4fd7b2664648c28120ecec138e4d395b459e5ca34f9cce2dd77fd" dependencies = [ "cfg-if", + "js-sys", "libc", "r-efi", "wasip2", + "wasm-bindgen", ] [[package]] @@ -525,72 +740,1097 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e629b9b98ef3dd8afe6ca2bd0f89306cec16d43d907889945bc5d6687f2f13c7" [[package]] -name = "globset" -version = "0.4.18" +name = "gix" +version = "0.72.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "01237e8d3d78581f71642be8b0c2ae8c0b2b5c251c9c5d9ebbea3c1ea280dce8" +dependencies = [ + "gix-actor", + "gix-attributes", + "gix-command", + "gix-commitgraph", + "gix-config", + "gix-credentials", + "gix-date", + "gix-diff", + "gix-discover", + "gix-features", + "gix-filter", + "gix-fs", + "gix-glob", + "gix-hash", + "gix-hashtable", + "gix-ignore", + "gix-index", + "gix-lock", + "gix-negotiate", + "gix-object", + "gix-odb", + "gix-pack", + "gix-path", + "gix-pathspec", + "gix-prompt", + "gix-protocol", + "gix-ref", + "gix-refspec", + "gix-revision", + "gix-revwalk", + "gix-sec", + "gix-shallow", + "gix-submodule", + "gix-tempfile", + "gix-trace", + "gix-transport", + "gix-traverse", + "gix-url", + "gix-utils", + "gix-validate", + "gix-worktree", + "gix-worktree-state", + "once_cell", + "smallvec", + "thiserror", +] + +[[package]] +name = "gix-actor" +version = "0.35.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "52dfc19153a48bde0cbd630453615c8151bce3a5adfac7a0aebfbf0a1e1f57e3" +checksum = "987a51a7e66db6ef4dc030418eb2a42af6b913a79edd8670766122d8af3ba59e" dependencies = [ - "aho-corasick", "bstr", - "log", - "regex-automata", - "regex-syntax", + "gix-date", + "gix-utils", + "itoa", + "thiserror", + "winnow", ] [[package]] -name = "globwalk" -version = "0.9.1" +name = "gix-attributes" +version = "0.26.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0bf760ebf69878d9fd8f110c89703d90ce35095324d1f1edcb595c63945ee757" +checksum = "6f50d813d5c2ce9463ba0c29eea90060df08e38ad8f34b8a192259f8bce5c078" +dependencies = [ + "bstr", + "gix-glob", + "gix-path", + "gix-quote", + "gix-trace", + "kstring", + "smallvec", + "thiserror", + "unicode-bom", +] + +[[package]] +name = "gix-bitmap" +version = "0.2.16" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d982fc7ef0608e669851d0d2a6141dae74c60d5a27e8daa451f2a4857bbf41e2" +dependencies = [ + "thiserror", +] + +[[package]] +name = "gix-chunk" +version = "0.4.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5c356b3825677cb6ff579551bb8311a81821e184453cbd105e2fc5311b288eeb" +dependencies = [ + "thiserror", +] + +[[package]] +name = "gix-command" +version = "0.6.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "46f9c425730a654835351e6da8c3c69ba1804f8b8d4e96d027254151138d5c64" +dependencies = [ + "bstr", + "gix-path", + "gix-quote", + "gix-trace", + "shell-words", +] + +[[package]] +name = "gix-commitgraph" +version = "0.28.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e05050fd6caa6c731fe3bd7f9485b3b520be062d3d139cb2626e052d6c127951" +dependencies = [ + "bstr", + "gix-chunk", + "gix-hash", + "memmap2", + "thiserror", +] + +[[package]] +name = "gix-config" +version = "0.45.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "48f3c8f357ae049bfb77493c2ec9010f58cfc924ae485e1116c3718fc0f0d881" +dependencies = [ + "bstr", + "gix-config-value", + "gix-features", + "gix-glob", + "gix-path", + "gix-ref", + "gix-sec", + "memchr", + "once_cell", + "smallvec", + "thiserror", + "unicode-bom", + "winnow", +] + +[[package]] +name = "gix-config-value" +version = "0.15.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2c489abb061c74b0c3ad790e24a606ef968cebab48ec673d6a891ece7d5aef64" dependencies = [ "bitflags 2.10.0", - "ignore", + "bstr", + "gix-path", + "libc", + "thiserror", +] + +[[package]] +name = "gix-credentials" +version = "0.29.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ce1c7307e36026b6088e5b12014ffe6d4f509c911ee453e22a7be4003a159c9b" +dependencies = [ + "bstr", + "gix-command", + "gix-config-value", + "gix-path", + "gix-prompt", + "gix-sec", + "gix-trace", + "gix-url", + "thiserror", +] + +[[package]] +name = "gix-date" +version = "0.10.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "661245d045aa7c16ba4244daaabd823c562c3e45f1f25b816be2c57ee09f2171" +dependencies = [ + "bstr", + "itoa", + "jiff", + "smallvec", + "thiserror", +] + +[[package]] +name = "gix-diff" +version = "0.52.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5e9b43e95fe352da82a969f0c84ff860c2de3e724d93f6681fedbcd6c917f252" +dependencies = [ + "bstr", + "gix-hash", + "gix-object", + "thiserror", +] + +[[package]] +name = "gix-discover" +version = "0.40.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dccfe3e25b4ea46083916c56db3ba9d1e6ef6dce54da485f0463f9fc0fe1837c" +dependencies = [ + "bstr", + "dunce", + "gix-fs", + "gix-hash", + "gix-path", + "gix-ref", + "gix-sec", + "thiserror", +] + +[[package]] +name = "gix-features" +version = "0.42.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "56f4399af6ec4fd9db84dd4cf9656c5c785ab492ab40a7c27ea92b4241923fed" +dependencies = [ + "bytes", + "crc32fast", + "flate2", + "gix-path", + "gix-trace", + "gix-utils", + "libc", + "once_cell", + "prodash", + "thiserror", "walkdir", ] [[package]] -name = "hashbrown" -version = "0.16.1" +name = "gix-filter" +version = "0.19.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ecf004912949bbcf308d71aac4458321748ecb59f4d046830d25214208c471f1" +dependencies = [ + "bstr", + "encoding_rs", + "gix-attributes", + "gix-command", + "gix-hash", + "gix-object", + "gix-packetline-blocking", + "gix-path", + "gix-quote", + "gix-trace", + "gix-utils", + "smallvec", + "thiserror", +] + +[[package]] +name = "gix-fs" +version = "0.15.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "67a0637149b4ef24d3ea55f81f77231401c8463fae6da27331c987957eb597c7" +dependencies = [ + "bstr", + "fastrand", + "gix-features", + "gix-path", + "gix-utils", + "thiserror", +] + +[[package]] +name = "gix-glob" +version = "0.20.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "90181472925b587f6079698f79065ff64786e6d6c14089517a1972bca99fb6e9" +dependencies = [ + "bitflags 2.10.0", + "bstr", + "gix-features", + "gix-path", +] + +[[package]] +name = "gix-hash" +version = "0.18.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8d4900562c662852a6b42e2ef03442eccebf24f047d8eab4f23bc12ef0d785d8" +dependencies = [ + "faster-hex", + "gix-features", + "sha1-checked", + "thiserror", +] + +[[package]] +name = "gix-hashtable" +version = "0.8.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b5b5cb3c308b4144f2612ff64e32130e641279fcf1a84d8d40dad843b4f64904" +dependencies = [ + "gix-hash", + "hashbrown 0.14.5", + "parking_lot", +] + +[[package]] +name = "gix-ignore" +version = "0.15.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ae358c3c96660b10abc7da63c06788dfded603e717edbd19e38c6477911b71c8" +dependencies = [ + "bstr", + "gix-glob", + "gix-path", + "gix-trace", + "unicode-bom", +] + +[[package]] +name = "gix-index" +version = "0.40.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b38e919efd59cb8275d23ad2394b2ab9d002007b27620e145d866d546403b665" +dependencies = [ + "bitflags 2.10.0", + "bstr", + "filetime", + "fnv", + "gix-bitmap", + "gix-features", + "gix-fs", + "gix-hash", + "gix-lock", + "gix-object", + "gix-traverse", + "gix-utils", + "gix-validate", + "hashbrown 0.14.5", + "itoa", + "libc", + "memmap2", + "rustix", + "smallvec", + "thiserror", +] + +[[package]] +name = "gix-lock" +version = "17.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "570f8b034659f256366dc90f1a24924902f20acccd6a15be96d44d1269e7a796" +dependencies = [ + "gix-tempfile", + "gix-utils", + "thiserror", +] + +[[package]] +name = "gix-negotiate" +version = "0.20.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2e1ea901acc4d5b44553132a29e8697210cb0e739b2d9752d713072e9391e3c9" +dependencies = [ + "bitflags 2.10.0", + "gix-commitgraph", + "gix-date", + "gix-hash", + "gix-object", + "gix-revwalk", + "smallvec", + "thiserror", +] + +[[package]] +name = "gix-object" +version = "0.49.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d957ca3640c555d48bb27f8278c67169fa1380ed94f6452c5590742524c40fbb" +dependencies = [ + "bstr", + "gix-actor", + "gix-date", + "gix-features", + "gix-hash", + "gix-hashtable", + "gix-path", + "gix-utils", + "gix-validate", + "itoa", + "smallvec", + "thiserror", + "winnow", +] + +[[package]] +name = "gix-odb" +version = "0.69.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "868f703905fdbcfc1bd750942f82419903ecb7039f5288adb5206d6de405e0c9" +dependencies = [ + "arc-swap", + "gix-date", + "gix-features", + "gix-fs", + "gix-hash", + "gix-hashtable", + "gix-object", + "gix-pack", + "gix-path", + "gix-quote", + "parking_lot", + "tempfile", + "thiserror", +] + +[[package]] +name = "gix-pack" +version = "0.59.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9d49c55d69c8449f2a0a5a77eb9cbacfebb6b0e2f1215f0fc23a4cb60528a450" +dependencies = [ + "clru", + "gix-chunk", + "gix-features", + "gix-hash", + "gix-hashtable", + "gix-object", + "gix-path", + "gix-tempfile", + "memmap2", + "parking_lot", + "smallvec", + "thiserror", +] + +[[package]] +name = "gix-packetline" +version = "0.19.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "64286a8b5148e76ab80932e72762dd27ccf6169dd7a134b027c8a262a8262fcf" +dependencies = [ + "bstr", + "faster-hex", + "gix-trace", + "thiserror", +] + +[[package]] +name = "gix-packetline-blocking" +version = "0.19.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "89c59c3ad41e68cb38547d849e9ef5ccfc0d00f282244ba1441ae856be54d001" +dependencies = [ + "bstr", + "faster-hex", + "gix-trace", + "thiserror", +] + +[[package]] +name = "gix-path" +version = "0.10.22" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7cb06c3e4f8eed6e24fd915fa93145e28a511f4ea0e768bae16673e05ed3f366" +dependencies = [ + "bstr", + "gix-trace", + "gix-validate", + "thiserror", +] + +[[package]] +name = "gix-pathspec" +version = "0.11.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ce061c50e5f8f7c830cacb3da3e999ae935e283ce8522249f0ce2256d110979d" +dependencies = [ + "bitflags 2.10.0", + "bstr", + "gix-attributes", + "gix-config-value", + "gix-glob", + "gix-path", + "thiserror", +] + +[[package]] +name = "gix-prompt" +version = "0.11.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "868e6516dfa16fdcbc5f8c935167d085f2ae65ccd4c9476a4319579d12a69d8d" +dependencies = [ + "gix-command", + "gix-config-value", + "parking_lot", + "rustix", + "thiserror", +] + +[[package]] +name = "gix-protocol" +version = "0.50.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f5c17d78bb0414f8d60b5f952196dc2e47ec320dca885de9128ecdb4a0e38401" +dependencies = [ + "bstr", + "gix-credentials", + "gix-date", + "gix-features", + "gix-hash", + "gix-lock", + "gix-negotiate", + "gix-object", + "gix-ref", + "gix-refspec", + "gix-revwalk", + "gix-shallow", + "gix-trace", + "gix-transport", + "gix-utils", + "maybe-async", + "thiserror", + "winnow", +] + +[[package]] +name = "gix-quote" +version = "0.6.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "96fc2ff2ec8cc0c92807f02eab1f00eb02619fc2810d13dc42679492fcc36757" +dependencies = [ + "bstr", + "gix-utils", + "thiserror", +] + +[[package]] +name = "gix-ref" +version = "0.52.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d1b7985657029684d759f656b09abc3e2c73085596d5cdb494428823970a7762" +dependencies = [ + "gix-actor", + "gix-features", + "gix-fs", + "gix-hash", + "gix-lock", + "gix-object", + "gix-path", + "gix-tempfile", + "gix-utils", + "gix-validate", + "memmap2", + "thiserror", + "winnow", +] + +[[package]] +name = "gix-refspec" +version = "0.30.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "445ed14e3db78e8e79980085e3723df94e1c8163b3ae5bc8ed6a8fe6cf983b42" +dependencies = [ + "bstr", + "gix-hash", + "gix-revision", + "gix-validate", + "smallvec", + "thiserror", +] + +[[package]] +name = "gix-revision" +version = "0.34.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "78d0b8e5cbd1c329e25383e088cb8f17439414021a643b30afa5146b71e3c65d" +dependencies = [ + "bstr", + "gix-commitgraph", + "gix-date", + "gix-hash", + "gix-object", + "gix-revwalk", + "thiserror", +] + +[[package]] +name = "gix-revwalk" +version = "0.20.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1bc756b73225bf005ddeb871d1ca7b3c33e2417d0d53e56effa5a36765b52b28" +dependencies = [ + "gix-commitgraph", + "gix-date", + "gix-hash", + "gix-hashtable", + "gix-object", + "smallvec", + "thiserror", +] + +[[package]] +name = "gix-sec" +version = "0.11.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d0dabbc78c759ecc006b970339394951b2c8e1e38a37b072c105b80b84c308fd" +dependencies = [ + "bitflags 2.10.0", + "gix-path", + "libc", + "windows-sys 0.59.0", +] + +[[package]] +name = "gix-shallow" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6b9a6f6e34d6ede08f522d89e5c7990b4f60524b8ae6ebf8e850963828119ad4" +dependencies = [ + "bstr", + "gix-hash", + "gix-lock", + "thiserror", +] + +[[package]] +name = "gix-submodule" +version = "0.19.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5f51472f05a450cc61bc91ed2f62fb06e31e2bbb31c420bc4be8793f26c8b0c1" +dependencies = [ + "bstr", + "gix-config", + "gix-path", + "gix-pathspec", + "gix-refspec", + "gix-url", + "thiserror", +] + +[[package]] +name = "gix-tempfile" +version = "17.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c750e8c008453a2dba67a2b0d928b7716e05da31173a3f5e351d5457ad4470aa" +dependencies = [ + "gix-fs", + "libc", + "once_cell", + "parking_lot", + "tempfile", +] + +[[package]] +name = "gix-trace" +version = "0.1.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f69a13643b8437d4ca6845e08143e847a36ca82903eed13303475d0ae8b162e0" + +[[package]] +name = "gix-transport" +version = "0.47.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "edfe22ba26d4b65c17879f12b9882eafe65d3c8611c933b272fce2c10f546f59" +dependencies = [ + "base64", + "bstr", + "gix-command", + "gix-credentials", + "gix-features", + "gix-packetline", + "gix-quote", + "gix-sec", + "gix-url", + "reqwest", + "thiserror", +] + +[[package]] +name = "gix-traverse" +version = "0.46.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b8648172f85aca3d6e919c06504b7ac26baef54e04c55eb0100fa588c102cc33" +dependencies = [ + "bitflags 2.10.0", + "gix-commitgraph", + "gix-date", + "gix-hash", + "gix-hashtable", + "gix-object", + "gix-revwalk", + "smallvec", + "thiserror", +] + +[[package]] +name = "gix-url" +version = "0.31.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "42a1ad0b04a5718b5cb233e6888e52a9b627846296161d81dcc5eb9203ec84b8" +dependencies = [ + "bstr", + "gix-features", + "gix-path", + "percent-encoding", + "thiserror", + "url", +] + +[[package]] +name = "gix-utils" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "befcdbdfb1238d2854591f760a48711bed85e72d80a10e8f2f93f656746ef7c5" +dependencies = [ + "fastrand", + "unicode-normalization", +] + +[[package]] +name = "gix-validate" +version = "0.10.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5b1e63a5b516e970a594f870ed4571a8fdcb8a344e7bd407a20db8bd61dbfde4" +dependencies = [ + "bstr", + "thiserror", +] + +[[package]] +name = "gix-worktree" +version = "0.41.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "54f1916f8d928268300c977d773dd70a8746b646873b77add0a34876a8c847e9" +dependencies = [ + "bstr", + "gix-attributes", + "gix-features", + "gix-fs", + "gix-glob", + "gix-hash", + "gix-ignore", + "gix-index", + "gix-object", + "gix-path", + "gix-validate", +] + +[[package]] +name = "gix-worktree-state" +version = "0.19.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f81e31496d034dbdac87535b0b9d4659dbbeabaae1045a0dce7c69b5d16ea7d6" +dependencies = [ + "bstr", + "gix-features", + "gix-filter", + "gix-fs", + "gix-glob", + "gix-hash", + "gix-index", + "gix-object", + "gix-path", + "gix-worktree", + "io-close", + "thiserror", +] + +[[package]] +name = "globset" +version = "0.4.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "52dfc19153a48bde0cbd630453615c8151bce3a5adfac7a0aebfbf0a1e1f57e3" +dependencies = [ + "aho-corasick", + "bstr", + "log", + "regex-automata", + "regex-syntax", +] + +[[package]] +name = "globwalk" +version = "0.9.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0bf760ebf69878d9fd8f110c89703d90ce35095324d1f1edcb595c63945ee757" +dependencies = [ + "bitflags 2.10.0", + "ignore", + "walkdir", +] + +[[package]] +name = "h2" +version = "0.4.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2f44da3a8150a6703ed5d34e164b875fd14c2cdab9af1252a9a1020bde2bdc54" +dependencies = [ + "atomic-waker", + "bytes", + "fnv", + "futures-core", + "futures-sink", + "http", + "indexmap", + "slab", + "tokio", + "tokio-util", + "tracing", +] + +[[package]] +name = "hash32" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "47d60b12902ba28e2730cd37e95b8c9223af2808df9e902d4df49588d1470606" +dependencies = [ + "byteorder", +] + +[[package]] +name = "hashbrown" +version = "0.14.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e5274423e17b7c9fc20b6e7e208532f9b19825d82dfd615708b70edd83df41f1" +dependencies = [ + "ahash", + "allocator-api2", +] + +[[package]] +name = "hashbrown" +version = "0.16.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "841d1cc9bed7f9236f321df977030373f4a4163ae1a7dbfe1a51a2c1a51d9100" + +[[package]] +name = "heapless" +version = "0.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0bfb9eb618601c89945a70e254898da93b13be0388091d42117462b265bb3fad" +dependencies = [ + "hash32", + "stable_deref_trait", +] + +[[package]] +name = "heck" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2304e00983f87ffb38b55b444b5e3b60a884b5d30c0fca7d82fe33449bbe55ea" + +[[package]] +name = "http" +version = "1.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e3ba2a386d7f85a81f119ad7498ebe444d2e22c2af0b86b069416ace48b3311a" +dependencies = [ + "bytes", + "itoa", +] + +[[package]] +name = "http-body" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1efedce1fb8e6913f23e0c92de8e62cd5b772a67e7b3946df930a62566c93184" +dependencies = [ + "bytes", + "http", +] + +[[package]] +name = "http-body-util" +version = "0.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b021d93e26becf5dc7e1b75b1bed1fd93124b374ceb73f43d4d4eafec896a64a" +dependencies = [ + "bytes", + "futures-core", + "http", + "http-body", + "pin-project-lite", +] + +[[package]] +name = "httparse" +version = "1.10.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6dbf3de79e51f3d586ab4cb9d5c3e2c14aa28ed23d180cf89b4df0454a69cc87" + +[[package]] +name = "humansize" +version = "2.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6cb51c9a029ddc91b07a787f1d86b53ccfa49b0e86688c946ebe8d3555685dd7" +dependencies = [ + "libm", +] + +[[package]] +name = "hyper" +version = "1.8.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2ab2d4f250c3d7b1c9fcdff1cece94ea4e2dfbec68614f7b87cb205f24ca9d11" +dependencies = [ + "atomic-waker", + "bytes", + "futures-channel", + "futures-core", + "h2", + "http", + "http-body", + "httparse", + "itoa", + "pin-project-lite", + "pin-utils", + "smallvec", + "tokio", + "want", +] + +[[package]] +name = "hyper-rustls" +version = "0.27.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e3c93eb611681b207e1fe55d5a71ecf91572ec8a6705cdb6857f7d8d5242cf58" +dependencies = [ + "http", + "hyper", + "hyper-util", + "rustls", + "rustls-pki-types", + "tokio", + "tokio-rustls", + "tower-service", + "webpki-roots", +] + +[[package]] +name = "hyper-util" +version = "0.1.20" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "96547c2556ec9d12fb1578c4eaf448b04993e7fb79cbaad930a656880a6bdfa0" +dependencies = [ + "base64", + "bytes", + "futures-channel", + "futures-util", + "http", + "http-body", + "hyper", + "ipnet", + "libc", + "percent-encoding", + "pin-project-lite", + "socket2", + "system-configuration", + "tokio", + "tower-service", + "tracing", + "windows-registry", +] + +[[package]] +name = "iana-time-zone" +version = "0.1.65" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e31bc9ad994ba00e440a8aa5c9ef0ec67d5cb5e5cb0cc7f8b744a35b389cc470" +dependencies = [ + "android_system_properties", + "core-foundation-sys", + "iana-time-zone-haiku", + "js-sys", + "log", + "wasm-bindgen", + "windows-core", +] + +[[package]] +name = "iana-time-zone-haiku" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f31827a206f56af32e590ba56d5d2d085f558508192593743f16b2306495269f" +dependencies = [ + "cc", +] + +[[package]] +name = "icu_collections" +version = "2.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4c6b649701667bbe825c3b7e6388cb521c23d88644678e83c0c4d0a621a34b43" +dependencies = [ + "displaydoc", + "potential_utf", + "yoke", + "zerofrom", + "zerovec", +] + +[[package]] +name = "icu_locale_core" +version = "2.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "edba7861004dd3714265b4db54a3c390e880ab658fec5f7db895fae2046b5bb6" +dependencies = [ + "displaydoc", + "litemap", + "tinystr", + "writeable", + "zerovec", +] + +[[package]] +name = "icu_normalizer" +version = "2.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5f6c8828b67bf8908d82127b2054ea1b4427ff0230ee9141c54251934ab1b599" +dependencies = [ + "icu_collections", + "icu_normalizer_data", + "icu_properties", + "icu_provider", + "smallvec", + "zerovec", +] + +[[package]] +name = "icu_normalizer_data" +version = "2.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "841d1cc9bed7f9236f321df977030373f4a4163ae1a7dbfe1a51a2c1a51d9100" +checksum = "7aedcccd01fc5fe81e6b489c15b247b8b0690feb23304303a9e560f37efc560a" [[package]] -name = "heck" -version = "0.5.0" +name = "icu_properties" +version = "2.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2304e00983f87ffb38b55b444b5e3b60a884b5d30c0fca7d82fe33449bbe55ea" +checksum = "020bfc02fe870ec3a66d93e677ccca0562506e5872c650f893269e08615d74ec" +dependencies = [ + "icu_collections", + "icu_locale_core", + "icu_properties_data", + "icu_provider", + "zerotrie", + "zerovec", +] [[package]] -name = "humansize" -version = "2.1.3" +name = "icu_properties_data" +version = "2.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6cb51c9a029ddc91b07a787f1d86b53ccfa49b0e86688c946ebe8d3555685dd7" +checksum = "616c294cf8d725c6afcd8f55abc17c56464ef6211f9ed59cccffe534129c77af" + +[[package]] +name = "icu_provider" +version = "2.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "85962cf0ce02e1e0a629cc34e7ca3e373ce20dda4c4d7294bbd0bf1fdb59e614" dependencies = [ - "libm", + "displaydoc", + "icu_locale_core", + "writeable", + "yoke", + "zerofrom", + "zerotrie", + "zerovec", ] [[package]] -name = "iana-time-zone" -version = "0.1.65" +name = "idna" +version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e31bc9ad994ba00e440a8aa5c9ef0ec67d5cb5e5cb0cc7f8b744a35b389cc470" +checksum = "3b0875f23caa03898994f6ddc501886a45c7d3d62d04d2d90788d47be1b1e4de" dependencies = [ - "android_system_properties", - "core-foundation-sys", - "iana-time-zone-haiku", - "js-sys", - "log", - "wasm-bindgen", - "windows-core", + "idna_adapter", + "smallvec", + "utf8_iter", ] [[package]] -name = "iana-time-zone-haiku" -version = "0.1.2" +name = "idna_adapter" +version = "1.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f31827a206f56af32e590ba56d5d2d085f558508192593743f16b2306495269f" +checksum = "3acae9609540aa318d1bc588455225fb2085b9ed0c4f6bd0d9d5bcd86f1a0344" dependencies = [ - "cc", + "icu_normalizer", + "icu_properties", ] [[package]] @@ -616,7 +1856,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7714e70437a7dc3ac8eb7e6f8df75fd8eb422675fc7678aff7364301092b1017" dependencies = [ "equivalent", - "hashbrown", + "hashbrown 0.16.1", ] [[package]] @@ -649,6 +1889,32 @@ dependencies = [ "unicode-width 0.1.14", ] +[[package]] +name = "io-close" +version = "0.3.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9cadcf447f06744f8ce713d2d6239bb5bde2c357a452397a9ed90c625da390bc" +dependencies = [ + "libc", + "winapi", +] + +[[package]] +name = "ipnet" +version = "2.11.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "469fb0b9cefa57e3ef31275ee7cacb78f2fdca44e4765491884a2b119d4eb130" + +[[package]] +name = "iri-string" +version = "0.7.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c91338f0783edbd6195decb37bae672fd3b165faffb89bf7b9e6942f8b1a731a" +dependencies = [ + "memchr", + "serde", +] + [[package]] name = "is_ci" version = "1.2.0" @@ -667,6 +1933,47 @@ version = "1.0.17" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "92ecc6618181def0457392ccd0ee51198e065e016d1d527a7ac1b6dc7c1f09d2" +[[package]] +name = "jiff" +version = "0.2.20" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c867c356cc096b33f4981825ab281ecba3db0acefe60329f044c1789d94c6543" +dependencies = [ + "jiff-static", + "jiff-tzdb-platform", + "log", + "portable-atomic", + "portable-atomic-util", + "serde_core", + "windows-sys 0.61.2", +] + +[[package]] +name = "jiff-static" +version = "0.2.20" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f7946b4325269738f270bb55b3c19ab5c5040525f83fd625259422a9d25d9be5" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "jiff-tzdb" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "68971ebff725b9e2ca27a601c5eb38a4c5d64422c4cbab0c535f248087eda5c2" + +[[package]] +name = "jiff-tzdb-platform" +version = "0.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "875a5a69ac2bab1a891711cf5eccbec1ce0341ea805560dcd90b7a2e925132e8" +dependencies = [ + "jiff-tzdb", +] + [[package]] name = "js-sys" version = "0.3.85" @@ -677,6 +1984,15 @@ dependencies = [ "wasm-bindgen", ] +[[package]] +name = "kstring" +version = "2.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "558bf9508a558512042d3095138b1f7b8fe90c5467d94f9f1da28b3731c5dbd1" +dependencies = [ + "static_assertions", +] + [[package]] name = "lazy_static" version = "1.5.0" @@ -695,12 +2011,29 @@ version = "0.2.16" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b6d2cec3eae94f9f509c767b45932f1ada8350c4bdb85af2fcab4a3c14807981" +[[package]] +name = "libredox" +version = "0.1.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3d0b95e02c851351f877147b7deea7b1afb1df71b63aa5f8270716e0c5720616" +dependencies = [ + "bitflags 2.10.0", + "libc", + "redox_syscall 0.7.1", +] + [[package]] name = "linux-raw-sys" version = "0.11.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "df1d3c3b53da64cf5760482273a98e575c651a67eec7f77df96b5b642de8f039" +[[package]] +name = "litemap" +version = "0.8.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6373607a59f0be73a39b6fe456b8192fcc3585f602af20751600e974dd455e77" + [[package]] name = "lock_api" version = "0.4.14" @@ -716,12 +2049,38 @@ version = "0.4.29" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5e5032e24019045c762d3c0f28f5b6b8bbf38563a65908389bf7978758920897" +[[package]] +name = "lru-slab" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "112b39cec0b298b6c1999fee3e31427f74f676e4cb9879ed1a121b43661a4154" + +[[package]] +name = "maybe-async" +version = "0.2.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5cf92c10c7e361d6b99666ec1c6f9805b0bea2c3bd8c78dc6fe98ac5bd78db11" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + [[package]] name = "memchr" version = "2.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f8ca58f447f06ed17d5fc4043ce1b10dd205e060fb3ce5b979b8ed8e59ff3f79" +[[package]] +name = "memmap2" +version = "0.9.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "744133e4a0e0a658e1374cf3bf8e415c4052a15a111acd372764c55b4177d490" +dependencies = [ + "libc", +] + [[package]] name = "miette" version = "7.6.0" @@ -752,6 +2111,12 @@ dependencies = [ "syn", ] +[[package]] +name = "mime" +version = "0.3.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6877bb514081ee2a7ff5ef9de3281f14a4dd4bceac4c09388074a6b5df8a139a" + [[package]] name = "miniz_oxide" version = "0.8.9" @@ -759,6 +2124,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1fa76a2c86f704bdb222d66965fb3d63269ce38518b83cb0575fca855ebb6316" dependencies = [ "adler2", + "simd-adler32", ] [[package]] @@ -773,6 +2139,17 @@ dependencies = [ "windows-sys 0.48.0", ] +[[package]] +name = "mio" +version = "1.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a69bcab0ad47271a0234d9422b131806bf3968021e5dc9328caf2d4cd58557fc" +dependencies = [ + "libc", + "wasi", + "windows-sys 0.61.2", +] + [[package]] name = "newline-converter" version = "0.3.0" @@ -830,6 +2207,12 @@ version = "1.70.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "384b8ab6d37215f3c5301a95a4accb5d64aa607f1fcb26a11b5303878451b4fe" +[[package]] +name = "option-ext" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "04744f49eae99ab78e0d5c0b603ab218f515ea8cfe5a456d7629ad883a3b6e7d" + [[package]] name = "owo-colors" version = "4.2.3" @@ -854,7 +2237,7 @@ checksum = "2621685985a2ebf1c516881c026032ac7deafcda1a2c9b7850dc81e3dfcb64c1" dependencies = [ "cfg-if", "libc", - "redox_syscall", + "redox_syscall 0.5.18", "smallvec", "windows-link", ] @@ -943,7 +2326,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3c80231409c20246a13fddb31776fb942c38553c51e871f8cbd687a4cfb5843d" dependencies = [ "phf_shared", - "rand", + "rand 0.8.5", ] [[package]] @@ -955,12 +2338,42 @@ dependencies = [ "siphasher", ] +[[package]] +name = "pin-project-lite" +version = "0.2.16" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3b3cff922bd51709b605d9ead9aa71031d81447142d828eb4a6eba76fe619f9b" + +[[package]] +name = "pin-utils" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184" + [[package]] name = "portable-atomic" version = "1.13.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c33a9471896f1c69cecef8d20cbe2f7accd12527ce60845ff44c153bb2a21b49" +[[package]] +name = "portable-atomic-util" +version = "0.2.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7a9db96d7fa8782dd8c15ce32ffe8680bbd1e978a43bf51a34d39483540495f5" +dependencies = [ + "portable-atomic", +] + +[[package]] +name = "potential_utf" +version = "0.1.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b73949432f5e2a09657003c25bca5e19a0e9c84f8058ca374f49e0ebe605af77" +dependencies = [ + "zerovec", +] + [[package]] name = "ppv-lite86" version = "0.2.21" @@ -979,6 +2392,71 @@ dependencies = [ "unicode-ident", ] +[[package]] +name = "prodash" +version = "29.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f04bb108f648884c23b98a0e940ebc2c93c0c3b89f04dbaf7eb8256ce617d1bc" +dependencies = [ + "log", + "parking_lot", +] + +[[package]] +name = "quinn" +version = "0.11.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b9e20a958963c291dc322d98411f541009df2ced7b5a4f2bd52337638cfccf20" +dependencies = [ + "bytes", + "cfg_aliases", + "pin-project-lite", + "quinn-proto", + "quinn-udp", + "rustc-hash", + "rustls", + "socket2", + "thiserror", + "tokio", + "tracing", + "web-time", +] + +[[package]] +name = "quinn-proto" +version = "0.11.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f1906b49b0c3bc04b5fe5d86a77925ae6524a19b816ae38ce1e426255f1d8a31" +dependencies = [ + "bytes", + "getrandom 0.3.4", + "lru-slab", + "rand 0.9.2", + "ring", + "rustc-hash", + "rustls", + "rustls-pki-types", + "slab", + "thiserror", + "tinyvec", + "tracing", + "web-time", +] + +[[package]] +name = "quinn-udp" +version = "0.5.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "addec6a0dcad8a8d96a771f815f0eaf55f9d1805756410b39f5fa81332574cbd" +dependencies = [ + "cfg_aliases", + "libc", + "once_cell", + "socket2", + "tracing", + "windows-sys 0.59.0", +] + [[package]] name = "quote" version = "1.0.44" @@ -1001,8 +2479,18 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "34af8d1a0e25924bc5b7c43c079c942339d8f0a8b57c39049bef581b46327404" dependencies = [ "libc", - "rand_chacha", - "rand_core", + "rand_chacha 0.3.1", + "rand_core 0.6.4", +] + +[[package]] +name = "rand" +version = "0.9.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6db2770f06117d490610c7488547d543617b21bfa07796d7a12f6f1bd53850d1" +dependencies = [ + "rand_chacha 0.9.0", + "rand_core 0.9.5", ] [[package]] @@ -1012,7 +2500,17 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e6c10a63a0fa32252be49d21e7709d4d4baf8d231c2dbce1eaa8141b9b127d88" dependencies = [ "ppv-lite86", - "rand_core", + "rand_core 0.6.4", +] + +[[package]] +name = "rand_chacha" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d3022b5f1df60f26e1ffddd6c66e8aa15de382ae63b3a0c1bfc0e4d3e3f325cb" +dependencies = [ + "ppv-lite86", + "rand_core 0.9.5", ] [[package]] @@ -1024,6 +2522,15 @@ dependencies = [ "getrandom 0.2.17", ] +[[package]] +name = "rand_core" +version = "0.9.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "76afc826de14238e6e8c374ddcc1fa19e374fd8dd986b0d2af0d02377261d83c" +dependencies = [ + "getrandom 0.3.4", +] + [[package]] name = "redox_syscall" version = "0.5.18" @@ -1033,6 +2540,26 @@ dependencies = [ "bitflags 2.10.0", ] +[[package]] +name = "redox_syscall" +version = "0.7.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "35985aa610addc02e24fc232012c86fd11f14111180f902b67e2d5331f8ebf2b" +dependencies = [ + "bitflags 2.10.0", +] + +[[package]] +name = "redox_users" +version = "0.5.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a4e608c6638b9c18977b00b475ac1f28d14e84b27d8d42f70e0bf1e3dec127ac" +dependencies = [ + "getrandom 0.2.17", + "libredox", + "thiserror", +] + [[package]] name = "regex" version = "1.12.3" @@ -1068,6 +2595,49 @@ version = "0.8.9" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a96887878f22d7bad8a3b6dc5b7440e0ada9a245242924394987b21cf2210a4c" +[[package]] +name = "reqwest" +version = "0.12.28" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "eddd3ca559203180a307f12d114c268abf583f59b03cb906fd0b3ff8646c1147" +dependencies = [ + "base64", + "bytes", + "encoding_rs", + "futures-channel", + "futures-core", + "futures-util", + "h2", + "http", + "http-body", + "http-body-util", + "hyper", + "hyper-rustls", + "hyper-util", + "js-sys", + "log", + "mime", + "percent-encoding", + "pin-project-lite", + "quinn", + "rustls", + "rustls-pki-types", + "serde", + "serde_json", + "serde_urlencoded", + "sync_wrapper", + "tokio", + "tokio-rustls", + "tower", + "tower-http", + "tower-service", + "url", + "wasm-bindgen", + "wasm-bindgen-futures", + "web-sys", + "webpki-roots", +] + [[package]] name = "rhai" version = "1.24.0" @@ -1097,12 +2667,32 @@ dependencies = [ "syn", ] +[[package]] +name = "ring" +version = "0.17.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a4689e6c2294d81e88dc6261c768b63bc4fcdb852be6d1352498b114f61383b7" +dependencies = [ + "cc", + "cfg-if", + "getrandom 0.2.17", + "libc", + "untrusted", + "windows-sys 0.52.0", +] + [[package]] name = "rustc-demangle" version = "0.1.27" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b50b8869d9fc858ce7266cce0194bd74df58b9d0e3f6df3a9fc8eb470d95c09d" +[[package]] +name = "rustc-hash" +version = "2.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "357703d41365b4b27c590e3ed91eabb1b663f07c4c084095e60cbed4362dff0d" + [[package]] name = "rustix" version = "1.1.3" @@ -1116,11 +2706,52 @@ dependencies = [ "windows-sys 0.61.2", ] +[[package]] +name = "rustls" +version = "0.23.36" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c665f33d38cea657d9614f766881e4d510e0eda4239891eea56b4cadcf01801b" +dependencies = [ + "once_cell", + "ring", + "rustls-pki-types", + "rustls-webpki", + "subtle", + "zeroize", +] + +[[package]] +name = "rustls-pki-types" +version = "1.14.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "be040f8b0a225e40375822a563fa9524378b9d63112f53e19ffff34df5d33fdd" +dependencies = [ + "web-time", + "zeroize", +] + +[[package]] +name = "rustls-webpki" +version = "0.103.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d7df23109aa6c1567d1c575b9952556388da57401e4ace1d15f79eedad0d8f53" +dependencies = [ + "ring", + "rustls-pki-types", + "untrusted", +] + [[package]] name = "rustversion" version = "1.0.22" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b39cdef0fa800fc44525c84ccb54a029961a8215f9619753635a9c0d2538d46d" +checksum = "b39cdef0fa800fc44525c84ccb54a029961a8215f9619753635a9c0d2538d46d" + +[[package]] +name = "ryu" +version = "1.0.23" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9774ba4a74de5f7b1c1451ed6cd5285a32eddb5cccb8cc655a4e50009e06477f" [[package]] name = "same-file" @@ -1189,6 +2820,39 @@ dependencies = [ "serde", ] +[[package]] +name = "serde_urlencoded" +version = "0.7.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d3491c14715ca2294c4d6a88f15e84739788c1d030eed8c110436aafdaa2f3fd" +dependencies = [ + "form_urlencoded", + "itoa", + "ryu", + "serde", +] + +[[package]] +name = "sha1" +version = "0.10.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e3bf829a2d51ab4a5ddf1352d8470c140cadc8301b2ae1789db023f01cedd6ba" +dependencies = [ + "cfg-if", + "cpufeatures", + "digest", +] + +[[package]] +name = "sha1-checked" +version = "0.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "89f599ac0c323ebb1c6082821a54962b839832b03984598375bff3975b804423" +dependencies = [ + "digest", + "sha1", +] + [[package]] name = "sha2" version = "0.10.9" @@ -1200,6 +2864,12 @@ dependencies = [ "digest", ] +[[package]] +name = "shell-words" +version = "1.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dc6fe69c597f9c37bfeeeeeb33da3530379845f10be461a66d16d03eca2ded77" + [[package]] name = "shlex" version = "1.3.0" @@ -1223,7 +2893,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b75a19a7a740b25bc7944bdee6172368f988763b744e3d4dfe753f6b4ece40cc" dependencies = [ "libc", - "mio", + "mio 0.8.11", "signal-hook", ] @@ -1237,12 +2907,24 @@ dependencies = [ "libc", ] +[[package]] +name = "simd-adler32" +version = "0.3.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e320a6c5ad31d271ad523dcf3ad13e2767ad8b1cb8f047f75a8aeaf8da139da2" + [[package]] name = "siphasher" version = "1.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b2aa850e253778c88a04c3d7323b043aeda9d3e30d5971937c1855769763678e" +[[package]] +name = "slab" +version = "0.4.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7a2ae44ef20feb57a68b23d846850f861394c2e02dc425a50098ae8c90267589" + [[package]] name = "slug" version = "0.1.6" @@ -1270,12 +2952,28 @@ dependencies = [ "version_check", ] +[[package]] +name = "socket2" +version = "0.6.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "17129e116933cf371d018bb80ae557e889637989d8638274fb25622827b03881" +dependencies = [ + "libc", + "windows-sys 0.60.2", +] + [[package]] name = "spin" version = "0.5.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6e63cff320ae2c57904679ba7cb63280a3dc4613885beafb148ee7bf9aa9042d" +[[package]] +name = "stable_deref_trait" +version = "1.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6ce2be8dc25455e1f91df71bfa12ad37d7af1092ae736f3a6cd0e37bc7810596" + [[package]] name = "static_assertions" version = "1.1.0" @@ -1288,6 +2986,12 @@ version = "0.11.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7da8b5736845d9f2fcb837ea5d9e2628564b3b043a70948a3f0b778838c5fb4f" +[[package]] +name = "subtle" +version = "2.6.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "13c2bddecc57b384dee18652358fb23172facb8a2c51ccc10d74c157bdea3292" + [[package]] name = "supports-color" version = "3.0.2" @@ -1320,6 +3024,47 @@ dependencies = [ "unicode-ident", ] +[[package]] +name = "sync_wrapper" +version = "1.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0bf256ce5efdfa370213c1dabab5935a12e49f2c58d15e9eac2870d3b4f27263" +dependencies = [ + "futures-core", +] + +[[package]] +name = "synstructure" +version = "0.13.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "728a70f3dbaf5bab7f0c4b1ac8d7ae5ea60a4b5549c8a5914361c99147a709d2" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "system-configuration" +version = "0.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a13f3d0daba03132c0aa9767f98351b3488edc2c100cda2d2ec2b04f3d8d3c8b" +dependencies = [ + "bitflags 2.10.0", + "core-foundation", + "system-configuration-sys", +] + +[[package]] +name = "system-configuration-sys" +version = "0.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8e1d1b10ced5ca923a1fcb8d03e96b8d3268065d724548c0211415ff6ac6bac4" +dependencies = [ + "core-foundation-sys", + "libc", +] + [[package]] name = "tempfile" version = "3.24.0" @@ -1347,7 +3092,7 @@ dependencies = [ "percent-encoding", "pest", "pest_derive", - "rand", + "rand 0.8.5", "regex", "serde", "serde_json", @@ -1419,6 +3164,68 @@ dependencies = [ "crunchy", ] +[[package]] +name = "tinystr" +version = "0.8.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "42d3e9c45c09de15d06dd8acf5f4e0e399e85927b7f00711024eb7ae10fa4869" +dependencies = [ + "displaydoc", + "zerovec", +] + +[[package]] +name = "tinyvec" +version = "1.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bfa5fdc3bce6191a1dbc8c02d5c8bffcf557bafa17c124c5264a458f1b0613fa" +dependencies = [ + "tinyvec_macros", +] + +[[package]] +name = "tinyvec_macros" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1f3ccbac311fea05f86f61904b462b55fb3df8837a366dfc601a0161d0532f20" + +[[package]] +name = "tokio" +version = "1.49.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "72a2903cd7736441aac9df9d7688bd0ce48edccaadf181c3b90be801e81d3d86" +dependencies = [ + "bytes", + "libc", + "mio 1.1.1", + "pin-project-lite", + "socket2", + "windows-sys 0.61.2", +] + +[[package]] +name = "tokio-rustls" +version = "0.26.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1729aa945f29d91ba541258c8df89027d5792d85a8841fb65e8bf0f4ede4ef61" +dependencies = [ + "rustls", + "tokio", +] + +[[package]] +name = "tokio-util" +version = "0.7.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9ae9cec805b01e8fc3fd2fe289f89149a9b66dd16786abd8b19cfa7b48cb0098" +dependencies = [ + "bytes", + "futures-core", + "futures-sink", + "pin-project-lite", + "tokio", +] + [[package]] name = "toml" version = "0.8.23" @@ -1460,6 +3267,76 @@ version = "0.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5d99f8c9a7727884afe522e9bd5edbfc91a3312b36a77b5fb8926e4c31a41801" +[[package]] +name = "tower" +version = "0.5.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ebe5ef63511595f1344e2d5cfa636d973292adc0eec1f0ad45fae9f0851ab1d4" +dependencies = [ + "futures-core", + "futures-util", + "pin-project-lite", + "sync_wrapper", + "tokio", + "tower-layer", + "tower-service", +] + +[[package]] +name = "tower-http" +version = "0.6.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d4e6559d53cc268e5031cd8429d05415bc4cb4aefc4aa5d6cc35fbf5b924a1f8" +dependencies = [ + "bitflags 2.10.0", + "bytes", + "futures-util", + "http", + "http-body", + "iri-string", + "pin-project-lite", + "tower", + "tower-layer", + "tower-service", +] + +[[package]] +name = "tower-layer" +version = "0.3.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "121c2a6cda46980bb0fcd1647ffaf6cd3fc79a013de288782836f6df9c48780e" + +[[package]] +name = "tower-service" +version = "0.3.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8df9b6e13f2d32c91b9bd719c00d1958837bc7dec474d94952798cc8e69eeec3" + +[[package]] +name = "tracing" +version = "0.1.44" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "63e71662fa4b2a2c3a26f570f037eb95bb1f85397f3cd8076caed2f026a6d100" +dependencies = [ + "pin-project-lite", + "tracing-core", +] + +[[package]] +name = "tracing-core" +version = "0.1.36" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "db97caf9d906fbde555dd62fa95ddba9eecfd14cb388e4f491a66d74cd5fb79a" +dependencies = [ + "once_cell", +] + +[[package]] +name = "try-lock" +version = "0.2.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e421abadd41a4225275504ea4d6566923418b7f05506fbc9c0fe86ba7396114b" + [[package]] name = "typenum" version = "1.19.0" @@ -1472,6 +3349,12 @@ version = "0.1.7" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2896d95c02a80c6d6a5d6e953d479f5ddf2dfdb6a244441010e373ac0fb88971" +[[package]] +name = "unicode-bom" +version = "2.0.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7eec5d1121208364f6793f7d2e222bf75a915c19557537745b195b253dd64217" + [[package]] name = "unicode-ident" version = "1.0.22" @@ -1484,6 +3367,15 @@ version = "0.1.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3b09c83c3c29d37506a3e260c08c03743a6bb66a9cd432c6934ab501a190571f" +[[package]] +name = "unicode-normalization" +version = "0.1.25" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5fd4f6878c9cb28d874b009da9e8d183b5abc80117c40bbd187a1fde336be6e8" +dependencies = [ + "tinyvec", +] + [[package]] name = "unicode-segmentation" version = "1.12.0" @@ -1502,6 +3394,30 @@ version = "0.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b4ac048d71ede7ee76d585517add45da530660ef4390e49b098733c6e897f254" +[[package]] +name = "untrusted" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8ecb6da28b8a351d773b68d5825ac39017e680750f980f3a1a85cd8dd28a47c1" + +[[package]] +name = "url" +version = "2.5.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ff67a8a4397373c3ef660812acab3268222035010ab8680ec4215f38ba3d0eed" +dependencies = [ + "form_urlencoded", + "idna", + "percent-encoding", + "serde", +] + +[[package]] +name = "utf8_iter" +version = "1.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b6c140620e7ffbb22c2dee59cafe6084a59b5ffc27a8859a5f0d494b5d52b6be" + [[package]] name = "utf8parse" version = "0.2.2" @@ -1524,6 +3440,15 @@ dependencies = [ "winapi-util", ] +[[package]] +name = "want" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bfa7760aed19e106de2c7c0b581b509f2f25d3dacaf737cb82ac61bc6d760b0e" +dependencies = [ + "try-lock", +] + [[package]] name = "wasi" version = "0.11.1+wasi-snapshot-preview1" @@ -1552,6 +3477,20 @@ dependencies = [ "wasm-bindgen-shared", ] +[[package]] +name = "wasm-bindgen-futures" +version = "0.4.58" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "70a6e77fd0ae8029c9ea0063f87c46fde723e7d887703d74ad2616d792e51e6f" +dependencies = [ + "cfg-if", + "futures-util", + "js-sys", + "once_cell", + "wasm-bindgen", + "web-sys", +] + [[package]] name = "wasm-bindgen-macro" version = "0.2.108" @@ -1584,6 +3523,16 @@ dependencies = [ "unicode-ident", ] +[[package]] +name = "web-sys" +version = "0.3.85" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "312e32e551d92129218ea9a2452120f4aabc03529ef03e4d0d82fb2780608598" +dependencies = [ + "js-sys", + "wasm-bindgen", +] + [[package]] name = "web-time" version = "1.1.0" @@ -1594,6 +3543,15 @@ dependencies = [ "wasm-bindgen", ] +[[package]] +name = "webpki-roots" +version = "1.0.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "22cfaf3c063993ff62e73cb4311efde4db1efb31ab78a3e5c457939ad5cc0bed" +dependencies = [ + "rustls-pki-types", +] + [[package]] name = "winapi" version = "0.3.9" @@ -1666,6 +3624,17 @@ version = "0.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f0805222e57f7521d6a62e36fa9163bc891acd422f971defe97d64e70d0a4fe5" +[[package]] +name = "windows-registry" +version = "0.6.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "02752bf7fbdcce7f2a27a742f798510f3e5ad88dbe84871e5168e2120c3d5720" +dependencies = [ + "windows-link", + "windows-result", + "windows-strings", +] + [[package]] name = "windows-result" version = "0.4.1" @@ -1693,6 +3662,15 @@ dependencies = [ "windows-targets 0.48.5", ] +[[package]] +name = "windows-sys" +version = "0.52.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "282be5f36a8ce781fad8c8ae18fa3f9beff57ec1b52cb3de0789201425d9a33d" +dependencies = [ + "windows-targets 0.52.6", +] + [[package]] name = "windows-sys" version = "0.59.0" @@ -1921,6 +3899,35 @@ version = "0.51.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d7249219f66ced02969388cf2bb044a09756a083d0fab1e566056b04d9fbcaa5" +[[package]] +name = "writeable" +version = "0.6.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9edde0db4769d2dc68579893f2306b26c6ecfbe0ef499b013d731b7b9247e0b9" + +[[package]] +name = "yoke" +version = "0.8.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "72d6e5c6afb84d73944e5cedb052c4680d5657337201555f9f2a16b7406d4954" +dependencies = [ + "stable_deref_trait", + "yoke-derive", + "zerofrom", +] + +[[package]] +name = "yoke-derive" +version = "0.8.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b659052874eb698efe5b9e8cf382204678a0086ebf46982b79d6ca3182927e5d" +dependencies = [ + "proc-macro2", + "quote", + "syn", + "synstructure", +] + [[package]] name = "zerocopy" version = "0.8.39" @@ -1941,6 +3948,72 @@ dependencies = [ "syn", ] +[[package]] +name = "zerofrom" +version = "0.1.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "50cc42e0333e05660c3587f3bf9d0478688e15d870fab3346451ce7f8c9fbea5" +dependencies = [ + "zerofrom-derive", +] + +[[package]] +name = "zerofrom-derive" +version = "0.1.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d71e5d6e06ab090c67b5e44993ec16b72dcbaabc526db883a360057678b48502" +dependencies = [ + "proc-macro2", + "quote", + "syn", + "synstructure", +] + +[[package]] +name = "zeroize" +version = "1.8.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b97154e67e32c85465826e8bcc1c59429aaaf107c1e4a9e53c8d8ccd5eff88d0" + +[[package]] +name = "zerotrie" +version = "0.2.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2a59c17a5562d507e4b54960e8569ebee33bee890c70aa3fe7b97e85a9fd7851" +dependencies = [ + "displaydoc", + "yoke", + "zerofrom", +] + +[[package]] +name = "zerovec" +version = "0.11.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6c28719294829477f525be0186d13efa9a3c602f7ec202ca9e353d310fb9a002" +dependencies = [ + "yoke", + "zerofrom", + "zerovec-derive", +] + +[[package]] +name = "zerovec-derive" +version = "0.11.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "eadce39539ca5cb3985590102671f2567e659fca9666581ad3411d59207951f3" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "zlib-rs" +version = "0.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a7948af682ccbc3342b6e9420e8c51c1fe5d7bf7756002b4a3c6cabfe96a7e3c" + [[package]] name = "zmij" version = "1.0.19" diff --git a/Cargo.toml b/Cargo.toml index eb294dc..864f788 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -26,3 +26,5 @@ console = "0.15" dirs = "6" rhai = { version = "1", features = ["sync"] } tempfile = "3" +gix = { version = "0.72", default-features = false, features = ["blocking-network-client", "blocking-http-transport-reqwest-rust-tls", "worktree-mutation"] } +sha2 = "0.10" diff --git a/crates/diecut-core/Cargo.toml b/crates/diecut-core/Cargo.toml index c1dfc9b..f7bcfe0 100644 --- a/crates/diecut-core/Cargo.toml +++ b/crates/diecut-core/Cargo.toml @@ -20,6 +20,7 @@ inquire = { workspace = true } indicatif = { workspace = true } console = { workspace = true } rhai = { workspace = true } - -[dev-dependencies] +dirs = { workspace = true } +gix = { workspace = true } tempfile = { workspace = true } +sha2 = { workspace = true } diff --git a/crates/diecut-core/src/error.rs b/crates/diecut-core/src/error.rs index 8945b8c..02ccf57 100644 --- a/crates/diecut-core/src/error.rs +++ b/crates/diecut-core/src/error.rs @@ -18,7 +18,7 @@ pub enum DicecutError { source: toml::de::Error, }, - #[error("Invalid variable definition for '{name}'")] + #[error("Invalid variable definition for '{name}': {reason}")] ConfigInvalidVariable { name: String, reason: String }, #[error("Validation failed for variable '{name}': {message}")] @@ -96,10 +96,6 @@ pub enum DicecutError { ))] UnsupportedFormat { path: PathBuf }, - #[error("Git source not yet implemented: {url}")] - #[diagnostic(help("Git template sources will be available in a future release"))] - GitNotImplemented { url: String }, - #[error("Invalid template abbreviation: {input}")] #[diagnostic(help( "Supported abbreviations: gh:user/repo, gl:user/repo, bb:user/repo, sr:~user/repo" @@ -109,6 +105,22 @@ pub enum DicecutError { #[error("Hook '{hook}' failed: {message}")] #[diagnostic(help("Check the Rhai script for errors"))] HookError { hook: String, message: String }, + + #[error("Cache metadata error: {context}")] + #[diagnostic(help("Try clearing the cache with `diecut cache clear`"))] + CacheMetadata { context: String }, + + #[error("Unsafe URL scheme in '{url}': {reason}")] + #[diagnostic(help("Use https:// URLs for remote templates"))] + UnsafeUrl { url: String, reason: String }, + + #[error("Git clone failed for {url}")] + #[diagnostic(help("Check the URL and your network connection"))] + GitClone { url: String, reason: String }, + + #[error("Git checkout failed for ref '{git_ref}'")] + #[diagnostic(help("Ensure the branch, tag, or commit exists in the repository"))] + GitCheckout { git_ref: String, reason: String }, } pub type Result = std::result::Result; diff --git a/crates/diecut-core/src/lib.rs b/crates/diecut-core/src/lib.rs index 8738e36..de4146c 100644 --- a/crates/diecut-core/src/lib.rs +++ b/crates/diecut-core/src/lib.rs @@ -16,7 +16,7 @@ use crate::adapter::resolve_template; use crate::error::{DicecutError, Result}; use crate::prompt::{collect_variables, PromptOptions}; use crate::render::{build_context_with_namespace, walk_and_render, GeneratedProject}; -use crate::template::{resolve_source, TemplateSource}; +use crate::template::{get_or_clone, resolve_source, TemplateSource}; /// Options for the `generate` operation. pub struct GenerateOptions { @@ -38,8 +38,8 @@ pub fn generate(options: GenerateOptions) -> Result { let source = resolve_source(&options.template)?; let template_dir = match &source { TemplateSource::Local(path) => path.clone(), - TemplateSource::Git { url, .. } => { - return Err(DicecutError::GitNotImplemented { url: url.clone() }); + TemplateSource::Git { url, git_ref } => { + get_or_clone(url, git_ref.as_deref())? } }; diff --git a/crates/diecut-core/src/template/cache.rs b/crates/diecut-core/src/template/cache.rs new file mode 100644 index 0000000..caf9eb2 --- /dev/null +++ b/crates/diecut-core/src/template/cache.rs @@ -0,0 +1,380 @@ +use std::path::{Path, PathBuf}; + +use sha2::{Sha256, Digest}; + +use serde::{Deserialize, Serialize}; + +use crate::error::{DicecutError, Result}; +use crate::template::clone::clone_template; + +/// Metadata stored alongside a cached template. +#[derive(Debug, Serialize, Deserialize)] +pub struct CacheMetadata { + /// The original git URL. + pub url: String, + /// The git ref (branch, tag, or commit) if specified. + pub git_ref: Option, + /// When the template was cached (Unix timestamp in seconds). + pub cached_at: String, +} + +/// A cached template entry returned by `list_cached()`. +#[derive(Debug)] +pub struct CachedTemplate { + /// The cache key (directory name). + pub key: String, + /// The path to the cached template. + pub path: PathBuf, + /// Metadata about the cached template. + pub metadata: CacheMetadata, +} + +const CACHE_METADATA_FILE: &str = ".diecut-cache.toml"; + +/// Get the cache directory for templates. +/// +/// Checks `DIECUT_CACHE_DIR` env var first. Falls back to +/// `~/.cache/diecut/templates/` on Linux/macOS (XDG-compliant). +/// Returns an error if neither source provides a cache directory. +pub fn get_cache_dir() -> Result { + if let Ok(dir) = std::env::var("DIECUT_CACHE_DIR") { + return Ok(PathBuf::from(dir)); + } + dirs::cache_dir() + .map(|d| d.join("diecut").join("templates")) + .ok_or_else(|| DicecutError::Io { + context: "unable to determine cache directory: set DIECUT_CACHE_DIR or ensure a home directory exists".into(), + source: std::io::Error::new(std::io::ErrorKind::NotFound, "no cache directory available"), + }) +} + +/// Normalize a URL by stripping trailing `.git` and `/` for consistent comparison. +fn normalize_url(url: &str) -> &str { + url.trim_end_matches('/').trim_end_matches(".git") +} + +/// Generate a deterministic cache key from a URL and optional ref. +/// +/// Normalizes the URL by stripping trailing `.git` and trailing `/` before +/// hashing, so `https://github.com/user/repo` and +/// `https://github.com/user/repo.git` produce the same key. +pub(crate) fn cache_key(url: &str, git_ref: Option<&str>) -> String { + let normalized = normalize_url(url); + + let mut hasher = Sha256::new(); + hasher.update(normalized.as_bytes()); + if let Some(r) = git_ref { + hasher.update(b"\0"); + hasher.update(r.as_bytes()); + } + let digest = hasher.finalize(); + let hash: String = digest.iter().take(8).map(|b| format!("{b:02x}")).collect(); + + // Sanitize components to prevent path traversal + let sanitize = |s: &str| -> String { + s.replace(['/', '\\'], "_").replace("..", "_") + }; + + // Build a human-readable prefix from the URL + let prefix = sanitize( + normalized + .rsplit('/') + .next() + .unwrap_or("template"), + ); + + match git_ref { + Some(r) => format!("{prefix}-{}-{hash}", sanitize(r)), + None => format!("{prefix}-{hash}"), + } +} + +/// Check cache first, clone if missing, return path to the template. +/// +/// Note: this function does not protect against concurrent access. If multiple +/// processes call `get_or_clone` for the same URL simultaneously, they may +/// both clone and race to populate the cache entry. +pub fn get_or_clone(url: &str, git_ref: Option<&str>) -> Result { + let cache_dir = get_cache_dir()?; + let key = cache_key(url, git_ref); + let cached_path = cache_dir.join(&key); + + // Check if we have a valid cached copy + if cached_path.exists() && cached_path.join(CACHE_METADATA_FILE).exists() { + return Ok(cached_path); + } + + // Ensure cache directory exists before cloning + std::fs::create_dir_all(&cache_dir).map_err(|e| DicecutError::Io { + context: format!("creating cache directory {}", cache_dir.display()), + source: e, + })?; + + // Clone to a temp location, then move into cache. + // tmp_dir is kept alive so the temp directory is cleaned up on error. + let tmp_dir = clone_template(url, git_ref)?; + + // Write cache metadata + let metadata = CacheMetadata { + url: url.to_string(), + git_ref: git_ref.map(String::from), + cached_at: unix_timestamp_secs(), + }; + let metadata_toml = toml::to_string_pretty(&metadata).map_err(|e| DicecutError::CacheMetadata { + context: format!("serializing cache metadata: {e}"), + })?; + std::fs::write(tmp_dir.path().join(CACHE_METADATA_FILE), metadata_toml).map_err(|e| { + DicecutError::Io { + context: "writing cache metadata".into(), + source: e, + } + })?; + + // Remove any stale cache entry + if cached_path.exists() { + std::fs::remove_dir_all(&cached_path).map_err(|e| DicecutError::Io { + context: format!("removing stale cache entry {}", cached_path.display()), + source: e, + })?; + } + + // Move cloned directory into cache. Only persist (leak) the tempdir + // after successful placement — on error, drop cleans it up. + std::fs::rename(tmp_dir.path(), &cached_path).or_else(|rename_err| { + // rename can fail across filesystems; fall back to copy + delete + copy_dir_all(tmp_dir.path(), &cached_path).map_err(|e| DicecutError::Io { + context: format!( + "copying cloned template to cache (rename failed: {rename_err}): {e}" + ), + source: std::io::Error::other(e.to_string()), + })?; + Ok(()) + })?; + + // Successfully placed in cache — prevent TempDir from cleaning up + // the source (it may already be gone after a successful rename). + let _ = tmp_dir.keep(); + + Ok(cached_path) +} + +/// List all cached templates. +pub fn list_cached() -> Result> { + let cache_dir = get_cache_dir()?; + if !cache_dir.exists() { + return Ok(Vec::new()); + } + + let mut entries = Vec::new(); + let read_dir = std::fs::read_dir(&cache_dir).map_err(|e| DicecutError::Io { + context: format!("reading cache directory {}", cache_dir.display()), + source: e, + })?; + + for entry in read_dir { + let entry = entry.map_err(|e| DicecutError::Io { + context: "reading cache directory entry".into(), + source: e, + })?; + + let path = entry.path(); + if !path.is_dir() { + continue; + } + + let metadata_path = path.join(CACHE_METADATA_FILE); + if !metadata_path.exists() { + continue; + } + + let metadata_str = std::fs::read_to_string(&metadata_path).map_err(|e| DicecutError::Io { + context: format!("reading cache metadata {}", metadata_path.display()), + source: e, + })?; + + let metadata: CacheMetadata = + toml::from_str(&metadata_str).map_err(|e| DicecutError::CacheMetadata { + context: format!("parsing cache metadata: {e}"), + })?; + + let key = entry + .file_name() + .to_string_lossy() + .into_owned(); + + entries.push(CachedTemplate { + key, + path, + metadata, + }); + } + + Ok(entries) +} + +/// Clear cached templates. +/// +/// If `url` is provided, only the cache entry matching that URL is removed. +/// If `url` is None, the entire cache directory is cleared. +pub fn clear_cache(url: Option<&str>) -> Result<()> { + let cache_dir = get_cache_dir()?; + + if let Some(url) = url { + // Clear specific entries matching this URL (any ref) + if !cache_dir.exists() { + return Ok(()); + } + let normalized_input = normalize_url(url); + let entries = list_cached()?; + for entry in entries { + if normalize_url(&entry.metadata.url) == normalized_input { + std::fs::remove_dir_all(&entry.path).map_err(|e| DicecutError::Io { + context: format!("removing cached template {}", entry.path.display()), + source: e, + })?; + } + } + } else { + // Clear entire cache + if cache_dir.exists() { + std::fs::remove_dir_all(&cache_dir).map_err(|e| DicecutError::Io { + context: format!("removing cache directory {}", cache_dir.display()), + source: e, + })?; + } + } + + Ok(()) +} + +/// Recursively copy a directory, skipping symlinks. +fn copy_dir_all(src: &Path, dst: &Path) -> Result<()> { + std::fs::create_dir_all(dst).map_err(|e| DicecutError::Io { + context: format!("creating directory {}", dst.display()), + source: e, + })?; + + for entry in std::fs::read_dir(src).map_err(|e| DicecutError::Io { + context: format!("reading directory {}", src.display()), + source: e, + })? { + let entry = entry.map_err(|e| DicecutError::Io { + context: "reading directory entry".into(), + source: e, + })?; + + let file_type = entry.file_type().map_err(|e| DicecutError::Io { + context: "reading file type of directory entry".into(), + source: e, + })?; + + // Skip symlinks to prevent symlink-following attacks + if file_type.is_symlink() { + continue; + } + + let src_path = entry.path(); + let dst_path = dst.join(entry.file_name()); + + if file_type.is_dir() { + copy_dir_all(&src_path, &dst_path)?; + } else { + std::fs::copy(&src_path, &dst_path).map_err(|e| DicecutError::Io { + context: format!("copying {} to {}", src_path.display(), dst_path.display()), + source: e, + })?; + } + } + + Ok(()) +} + +/// Get the current time as a Unix timestamp in seconds. +fn unix_timestamp_secs() -> String { + let duration = std::time::SystemTime::now() + .duration_since(std::time::UNIX_EPOCH) + .unwrap_or_default(); + format!("{}", duration.as_secs()) +} + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn cache_key_deterministic() { + let key1 = cache_key("https://github.com/user/repo.git", None); + let key2 = cache_key("https://github.com/user/repo.git", None); + assert_eq!(key1, key2); + } + + #[test] + fn cache_key_normalizes_trailing_git() { + let key1 = cache_key("https://github.com/user/repo.git", None); + let key2 = cache_key("https://github.com/user/repo", None); + assert_eq!(key1, key2); + } + + #[test] + fn cache_key_normalizes_trailing_slash() { + let key1 = cache_key("https://github.com/user/repo/", None); + let key2 = cache_key("https://github.com/user/repo", None); + assert_eq!(key1, key2); + } + + #[test] + fn cache_key_differs_by_ref() { + let key1 = cache_key("https://github.com/user/repo", Some("main")); + let key2 = cache_key("https://github.com/user/repo", Some("develop")); + assert_ne!(key1, key2); + } + + #[test] + fn cache_key_none_ref_differs_from_some() { + let key1 = cache_key("https://github.com/user/repo", None); + let key2 = cache_key("https://github.com/user/repo", Some("main")); + assert_ne!(key1, key2); + } + + #[test] + fn cache_key_includes_repo_name() { + let key = cache_key("https://github.com/user/my-template.git", None); + assert!(key.starts_with("my-template-")); + } + + #[test] + fn cache_key_includes_ref_in_name() { + let key = cache_key("https://github.com/user/repo", Some("v2.0")); + assert!(key.contains("v2.0")); + } + + #[test] + fn get_cache_dir_returns_xdg_path() { + let dir = get_cache_dir().unwrap(); + assert!(dir.ends_with("diecut/templates")); + } + + #[test] + fn get_cache_dir_respects_env_var() { + std::env::set_var("DIECUT_CACHE_DIR", "/tmp/test-diecut-cache"); + let dir = get_cache_dir().unwrap(); + std::env::remove_var("DIECUT_CACHE_DIR"); + assert_eq!(dir, PathBuf::from("/tmp/test-diecut-cache")); + } + + #[test] + fn normalize_url_strips_trailing_git_and_slash() { + assert_eq!(normalize_url("https://github.com/user/repo.git"), "https://github.com/user/repo"); + assert_eq!(normalize_url("https://github.com/user/repo/"), "https://github.com/user/repo"); + assert_eq!(normalize_url("https://github.com/user/repo"), "https://github.com/user/repo"); + } + + #[test] + fn list_cached_empty_when_no_cache() { + // With a non-existent cache dir, list_cached should return empty + let entries = list_cached(); + // This may or may not have entries depending on system state, + // but it should not error + assert!(entries.is_ok()); + } +} diff --git a/crates/diecut-core/src/template/clone.rs b/crates/diecut-core/src/template/clone.rs new file mode 100644 index 0000000..33a892a --- /dev/null +++ b/crates/diecut-core/src/template/clone.rs @@ -0,0 +1,102 @@ +use crate::error::{DicecutError, Result}; + +/// Clone a git repository to a temporary directory. +/// +/// If `git_ref` is provided, the repository is checked out at that ref +/// (branch, tag, or commit). Returns the `TempDir` handle — the temporary +/// directory is automatically cleaned up when the handle is dropped. +/// +/// Rejects `file://` URLs to prevent local file access attacks. +/// Prints a warning for `http://` URLs (non-TLS). +pub fn clone_template(url: &str, git_ref: Option<&str>) -> Result { + // Reject file:// URLs to prevent local filesystem access + if url.starts_with("file://") { + return Err(DicecutError::UnsafeUrl { + url: url.to_string(), + reason: "file:// URLs are not allowed for remote templates".into(), + }); + } + + // Warn on non-TLS http:// URLs + if url.starts_with("http://") { + eprintln!("warning: using insecure http:// URL; consider using https:// instead"); + } + + let tmp_dir = tempfile::tempdir().map_err(|e| DicecutError::Io { + context: "creating temporary directory for git clone".into(), + source: e, + })?; + + // Use prepare_clone (with worktree) so we get a checked-out working copy + let mut prepare = gix::prepare_clone(url, tmp_dir.path()).map_err(|e| { + DicecutError::GitClone { + url: url.to_string(), + reason: e.to_string(), + } + })?; + + // If a specific ref is requested, configure it before fetching + if let Some(ref_name) = git_ref { + prepare = prepare.with_ref_name(Some(ref_name)).map_err(|e| { + DicecutError::GitCheckout { + git_ref: ref_name.to_string(), + reason: e.to_string(), + } + })?; + } + + // Fetch and prepare for checkout + let (mut checkout, _outcome) = prepare + .fetch_then_checkout(gix::progress::Discard, &gix::interrupt::IS_INTERRUPTED) + .map_err(|e| DicecutError::GitClone { + url: url.to_string(), + reason: e.to_string(), + })?; + + // Checkout the main worktree + let (_repo, _outcome) = + checkout + .main_worktree(gix::progress::Discard, &gix::interrupt::IS_INTERRUPTED) + .map_err(|e| DicecutError::GitClone { + url: url.to_string(), + reason: format!("worktree checkout failed: {e}"), + })?; + + Ok(tmp_dir) +} + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn clone_rejects_invalid_url() { + let result = clone_template("://bad", None); + assert!(result.is_err()); + match result.unwrap_err() { + DicecutError::GitClone { url, .. } => { + assert_eq!(url, "://bad"); + } + other => panic!("expected GitClone error, got: {other:?}"), + } + } + + #[test] + fn clone_fails_on_unreachable_host() { + // Network call that should fail quickly on a non-routable address + let result = clone_template("https://nonexistent.invalid/repo.git", None); + assert!(result.is_err()); + } + + #[test] + fn clone_rejects_file_url() { + let result = clone_template("file:///tmp/repo", None); + assert!(result.is_err()); + match result.unwrap_err() { + DicecutError::UnsafeUrl { url, .. } => { + assert_eq!(url, "file:///tmp/repo"); + } + other => panic!("expected UnsafeUrl error, got: {other:?}"), + } + } +} diff --git a/crates/diecut-core/src/template/mod.rs b/crates/diecut-core/src/template/mod.rs index 6024891..8d2ce45 100644 --- a/crates/diecut-core/src/template/mod.rs +++ b/crates/diecut-core/src/template/mod.rs @@ -1,3 +1,7 @@ +pub mod cache; +pub mod clone; pub mod source; +pub use cache::{get_or_clone, list_cached, clear_cache, CachedTemplate}; +pub use clone::clone_template; pub use source::{resolve_source, resolve_source_with_ref, TemplateSource}; diff --git a/crates/diecut-core/src/template/source.rs b/crates/diecut-core/src/template/source.rs index 4fa2711..7223e5e 100644 --- a/crates/diecut-core/src/template/source.rs +++ b/crates/diecut-core/src/template/source.rs @@ -34,8 +34,9 @@ fn expand_abbreviation(input: &str) -> Result { return Ok(format!("{base_url}{rest}{suffix}")); } } - // Not an abbreviation at all — caller should handle this. - unreachable!("expand_abbreviation called on non-abbreviation input"); + Err(DicecutError::InvalidAbbreviation { + input: input.to_string(), + }) } /// Returns `true` when the argument looks like a known abbreviation prefix.