diff --git a/Cargo.lock b/Cargo.lock index 51a2a65..e9f19e9 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -13,9 +13,9 @@ dependencies = [ [[package]] name = "anstream" -version = "0.6.20" +version = "0.6.21" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3ae563653d1938f79b1ab1b5e668c87c76a9930414574a6583a7b7e11a8e6192" +checksum = "43d5b281e737544384e969a5ccad3f1cdd24b48086a0fc1b2a5262a26b8f4f4a" dependencies = [ "anstyle", "anstyle-parse", @@ -28,9 +28,9 @@ dependencies = [ [[package]] name = "anstyle" -version = "1.0.11" +version = "1.0.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "862ed96ca487e809f1c8e5a8447f6ee2cf102f846893800b20cebdf541fc6bbd" +checksum = "5192cca8006f1fd4f7237516f40fa183bb07f8fbdfedaa0036de5ea9b0b45e78" [[package]] name = "anstyle-parse" @@ -97,10 +97,11 @@ checksum = "46c5e41b57b8bba42a04676d81cb89e9ee8e859a1a66f80a5a72e1cb76b34d43" [[package]] name = "cc" -version = "1.2.34" +version = "1.2.41" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "42bc4aea80032b7bf409b0bc7ccad88853858911b7713a8062fdc0623867bedc" +checksum = "ac9fe6cdbb24b6ade63616c0a0688e45bb56732262c158df3c0c4bea4ca47cb7" dependencies = [ + "find-msvc-tools", "jobserver", "libc", "shlex", @@ -108,15 +109,15 @@ dependencies = [ [[package]] name = "cfg-if" -version = "1.0.3" +version = "1.0.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2fd1289c04a9ea8cb22300a459a72a385d7c73d3259e2ed7dcb2af674838cfa9" +checksum = "9330f8b2ff13f34540b44e946ef35111825727b38d33286ef986142615121801" [[package]] name = "clap" -version = "4.5.46" +version = "4.5.50" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2c5e4fcf9c21d2e544ca1ee9d8552de13019a42aa7dbf32747fa7aaf1df76e57" +checksum = "0c2cfd7bf8a6017ddaa4e32ffe7403d547790db06bd171c1c53926faab501623" dependencies = [ "clap_builder", "clap_derive", @@ -124,9 +125,9 @@ dependencies = [ [[package]] name = "clap_builder" -version = "4.5.46" +version = "4.5.50" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fecb53a0e6fcfb055f686001bc2e2592fa527efaf38dbe81a6a9563562e57d41" +checksum = "0a4c05b9e80c5ccd3a7ef080ad7b6ba7d6fc00a985b8b157197075677c82c7a0" dependencies = [ "anstream", "anstyle", @@ -136,9 +137,9 @@ dependencies = [ [[package]] name = "clap_derive" -version = "4.5.45" +version = "4.5.49" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "14cb31bb0a7d536caef2639baa7fad459e15c3144efefa6dbd1c84562c4739f6" +checksum = "2a0b5487afeab2deb2ff4e03a807ad1a03ac532ff5a2cee5d86884440c7f7671" dependencies = [ "heck", "proc-macro2", @@ -148,9 +149,9 @@ dependencies = [ [[package]] name = "clap_lex" -version = "0.7.5" +version = "0.7.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b94f61472cee1439c0b966b47e3aca9ae07e45d070759512cd390ea2bebc6675" +checksum = "a1d728cc89cf3aee9ff92b05e62b19ee65a02b5702cff7d5a377e32c6ae29d8d" [[package]] name = "colorchoice" @@ -204,6 +205,12 @@ dependencies = [ "syn", ] +[[package]] +name = "find-msvc-tools" +version = "0.1.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "52051878f80a721bb68ebfbc930e07b65ba72f2da88968ea5c06fd6ca3d3a127" + [[package]] name = "foldhash" version = "0.1.5" @@ -212,14 +219,14 @@ checksum = "d9c4f5dac5e15c24eb999c26181a6ca40b39fe946cbe4c263c7209467bc83af2" [[package]] name = "getrandom" -version = "0.3.3" +version = "0.3.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "26145e563e54f2cadc477553f1ec5ee650b00862f0a58bcd12cbdc5f0ea2d2f4" +checksum = "899def5c37c4fd7b2664648c28120ecec138e4d395b459e5ca34f9cce2dd77fd" dependencies = [ "cfg-if", "libc", "r-efi", - "wasi", + "wasip2", ] [[package]] @@ -237,13 +244,19 @@ dependencies = [ "foldhash", ] +[[package]] +name = "hashbrown" +version = "0.16.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5419bdc4f6a9207fbeba6d11b604d481addf78ecd10c11ad51e76c2f6482748d" + [[package]] name = "hashlink" version = "0.10.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7382cf6263419f2d8df38c55d7da83da5c18aef87fc7a7fc1fb1e344edfe14c1" dependencies = [ - "hashbrown", + "hashbrown 0.15.5", "serde", ] @@ -274,19 +287,19 @@ dependencies = [ [[package]] name = "indexmap" -version = "2.11.0" +version = "2.12.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f2481980430f9f78649238835720ddccc57e52df14ffce1c6f37391d61b563e9" +checksum = "6717a8d2a5a929a1a2eb43a12812498ed141a0bcfb7e8f7844fbdbe4303bba9f" dependencies = [ "equivalent", - "hashbrown", + "hashbrown 0.16.0", ] [[package]] name = "is_terminal_polyfill" -version = "1.70.1" +version = "1.70.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7943c866cc5cd64cbc25b2e01621d07fa8eb2a1a23160ee81ce38704e97b8ecf" +checksum = "a6cb138bb79a146c1bd460005623e142ef0181e3d0219cb493e02f7d08a35695" [[package]] name = "itoa" @@ -306,9 +319,9 @@ dependencies = [ [[package]] name = "js-sys" -version = "0.3.77" +version = "0.3.81" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1cfaf33c695fc6e08064efbc1f72ec937429614f25eef83af942d0e227c3a28f" +checksum = "ec48937a97411dcb524a265206ccd4c90bb711fca92b2792c407f268825b9305" dependencies = [ "once_cell", "wasm-bindgen", @@ -322,9 +335,9 @@ checksum = "bbd2bcb4c963f2ddae06a2efc7e9f3591312473c50c6685e1f298068316e66fe" [[package]] name = "libc" -version = "0.2.175" +version = "0.2.177" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6a82ae493e598baaea5209805c49bbf2ea7de956d50d7da0da1164f9c6d28543" +checksum = "2874a2af47a2325c2001a6e6fad9b16a53b802102b528163885171cf92b15976" [[package]] name = "libfuzzer-sys" @@ -338,15 +351,15 @@ dependencies = [ [[package]] name = "log" -version = "0.4.27" +version = "0.4.28" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "13dc2df351e3202783a1fe0d44375f7295ffb4049267b0f3018346dc122a1d94" +checksum = "34080505efa8e45a4b816c349525ebe327ceaa8559756f0356cba97ef3bf7432" [[package]] name = "memchr" -version = "2.7.5" +version = "2.7.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "32a282da65faaf38286cf3be983213fcf1d2e2a58700e808f83f4ea9a4804bc0" +checksum = "f52b00d39961fc5b2736ea853c9cc86238e165017a493d1d5c8eac6bdc4cc273" [[package]] name = "minicov" @@ -366,9 +379,9 @@ checksum = "42f5e15c9953c5e4ccceeb2e7382a716482c34515315f7b03532b8b4e8393d2d" [[package]] name = "once_cell_polyfill" -version = "1.70.1" +version = "1.70.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a4895175b425cb1f87721b59f0f286c2092bd4af812243672510e1ac53e2e0ad" +checksum = "384b8ab6d37215f3c5301a95a4accb5d64aa607f1fcb26a11b5303878451b4fe" [[package]] name = "paste" @@ -465,9 +478,9 @@ dependencies = [ [[package]] name = "quote" -version = "1.0.40" +version = "1.0.41" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1885c039570dc00dcb4ff087a89e185fd56bae234ddc7f056a945bf36467248d" +checksum = "ce25767e7b499d1b604768e7cde645d14cc8584231ea6b295e9c9eb22c02e1d1" dependencies = [ "proc-macro2", ] @@ -480,9 +493,9 @@ checksum = "69cdb34c158ceb288df11e18b4bd39de994f6657d83847bdffdbd7f346754b0f" [[package]] name = "regex" -version = "1.11.2" +version = "1.12.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "23d7fd106d8c02486a8d64e778353d1cffe08ce79ac2e82f540c86d0facf6912" +checksum = "843bc0191f75f3e22651ae5f1e72939ab2f72a4bc30fa80a066bd66edefc24d4" dependencies = [ "aho-corasick", "memchr", @@ -492,9 +505,9 @@ dependencies = [ [[package]] name = "regex-automata" -version = "0.4.10" +version = "0.4.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6b9458fa0bfeeac22b5ca447c63aaf45f28439a709ccd244698632f9aa6394d6" +checksum = "5276caf25ac86c8d810222b3dbb938e512c55c6831a10f3e6ed1c93b84041f1c" dependencies = [ "aho-corasick", "memchr", @@ -503,9 +516,9 @@ dependencies = [ [[package]] name = "regex-syntax" -version = "0.8.6" +version = "0.8.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "caf4aa5b0f434c91fe5c7f1ecb6a5ece2130b02ad2a590589dda5146df959001" +checksum = "7a2d987857b319362043e95f5353c0535c1f58eec5336fdfcf626430af7def58" [[package]] name = "rustversion" @@ -530,18 +543,28 @@ dependencies = [ [[package]] name = "serde" -version = "1.0.219" +version = "1.0.228" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9a8e94ea7f378bd32cbbd37198a4a91436180c5bb472411e48b5ec2e2124ae9e" +dependencies = [ + "serde_core", + "serde_derive", +] + +[[package]] +name = "serde_core" +version = "1.0.228" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5f0e2c6ed6606019b4e29e69dbaba95b11854410e5347d525002456dbbb786b6" +checksum = "41d385c7d4ca58e59fc732af25c3983b67ac852c1a25000afe1175de458b67ad" dependencies = [ "serde_derive", ] [[package]] name = "serde_derive" -version = "1.0.219" +version = "1.0.228" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5b0276cf7f2c73365f7157c8123c21cd9a50fbbd844757af28ca1f5925fc2a00" +checksum = "d540f220d3187173da220f885ab66608367b6574e925011a9353e4badda91d79" dependencies = [ "proc-macro2", "quote", @@ -550,15 +573,16 @@ dependencies = [ [[package]] name = "serde_json" -version = "1.0.143" +version = "1.0.145" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d401abef1d108fbd9cbaebc3e46611f4b1021f714a0597a71f41ee463f5f4a5a" +checksum = "402a6f66d8c709116cf22f558eab210f5a50187f702eb4d7e5ef38d9a7f1c79c" dependencies = [ "indexmap", "itoa", "memchr", "ryu", "serde", + "serde_core", ] [[package]] @@ -581,9 +605,9 @@ checksum = "7da8b5736845d9f2fcb837ea5d9e2628564b3b043a70948a3f0b778838c5fb4f" [[package]] name = "syn" -version = "2.0.106" +version = "2.0.107" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ede7c438028d4436d71104916910f5bb611972c5cfd7f89b8300a8186e6fada6" +checksum = "2a26dbd934e5451d21ef060c018dae56fc073894c5a7896f882928a76e6d081b" dependencies = [ "proc-macro2", "quote", @@ -612,9 +636,9 @@ dependencies = [ [[package]] name = "tree-sitter" -version = "0.25.8" +version = "0.25.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6d7b8994f367f16e6fa14b5aebbcb350de5d7cbea82dc5b00ae997dd71680dd2" +checksum = "78f873475d258561b06f1c595d93308a7ed124d9977cb26b148c2084a4a3cc87" dependencies = [ "cc", "regex", @@ -641,9 +665,9 @@ dependencies = [ [[package]] name = "unicode-ident" -version = "1.0.18" +version = "1.0.20" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5a5f39404a5da50712a4c1eecf25e90dd62b613502b7e925fd4e4d19b5c96512" +checksum = "462eeb75aeb73aea900253ce739c8e18a67423fadf006037cd3ff27e82748a06" [[package]] name = "unicode-width" @@ -668,31 +692,32 @@ dependencies = [ ] [[package]] -name = "wasi" -version = "0.14.3+wasi-0.2.4" +name = "wasip2" +version = "1.0.1+wasi-0.2.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6a51ae83037bdd272a9e28ce236db8c07016dd0d50c27038b3f407533c030c95" +checksum = "0562428422c63773dad2c345a1882263bbf4d65cf3f42e90921f787ef5ad58e7" dependencies = [ "wit-bindgen", ] [[package]] name = "wasm-bindgen" -version = "0.2.100" +version = "0.2.104" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1edc8929d7499fc4e8f0be2262a241556cfc54a0bea223790e71446f2aab1ef5" +checksum = "c1da10c01ae9f1ae40cbfac0bac3b1e724b320abfcf52229f80b547c0d250e2d" dependencies = [ "cfg-if", "once_cell", "rustversion", "wasm-bindgen-macro", + "wasm-bindgen-shared", ] [[package]] name = "wasm-bindgen-backend" -version = "0.2.100" +version = "0.2.104" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2f0a0651a5c2bc21487bde11ee802ccaf4c51935d0d3d42a6101f98161700bc6" +checksum = "671c9a5a66f49d8a47345ab942e2cb93c7d1d0339065d4f8139c486121b43b19" dependencies = [ "bumpalo", "log", @@ -704,9 +729,9 @@ dependencies = [ [[package]] name = "wasm-bindgen-futures" -version = "0.4.50" +version = "0.4.54" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "555d470ec0bc3bb57890405e5d4322cc9ea83cebb085523ced7be4144dac1e61" +checksum = "7e038d41e478cc73bae0ff9b36c60cff1c98b8f38f8d7e8061e79ee63608ac5c" dependencies = [ "cfg-if", "js-sys", @@ -717,9 +742,9 @@ dependencies = [ [[package]] name = "wasm-bindgen-macro" -version = "0.2.100" +version = "0.2.104" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7fe63fc6d09ed3792bd0897b314f53de8e16568c2b3f7982f468c0bf9bd0b407" +checksum = "7ca60477e4c59f5f2986c50191cd972e3a50d8a95603bc9434501cf156a9a119" dependencies = [ "quote", "wasm-bindgen-macro-support", @@ -727,9 +752,9 @@ dependencies = [ [[package]] name = "wasm-bindgen-macro-support" -version = "0.2.100" +version = "0.2.104" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8ae87ea40c9f689fc23f209965b6fb8a99ad69aeeb0231408be24920604395de" +checksum = "9f07d2f20d4da7b26400c9f4a0511e6e0345b040694e8a75bd41d578fa4421d7" dependencies = [ "proc-macro2", "quote", @@ -740,18 +765,18 @@ dependencies = [ [[package]] name = "wasm-bindgen-shared" -version = "0.2.100" +version = "0.2.104" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1a05d73b933a847d6cccdda8f838a22ff101ad9bf93e33684f39c1f5f0eece3d" +checksum = "bad67dc8b2a1a6e5448428adec4c3e84c43e561d8c9ee8a9e5aabeb193ec41d1" dependencies = [ "unicode-ident", ] [[package]] name = "wasm-bindgen-test" -version = "0.3.50" +version = "0.3.54" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "66c8d5e33ca3b6d9fa3b4676d774c5778031d27a578c2b007f905acf816152c3" +checksum = "4e381134e148c1062f965a42ed1f5ee933eef2927c3f70d1812158f711d39865" dependencies = [ "js-sys", "minicov", @@ -762,9 +787,9 @@ dependencies = [ [[package]] name = "wasm-bindgen-test-macro" -version = "0.3.50" +version = "0.3.54" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "17d5042cc5fa009658f9a7333ef24291b1291a25b6382dd68862a7f3b969f69b" +checksum = "b673bca3298fe582aeef8352330ecbad91849f85090805582400850f8270a2e8" dependencies = [ "proc-macro2", "quote", @@ -783,9 +808,9 @@ dependencies = [ [[package]] name = "web-sys" -version = "0.3.77" +version = "0.3.81" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "33b6dd2ef9186f1f2072e409e99cd22a975331a6b3591b12c764e0e55c60d5d2" +checksum = "9367c417a924a74cae129e6a2ae3b47fabb1f8995595ab474029da749a8be120" dependencies = [ "js-sys", "wasm-bindgen", @@ -793,18 +818,18 @@ dependencies = [ [[package]] name = "winapi-util" -version = "0.1.10" +version = "0.1.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0978bf7171b3d90bac376700cb56d606feb40f251a475a5d6634613564460b22" +checksum = "c2a7b1c03c876122aa43f3020e6c3c3ee5c05081c9a00739faf7503aeba10d22" dependencies = [ - "windows-sys 0.60.2", + "windows-sys 0.61.2", ] [[package]] name = "windows-link" -version = "0.1.3" +version = "0.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5e6ad25900d524eaabdbbb96d20b4311e1e7ae1699af4fb28c17ae66c80d798a" +checksum = "f0805222e57f7521d6a62e36fa9163bc891acd422f971defe97d64e70d0a4fe5" [[package]] name = "windows-sys" @@ -821,7 +846,16 @@ version = "0.60.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f2f500e4d28234f72040990ec9d39e3a6b950f9f22d3dba18416c35882612bcb" dependencies = [ - "windows-targets 0.53.3", + "windows-targets 0.53.5", +] + +[[package]] +name = "windows-sys" +version = "0.61.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ae137229bcbd6cdf0f7b80a31df61766145077ddf49416a728b02cb3921ff3fc" +dependencies = [ + "windows-link", ] [[package]] @@ -842,19 +876,19 @@ dependencies = [ [[package]] name = "windows-targets" -version = "0.53.3" +version = "0.53.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d5fe6031c4041849d7c496a8ded650796e7b6ecc19df1a431c1a363342e5dc91" +checksum = "4945f9f551b88e0d65f3db0bc25c33b8acea4d9e41163edf90dcd0b19f9069f3" dependencies = [ "windows-link", - "windows_aarch64_gnullvm 0.53.0", - "windows_aarch64_msvc 0.53.0", - "windows_i686_gnu 0.53.0", - "windows_i686_gnullvm 0.53.0", - "windows_i686_msvc 0.53.0", - "windows_x86_64_gnu 0.53.0", - "windows_x86_64_gnullvm 0.53.0", - "windows_x86_64_msvc 0.53.0", + "windows_aarch64_gnullvm 0.53.1", + "windows_aarch64_msvc 0.53.1", + "windows_i686_gnu 0.53.1", + "windows_i686_gnullvm 0.53.1", + "windows_i686_msvc 0.53.1", + "windows_x86_64_gnu 0.53.1", + "windows_x86_64_gnullvm 0.53.1", + "windows_x86_64_msvc 0.53.1", ] [[package]] @@ -865,9 +899,9 @@ checksum = "32a4622180e7a0ec044bb555404c800bc9fd9ec262ec147edd5989ccd0c02cd3" [[package]] name = "windows_aarch64_gnullvm" -version = "0.53.0" +version = "0.53.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "86b8d5f90ddd19cb4a147a5fa63ca848db3df085e25fee3cc10b39b6eebae764" +checksum = "a9d8416fa8b42f5c947f8482c43e7d89e73a173cead56d044f6a56104a6d1b53" [[package]] name = "windows_aarch64_msvc" @@ -877,9 +911,9 @@ checksum = "09ec2a7bb152e2252b53fa7803150007879548bc709c039df7627cabbd05d469" [[package]] name = "windows_aarch64_msvc" -version = "0.53.0" +version = "0.53.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c7651a1f62a11b8cbd5e0d42526e55f2c99886c77e007179efff86c2b137e66c" +checksum = "b9d782e804c2f632e395708e99a94275910eb9100b2114651e04744e9b125006" [[package]] name = "windows_i686_gnu" @@ -889,9 +923,9 @@ checksum = "8e9b5ad5ab802e97eb8e295ac6720e509ee4c243f69d781394014ebfe8bbfa0b" [[package]] name = "windows_i686_gnu" -version = "0.53.0" +version = "0.53.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c1dc67659d35f387f5f6c479dc4e28f1d4bb90ddd1a5d3da2e5d97b42d6272c3" +checksum = "960e6da069d81e09becb0ca57a65220ddff016ff2d6af6a223cf372a506593a3" [[package]] name = "windows_i686_gnullvm" @@ -901,9 +935,9 @@ checksum = "0eee52d38c090b3caa76c563b86c3a4bd71ef1a819287c19d586d7334ae8ed66" [[package]] name = "windows_i686_gnullvm" -version = "0.53.0" +version = "0.53.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9ce6ccbdedbf6d6354471319e781c0dfef054c81fbc7cf83f338a4296c0cae11" +checksum = "fa7359d10048f68ab8b09fa71c3daccfb0e9b559aed648a8f95469c27057180c" [[package]] name = "windows_i686_msvc" @@ -913,9 +947,9 @@ checksum = "240948bc05c5e7c6dabba28bf89d89ffce3e303022809e73deaefe4f6ec56c66" [[package]] name = "windows_i686_msvc" -version = "0.53.0" +version = "0.53.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "581fee95406bb13382d2f65cd4a908ca7b1e4c2f1917f143ba16efe98a589b5d" +checksum = "1e7ac75179f18232fe9c285163565a57ef8d3c89254a30685b57d83a38d326c2" [[package]] name = "windows_x86_64_gnu" @@ -925,9 +959,9 @@ checksum = "147a5c80aabfbf0c7d901cb5895d1de30ef2907eb21fbbab29ca94c5b08b1a78" [[package]] name = "windows_x86_64_gnu" -version = "0.53.0" +version = "0.53.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2e55b5ac9ea33f2fc1716d1742db15574fd6fc8dadc51caab1c16a3d3b4190ba" +checksum = "9c3842cdd74a865a8066ab39c8a7a473c0778a3f29370b5fd6b4b9aa7df4a499" [[package]] name = "windows_x86_64_gnullvm" @@ -937,9 +971,9 @@ checksum = "24d5b23dc417412679681396f2b49f3de8c1473deb516bd34410872eff51ed0d" [[package]] name = "windows_x86_64_gnullvm" -version = "0.53.0" +version = "0.53.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0a6e035dd0599267ce1ee132e51c27dd29437f63325753051e71dd9e42406c57" +checksum = "0ffa179e2d07eee8ad8f57493436566c7cc30ac536a3379fdf008f47f6bb7ae1" [[package]] name = "windows_x86_64_msvc" @@ -949,21 +983,21 @@ checksum = "589f6da84c646204747d1270a2a5661ea66ed1cced2631d546fdfb155959f9ec" [[package]] name = "windows_x86_64_msvc" -version = "0.53.0" +version = "0.53.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "271414315aff87387382ec3d271b52d7ae78726f5d44ac98b4f4030c91880486" +checksum = "d6bbff5f0aada427a1e5a6da5f1f98158182f26556f345ac9e04d36d0ebed650" [[package]] name = "wit-bindgen" -version = "0.45.0" +version = "0.46.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "052283831dbae3d879dc7f51f3d92703a316ca49f91540417d38591826127814" +checksum = "f17a85883d4e6d00e8a97c586de764dabcc06133f7f1d55dce5cdc070ad7fe59" [[package]] name = "yaml-rust2" -version = "0.10.3" +version = "0.10.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4ce2a4ff45552406d02501cea6c18d8a7e50228e7736a872951fe2fe75c91be7" +checksum = "2462ea039c445496d8793d052e13787f2b90e750b833afee748e601c17621ed9" dependencies = [ "arraydeque", "encoding_rs", diff --git a/crates/qmd-syntax-helper/src/conversions/definition_lists.rs b/crates/qmd-syntax-helper/src/conversions/definition_lists.rs index 9124fd6..be74972 100644 --- a/crates/qmd-syntax-helper/src/conversions/definition_lists.rs +++ b/crates/qmd-syntax-helper/src/conversions/definition_lists.rs @@ -56,6 +56,20 @@ impl DefinitionListConverter { start_idx -= 1; } + // Check if the "term" is actually a table row or grid table border + // Table rows contain multiple pipe characters (e.g., | cell | cell |) + // Grid table borders start with + and contain multiple + characters + // This helps distinguish table captions from definition lists + let has_pipes = lines[start_idx].matches('|').count() >= 2; + let is_grid_border = + lines[start_idx].starts_with('+') && lines[start_idx].matches('+').count() >= 2; + + if has_pipes || is_grid_border { + // This is likely a table caption, not a definition list + i += 1; + continue; + } + // Now scan forward to collect all terms and definitions in this list let mut end_idx = i; i += 1; diff --git a/crates/qmd-syntax-helper/src/conversions/div_whitespace.rs b/crates/qmd-syntax-helper/src/conversions/div_whitespace.rs index be2b034..c8119a4 100644 --- a/crates/qmd-syntax-helper/src/conversions/div_whitespace.rs +++ b/crates/qmd-syntax-helper/src/conversions/div_whitespace.rs @@ -14,7 +14,10 @@ impl DivWhitespaceConverter { } /// Parse a file and get diagnostic messages - fn get_parse_errors(&self, file_path: &Path) -> Result> { + fn get_parse_errors( + &self, + file_path: &Path, + ) -> Result> { let content = fs::read_to_string(file_path) .with_context(|| format!("Failed to read file: {}", file_path.display()))?; @@ -39,10 +42,22 @@ impl DivWhitespaceConverter { } /// Find div fence errors that need whitespace fixes - fn find_div_whitespace_errors(&self, content: &str, errors: &[quarto_error_reporting::DiagnosticMessage]) -> Vec { + fn find_div_whitespace_errors( + &self, + content: &str, + errors: &[quarto_error_reporting::DiagnosticMessage], + ) -> Vec { let mut fix_positions = Vec::new(); let lines: Vec<&str> = content.lines().collect(); + // Pre-compute line start offsets for O(1) lookup instead of O(N) per error + let mut line_starts = Vec::with_capacity(lines.len()); + let mut offset = 0; + for line in &lines { + line_starts.push(offset); + offset += line.len() + 1; // +1 for newline + } + for error in errors { // Skip errors that are not about div fences // We're looking for "Missing Space After Div Fence" or errors on lines with ::: @@ -54,7 +69,9 @@ impl DivWhitespaceConverter { // Extract row from location (if available) // SourceInfo uses 0-indexed rows, div_whitespace uses them too - let error_row = error.location.as_ref() + let error_row = error + .location + .as_ref() .map(|loc| loc.range.start.row) .unwrap_or(0); @@ -79,11 +96,8 @@ impl DivWhitespaceConverter { if after_colon.starts_with('{') { // Calculate the position right after ::: // We need byte offset, not char offset - let line_start = content - .lines() - .take(line_idx) - .map(|l| l.len() + 1) // +1 for newline - .sum::(); + // Use pre-computed offset for O(1) lookup + let line_start = line_starts[line_idx]; let indent_bytes = line.len() - trimmed.len(); let fix_pos = line_start + indent_bytes + 3; // +3 for ":::" diff --git a/crates/qmd-syntax-helper/src/main.rs b/crates/qmd-syntax-helper/src/main.rs index dbfceb1..ae7be58 100644 --- a/crates/qmd-syntax-helper/src/main.rs +++ b/crates/qmd-syntax-helper/src/main.rs @@ -85,41 +85,76 @@ fn main() -> Result<()> { output, } => { let file_paths = expand_globs(&files)?; + let total_files_checked = file_paths.len(); let rules = resolve_rules(®istry, &rule_names)?; let mut all_results = Vec::new(); for file_path in file_paths { + // Print filename first in verbose mode if verbose && !json { println!("Checking: {}", file_path.display()); } + // Collect results for this file + let mut file_results = Vec::new(); + for rule in &rules { match rule.check(&file_path, verbose && !json) { Ok(results) => { - for result in results { - all_results.push(result.clone()); - if !json && result.has_issue { + file_results.extend(results); + } + Err(e) => { + if !json { + // For errors, print filename first if not verbose + if !verbose { + println!("{}", file_path.display()); + } + eprintln!(" {} Error checking {}: {}", "✗".red(), rule.name(), e); + } + } + } + } + + // Print results based on mode + if !json { + if verbose { + // Verbose: filename already printed, just print issues + for result in &file_results { + if result.has_issue { + println!( + " {} {}", + "✗".red(), + result.message.as_ref().unwrap_or(&String::new()) + ); + } + } + } else { + // Non-verbose: only print filename if there are issues + let has_issues = file_results.iter().any(|r| r.has_issue); + if has_issues { + println!("{}", file_path.display()); + for result in &file_results { + if result.has_issue { println!( " {} {}", "✗".red(), - result.message.unwrap_or_default() + result.message.as_ref().unwrap_or(&String::new()) ); } } - } - Err(e) => { - if !json { - eprintln!(" {} Error checking {}: {}", "✗".red(), rule.name(), e); - } + println!(); // Blank line between files } } } + + // Add to overall results + all_results.extend(file_results); } // Print summary if not in JSON mode - if !json && !all_results.is_empty() { - print_check_summary(&all_results); + if !json { + print_check_summary(&all_results, total_files_checked); } // Output handling @@ -214,13 +249,9 @@ fn resolve_rules( } } -fn print_check_summary(results: &[rule::CheckResult]) { +fn print_check_summary(results: &[rule::CheckResult], total_files: usize) { use std::collections::{HashMap, HashSet}; - // Get unique files checked - let unique_files: HashSet<&str> = results.iter().map(|r| r.file_path.as_str()).collect(); - let total_files = unique_files.len(); - // Count files with issues (at least one result with has_issue=true) let mut files_with_issues = HashSet::new(); let mut total_issues = 0; diff --git a/crates/qmd-syntax-helper/src/utils/glob_expand.rs b/crates/qmd-syntax-helper/src/utils/glob_expand.rs index 09762f4..7c18c31 100644 --- a/crates/qmd-syntax-helper/src/utils/glob_expand.rs +++ b/crates/qmd-syntax-helper/src/utils/glob_expand.rs @@ -15,14 +15,25 @@ pub fn expand_globs(patterns: &[String]) -> Result> { let paths = glob::glob(pattern) .with_context(|| format!("Invalid glob pattern: {}", pattern))?; + let mut match_count = 0; for path in paths { let path = path.with_context(|| format!("Failed to read glob match for: {}", pattern))?; files.push(path); + match_count += 1; + } + + // Warn if glob matched nothing + if match_count == 0 { + eprintln!("Warning: No files matched pattern: {}", pattern); } } else { - // It's a literal path - use as-is - files.push(PathBuf::from(pattern)); + // It's a literal path - verify it exists + let path = PathBuf::from(pattern); + if !path.exists() { + anyhow::bail!("File not found: {}", pattern); + } + files.push(path); } } @@ -32,19 +43,52 @@ pub fn expand_globs(patterns: &[String]) -> Result> { #[cfg(test)] mod tests { use super::*; + use std::fs::File; + use std::io::Write; #[test] fn test_literal_path() { - let patterns = vec!["test.qmd".to_string()]; + // Create a temporary test file + let test_file = "test-glob-expand.qmd"; + File::create(test_file).unwrap().write_all(b"test").unwrap(); + + let patterns = vec![test_file.to_string()]; let result = expand_globs(&patterns).unwrap(); assert_eq!(result.len(), 1); - assert_eq!(result[0], PathBuf::from("test.qmd")); + assert_eq!(result[0], PathBuf::from(test_file)); + + // Clean up + std::fs::remove_file(test_file).unwrap(); } #[test] fn test_multiple_literals() { - let patterns = vec!["a.qmd".to_string(), "b.qmd".to_string()]; + // Create temporary test files + let test_file_a = "test-a-glob-expand.qmd"; + let test_file_b = "test-b-glob-expand.qmd"; + File::create(test_file_a) + .unwrap() + .write_all(b"test") + .unwrap(); + File::create(test_file_b) + .unwrap() + .write_all(b"test") + .unwrap(); + + let patterns = vec![test_file_a.to_string(), test_file_b.to_string()]; let result = expand_globs(&patterns).unwrap(); assert_eq!(result.len(), 2); + + // Clean up + std::fs::remove_file(test_file_a).unwrap(); + std::fs::remove_file(test_file_b).unwrap(); + } + + #[test] + fn test_nonexistent_file_errors() { + let patterns = vec!["file-that-does-not-exist.qmd".to_string()]; + let result = expand_globs(&patterns); + assert!(result.is_err()); + assert!(result.unwrap_err().to_string().contains("File not found")); } } diff --git a/crates/quarto-error-reporting/src/diagnostic.rs b/crates/quarto-error-reporting/src/diagnostic.rs index 5608f71..ab2b1fd 100644 --- a/crates/quarto-error-reporting/src/diagnostic.rs +++ b/crates/quarto-error-reporting/src/diagnostic.rs @@ -296,17 +296,20 @@ impl DiagnosticMessage { // Check if we have any location info that could be displayed with ariadne // This includes the main diagnostic location OR any detail with a location - let has_any_location = self.location.is_some() - || self.details.iter().any(|d| d.location.is_some()); + let has_any_location = + self.location.is_some() || self.details.iter().any(|d| d.location.is_some()); // If we have location info and source context, render ariadne source display let has_ariadne = if has_any_location && ctx.is_some() { // Use main location if available, otherwise use first detail location - let location = self.location.as_ref() + let location = self + .location + .as_ref() .or_else(|| self.details.iter().find_map(|d| d.location.as_ref())); if let Some(loc) = location { - if let Some(ariadne_output) = self.render_ariadne_source_context(loc, ctx.unwrap()) { + if let Some(ariadne_output) = self.render_ariadne_source_context(loc, ctx.unwrap()) + { result.push_str(&ariadne_output); true } else { @@ -494,14 +497,22 @@ impl DiagnosticMessage { } /// Extract the original file_id from a SourceInfo by traversing the mapping chain - fn extract_file_id(source_info: &quarto_source_map::SourceInfo) -> Option { + fn extract_file_id( + source_info: &quarto_source_map::SourceInfo, + ) -> Option { match &source_info.mapping { quarto_source_map::SourceMapping::Original { file_id } => Some(*file_id), - quarto_source_map::SourceMapping::Substring { parent, .. } => Self::extract_file_id(parent), - quarto_source_map::SourceMapping::Transformed { parent, .. } => Self::extract_file_id(parent), + quarto_source_map::SourceMapping::Substring { parent, .. } => { + Self::extract_file_id(parent) + } + quarto_source_map::SourceMapping::Transformed { parent, .. } => { + Self::extract_file_id(parent) + } quarto_source_map::SourceMapping::Concat { pieces } => { // For concatenated sources, use the first piece's file_id - pieces.first().and_then(|p| Self::extract_file_id(&p.source_info)) + pieces + .first() + .and_then(|p| Self::extract_file_id(&p.source_info)) } } } @@ -545,11 +556,8 @@ impl DiagnosticMessage { }; // Build the report using the mapped offset for proper line:column display - let mut report = Report::build( - report_kind, - file.path.clone(), - start_mapped.location.offset, - ); + let mut report = + Report::build(report_kind, file.path.clone(), start_mapped.location.offset); // Add title with error code if let Some(code) = &self.code { @@ -608,7 +616,10 @@ impl DiagnosticMessage { let report = report.finish(); let mut output = Vec::new(); report - .write((file.path.clone(), Source::from(content.as_str())), &mut output) + .write( + (file.path.clone(), Source::from(content.as_str())), + &mut output, + ) .ok()?; String::from_utf8(output).ok() diff --git a/crates/quarto-markdown-pandoc/src/utils/tree_sitter_log_observer.rs b/crates/quarto-markdown-pandoc/src/utils/tree_sitter_log_observer.rs index 4a2bbc3..e1ae909 100644 --- a/crates/quarto-markdown-pandoc/src/utils/tree_sitter_log_observer.rs +++ b/crates/quarto-markdown-pandoc/src/utils/tree_sitter_log_observer.rs @@ -3,7 +3,7 @@ * Copyright (c) 2025 Posit, PBC */ -use std::collections::HashMap; +use std::collections::HashMap; // Still needed for TreeSitterParseLog::processes #[derive(Debug, PartialEq, Eq, Clone)] pub enum TreeSitterLogState { @@ -82,24 +82,39 @@ impl TreeSitterLogObserver { } pub fn log(&mut self, _log_type: tree_sitter::LogType, message: &str) { // Implement your logging logic here - let str = message.to_string(); - - let words: Vec<&str> = str.split_whitespace().collect(); - if words.len() == 0 { + let words: Vec<&str> = message.split_whitespace().collect(); + if words.is_empty() { eprintln!("Empty log message from tree-sitter"); return; } - let params: HashMap = words[1..] - .iter() - .filter_map(|pair| { - let pair = pair.trim_suffix(","); - let mut split = pair.splitn(2, ':'); - if let (Some(key), Some(value_str)) = (split.next(), split.next()) { - return Some((key.to_string(), value_str.to_string())); + + // Extract parameters directly into typed variables instead of creating a HashMap. + // This eliminates expensive allocations: each HashMap creation costs ~608 bytes + // (HashMap allocation + String allocations for keys and values + hash computations). + // With only 6 possible parameters that are always parsed to the same types, + // we can use simple Option variables on the stack (48 bytes total). + let mut version: Option = None; + let mut state: Option = None; + let mut row: Option = None; + let mut col: Option = None; + let mut sym: Option<&str> = None; + let mut size: Option = None; + + // Single pass through parameters + for pair in &words[1..] { + let pair = pair.trim_end_matches(','); + if let Some((key, value)) = pair.split_once(':') { + match key { + "version" => version = value.parse().ok(), + "state" => state = value.parse().ok(), + "row" => row = value.parse().ok(), + "col" => col = value.parse().ok(), + "sym" => sym = Some(value), + "size" => size = value.parse().ok(), + _ => {} // Ignore unknown parameters } - None - }) - .collect(); + } + } match words[0] { "new_parse" => { if self.state != TreeSitterLogState::Idle { @@ -121,11 +136,7 @@ impl TreeSitterLogObserver { self.state = TreeSitterLogState::Idle; } "resume" => { - let version = params - .get("version") - .expect("Missing 'version' in process log") - .parse::() - .expect("Failed to parse 'version' as usize"); + let version = version.expect("Missing 'version' in process log"); let current_parse = self .parses .last_mut() @@ -133,26 +144,10 @@ impl TreeSitterLogObserver { current_parse.current_process = Some(version); } "process" => { - let version = params - .get("version") - .expect("Missing 'version' in process log") - .parse::() - .expect("Failed to parse 'version' as usize"); - let state = params - .get("state") - .expect("Missing 'state' in process log") - .parse::() - .expect("Failed to parse 'state' as usize"); - let row = params - .get("row") - .expect("Missing 'row' in process log") - .parse::() - .expect("Failed to parse 'row' as usize"); - let column = params - .get("col") - .expect("Missing 'col' in process log") - .parse::() - .expect("Failed to parse 'col' as usize"); + let version = version.expect("Missing 'version' in process log"); + let state = state.expect("Missing 'state' in process log"); + let row = row.expect("Missing 'row' in process log"); + let column = col.expect("Missing 'col' in process log"); let current_parse = self .parses @@ -196,6 +191,9 @@ impl TreeSitterLogObserver { .push(current_process_message.clone()); } "lexed_lookahead" => { + let sym_str = sym.expect("Missing 'sym' in lexed_lookahead log"); + let size_val = size.expect("Missing 'size' in lexed_lookahead log"); + let current_parse = self .parses .last_mut() @@ -208,15 +206,13 @@ impl TreeSitterLogObserver { .current_message .as_mut() .expect("No current process message"); - current_parse.current_lookahead = Some(( - params.get("sym").unwrap().to_string(), - params.get("size").unwrap().parse::().unwrap(), - )); - current_process_message.sym = params.get("sym").unwrap().to_string(); - current_process_message.size = - params.get("size").unwrap().parse::().unwrap(); + current_parse.current_lookahead = Some((sym_str.to_string(), size_val)); + current_process_message.sym = sym_str.to_string(); + current_process_message.size = size_val; } "shift" => { + let state_val = state.expect("Missing 'state' in shift log"); + let current_parse = self .parses .last_mut() @@ -229,18 +225,13 @@ impl TreeSitterLogObserver { .current_message .as_mut() .expect("No current process message"); - let state = params - .get("state") - .expect("Missing 'state' in shift log") - .parse::() - .expect("Failed to parse 'state' as usize"); let size = current_parse .current_lookahead .as_ref() .map(|(_, s)| *s) .unwrap_or(0); current_parse.consumed_tokens.push(ConsumedToken { - lr_state: state, + lr_state: state_val, row: current_process_message.row, column: current_process_message.column, size, @@ -278,11 +269,8 @@ impl TreeSitterLogObserver { } } } - match self.parses.last_mut() { - Some(current_parse) => { - current_parse.messages.push(str); - } - _ => {} + if let Some(current_parse) = self.parses.last_mut() { + current_parse.messages.push(message.to_string()); } } }