diff options
author | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-05-30 18:31:44 +0000 |
---|---|---|
committer | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-05-30 18:31:44 +0000 |
commit | c23a457e72abe608715ac76f076f47dc42af07a5 (patch) | |
tree | 2772049aaf84b5c9d0ed12ec8d86812f7a7904b6 /vendor/gix-config | |
parent | Releasing progress-linux version 1.73.0+dfsg1-1~progress7.99u1. (diff) | |
download | rustc-c23a457e72abe608715ac76f076f47dc42af07a5.tar.xz rustc-c23a457e72abe608715ac76f076f47dc42af07a5.zip |
Merging upstream version 1.74.1+dfsg1.
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'vendor/gix-config')
26 files changed, 1123 insertions, 813 deletions
diff --git a/vendor/gix-config/.cargo-checksum.json b/vendor/gix-config/.cargo-checksum.json index 969bf3652..5980d277e 100644 --- a/vendor/gix-config/.cargo-checksum.json +++ b/vendor/gix-config/.cargo-checksum.json @@ -1 +1 @@ -{"files":{"CHANGELOG.md":"4cedc316d93a26817338d5ebc1e4be5601b54f76fbc04029f50d8804a603c2a6","Cargo.toml":"b305a7d7647e894ae4269c87a2aed9b75b624a71e4bb443852f3ed41311dd5a7","LICENSE-APACHE":"cb4780590812826851ba250f90bed0ed19506ec98f6865a0e2e20bbf62391ff9","LICENSE-MIT":"49df47913ab2beafe8dc45607877ae64198bf0eee64aaad3e82ed9e4d27424e8","README.md":"83f6ef126630abc0e0a5eec8b51c559dbd56211e3a66e3ec021bcea04434f452","src/file/access/comfort.rs":"00a236fcfd4b2b37bf2d4c0763573c13a430564f01af417828d412f4827c0f45","src/file/access/mod.rs":"89141297ba7e1651c60a3637760598f8509fe651a80dc5801aace66bd2c52292","src/file/access/mutate.rs":"7396aa250717bc0a15b9da3701746c3cab0a3c6cb09342922062b26d61b0a1c1","src/file/access/raw.rs":"b19593f0c95f8a28c680592551307a67c36ac82f49b074dae78d23f22d43d8ac","src/file/access/read_only.rs":"218ba05c1f014b4a2a86fcfc6cf4e8e8a34967deded0fa934d07e0119ab496c8","src/file/impls.rs":"c066fdeaeca00a8899704216be060d2b461aa21bd9800883d29e3cc0a59f5fd8","src/file/includes/mod.rs":"f82ed5445391c8442da672b7f8c92f85844ba58d35aa0dfcaf2dfa8c209307d2","src/file/includes/types.rs":"0c1c7c52cee624d840e356f0db0c7791392f89cc6ab0fc7cf074bd05d952c85a","src/file/init/comfort.rs":"6e7a730d7a59dbcc41967b4f962de9b02e69aae7bc4cadf30316bc13eb9eac90","src/file/init/from_env.rs":"db5ec43667e0cd3f35d53e9d2137dbdbcd661fe8e0452c28e91ac8172c1d3af7","src/file/init/from_paths.rs":"ae06b7e488b335b7ac75a4a7a692f172354e1303d94425e7c9713199cc491ad7","src/file/init/mod.rs":"3432a5eac10605c86c6fcff6dab169a8e3ddba8fe8f90603559a9e94f1ac3474","src/file/init/types.rs":"ceeceed969b084123b9c82cbefd0d2b1bae0dcd12714dad1ce99d6ee75866d62","src/file/meta.rs":"02c46267b6088e7d1be3f7402929b3b98cdab71c682e1efae2c0eebd88ac97ad","src/file/mod.rs":"9e3a0a327fab36de1e83fb3d2057b43afa3e83712e00e5ab8c559e72d1d9f375","src/file/mutable/mod.rs":"ac64e210920df986e15ff4136bc7966ba15c2a2dc246fc34320ad2f6fec19ab0","src/file/mutable/multi_value.rs":"b3824387af097c410c8a9627239036e15525af5d4113ebcfbb4c48e6f8591337","src/file/mutable/section.rs":"7ac4774a3115e3446a4eb41170f835e796f561e61c7e16ae9231d0f13441ac0c","src/file/mutable/value.rs":"4211ff648477e37c4f8bcf7fa497233b09a24a8b411e57fc4be441d793377f4d","src/file/section/body.rs":"41b7672cb98abfe5b9787dd84c9af2818d2e02bfe5a5249af610bea2eef5014a","src/file/section/mod.rs":"271f9c58822f9c8e445ad32e6d59b7d12657e7a28069a451930c608f4df697f1","src/file/tests.rs":"cceccb786694f29e858e54a6fdc6769a64ae58989809bdd60e09041156050f1e","src/file/util.rs":"2b9c52b242c45cf7075cddf5383523c095c01ce612b9da139a853039beff6bc8","src/file/write.rs":"63e16eb5324b3482654dce16761a0b894b8bfe370aacefa21b7cd52c8bc3cab5","src/lib.rs":"b0d5ec429067741a1e3b0e5820e24d1af614282f14bd818fe3919acb3239ba44","src/lookup.rs":"205df00cabf25f0fd3709325e75cdc2c1cd2af4ef86bbd15253543a9bb962e62","src/parse/comment.rs":"dfe1ad56385490062792c59b3068552e847b9c55b7a91ee480b7ea6026f12889","src/parse/error.rs":"7e3ce30c7036cb6900be5e751657b879fc8a7dcab760f10ea481d4a57a90b347","src/parse/event.rs":"02110fb38c7f1ea3eff1cecccc6c39f4a60958f18ab6d73220b104c2d6bd7213","src/parse/events.rs":"d2d99a8eedfce801eb0639493d2822480e88cb73d6bfd6510e90535c931d13cf","src/parse/key.rs":"6922c4d0293546bc6b9a97364a6dc97b9cdb0c8ba8ffdc44c059be63ce4c16c7","src/parse/mod.rs":"08e392c9f45e9313ba471e96b20d3c570c15015b2ddc09c9d4f47535b10746a6","src/parse/nom/mod.rs":"b7525ffd344f1e149978822d1cca369186cabc3986be43a54e4336043d0bf8b6","src/parse/nom/tests.rs":"6841d40eb8580a166bd5f3fdcacdcde5702527126e886239847fd29d87df2cf7","src/parse/section/header.rs":"0d7a1a4d892ac5c0abd86c4951f4806f159ea7c37dbe89bfc86b67dfe76014ec","src/parse/section/mod.rs":"5be22e4d120a12a59be38fcb25a95ce7b0e581ded53e99311ffb0f3780ac841a","src/parse/section/unvalidated.rs":"ffbc552e5c6f78fca05ad05f703fef9889777c22facb526ea5fca9c0121ae8c4","src/parse/tests.rs":"911f6972060feb521448f4e6ec9824ff524a9bc51d80fe1460548a6b88036dc4","src/source.rs":"719ed8b2df9079816420a27f3d9ed3cd66f00c1603b1ef76d13145fa93a59928","src/types.rs":"9f4b61b86e1e438cd31518c478b16c9f97f626f1bcea8b93fee7797c82d6be0d","src/value/mod.rs":"1e46a250fc69cecb11d762290fa0c5a2b8f51451541e9e457d0bacafd160e54d","src/value/normalize.rs":"54ca650fdaaf24124df0c6d9137eb90dfda314b28386778970aa25e6b01397f5"},"package":"51f310120ae1ba8f0ca52fb22876ce9bad5b15c8ffb3eb7302e4b64a3b9f681c"}
\ No newline at end of file +{"files":{"CHANGELOG.md":"c7420b36fdb8df169d5602db844ca9ae6e7ccff9ffb5a839c67f7fc237b23409","Cargo.toml":"3a1f6695b5517513fcb28b6c36ee6c3da8515ecd7dd438c0426de7ddd1cd5d5a","LICENSE-APACHE":"cb4780590812826851ba250f90bed0ed19506ec98f6865a0e2e20bbf62391ff9","LICENSE-MIT":"49df47913ab2beafe8dc45607877ae64198bf0eee64aaad3e82ed9e4d27424e8","README.md":"e57a2cbe8b6bbe265bb59ac9c27fe3cbe97b325d7bce60f25654bda3fa7686f4","src/file/access/comfort.rs":"35cc4a95b75bf2a9eee0658d92a2f9ed1aa435f9789924ac935e45787d9ca804","src/file/access/mod.rs":"89141297ba7e1651c60a3637760598f8509fe651a80dc5801aace66bd2c52292","src/file/access/mutate.rs":"7bfade3b76dcd41f52ef15cdd39aa0ee3b2faa7d299b60eeb1f59ecd25cd2138","src/file/access/raw.rs":"7efa0a466a682fea7e34e8eba59c5faa2f3b4d74c0323876d71676d1639f3566","src/file/access/read_only.rs":"e525277fb12e0d8487c18d9df54d3ec0a473844ef5505f3e217c19c6b9a13af8","src/file/impls.rs":"c066fdeaeca00a8899704216be060d2b461aa21bd9800883d29e3cc0a59f5fd8","src/file/includes/mod.rs":"f82ed5445391c8442da672b7f8c92f85844ba58d35aa0dfcaf2dfa8c209307d2","src/file/includes/types.rs":"0c1c7c52cee624d840e356f0db0c7791392f89cc6ab0fc7cf074bd05d952c85a","src/file/init/comfort.rs":"f53191855e04022bd1ee54dae89bd51866ebfd7c17518f2ace576d7f8dd1cf0e","src/file/init/from_env.rs":"97f976c4114d9bb6654ffd744b3e7be827134274affe5e902026730bc4e5e8f5","src/file/init/from_paths.rs":"af6d2aefb7abe28393982c4899379a8878cf277e510bf97fa9319034518ea29a","src/file/init/mod.rs":"3432a5eac10605c86c6fcff6dab169a8e3ddba8fe8f90603559a9e94f1ac3474","src/file/init/types.rs":"ceeceed969b084123b9c82cbefd0d2b1bae0dcd12714dad1ce99d6ee75866d62","src/file/meta.rs":"02c46267b6088e7d1be3f7402929b3b98cdab71c682e1efae2c0eebd88ac97ad","src/file/mod.rs":"161fa786ead8ca043467fd5c7714db6ecb277b09f9a0e6034c5427bc6ccc8650","src/file/mutable/mod.rs":"cd2a5d54b9d8f45c01a1938fdc8d48f5416b3ce9c80923ce53fd57d897c0c627","src/file/mutable/multi_value.rs":"b3824387af097c410c8a9627239036e15525af5d4113ebcfbb4c48e6f8591337","src/file/mutable/section.rs":"2fcf2a642d1ebc14292484748e967f0a9de0cc8bb45518a36e951575973c53cc","src/file/mutable/value.rs":"4211ff648477e37c4f8bcf7fa497233b09a24a8b411e57fc4be441d793377f4d","src/file/section/body.rs":"475982db8cc36f9e265e7302f8e21c39dcd145644fd8b4961a93a68cd98ed382","src/file/section/mod.rs":"f86284e584e0f945c7d3b75b76a64ad8e7deb62917edd77cab624c2c01fda326","src/file/tests.rs":"cceccb786694f29e858e54a6fdc6769a64ae58989809bdd60e09041156050f1e","src/file/util.rs":"2b9c52b242c45cf7075cddf5383523c095c01ce612b9da139a853039beff6bc8","src/file/write.rs":"8a2ee27cdcbc487575f0839a4d30d62c56bbf60eb26aaca427343482b3b480cf","src/lib.rs":"3067b8d857e4ba7db9c4d620bc6f166119ae15f884606b20885a568361e927f9","src/lookup.rs":"205df00cabf25f0fd3709325e75cdc2c1cd2af4ef86bbd15253543a9bb962e62","src/parse/comment.rs":"dfe1ad56385490062792c59b3068552e847b9c55b7a91ee480b7ea6026f12889","src/parse/error.rs":"7e3ce30c7036cb6900be5e751657b879fc8a7dcab760f10ea481d4a57a90b347","src/parse/event.rs":"1130a828c5b7cad96074c9359d42d7327c5c6b8c7eceadacca8f667c36d0d9b1","src/parse/events.rs":"7e5f5010425838bde9f773bb5051c9851276b71471ded47d1abaedd3af0a82f6","src/parse/key.rs":"d9e9bf4249bdf1563613c0994888caac5824c8e9e1fa87e5deeb28e84a52c5ad","src/parse/mod.rs":"ca9469b95273ccdd8f7a21da73f2833e8f56d0b6f4c7e358eca745bb7942c9fd","src/parse/nom/mod.rs":"0e0f4d795e937dec90f4c660d2d3ffc53195ea5cc019dfe1bf094d8f784ac3a2","src/parse/nom/tests.rs":"9e4edcc7b9f5a3ba2e0a3f24f97bf0f8d5b611ff767edc640a6d49b68eb04876","src/parse/section/header.rs":"449c37a084752d32a37d14d47e996d21b614f0f5f14047747cd5947a08b810d1","src/parse/section/mod.rs":"5be22e4d120a12a59be38fcb25a95ce7b0e581ded53e99311ffb0f3780ac841a","src/parse/section/unvalidated.rs":"ffbc552e5c6f78fca05ad05f703fef9889777c22facb526ea5fca9c0121ae8c4","src/parse/tests.rs":"911f6972060feb521448f4e6ec9824ff524a9bc51d80fe1460548a6b88036dc4","src/source.rs":"719ed8b2df9079816420a27f3d9ed3cd66f00c1603b1ef76d13145fa93a59928","src/types.rs":"7a05db6b5fd1c43a0a908f223bdb301c16406dbd20bc3a165205244df3933296","src/value/mod.rs":"1e46a250fc69cecb11d762290fa0c5a2b8f51451541e9e457d0bacafd160e54d","src/value/normalize.rs":"54ca650fdaaf24124df0c6d9137eb90dfda314b28386778970aa25e6b01397f5"},"package":"c171514b40487d3f677ae37efc0f45ac980e3169f23c27eb30a70b47fdf88ab5"}
\ No newline at end of file diff --git a/vendor/gix-config/CHANGELOG.md b/vendor/gix-config/CHANGELOG.md index d6439d26c..a26ae116b 100644 --- a/vendor/gix-config/CHANGELOG.md +++ b/vendor/gix-config/CHANGELOG.md @@ -5,6 +5,357 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). +## 0.30.0 (2023-09-24) + +<csr-id-db0c4017142fd25d26d1c6860972b1ac84b24a6e/> + +### Chore + + - <csr-id-db0c4017142fd25d26d1c6860972b1ac84b24a6e/> add more test cases to pin behaviour around string and path handling. + This is important to know how to consistently handle empty strings - should they + not be present? Or should they be flagged as error? + + The answer here is that the caller has to deal with it, as we report these values + if they are present which only requires an equals sign. + +### Commit Statistics + +<csr-read-only-do-not-edit/> + + - 3 commits contributed to the release over the course of 15 calendar days. + - 16 days passed between releases. + - 1 commit was understood as [conventional](https://www.conventionalcommits.org). + - 0 issues like '(#ID)' were seen in commit messages + +### Commit Details + +<csr-read-only-do-not-edit/> + +<details><summary>view details</summary> + + * **Uncategorized** + - Prepare changelogs prior to release ([`8a60d5b`](https://github.com/Byron/gitoxide/commit/8a60d5b80877c213c3b646d3061e8a33e0e433ec)) + - Merge branch 'path-config' ([`9c528dc`](https://github.com/Byron/gitoxide/commit/9c528dc8282c8b2f3a023e523dccdd0f7a711e61)) + - Add more test cases to pin behaviour around string and path handling. ([`db0c401`](https://github.com/Byron/gitoxide/commit/db0c4017142fd25d26d1c6860972b1ac84b24a6e)) +</details> + +## 0.29.0 (2023-09-08) + +### New Features + + - <csr-id-2b8d09f785f471aa12fc6793f0ea40c1f8d9ea4a/> remove `log` dependency in favor of `gix-trace` + +### Bug Fixes (BREAKING) + + - <csr-id-072ee32f693a31161cd6a843da6582d13efbb20b/> use `dyn` trait where possible. + This reduces compile time due to avoiding duplication. + +### Commit Statistics + +<csr-read-only-do-not-edit/> + + - 9 commits contributed to the release over the course of 17 calendar days. + - 17 days passed between releases. + - 2 commits were understood as [conventional](https://www.conventionalcommits.org). + - 0 issues like '(#ID)' were seen in commit messages + +### Thanks Clippy + +<csr-read-only-do-not-edit/> + +[Clippy](https://github.com/rust-lang/rust-clippy) helped 1 time to make code idiomatic. + +### Commit Details + +<csr-read-only-do-not-edit/> + +<details><summary>view details</summary> + + * **Uncategorized** + - Release gix-date v0.8.0, gix-hash v0.13.0, gix-features v0.34.0, gix-actor v0.26.0, gix-object v0.36.0, gix-path v0.10.0, gix-glob v0.12.0, gix-attributes v0.18.0, gix-packetline-blocking v0.16.6, gix-filter v0.4.0, gix-fs v0.6.0, gix-commitgraph v0.20.0, gix-hashtable v0.4.0, gix-revwalk v0.7.0, gix-traverse v0.32.0, gix-worktree-stream v0.4.0, gix-archive v0.4.0, gix-config-value v0.14.0, gix-tempfile v9.0.0, gix-lock v9.0.0, gix-ref v0.36.0, gix-sec v0.10.0, gix-config v0.29.0, gix-prompt v0.7.0, gix-url v0.23.0, gix-credentials v0.19.0, gix-diff v0.35.0, gix-discover v0.24.0, gix-ignore v0.7.0, gix-index v0.24.0, gix-macros v0.1.0, gix-mailmap v0.18.0, gix-negotiate v0.7.0, gix-pack v0.42.0, gix-odb v0.52.0, gix-pathspec v0.2.0, gix-packetline v0.16.6, gix-transport v0.36.0, gix-protocol v0.39.0, gix-revision v0.21.0, gix-refspec v0.17.0, gix-submodule v0.3.0, gix-worktree v0.25.0, gix-worktree-state v0.2.0, gix v0.53.0, safety bump 39 crates ([`8bd0456`](https://github.com/Byron/gitoxide/commit/8bd045676bb2cdc02624ab93e73ff8518064ca38)) + - Prepare changelogs for release ([`375db06`](https://github.com/Byron/gitoxide/commit/375db06a8442378c3f7a922fae38e2a6694d9d04)) + - Merge branch 'optimizations' ([`6135a5e`](https://github.com/Byron/gitoxide/commit/6135a5ea8709646f01da62939a59dd3a9750e007)) + - Optimize internal `gix` usage for faster compile time ([`9d33e2f`](https://github.com/Byron/gitoxide/commit/9d33e2f5c6a1c370654ef0db90b29c0a023dcf3d)) + - Remove `log` dependency in favor of `gix-trace` ([`2b8d09f`](https://github.com/Byron/gitoxide/commit/2b8d09f785f471aa12fc6793f0ea40c1f8d9ea4a)) + - Merge branch `dyn`ification ([`f658fcc`](https://github.com/Byron/gitoxide/commit/f658fcc52dc2200ae34ca53dc10be97fb9012057)) + - Use `dyn` trait where possible. ([`072ee32`](https://github.com/Byron/gitoxide/commit/072ee32f693a31161cd6a843da6582d13efbb20b)) + - Thanks clippy ([`5044c3b`](https://github.com/Byron/gitoxide/commit/5044c3b87456cf58ebfbbd00f23c9ba671cb290c)) + - Merge branch 'gix-submodule' ([`363ee77`](https://github.com/Byron/gitoxide/commit/363ee77400805f473c9ad66eadad9214e7ab66f4)) +</details> + +## 0.28.0 (2023-08-22) + +<csr-id-ef54aab9e5521add4154ee8d902d62612a9d8d4a/> + +### Chore + + - <csr-id-ef54aab9e5521add4154ee8d902d62612a9d8d4a/> switch `nom` to `winnow` in remaining uses in `gix-object`, `gix-ref`, and `gix-actor` for ~20% more performance. + It's likely that over time, these parsers will get even faster due to improvements to `winnow`. + Thanks, Ed Page, for single-handedly performing this transition. + +### Bug Fixes + + - <csr-id-c51c8daee1ab54130ae3ed83ce67d08f01c4881a/> fix incorrect s/git-config/gix-config/ + 3a861c8f049f6502d3bcbdac752659aa1aeda46a just blindly replaced any + occurence of "git-config" or "git_config" with "gix-config"/"gix_config". + + There is no such thing as a gix-config file. + gix-config is a git-config file parser. + - <csr-id-66dadf807f41aa9e828639c52a7d220bf4f3df72/> regression that could cause non-linear parsing behaviour. + +### Commit Statistics + +<csr-read-only-do-not-edit/> + + - 17 commits contributed to the release over the course of 4 calendar days. + - 15 days passed between releases. + - 3 commits were understood as [conventional](https://www.conventionalcommits.org). + - 0 issues like '(#ID)' were seen in commit messages + +### Commit Details + +<csr-read-only-do-not-edit/> + +<details><summary>view details</summary> + + * **Uncategorized** + - Release gix-date v0.7.3, gix-hash v0.12.0, gix-features v0.33.0, gix-actor v0.25.0, gix-object v0.35.0, gix-path v0.9.0, gix-glob v0.11.0, gix-quote v0.4.7, gix-attributes v0.17.0, gix-command v0.2.9, gix-packetline-blocking v0.16.5, gix-filter v0.3.0, gix-fs v0.5.0, gix-commitgraph v0.19.0, gix-hashtable v0.3.0, gix-revwalk v0.6.0, gix-traverse v0.31.0, gix-worktree-stream v0.3.0, gix-archive v0.3.0, gix-config-value v0.13.0, gix-tempfile v8.0.0, gix-lock v8.0.0, gix-ref v0.35.0, gix-sec v0.9.0, gix-config v0.28.0, gix-prompt v0.6.0, gix-url v0.22.0, gix-credentials v0.18.0, gix-diff v0.34.0, gix-discover v0.23.0, gix-ignore v0.6.0, gix-bitmap v0.2.7, gix-index v0.22.0, gix-mailmap v0.17.0, gix-negotiate v0.6.0, gix-pack v0.41.0, gix-odb v0.51.0, gix-pathspec v0.1.0, gix-packetline v0.16.5, gix-transport v0.35.0, gix-protocol v0.38.0, gix-revision v0.20.0, gix-refspec v0.16.0, gix-submodule v0.2.0, gix-worktree v0.24.0, gix-worktree-state v0.1.0, gix v0.52.0, gitoxide-core v0.31.0, gitoxide v0.29.0, safety bump 41 crates ([`30b2761`](https://github.com/Byron/gitoxide/commit/30b27615047692d3ced1b2d9c2ac15a80f79fbee)) + - Update changelogs prior to release ([`f23ea88`](https://github.com/Byron/gitoxide/commit/f23ea8828f2d9ba7559973daca388c9591bcc5fc)) + - Merge branch 'gix-submodule' ([`8f3f358`](https://github.com/Byron/gitoxide/commit/8f3f358800f1fe77d7ba7ebd396a90b692d3c0c1)) + - More cleanup of test crates ([`73c685a`](https://github.com/Byron/gitoxide/commit/73c685a67debcfa26a940f37bbca69cb3a4af57e)) + - Just fmt ([`0d258f4`](https://github.com/Byron/gitoxide/commit/0d258f40afcd848509e2b0c7c264e9f346ed1726)) + - Switch `nom` to `winnow` in remaining uses in `gix-object`, `gix-ref`, and `gix-actor` for ~20% more performance. ([`ef54aab`](https://github.com/Byron/gitoxide/commit/ef54aab9e5521add4154ee8d902d62612a9d8d4a)) + - Upgrade `winnow` to latest patch release ([`8c41848`](https://github.com/Byron/gitoxide/commit/8c4184817e4e4364c34badc8ff0a71c6ae952efd)) + - Merge pull request #988 from not-my-profile/fix-gix-config-sub ([`7735047`](https://github.com/Byron/gitoxide/commit/7735047198bd7cc5059ca338f5c2147dd273f711)) + - Fix incorrect s/git-config/gix-config/ ([`c51c8da`](https://github.com/Byron/gitoxide/commit/c51c8daee1ab54130ae3ed83ce67d08f01c4881a)) + - Regression that could cause non-linear parsing behaviour. ([`66dadf8`](https://github.com/Byron/gitoxide/commit/66dadf807f41aa9e828639c52a7d220bf4f3df72)) + - Further clarify the expectation after changing is_err() assertion to is_ok() ([`a743c5d`](https://github.com/Byron/gitoxide/commit/a743c5d9828d8d3cf621b0f89d5b61083cf8ff04)) + - Propogate value errors to user ([`0f9af3f`](https://github.com/Byron/gitoxide/commit/0f9af3fc904315fae61cfc2900a3f456ec81ffc2)) + - Improve config performance on degenerate cases ([`5366f79`](https://github.com/Byron/gitoxide/commit/5366f79ff67bcef506d25c3ac0f4b53c8d822e82)) + - Improve inner loop of config value parsing ([`e208362`](https://github.com/Byron/gitoxide/commit/e20836267101a3142e79ce89e5666f006503596f)) + - Upgrade to Winnow 0.5 ([`3f8c91f`](https://github.com/Byron/gitoxide/commit/3f8c91fa463fbb53d54b2bf359e0dee7387afa00)) + - Switch gix to winnow 0.3 ([`ee75de1`](https://github.com/Byron/gitoxide/commit/ee75de1e6035305fc23bdef2522ae5081272ac82)) + - Add fuzz-issue for reproduction ([`510192e`](https://github.com/Byron/gitoxide/commit/510192e0e5750bdfe461d701b3e124c03f22b7d9)) +</details> + +## 0.27.0 (2023-08-07) + +### Bug Fixes (BREAKING) + + - <csr-id-d091c78aa863180ea304cd4e0b60a2193a82a546/> `File::push_section()` is now infallible. + Previously it used a `Result` even though it couldn't fail anywhere. + +### Commit Statistics + +<csr-read-only-do-not-edit/> + + - 6 commits contributed to the release over the course of 3 calendar days. + - 4 days passed between releases. + - 1 commit was understood as [conventional](https://www.conventionalcommits.org). + - 0 issues like '(#ID)' were seen in commit messages + +### Commit Details + +<csr-read-only-do-not-edit/> + +<details><summary>view details</summary> + + * **Uncategorized** + - Release gix-glob v0.10.2, gix-date v0.7.2, gix-validate v0.8.0, gix-object v0.34.0, gix-ref v0.34.0, gix-config v0.27.0, gix-commitgraph v0.18.2, gix-revwalk v0.5.0, gix-revision v0.19.0, gix-refspec v0.15.0, gix-submodule v0.1.0, safety bump 18 crates ([`4604f83`](https://github.com/Byron/gitoxide/commit/4604f83ef238dc07c85aaeae097399b67f3cfd0c)) + - Prepare changelogs prior to release of `gix-submodule` ([`f3c4311`](https://github.com/Byron/gitoxide/commit/f3c43110e8d5f16cf87e50821044d8b3edbae235)) + - Merge branch 'submodules' ([`b629f8a`](https://github.com/Byron/gitoxide/commit/b629f8a774931d58c0a9b124fa75f85807c6c5d1)) + - `File::push_section()` is now infallible. ([`d091c78`](https://github.com/Byron/gitoxide/commit/d091c78aa863180ea304cd4e0b60a2193a82a546)) + - Merge branch 'dev-on-linux' ([`6b4a303`](https://github.com/Byron/gitoxide/commit/6b4a30330fe49fc97daa73f55bf56580cc0597aa)) + - Fix various tests to run properly on linux ([`ef8ccd9`](https://github.com/Byron/gitoxide/commit/ef8ccd9d16143d37155d063747c69cade80f162d)) +</details> + +## 0.26.2 (2023-08-02) + +The parsing switches from `nom` to `winnow`, which eases maintenance and improves performances. + +### Commit Statistics + +<csr-read-only-do-not-edit/> + + - 28 commits contributed to the release over the course of 7 calendar days. + - 10 days passed between releases. + - 0 commits were understood as [conventional](https://www.conventionalcommits.org). + - 0 issues like '(#ID)' were seen in commit messages + +### Commit Details + +<csr-read-only-do-not-edit/> + +<details><summary>view details</summary> + + * **Uncategorized** + - Release gix-actor v0.24.2, gix-object v0.33.2, gix-ref v0.33.3, gix-config v0.26.2, gix-prompt v0.5.5, gix-odb v0.50.2, gix-transport v0.34.2, gix-protocol v0.37.0, gix-worktree v0.23.1, gix v0.51.0, safety bump 3 crates ([`231ac1c`](https://github.com/Byron/gitoxide/commit/231ac1c6ad5ca9a84dbeb0dee14bfbf2fef1ae1e)) + - Prepare additional changelogs ([`db63815`](https://github.com/Byron/gitoxide/commit/db6381522395a0de047118e81df5cd3cbeb862b9)) + - Prepare changelogs ([`e4d2890`](https://github.com/Byron/gitoxide/commit/e4d2890a85bf60e9cdb4016dddfab3c4dccbe75e)) + - Merge branch 'config' ([`daf3389`](https://github.com/Byron/gitoxide/commit/daf338989e7d75d41efb1345ed95ee2a13c97007)) + - Minor refactor ([`224121b`](https://github.com/Byron/gitoxide/commit/224121b036a48c18ad859600ea9315d55150c0dd)) + - Make clippy happy ([`1a1e2f5`](https://github.com/Byron/gitoxide/commit/1a1e2f5efa7719908bb612e0534379e522b740bb)) + - Pull newline counting out of inner loop ([`beac408`](https://github.com/Byron/gitoxide/commit/beac4083447e836d139bd4d092596fbc636a40a2)) + - Remove value_impl's explicit start index tracking ([`63552ee`](https://github.com/Byron/gitoxide/commit/63552eea5377f5bd4672f1783dd7b36886698e62)) + - Remove value_impl's explicit end index tracking ([`8db009c`](https://github.com/Byron/gitoxide/commit/8db009ca9a19bebccaeacb5f992d05d89893b57b)) + - Upgrade to winnow 0.5 ([`fe997c8`](https://github.com/Byron/gitoxide/commit/fe997c8a32b0a1dc3ad3613fe8dd48a987c3a5bf)) + - Remove error creation shorthand ([`8581d25`](https://github.com/Byron/gitoxide/commit/8581d25dc9208bb7e32104c0320a5334572d7404)) + - Simplify value_impl escape parsing ([`9e6ba0f`](https://github.com/Byron/gitoxide/commit/9e6ba0f6f7064f7ee28ef4f3fab492e5294e54a6)) + - Clarify value_impl index handling ([`b790948`](https://github.com/Byron/gitoxide/commit/b790948da0499ee776e23ca359d08347b97cabab)) + - Flatten value_impl ([`5fc1096`](https://github.com/Byron/gitoxide/commit/5fc109633b7c9736323084beaa0e97ce5ef1e08b)) + - Normalize parser lifetimes ([`083efbc`](https://github.com/Byron/gitoxide/commit/083efbc0b37b45401663074964e3f911400a065e)) + - Simplify section ([`5f2b68e`](https://github.com/Byron/gitoxide/commit/5f2b68ec6743cbca3472d2935e5445e897fa5218)) + - Simplify section_header ([`0fe3854`](https://github.com/Byron/gitoxide/commit/0fe385484da0d999115cc760fd4b0353e5a31ff6)) + - Simplify sub_section parsing ([`d2e06c8`](https://github.com/Byron/gitoxide/commit/d2e06c878c2b7270a936ac225aa93e207355e86c)) + - Simplify simpler parsers ([`edb4e04`](https://github.com/Byron/gitoxide/commit/edb4e048ba973b2c0a4410d62cc3e5723ec64597)) + - Simplify error creation ([`bdcd379`](https://github.com/Byron/gitoxide/commit/bdcd379da821cd232cf8844d104d06901d8da450)) + - Prepare for winnow 0.5 upgrade ([`42ae766`](https://github.com/Byron/gitoxide/commit/42ae76691eab6b5ca77354a3358e0f95b8694d34)) + - Move off deprecated parsers ([`b0287a8`](https://github.com/Byron/gitoxide/commit/b0287a8ba8a5024350dd48e37f6fc626003382cb)) + - Upgrade to winnow 0.4 ([`a639994`](https://github.com/Byron/gitoxide/commit/a6399948f37d5c39f15340f26acb08bb36ae247f)) + - Prepare for winnow 0.4 upgrade ([`cfc642a`](https://github.com/Byron/gitoxide/commit/cfc642a0d1ddee4c1f38758af269bc43496ffbf1)) + - Move off of remaining deprecated parsers ([`18bee03`](https://github.com/Byron/gitoxide/commit/18bee03bf3a1ad4c0800ece97414553e3a6a50cb)) + - Switch to Parser inherent parsers ([`6ac1b37`](https://github.com/Byron/gitoxide/commit/6ac1b377a0d0c1b0ddabc13f3dbe5db3716a4234)) + - Switch to type-native winnow parsers ([`5b3ae94`](https://github.com/Byron/gitoxide/commit/5b3ae94503151d33e1bae60dd82fc32bad7154b0)) + - Switch gix-config to winnow 0.3 ([`3d9ae21`](https://github.com/Byron/gitoxide/commit/3d9ae21f97e50129576473a2682a10b793b356de)) +</details> + +## 0.26.1 (2023-07-22) + +A maintenance release without user-facing changes. + +### Commit Statistics + +<csr-read-only-do-not-edit/> + + - 2 commits contributed to the release. + - 3 days passed between releases. + - 0 commits were understood as [conventional](https://www.conventionalcommits.org). + - 0 issues like '(#ID)' were seen in commit messages + +### Commit Details + +<csr-read-only-do-not-edit/> + +<details><summary>view details</summary> + + * **Uncategorized** + - Release gix-config v0.26.1, gix v0.50.0 ([`d34a4ea`](https://github.com/Byron/gitoxide/commit/d34a4ea27cd83b916c84cf15e1c05da35576db5e)) + - Fix gix-config dependency versions ([`dbeb68d`](https://github.com/Byron/gitoxide/commit/dbeb68da2348bf555cc959fc60d255da9f50eda5)) +</details> + +## 0.26.0 (2023-07-19) + +A maintenance release without user-facing changes. + +### Commit Statistics + +<csr-read-only-do-not-edit/> + + - 4 commits contributed to the release over the course of 4 calendar days. + - 19 days passed between releases. + - 0 commits were understood as [conventional](https://www.conventionalcommits.org). + - 0 issues like '(#ID)' were seen in commit messages + +### Thanks Clippy + +<csr-read-only-do-not-edit/> + +[Clippy](https://github.com/rust-lang/rust-clippy) helped 1 time to make code idiomatic. + +### Commit Details + +<csr-read-only-do-not-edit/> + +<details><summary>view details</summary> + + * **Uncategorized** + - Release gix-features v0.32.0, gix-actor v0.24.0, gix-glob v0.10.0, gix-attributes v0.15.0, gix-commitgraph v0.18.0, gix-config-value v0.12.4, gix-fs v0.4.0, gix-object v0.33.0, gix-ref v0.33.0, gix-config v0.26.0, gix-command v0.2.7, gix-url v0.21.0, gix-credentials v0.17.0, gix-diff v0.33.0, gix-discover v0.22.0, gix-filter v0.1.0, gix-ignore v0.5.0, gix-revwalk v0.4.0, gix-traverse v0.30.0, gix-index v0.21.0, gix-mailmap v0.16.0, gix-negotiate v0.5.0, gix-pack v0.40.0, gix-odb v0.50.0, gix-transport v0.34.0, gix-protocol v0.36.0, gix-revision v0.18.0, gix-refspec v0.14.0, gix-worktree v0.22.0, gix v0.49.0 ([`68ae3ff`](https://github.com/Byron/gitoxide/commit/68ae3ff9d642ec56f088a6a682a073dc16f4e8ca)) + - Adjust package versions (by cargo-smart-release) ([`c70e54f`](https://github.com/Byron/gitoxide/commit/c70e54f163c312c87753a506eeaad462e8579bfb)) + - Prepare changelogs prior to release ([`e4dded0`](https://github.com/Byron/gitoxide/commit/e4dded05138562f9737a7dcfb60570c55769486d)) + - Thanks clippy ([`3ef32af`](https://github.com/Byron/gitoxide/commit/3ef32af9bf477cbc60d24da8bb3f15d20976e9e0)) +</details> + +## 0.25.1 (2023-06-29) + +A maintenance release without user-facing changes. + +### Commit Statistics + +<csr-read-only-do-not-edit/> + + - 3 commits contributed to the release. + - 0 commits were understood as [conventional](https://www.conventionalcommits.org). + - 0 issues like '(#ID)' were seen in commit messages + +### Commit Details + +<csr-read-only-do-not-edit/> + +<details><summary>view details</summary> + + * **Uncategorized** + - Release gix-glob v0.9.1, gix-attributes v0.14.1, gix-config-value v0.12.3, gix-ref v0.32.1, gix-sec v0.8.3, gix-config v0.25.1, gix-url v0.20.1, gix-credentials v0.16.1, gix-discover v0.21.1, gix-ignore v0.4.1, gix-pack v0.39.1, gix-odb v0.49.1, gix-worktree v0.21.1, gix v0.48.0 ([`69c6a36`](https://github.com/Byron/gitoxide/commit/69c6a36ba14cbef129deebda9fd8870005fefa17)) + - Prepare changelogs prior to release ([`c143cf4`](https://github.com/Byron/gitoxide/commit/c143cf48ee1885467e3e9262a3f8823a1247bfe0)) + - Align usage of `gix-path` across all crates ([`73c1292`](https://github.com/Byron/gitoxide/commit/73c1292be393986c4a1adde1400abf551e850da0)) +</details> + +## 0.25.0 (2023-06-29) + +A maintenance release without user-facing changes. + +### Commit Statistics + +<csr-read-only-do-not-edit/> + + - 3 commits contributed to the release over the course of 6 calendar days. + - 6 days passed between releases. + - 0 commits were understood as [conventional](https://www.conventionalcommits.org). + - 0 issues like '(#ID)' were seen in commit messages + +### Commit Details + +<csr-read-only-do-not-edit/> + +<details><summary>view details</summary> + + * **Uncategorized** + - Release gix-date v0.7.0, gix-trace v0.1.2, gix-actor v0.23.0, gix-commitgraph v0.17.1, gix-utils v0.1.4, gix-object v0.32.0, gix-ref v0.32.0, gix-config v0.25.0, gix-diff v0.32.0, gix-discover v0.21.0, gix-hashtable v0.2.3, gix-revwalk v0.3.0, gix-traverse v0.29.0, gix-index v0.20.0, gix-mailmap v0.15.0, gix-negotiate v0.4.0, gix-pack v0.39.0, gix-odb v0.49.0, gix-protocol v0.35.0, gix-revision v0.17.0, gix-refspec v0.13.0, gix-worktree v0.21.0, gix v0.48.0, safety bump 20 crates ([`27e8c18`](https://github.com/Byron/gitoxide/commit/27e8c18db5a9a21843381c116a8ed6d9f681b3f8)) + - Prepare changelogs prior to release ([`00f96fb`](https://github.com/Byron/gitoxide/commit/00f96fb3110a8f81a1bd0d74c757c15b8773c6f6)) + - Upgrade criterion ([`285ce12`](https://github.com/Byron/gitoxide/commit/285ce12c5564db3917923791729641383789fe89)) +</details> + +## 0.24.0 (2023-06-22) + +<csr-id-bcad5c22049d56a25ef69d6c7a3344e78f9a1d4d/> + +### Chore + + - <csr-id-bcad5c22049d56a25ef69d6c7a3344e78f9a1d4d/> Add `clippy::redundant-closure-for-method-calls` lint + +### Commit Statistics + +<csr-read-only-do-not-edit/> + + - 6 commits contributed to the release over the course of 10 calendar days. + - 15 days passed between releases. + - 1 commit was understood as [conventional](https://www.conventionalcommits.org). + - 0 issues like '(#ID)' were seen in commit messages + +### Commit Details + +<csr-read-only-do-not-edit/> + +<details><summary>view details</summary> + + * **Uncategorized** + - Release gix-date v0.6.0, gix-hash v0.11.3, gix-trace v0.1.1, gix-features v0.31.0, gix-actor v0.22.0, gix-path v0.8.2, gix-glob v0.9.0, gix-quote v0.4.5, gix-attributes v0.14.0, gix-chunk v0.4.3, gix-commitgraph v0.17.0, gix-config-value v0.12.2, gix-fs v0.3.0, gix-tempfile v7.0.0, gix-utils v0.1.3, gix-lock v7.0.0, gix-validate v0.7.6, gix-object v0.31.0, gix-ref v0.31.0, gix-sec v0.8.2, gix-config v0.24.0, gix-command v0.2.6, gix-prompt v0.5.2, gix-url v0.20.0, gix-credentials v0.16.0, gix-diff v0.31.0, gix-discover v0.20.0, gix-hashtable v0.2.2, gix-ignore v0.4.0, gix-bitmap v0.2.5, gix-revwalk v0.2.0, gix-traverse v0.28.0, gix-index v0.19.0, gix-mailmap v0.14.0, gix-negotiate v0.3.0, gix-pack v0.38.0, gix-odb v0.48.0, gix-packetline v0.16.3, gix-transport v0.33.0, gix-protocol v0.34.0, gix-revision v0.16.0, gix-refspec v0.12.0, gix-worktree v0.20.0, gix v0.47.0, gitoxide-core v0.29.0, gitoxide v0.27.0, safety bump 30 crates ([`ea9f942`](https://github.com/Byron/gitoxide/commit/ea9f9424e777f10da0e33bb9ffbbefd01c4c5a74)) + - Prepare changelogs prior to release ([`18b0a37`](https://github.com/Byron/gitoxide/commit/18b0a371941aa2d4d62512437d5daa351ba99ffd)) + - Merge branch 'corpus' ([`aa16c8c`](https://github.com/Byron/gitoxide/commit/aa16c8ce91452a3e3063cf1cf0240b6014c4743f)) + - Change MSRV to 1.65 ([`4f635fc`](https://github.com/Byron/gitoxide/commit/4f635fc4429350bae2582d25de86429969d28f30)) + - Merge branch 'help-874-redundant-closures' ([`fe59956`](https://github.com/Byron/gitoxide/commit/fe59956ad667303a923d7cfd9ffd72283df41d78)) + - Add `clippy::redundant-closure-for-method-calls` lint ([`bcad5c2`](https://github.com/Byron/gitoxide/commit/bcad5c22049d56a25ef69d6c7a3344e78f9a1d4d)) +</details> + ## 0.23.0 (2023-06-06) <csr-id-dbc6cbb4363c2532f81b0bd6e351c4577bb9e9a3/> @@ -17,7 +368,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 <csr-read-only-do-not-edit/> - - 9 commits contributed to the release over the course of 38 calendar days. + - 10 commits contributed to the release over the course of 38 calendar days. - 40 days passed between releases. - 1 commit was understood as [conventional](https://www.conventionalcommits.org). - 0 issues like '(#ID)' were seen in commit messages @@ -29,6 +380,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 <details><summary>view details</summary> * **Uncategorized** + - Release gix-date v0.5.1, gix-hash v0.11.2, gix-features v0.30.0, gix-actor v0.21.0, gix-path v0.8.1, gix-glob v0.8.0, gix-quote v0.4.4, gix-attributes v0.13.0, gix-chunk v0.4.2, gix-commitgraph v0.16.0, gix-config-value v0.12.1, gix-fs v0.2.0, gix-tempfile v6.0.0, gix-utils v0.1.2, gix-lock v6.0.0, gix-validate v0.7.5, gix-object v0.30.0, gix-ref v0.30.0, gix-sec v0.8.1, gix-config v0.23.0, gix-command v0.2.5, gix-prompt v0.5.1, gix-url v0.19.0, gix-credentials v0.15.0, gix-diff v0.30.0, gix-discover v0.19.0, gix-hashtable v0.2.1, gix-ignore v0.3.0, gix-bitmap v0.2.4, gix-traverse v0.26.0, gix-index v0.17.0, gix-mailmap v0.13.0, gix-revision v0.15.0, gix-negotiate v0.2.0, gix-pack v0.36.0, gix-odb v0.46.0, gix-packetline v0.16.2, gix-transport v0.32.0, gix-protocol v0.33.0, gix-refspec v0.11.0, gix-worktree v0.18.0, gix v0.45.0, safety bump 29 crates ([`9a9fa96`](https://github.com/Byron/gitoxide/commit/9a9fa96fa8a722bddc5c3b2270b0edf8f6615141)) - Prepare changelogs prior to release ([`8f15cec`](https://github.com/Byron/gitoxide/commit/8f15cec1ec7d5a9d56bb158f155011ef2bb3539b)) - Merge branch 'fix-docs' ([`420553a`](https://github.com/Byron/gitoxide/commit/420553a10d780e0b2dc466cac120989298a5f187)) - Cleaning up documentation ([`2578e57`](https://github.com/Byron/gitoxide/commit/2578e576bfa365d194a23a1fb0bf09be230873de)) @@ -2360,7 +2712,7 @@ This is a maintenance release without functional changes. - _None._ <csr-unknown> -lenfrom_envopenlenfrom_envopenlenfrom_envopenlenfrom_envopenlenfrom_envopenlenfrom_envopenlenfrom_envopenlenfrom_envopenlenfrom_envopenlenfrom_envopenlenfrom_envopenlenfrom_envopenlenfrom_envopenlenfrom_envopenlenfrom_envopenlenfrom_envopenlenfrom_envopenlenfrom_envopenlenfrom_envopenlenfrom_envopenlenfrom_envopenlenfrom_envopenlenfrom_envopenlenfrom_envopen<csr-unknown/> +lenfrom_envopenlenfrom_envopenlenfrom_envopenlenfrom_envopenlenfrom_envopenlenfrom_envopenlenfrom_envopenlenfrom_envopenlenfrom_envopenlenfrom_envopenlenfrom_envopenlenfrom_envopenlenfrom_envopenlenfrom_envopenlenfrom_envopenlenfrom_envopenlenfrom_envopenlenfrom_envopenlenfrom_envopenlenfrom_envopenlenfrom_envopenlenfrom_envopenlenfrom_envopenlenfrom_envopenlenfrom_envopenlenfrom_envopenlenfrom_envopenlenfrom_envopenlenfrom_envopenlenfrom_envopenlenfrom_envopenlenfrom_envopenlenfrom_envopenlenfrom_envopenlenfrom_envopenlenfrom_envopenlenfrom_envopenlenfrom_envopenlenfrom_envopenlenfrom_envopenlenfrom_envopenlenfrom_envopenlenfrom_envopenlenfrom_envopenlenfrom_envopenlenfrom_envopenlenfrom_envopen<csr-unknown/> <csr-unknown/> ## v0.1.1 (2021-05-09) diff --git a/vendor/gix-config/Cargo.toml b/vendor/gix-config/Cargo.toml index 26b169109..77df2601d 100644 --- a/vendor/gix-config/Cargo.toml +++ b/vendor/gix-config/Cargo.toml @@ -11,9 +11,9 @@ [package] edition = "2021" -rust-version = "1.64" +rust-version = "1.65" name = "gix-config" -version = "0.23.0" +version = "0.30.0" authors = ["Edward Shen <code@eddie.sh>"] include = [ "src/**/*", @@ -22,10 +22,10 @@ include = [ "CHANGELOG.md", ] autotests = false -description = "A gix-config file parser and editor from the gitoxide project" +description = "A git-config file parser and editor from the gitoxide project" readme = "README.md" keywords = [ - "gix-config", + "git-config", "git", "config", "gitoxide", @@ -60,34 +60,26 @@ version = "0.2.0" optional = true [dependencies.gix-config-value] -version = "^0.12.1" +version = "^0.14.0" [dependencies.gix-features] -version = "^0.30.0" +version = "^0.35.0" [dependencies.gix-glob] -version = "^0.8.0" +version = "^0.13.0" [dependencies.gix-path] -version = "^0.8.1" +version = "^0.10.0" [dependencies.gix-ref] -version = "^0.30.0" +version = "^0.37.0" [dependencies.gix-sec] -version = "^0.8.1" - -[dependencies.log] -version = "0.4.17" +version = "^0.10.0" [dependencies.memchr] version = "2" -[dependencies.nom] -version = "7" -features = ["std"] -default_features = false - [dependencies.once_cell] version = "1.14.0" @@ -106,8 +98,12 @@ version = "1.0.26" [dependencies.unicode-bom] version = "2.0.2" +[dependencies.winnow] +version = "0.5.14" +features = ["simd"] + [dev-dependencies.criterion] -version = "0.4.0" +version = "0.5.1" [features] serde = [ diff --git a/vendor/gix-config/README.md b/vendor/gix-config/README.md index 8118d83c9..ada9834bc 100644 --- a/vendor/gix-config/README.md +++ b/vendor/gix-config/README.md @@ -1,9 +1,9 @@ # gix-config -**gix-config is a library for interacting with `gix-config` files.** +**gix-config is a library for interacting with `git-config` files.** This crate intents to be a performant Rust implementation for reading and -writing `gix-config` files. It exposes tiers of abstractions, from simple +writing `git-config` files. It exposes tiers of abstractions, from simple config value wrappers to a high level reader and writer. The highlight of this crate is the zero-copy parser. We employ techniques to diff --git a/vendor/gix-config/src/file/access/comfort.rs b/vendor/gix-config/src/file/access/comfort.rs index b4953c597..ed62e7792 100644 --- a/vendor/gix-config/src/file/access/comfort.rs +++ b/vendor/gix-config/src/file/access/comfort.rs @@ -31,7 +31,8 @@ impl<'event> File<'event> { key: impl AsRef<str>, filter: &mut MetadataFilter, ) -> Option<Cow<'_, BStr>> { - self.raw_value_filter(section_name, subsection_name, key, filter).ok() + self.raw_value_filter(section_name.as_ref(), subsection_name, key.as_ref(), filter) + .ok() } /// Like [`string_filter()`][File::string_filter()], but suitable for statically known `key`s like `remote.origin.url`. @@ -40,7 +41,7 @@ impl<'event> File<'event> { key: impl Into<&'a BStr>, filter: &mut MetadataFilter, ) -> Option<Cow<'_, BStr>> { - let key = crate::parse::key(key)?; + let key = crate::parse::key(key.into())?; self.raw_value_filter(key.section_name, key.subsection_name, key.value_name, filter) .ok() } @@ -78,7 +79,7 @@ impl<'event> File<'event> { key: impl AsRef<str>, filter: &mut MetadataFilter, ) -> Option<crate::Path<'_>> { - self.raw_value_filter(section_name, subsection_name, key, filter) + self.raw_value_filter(section_name.as_ref(), subsection_name, key.as_ref(), filter) .ok() .map(crate::Path::from) } @@ -89,7 +90,7 @@ impl<'event> File<'event> { key: impl Into<&'a BStr>, filter: &mut MetadataFilter, ) -> Option<crate::Path<'_>> { - let key = crate::parse::key(key)?; + let key = crate::parse::key(key.into())?; self.path_filter(key.section_name, key.subsection_name, key.value_name, filter) } @@ -127,7 +128,7 @@ impl<'event> File<'event> { continue; } match section.value_implicit(key) { - Some(Some(v)) => return Some(crate::Boolean::try_from(v).map(|b| b.into())), + Some(Some(v)) => return Some(crate::Boolean::try_from(v).map(Into::into)), Some(None) => return Some(Ok(true)), None => continue, } @@ -141,7 +142,7 @@ impl<'event> File<'event> { key: impl Into<&'a BStr>, filter: &mut MetadataFilter, ) -> Option<Result<bool, value::Error>> { - let key = crate::parse::key(key)?; + let key = crate::parse::key(key.into())?; self.boolean_filter(key.section_name, key.subsection_name, key.value_name, filter) } @@ -168,7 +169,9 @@ impl<'event> File<'event> { key: impl AsRef<str>, filter: &mut MetadataFilter, ) -> Option<Result<i64, value::Error>> { - let int = self.raw_value_filter(section_name, subsection_name, key, filter).ok()?; + let int = self + .raw_value_filter(section_name.as_ref(), subsection_name, key.as_ref(), filter) + .ok()?; Some(crate::Integer::try_from(int.as_ref()).and_then(|b| { b.to_decimal() .ok_or_else(|| value::Error::new("Integer overflow", int.into_owned())) @@ -181,7 +184,7 @@ impl<'event> File<'event> { key: impl Into<&'a BStr>, filter: &mut MetadataFilter, ) -> Option<Result<i64, value::Error>> { - let key = crate::parse::key(key)?; + let key = crate::parse::key(key.into())?; self.integer_filter(key.section_name, key.subsection_name, key.value_name, filter) } @@ -192,12 +195,13 @@ impl<'event> File<'event> { subsection_name: Option<&BStr>, key: impl AsRef<str>, ) -> Option<Vec<Cow<'_, BStr>>> { - self.raw_values(section_name, subsection_name, key).ok() + self.raw_values(section_name.as_ref(), subsection_name, key.as_ref()) + .ok() } /// Like [`strings()`][File::strings()], but suitable for statically known `key`s like `remote.origin.url`. pub fn strings_by_key<'a>(&self, key: impl Into<&'a BStr>) -> Option<Vec<Cow<'_, BStr>>> { - let key = crate::parse::key(key)?; + let key = crate::parse::key(key.into())?; self.strings(key.section_name, key.subsection_name, key.value_name) } @@ -209,7 +213,8 @@ impl<'event> File<'event> { key: impl AsRef<str>, filter: &mut MetadataFilter, ) -> Option<Vec<Cow<'_, BStr>>> { - self.raw_values_filter(section_name, subsection_name, key, filter).ok() + self.raw_values_filter(section_name.as_ref(), subsection_name, key.as_ref(), filter) + .ok() } /// Like [`strings_filter()`][File::strings_filter()], but suitable for statically known `key`s like `remote.origin.url`. @@ -218,7 +223,7 @@ impl<'event> File<'event> { key: impl Into<&'a BStr>, filter: &mut MetadataFilter, ) -> Option<Vec<Cow<'_, BStr>>> { - let key = crate::parse::key(key)?; + let key = crate::parse::key(key.into())?; self.strings_filter(key.section_name, key.subsection_name, key.value_name, filter) } @@ -247,7 +252,7 @@ impl<'event> File<'event> { key: impl AsRef<str>, filter: &mut MetadataFilter, ) -> Option<Result<Vec<i64>, value::Error>> { - self.raw_values_filter(section_name, subsection_name, key, filter) + self.raw_values_filter(section_name.as_ref(), subsection_name, key.as_ref(), filter) .ok() .map(|values| { values @@ -268,7 +273,7 @@ impl<'event> File<'event> { key: impl Into<&'a BStr>, filter: &mut MetadataFilter, ) -> Option<Result<Vec<i64>, value::Error>> { - let key = crate::parse::key(key)?; + let key = crate::parse::key(key.into())?; self.integers_filter(key.section_name, key.subsection_name, key.value_name, filter) } } diff --git a/vendor/gix-config/src/file/access/mutate.rs b/vendor/gix-config/src/file/access/mutate.rs index e1cfc6e1c..4844a34f4 100644 --- a/vendor/gix-config/src/file/access/mutate.rs +++ b/vendor/gix-config/src/file/access/mutate.rs @@ -18,10 +18,17 @@ impl<'event> File<'event> { name: impl AsRef<str>, subsection_name: Option<&BStr>, ) -> Result<SectionMut<'a, 'event>, lookup::existing::Error> { + self.section_mut_inner(name.as_ref(), subsection_name) + } + + fn section_mut_inner<'a>( + &'a mut self, + name: &str, + subsection_name: Option<&BStr>, + ) -> Result<SectionMut<'a, 'event>, lookup::existing::Error> { let id = self - .section_ids_by_name_and_subname(name.as_ref(), subsection_name)? - .rev() - .next() + .section_ids_by_name_and_subname(name, subsection_name)? + .next_back() .expect("BUG: Section lookup vec was empty"); let nl = self.detect_newline_style_smallvec(); Ok(self @@ -65,7 +72,15 @@ impl<'event> File<'event> { subsection_name: Option<&BStr>, filter: &mut MetadataFilter, ) -> Result<SectionMut<'a, 'event>, section::header::Error> { - let name = name.as_ref(); + self.section_mut_or_create_new_filter_inner(name.as_ref(), subsection_name, filter) + } + + fn section_mut_or_create_new_filter_inner<'a>( + &'a mut self, + name: &str, + subsection_name: Option<&BStr>, + filter: &mut MetadataFilter, + ) -> Result<SectionMut<'a, 'event>, section::header::Error> { match self .section_ids_by_name_and_subname(name.as_ref(), subsection_name) .ok() @@ -97,8 +112,17 @@ impl<'event> File<'event> { subsection_name: Option<&BStr>, filter: &mut MetadataFilter, ) -> Result<Option<file::SectionMut<'a, 'event>>, lookup::existing::Error> { + self.section_mut_filter_inner(name.as_ref(), subsection_name, filter) + } + + fn section_mut_filter_inner<'a>( + &'a mut self, + name: &str, + subsection_name: Option<&BStr>, + filter: &mut MetadataFilter, + ) -> Result<Option<file::SectionMut<'a, 'event>>, lookup::existing::Error> { let id = self - .section_ids_by_name_and_subname(name.as_ref(), subsection_name)? + .section_ids_by_name_and_subname(name, subsection_name)? .rev() .find(|id| { let s = &self.sections[id]; @@ -131,10 +155,10 @@ impl<'event> File<'event> { /// # use std::borrow::Cow; /// # use gix_config::File; /// # use std::convert::TryFrom; - /// let mut gix_config = gix_config::File::default(); - /// let section = gix_config.new_section("hello", Some(Cow::Borrowed("world".into())))?; + /// let mut git_config = gix_config::File::default(); + /// let section = git_config.new_section("hello", Some(Cow::Borrowed("world".into())))?; /// let nl = section.newline().to_owned(); - /// assert_eq!(gix_config.to_string(), format!("[hello \"world\"]{nl}")); + /// assert_eq!(git_config.to_string(), format!("[hello \"world\"]{nl}")); /// # Ok::<(), Box<dyn std::error::Error>>(()) /// ``` /// @@ -146,13 +170,13 @@ impl<'event> File<'event> { /// # use std::convert::TryFrom; /// # use bstr::ByteSlice; /// # use gix_config::parse::section; - /// let mut gix_config = gix_config::File::default(); - /// let mut section = gix_config.new_section("hello", Some(Cow::Borrowed("world".into())))?; + /// let mut git_config = gix_config::File::default(); + /// let mut section = git_config.new_section("hello", Some(Cow::Borrowed("world".into())))?; /// section.push(section::Key::try_from("a")?, Some("b".into())); /// let nl = section.newline().to_owned(); - /// assert_eq!(gix_config.to_string(), format!("[hello \"world\"]{nl}\ta = b{nl}")); - /// let _section = gix_config.new_section("core", None); - /// assert_eq!(gix_config.to_string(), format!("[hello \"world\"]{nl}\ta = b{nl}[core]{nl}")); + /// assert_eq!(git_config.to_string(), format!("[hello \"world\"]{nl}\ta = b{nl}")); + /// let _section = git_config.new_section("core", None); + /// assert_eq!(git_config.to_string(), format!("[hello \"world\"]{nl}\ta = b{nl}[core]{nl}")); /// # Ok::<(), Box<dyn std::error::Error>>(()) /// ``` pub fn new_section( @@ -160,6 +184,14 @@ impl<'event> File<'event> { name: impl Into<Cow<'event, str>>, subsection: impl Into<Option<Cow<'event, BStr>>>, ) -> Result<SectionMut<'_, 'event>, section::header::Error> { + self.new_section_inner(name.into(), subsection.into()) + } + + fn new_section_inner( + &mut self, + name: Cow<'event, str>, + subsection: Option<Cow<'event, BStr>>, + ) -> Result<SectionMut<'_, 'event>, section::header::Error> { let id = self.push_section_internal(file::Section::new(name, subsection, OwnShared::clone(&self.meta))?); let nl = self.detect_newline_style_smallvec(); let mut section = self.sections.get_mut(&id).expect("each id yields a section").to_mut(nl); @@ -178,13 +210,13 @@ impl<'event> File<'event> { /// ``` /// # use gix_config::File; /// # use std::convert::TryFrom; - /// let mut gix_config = gix_config::File::try_from( + /// let mut git_config = gix_config::File::try_from( /// r#"[hello "world"] /// some-value = 4 /// "#)?; /// - /// let section = gix_config.remove_section("hello", Some("world".into())); - /// assert_eq!(gix_config.to_string(), ""); + /// let section = git_config.remove_section("hello", Some("world".into())); + /// assert_eq!(git_config.to_string(), ""); /// # Ok::<(), Box<dyn std::error::Error>>(()) /// ``` /// @@ -193,27 +225,26 @@ impl<'event> File<'event> { /// ``` /// # use gix_config::File; /// # use std::convert::TryFrom; - /// let mut gix_config = gix_config::File::try_from( + /// let mut git_config = gix_config::File::try_from( /// r#"[hello "world"] /// some-value = 4 /// [hello "world"] /// some-value = 5 /// "#)?; /// - /// let section = gix_config.remove_section("hello", Some("world".into())); - /// assert_eq!(gix_config.to_string(), "[hello \"world\"]\n some-value = 4\n"); + /// let section = git_config.remove_section("hello", Some("world".into())); + /// assert_eq!(git_config.to_string(), "[hello \"world\"]\n some-value = 4\n"); /// # Ok::<(), Box<dyn std::error::Error>>(()) /// ``` pub fn remove_section<'a>( &mut self, - name: &str, + name: impl AsRef<str>, subsection_name: impl Into<Option<&'a BStr>>, ) -> Option<file::Section<'event>> { let id = self - .section_ids_by_name_and_subname(name, subsection_name.into()) + .section_ids_by_name_and_subname(name.as_ref(), subsection_name.into()) .ok()? - .rev() - .next()?; + .next_back()?; self.remove_section_by_id(id) } @@ -256,12 +287,21 @@ impl<'event> File<'event> { /// later sections with the same name have precedent over earlier ones. pub fn remove_section_filter<'a>( &mut self, - name: &str, + name: impl AsRef<str>, subsection_name: impl Into<Option<&'a BStr>>, filter: &mut MetadataFilter, ) -> Option<file::Section<'event>> { + self.remove_section_filter_inner(name.as_ref(), subsection_name.into(), filter) + } + + fn remove_section_filter_inner( + &mut self, + name: &str, + subsection_name: Option<&BStr>, + filter: &mut MetadataFilter, + ) -> Option<file::Section<'event>> { let id = self - .section_ids_by_name_and_subname(name, subsection_name.into()) + .section_ids_by_name_and_subname(name, subsection_name) .ok()? .rev() .find(|id| filter(self.sections.get(id).expect("each id has a section").meta()))?; @@ -274,17 +314,13 @@ impl<'event> File<'event> { self.sections.remove(&id) } - /// Adds the provided section to the config, returning a mutable reference - /// to it for immediate editing. + /// Adds the provided `section` to the config, returning a mutable reference to it for immediate editing. /// Note that its meta-data will remain as is. - pub fn push_section( - &mut self, - section: file::Section<'event>, - ) -> Result<SectionMut<'_, 'event>, section::header::Error> { + pub fn push_section(&mut self, section: file::Section<'event>) -> SectionMut<'_, 'event> { let id = self.push_section_internal(section); let nl = self.detect_newline_style_smallvec(); let section = self.sections.get_mut(&id).expect("each id yields a section").to_mut(nl); - Ok(section) + section } /// Renames the section with `name` and `subsection_name`, modifying the last matching section @@ -298,8 +334,7 @@ impl<'event> File<'event> { ) -> Result<(), rename_section::Error> { let id = self .section_ids_by_name_and_subname(name.as_ref(), subsection_name.into())? - .rev() - .next() + .next_back() .expect("list of sections were empty, which violates invariant"); let section = self.sections.get_mut(&id).expect("known section-id"); section.header = section::Header::new(new_name, new_subsection_name)?; diff --git a/vendor/gix-config/src/file/access/raw.rs b/vendor/gix-config/src/file/access/raw.rs index 44b318f24..3736bf3a2 100644 --- a/vendor/gix-config/src/file/access/raw.rs +++ b/vendor/gix-config/src/file/access/raw.rs @@ -40,8 +40,17 @@ impl<'event> File<'event> { key: impl AsRef<str>, filter: &mut MetadataFilter, ) -> Result<Cow<'_, BStr>, lookup::existing::Error> { - let section_ids = self.section_ids_by_name_and_subname(section_name.as_ref(), subsection_name)?; - let key = key.as_ref(); + self.raw_value_filter_inner(section_name.as_ref(), subsection_name, key.as_ref(), filter) + } + + fn raw_value_filter_inner( + &self, + section_name: &str, + subsection_name: Option<&BStr>, + key: &str, + filter: &mut MetadataFilter, + ) -> Result<Cow<'_, BStr>, lookup::existing::Error> { + let section_ids = self.section_ids_by_name_and_subname(section_name, subsection_name)?; for section_id in section_ids.rev() { let section = self.sections.get(§ion_id).expect("known section id"); if !filter(section.meta()) { @@ -81,8 +90,18 @@ impl<'event> File<'event> { key: &'lookup str, filter: &mut MetadataFilter, ) -> Result<ValueMut<'_, 'lookup, 'event>, lookup::existing::Error> { + self.raw_value_mut_filter_inner(section_name.as_ref(), subsection_name, key, filter) + } + + fn raw_value_mut_filter_inner<'lookup>( + &mut self, + section_name: &str, + subsection_name: Option<&'lookup BStr>, + key: &'lookup str, + filter: &mut MetadataFilter, + ) -> Result<ValueMut<'_, 'lookup, 'event>, lookup::existing::Error> { let mut section_ids = self - .section_ids_by_name_and_subname(section_name.as_ref(), subsection_name)? + .section_ids_by_name_and_subname(section_name, subsection_name)? .rev(); let key = section::Key(Cow::<BStr>::Borrowed(key.into())); @@ -157,9 +176,9 @@ impl<'event> File<'event> { /// # use std::borrow::Cow; /// # use std::convert::TryFrom; /// # use bstr::BStr; - /// # let gix_config = gix_config::File::try_from("[core]a=b\n[core]\na=c\na=d").unwrap(); + /// # let git_config = gix_config::File::try_from("[core]a=b\n[core]\na=c\na=d").unwrap(); /// assert_eq!( - /// gix_config.raw_values("core", None, "a").unwrap(), + /// git_config.raw_values("core", None, "a").unwrap(), /// vec![ /// Cow::<BStr>::Borrowed("b".into()), /// Cow::<BStr>::Borrowed("c".into()), @@ -191,9 +210,18 @@ impl<'event> File<'event> { key: impl AsRef<str>, filter: &mut MetadataFilter, ) -> Result<Vec<Cow<'_, BStr>>, lookup::existing::Error> { + self.raw_values_filter_inner(section_name.as_ref(), subsection_name, key.as_ref(), filter) + } + + fn raw_values_filter_inner( + &self, + section_name: &str, + subsection_name: Option<&BStr>, + key: &str, + filter: &mut MetadataFilter, + ) -> Result<Vec<Cow<'_, BStr>>, lookup::existing::Error> { let mut values = Vec::new(); - let section_ids = self.section_ids_by_name_and_subname(section_name.as_ref(), subsection_name)?; - let key = key.as_ref(); + let section_ids = self.section_ids_by_name_and_subname(section_name, subsection_name)?; for section_id in section_ids { let section = self.sections.get(§ion_id).expect("known section id"); if !filter(section.meta()) { @@ -231,9 +259,9 @@ impl<'event> File<'event> { /// # use std::borrow::Cow; /// # use std::convert::TryFrom; /// # use bstr::BStr; - /// # let mut gix_config = gix_config::File::try_from("[core]a=b\n[core]\na=c\na=d").unwrap(); + /// # let mut git_config = gix_config::File::try_from("[core]a=b\n[core]\na=c\na=d").unwrap(); /// assert_eq!( - /// gix_config.raw_values("core", None, "a")?, + /// git_config.raw_values("core", None, "a")?, /// vec![ /// Cow::<BStr>::Borrowed("b".into()), /// Cow::<BStr>::Borrowed("c".into()), @@ -241,10 +269,10 @@ impl<'event> File<'event> { /// ] /// ); /// - /// gix_config.raw_values_mut("core", None, "a")?.set_all("g"); + /// git_config.raw_values_mut("core", None, "a")?.set_all("g"); /// /// assert_eq!( - /// gix_config.raw_values("core", None, "a")?, + /// git_config.raw_values("core", None, "a")?, /// vec![ /// Cow::<BStr>::Borrowed("g".into()), /// Cow::<BStr>::Borrowed("g".into()), @@ -277,7 +305,17 @@ impl<'event> File<'event> { key: &'lookup str, filter: &mut MetadataFilter, ) -> Result<MultiValueMut<'_, 'lookup, 'event>, lookup::existing::Error> { - let section_ids = self.section_ids_by_name_and_subname(section_name.as_ref(), subsection_name)?; + self.raw_values_mut_filter_inner(section_name.as_ref(), subsection_name, key, filter) + } + + fn raw_values_mut_filter_inner<'lookup>( + &mut self, + section_name: &str, + subsection_name: Option<&'lookup BStr>, + key: &'lookup str, + filter: &mut MetadataFilter, + ) -> Result<MultiValueMut<'_, 'lookup, 'event>, lookup::existing::Error> { + let section_ids = self.section_ids_by_name_and_subname(section_name, subsection_name)?; let key = section::Key(Cow::<BStr>::Borrowed(key.into())); let mut offsets = HashMap::new(); @@ -352,11 +390,11 @@ impl<'event> File<'event> { /// # use std::borrow::Cow; /// # use bstr::BStr; /// # use std::convert::TryFrom; - /// # let mut gix_config = gix_config::File::try_from("[core]a=b\n[core]\na=c\na=d").unwrap(); - /// gix_config.set_existing_raw_value("core", None, "a", "e")?; - /// assert_eq!(gix_config.raw_value("core", None, "a")?, Cow::<BStr>::Borrowed("e".into())); + /// # let mut git_config = gix_config::File::try_from("[core]a=b\n[core]\na=c\na=d").unwrap(); + /// git_config.set_existing_raw_value("core", None, "a", "e")?; + /// assert_eq!(git_config.raw_value("core", None, "a")?, Cow::<BStr>::Borrowed("e".into())); /// assert_eq!( - /// gix_config.raw_values("core", None, "a")?, + /// git_config.raw_values("core", None, "a")?, /// vec![ /// Cow::<BStr>::Borrowed("b".into()), /// Cow::<BStr>::Borrowed("c".into()), @@ -395,12 +433,12 @@ impl<'event> File<'event> { /// # use std::borrow::Cow; /// # use bstr::BStr; /// # use std::convert::TryFrom; - /// # let mut gix_config = gix_config::File::try_from("[core]a=b").unwrap(); - /// let prev = gix_config.set_raw_value("core", None, "a", "e")?; - /// gix_config.set_raw_value("core", None, "b", "f")?; + /// # let mut git_config = gix_config::File::try_from("[core]a=b").unwrap(); + /// let prev = git_config.set_raw_value("core", None, "a", "e")?; + /// git_config.set_raw_value("core", None, "b", "f")?; /// assert_eq!(prev.expect("present").as_ref(), "b"); - /// assert_eq!(gix_config.raw_value("core", None, "a")?, Cow::<BStr>::Borrowed("e".into())); - /// assert_eq!(gix_config.raw_value("core", None, "b")?, Cow::<BStr>::Borrowed("f".into())); + /// assert_eq!(git_config.raw_value("core", None, "a")?, Cow::<BStr>::Borrowed("e".into())); + /// assert_eq!(git_config.raw_value("core", None, "b")?, Cow::<BStr>::Borrowed("f".into())); /// # Ok::<(), Box<dyn std::error::Error>>(()) /// ``` pub fn set_raw_value<'b, Key, E>( @@ -432,7 +470,7 @@ impl<'event> File<'event> { section::key::Error: From<E>, { let mut section = self.section_mut_or_create_new_filter(section_name, subsection_name, filter)?; - Ok(section.set(key.try_into().map_err(section::key::Error::from)?, new_value)) + Ok(section.set(key.try_into().map_err(section::key::Error::from)?, new_value.into())) } /// Sets a multivar in a given section, optional subsection, and key value. @@ -468,14 +506,14 @@ impl<'event> File<'event> { /// # use std::borrow::Cow; /// # use std::convert::TryFrom; /// # use bstr::BStr; - /// # let mut gix_config = gix_config::File::try_from("[core]a=b\n[core]\na=c\na=d").unwrap(); + /// # let mut git_config = gix_config::File::try_from("[core]a=b\n[core]\na=c\na=d").unwrap(); /// let new_values = vec![ /// "x", /// "y", /// "z", /// ]; - /// gix_config.set_existing_raw_multi_value("core", None, "a", new_values.into_iter())?; - /// let fetched_config = gix_config.raw_values("core", None, "a")?; + /// git_config.set_existing_raw_multi_value("core", None, "a", new_values.into_iter())?; + /// let fetched_config = git_config.raw_values("core", None, "a")?; /// assert!(fetched_config.contains(&Cow::<BStr>::Borrowed("x".into()))); /// assert!(fetched_config.contains(&Cow::<BStr>::Borrowed("y".into()))); /// assert!(fetched_config.contains(&Cow::<BStr>::Borrowed("z".into()))); @@ -489,13 +527,13 @@ impl<'event> File<'event> { /// # use std::borrow::Cow; /// # use std::convert::TryFrom; /// # use bstr::BStr; - /// # let mut gix_config = gix_config::File::try_from("[core]a=b\n[core]\na=c\na=d").unwrap(); + /// # let mut git_config = gix_config::File::try_from("[core]a=b\n[core]\na=c\na=d").unwrap(); /// let new_values = vec![ /// "x", /// "y", /// ]; - /// gix_config.set_existing_raw_multi_value("core", None, "a", new_values.into_iter())?; - /// let fetched_config = gix_config.raw_values("core", None, "a")?; + /// git_config.set_existing_raw_multi_value("core", None, "a", new_values.into_iter())?; + /// let fetched_config = git_config.raw_values("core", None, "a")?; /// assert!(fetched_config.contains(&Cow::<BStr>::Borrowed("x".into()))); /// assert!(fetched_config.contains(&Cow::<BStr>::Borrowed("y".into()))); /// # Ok::<(), gix_config::lookup::existing::Error>(()) @@ -508,15 +546,15 @@ impl<'event> File<'event> { /// # use std::borrow::Cow; /// # use std::convert::TryFrom; /// # use bstr::BStr; - /// # let mut gix_config = gix_config::File::try_from("[core]a=b\n[core]\na=c\na=d").unwrap(); + /// # let mut git_config = gix_config::File::try_from("[core]a=b\n[core]\na=c\na=d").unwrap(); /// let new_values = vec![ /// "x", /// "y", /// "z", /// "discarded", /// ]; - /// gix_config.set_existing_raw_multi_value("core", None, "a", new_values)?; - /// assert!(!gix_config.raw_values("core", None, "a")?.contains(&Cow::<BStr>::Borrowed("discarded".into()))); + /// git_config.set_existing_raw_multi_value("core", None, "a", new_values)?; + /// assert!(!git_config.raw_values("core", None, "a")?.contains(&Cow::<BStr>::Borrowed("discarded".into()))); /// # Ok::<(), gix_config::lookup::existing::Error>(()) /// ``` pub fn set_existing_raw_multi_value<'a, Iter, Item>( diff --git a/vendor/gix-config/src/file/access/read_only.rs b/vendor/gix-config/src/file/access/read_only.rs index 5520c6566..eb1071fe2 100644 --- a/vendor/gix-config/src/file/access/read_only.rs +++ b/vendor/gix-config/src/file/access/read_only.rs @@ -42,11 +42,11 @@ impl<'event> File<'event> { /// a = 10k /// c = false /// "#; - /// let gix_config = gix_config::File::try_from(config)?; + /// let git_config = gix_config::File::try_from(config)?; /// // You can either use the turbofish to determine the type... - /// let a_value = gix_config.value::<Integer>("core", None, "a")?; + /// let a_value = git_config.value::<Integer>("core", None, "a")?; /// // ... or explicitly declare the type to avoid the turbofish - /// let c_value: Boolean = gix_config.value("core", None, "c")?; + /// let c_value: Boolean = git_config.value("core", None, "c")?; /// # Ok::<(), Box<dyn std::error::Error>>(()) /// ``` pub fn value<'a, T: TryFrom<Cow<'a, BStr>>>( @@ -96,9 +96,9 @@ impl<'event> File<'event> { /// a /// a = false /// "#; - /// let gix_config = gix_config::File::try_from(config).unwrap(); + /// let git_config = gix_config::File::try_from(config).unwrap(); /// // You can either use the turbofish to determine the type... - /// let a_value = gix_config.values::<Boolean>("core", None, "a")?; + /// let a_value = git_config.values::<Boolean>("core", None, "a")?; /// assert_eq!( /// a_value, /// vec![ @@ -108,7 +108,7 @@ impl<'event> File<'event> { /// ] /// ); /// // ... or explicitly declare the type to avoid the turbofish - /// let c_value: Vec<Boolean> = gix_config.values("core", None, "c").unwrap(); + /// let c_value: Vec<Boolean> = git_config.values("core", None, "c").unwrap(); /// assert_eq!(c_value, vec![Boolean(false)]); /// # Ok::<(), Box<dyn std::error::Error>>(()) /// ``` @@ -131,7 +131,7 @@ impl<'event> File<'event> { /// Returns the last found immutable section with a given `name` and optional `subsection_name`. pub fn section( &self, - name: impl AsRef<str>, + name: &str, subsection_name: Option<&BStr>, ) -> Result<&file::Section<'event>, lookup::existing::Error> { self.section_filter(name, subsection_name, &mut |_| true)? @@ -140,10 +140,7 @@ impl<'event> File<'event> { /// Returns the last found immutable section with a given `key`, identifying the name and subsection name like `core` /// or `remote.origin`. - pub fn section_by_key<'a>( - &self, - key: impl Into<&'a BStr>, - ) -> Result<&file::Section<'event>, lookup::existing::Error> { + pub fn section_by_key(&self, key: &BStr) -> Result<&file::Section<'event>, lookup::existing::Error> { let key = crate::parse::section::unvalidated::Key::parse(key).ok_or(lookup::existing::Error::KeyMissing)?; self.section(key.section_name, key.subsection_name) } @@ -154,7 +151,7 @@ impl<'event> File<'event> { /// is returned. pub fn section_filter<'a>( &'a self, - name: impl AsRef<str>, + name: &str, subsection_name: Option<&BStr>, filter: &mut MetadataFilter, ) -> Result<Option<&'a file::Section<'event>>, lookup::existing::Error> { @@ -171,9 +168,9 @@ impl<'event> File<'event> { } /// Like [`section_filter()`][File::section_filter()], but identifies the section with `key` like `core` or `remote.origin`. - pub fn section_filter_by_key<'a, 'b>( + pub fn section_filter_by_key<'a>( &'a self, - key: impl Into<&'b BStr>, + key: &BStr, filter: &mut MetadataFilter, ) -> Result<Option<&'a file::Section<'event>>, lookup::existing::Error> { let key = crate::parse::section::unvalidated::Key::parse(key).ok_or(lookup::existing::Error::KeyMissing)?; @@ -210,8 +207,8 @@ impl<'event> File<'event> { /// [core "apple"] /// e = f /// "#; - /// let gix_config = gix_config::File::try_from(config)?; - /// assert_eq!(gix_config.sections_by_name("core").map_or(0, |s|s.count()), 3); + /// let git_config = gix_config::File::try_from(config)?; + /// assert_eq!(git_config.sections_by_name("core").map_or(0, |s|s.count()), 3); /// # Ok::<(), Box<dyn std::error::Error>>(()) /// ``` #[must_use] diff --git a/vendor/gix-config/src/file/init/comfort.rs b/vendor/gix-config/src/file/init/comfort.rs index aa77fb9c0..4a5a1c68b 100644 --- a/vendor/gix-config/src/file/init/comfort.rs +++ b/vendor/gix-config/src/file/init/comfort.rs @@ -1,3 +1,5 @@ +use std::borrow::Cow; + use crate::{ file::{init, Metadata}, path, source, File, Source, @@ -30,7 +32,7 @@ impl File<'static> { let path = source .storage_location(&mut gix_path::env::var) .and_then(|p| p.is_file().then_some(p)) - .map(|p| p.into_owned()); + .map(Cow::into_owned); Metadata { path, @@ -53,9 +55,9 @@ impl File<'static> { /// A typical use of this is to [`append`][File::append()] this configuration to another one with lower /// precedence to obtain overrides. /// - /// See [`gix-config`'s documentation] for more information on the environment variables in question. + /// See [`git-config`'s documentation] for more information on the environment variables in question. /// - /// [`gix-config`'s documentation]: https://git-scm.com/docs/gix-config#Documentation/gix-config.txt-GITCONFIGCOUNT + /// [`git-config`'s documentation]: https://git-scm.com/docs/git-config#Documentation/git-config.txt-GITCONFIGCOUNT pub fn from_environment_overrides() -> Result<File<'static>, init::from_env::Error> { let home = gix_path::env::home_dir(); let options = init::Options { @@ -80,16 +82,16 @@ impl File<'static> { /// /// Includes will be resolved within limits as some information like the git installation directory is missing to interpolate /// paths with as well as git repository information like the branch name. - pub fn from_git_dir(dir: impl Into<std::path::PathBuf>) -> Result<File<'static>, from_git_dir::Error> { + pub fn from_git_dir(dir: std::path::PathBuf) -> Result<File<'static>, from_git_dir::Error> { let (mut local, git_dir) = { let source = Source::Local; - let mut path = dir.into(); + let mut path = dir; path.push( source .storage_location(&mut gix_path::env::var) .expect("location available for local"), ); - let local = Self::from_path_no_includes(&path, source)?; + let local = Self::from_path_no_includes(path.clone(), source)?; path.pop(); (local, path) }; diff --git a/vendor/gix-config/src/file/init/from_env.rs b/vendor/gix-config/src/file/init/from_env.rs index 167d37399..2c487e595 100644 --- a/vendor/gix-config/src/file/init/from_env.rs +++ b/vendor/gix-config/src/file/init/from_env.rs @@ -31,11 +31,11 @@ pub enum Error { /// Instantiation from environment variables impl File<'static> { /// Generates a config from `GIT_CONFIG_*` environment variables or returns `Ok(None)` if no configuration was found. - /// See [`gix-config`'s documentation] for more information on the environment variables in question. + /// See [`git-config`'s documentation] for more information on the environment variables in question. /// /// With `options` configured, it's possible to resolve `include.path` or `includeIf.<condition>.path` directives as well. /// - /// [`gix-config`'s documentation]: https://git-scm.com/docs/gix-config#Documentation/gix-config.txt-GITCONFIGCOUNT + /// [`git-config`'s documentation]: https://git-scm.com/docs/git-config#Documentation/git-config.txt-GITCONFIGCOUNT pub fn from_env(options: init::Options<'_>) -> Result<Option<File<'static>>, Error> { use std::env; let count: usize = match env::var("GIT_CONFIG_COUNT") { diff --git a/vendor/gix-config/src/file/init/from_paths.rs b/vendor/gix-config/src/file/init/from_paths.rs index 0eb7de69b..c0412a95f 100644 --- a/vendor/gix-config/src/file/init/from_paths.rs +++ b/vendor/gix-config/src/file/init/from_paths.rs @@ -23,8 +23,7 @@ impl File<'static> { /// Load the single file at `path` with `source` without following include directives. /// /// Note that the path will be checked for ownership to derive trust. - pub fn from_path_no_includes(path: impl Into<std::path::PathBuf>, source: crate::Source) -> Result<Self, Error> { - let path = path.into(); + pub fn from_path_no_includes(path: std::path::PathBuf, source: crate::Source) -> Result<Self, Error> { let trust = match gix_sec::Trust::from_path_ownership(&path) { Ok(t) => t, Err(err) => return Err(Error::Io { source: err, path }), @@ -49,7 +48,7 @@ impl File<'static> { )?) } - /// Constructs a `gix-config` file from the provided metadata, which must include a path to read from or be ignored. + /// Constructs a `git-config` file from the provided metadata, which must include a path to read from or be ignored. /// Returns `Ok(None)` if there was not a single input path provided, which is a possibility due to /// [`Metadata::path`] being an `Option`. /// If an input path doesn't exist, the entire operation will abort. See [`from_paths_metadata_buf()`][Self::from_paths_metadata_buf()] @@ -60,7 +59,12 @@ impl File<'static> { ) -> Result<Option<Self>, Error> { let mut buf = Vec::with_capacity(512); let err_on_nonexisting_paths = true; - Self::from_paths_metadata_buf(path_meta, &mut buf, err_on_nonexisting_paths, options) + Self::from_paths_metadata_buf( + &mut path_meta.into_iter().map(Into::into), + &mut buf, + err_on_nonexisting_paths, + options, + ) } /// Like [`from_paths_metadata()`][Self::from_paths_metadata()], but will use `buf` to temporarily store the config file @@ -68,17 +72,14 @@ impl File<'static> { /// /// If `err_on_nonexisting_paths` is false, instead of aborting with error, we will continue to the next path instead. pub fn from_paths_metadata_buf( - path_meta: impl IntoIterator<Item = impl Into<Metadata>>, + path_meta: &mut dyn Iterator<Item = Metadata>, buf: &mut Vec<u8>, err_on_non_existing_paths: bool, options: Options<'_>, ) -> Result<Option<Self>, Error> { let mut target = None; let mut seen = BTreeSet::default(); - for (path, mut meta) in path_meta.into_iter().filter_map(|meta| { - let mut meta = meta.into(); - meta.path.take().map(|p| (p, meta)) - }) { + for (path, mut meta) in path_meta.filter_map(|mut meta| meta.path.take().map(|p| (p, meta))) { if !seen.insert(path.clone()) { continue; } @@ -91,7 +92,7 @@ impl File<'static> { Err(err) => { let err = Error::Io { source: err, path }; if options.ignore_io_errors { - log::warn!("ignoring: {err:#?}"); + gix_features::trace::warn!("ignoring: {err:#?}"); continue; } else { return Err(err); @@ -103,7 +104,7 @@ impl File<'static> { Ok(_) => {} Err(err) => { if options.ignore_io_errors { - log::warn!( + gix_features::trace::warn!( "ignoring: {:#?}", Error::Io { source: err, diff --git a/vendor/gix-config/src/file/mod.rs b/vendor/gix-config/src/file/mod.rs index 2dd8c88fe..e99c6eb94 100644 --- a/vendor/gix-config/src/file/mod.rs +++ b/vendor/gix-config/src/file/mod.rs @@ -1,4 +1,4 @@ -//! A high level wrapper around a single or multiple `gix-config` file, for reading and mutation. +//! A high level wrapper around a single or multiple `git-config` file, for reading and mutation. use std::{ borrow::Cow, collections::HashMap, @@ -66,7 +66,7 @@ pub struct Metadata { pub trust: gix_sec::Trust, } -/// A section in a gix-config file, like `[core]` or `[remote "origin"]`, along with all of its keys. +/// A section in a git-config file, like `[core]` or `[remote "origin"]`, along with all of its keys. #[derive(Clone, Eq, PartialEq, Ord, PartialOrd, Hash, Debug)] pub struct Section<'a> { header: crate::parse::section::Header<'a>, @@ -104,7 +104,7 @@ impl AddAssign<usize> for Size { /// This value does not imply any ordering between sections, as new sections /// with higher section IDs may be in between lower ID sections after `File` mutation. /// -/// We need to use a section id because `gix-config` permits sections with +/// We need to use a section id because `git-config` permits sections with /// identical names, making it ambiguous when used in maps, for instance. /// /// This id guaranteed to be unique, but not guaranteed to be compact. In other diff --git a/vendor/gix-config/src/file/mutable/mod.rs b/vendor/gix-config/src/file/mutable/mod.rs index ad99e09b9..506a5484d 100644 --- a/vendor/gix-config/src/file/mutable/mod.rs +++ b/vendor/gix-config/src/file/mutable/mod.rs @@ -9,10 +9,10 @@ pub(crate) mod section; pub(crate) mod value; fn escape_value(value: &BStr) -> BString { - let starts_with_whitespace = value.first().map_or(false, |b| b.is_ascii_whitespace()); + let starts_with_whitespace = value.first().map_or(false, u8::is_ascii_whitespace); let ends_with_whitespace = value .get(value.len().saturating_sub(1)) - .map_or(false, |b| b.is_ascii_whitespace()); + .map_or(false, u8::is_ascii_whitespace); let contains_comment_indicators = value.find_byteset(b";#").is_some(); let quote = starts_with_whitespace || ends_with_whitespace || contains_comment_indicators; @@ -74,7 +74,7 @@ impl<'a> Whitespace<'a> { .find_map(|(idx, e)| matches!(e, Event::SectionKey(_)).then(|| idx)); key_pos .map(|key_pos| { - let pre_key = s.0[..key_pos].iter().rev().next().and_then(|e| match e { + let pre_key = s.0[..key_pos].iter().next_back().and_then(|e| match e { Event::Whitespace(s) => Some(s.clone()), _ => None, }); diff --git a/vendor/gix-config/src/file/mutable/section.rs b/vendor/gix-config/src/file/mutable/section.rs index def68ac60..336ccad2d 100644 --- a/vendor/gix-config/src/file/mutable/section.rs +++ b/vendor/gix-config/src/file/mutable/section.rs @@ -123,10 +123,10 @@ impl<'a, 'event> SectionMut<'a, 'event> { /// Sets the last key value pair if it exists, or adds the new value. /// Returns the previous value if it replaced a value, or None if it adds /// the value. - pub fn set<'b>(&mut self, key: Key<'event>, value: impl Into<&'b BStr>) -> Option<Cow<'event, BStr>> { + pub fn set(&mut self, key: Key<'event>, value: &BStr) -> Option<Cow<'event, BStr>> { match self.key_and_value_range_by(&key) { None => { - self.push(key, Some(value.into())); + self.push(key, Some(value)); None } Some((key_range, value_range)) => { @@ -136,15 +136,15 @@ impl<'a, 'event> SectionMut<'a, 'event> { self.section .body .0 - .insert(range_start, Event::Value(escape_value(value.into()).into())); + .insert(range_start, Event::Value(escape_value(value).into())); Some(ret) } } } /// Removes the latest value by key and returns it, if it exists. - pub fn remove(&mut self, key: impl AsRef<str>) -> Option<Cow<'event, BStr>> { - let key = Key::from_str_unchecked(key.as_ref()); + pub fn remove(&mut self, key: &str) -> Option<Cow<'event, BStr>> { + let key = Key::from_str_unchecked(key); let (key_range, _value_range) = self.key_and_value_range_by(&key)?; Some(self.remove_internal(key_range, true)) } @@ -185,7 +185,7 @@ impl<'a, 'event> SectionMut<'a, 'event> { assert!( whitespace .as_deref() - .map_or(true, |ws| ws.iter().all(|b| b.is_ascii_whitespace())), + .map_or(true, |ws| ws.iter().all(u8::is_ascii_whitespace)), "input whitespace must only contain whitespace characters." ); self.whitespace.pre_key = whitespace; diff --git a/vendor/gix-config/src/file/section/body.rs b/vendor/gix-config/src/file/section/body.rs index 694de18bd..1bc12725c 100644 --- a/vendor/gix-config/src/file/section/body.rs +++ b/vendor/gix-config/src/file/section/body.rs @@ -18,14 +18,14 @@ impl<'event> Body<'event> { /// Note that we consider values without key separator `=` non-existing. #[must_use] pub fn value(&self, key: impl AsRef<str>) -> Option<Cow<'_, BStr>> { - self.value_implicit(key).flatten() + self.value_implicit(key.as_ref()).flatten() } /// Retrieves the last matching value in a section with the given key, if present, and indicates an implicit value with `Some(None)`, /// and a non-existing one as `None` #[must_use] - pub fn value_implicit(&self, key: impl AsRef<str>) -> Option<Option<Cow<'_, BStr>>> { - let key = Key::from_str_unchecked(key.as_ref()); + pub fn value_implicit(&self, key: &str) -> Option<Option<Cow<'_, BStr>>> { + let key = Key::from_str_unchecked(key); let (_key_range, range) = self.key_and_value_range_by(&key)?; let range = match range { None => return Some(None), @@ -54,8 +54,8 @@ impl<'event> Body<'event> { /// Retrieves all values that have the provided key name. This may return /// an empty vec, which implies there were no values with the provided key. #[must_use] - pub fn values(&self, key: impl AsRef<str>) -> Vec<Cow<'_, BStr>> { - let key = &Key::from_str_unchecked(key.as_ref()); + pub fn values(&self, key: &str) -> Vec<Cow<'_, BStr>> { + let key = &Key::from_str_unchecked(key); let mut values = Vec::new(); let mut expect_value = false; let mut concatenated_value = BString::default(); @@ -92,8 +92,8 @@ impl<'event> Body<'event> { /// Returns true if the section contains the provided key. #[must_use] - pub fn contains_key(&self, key: impl AsRef<str>) -> bool { - let key = &Key::from_str_unchecked(key.as_ref()); + pub fn contains_key(&self, key: &str) -> bool { + let key = &Key::from_str_unchecked(key); self.0.iter().any(|e| { matches!(e, Event::SectionKey(k) if k == key diff --git a/vendor/gix-config/src/file/section/mod.rs b/vendor/gix-config/src/file/section/mod.rs index f73405960..f07a145e3 100644 --- a/vendor/gix-config/src/file/section/mod.rs +++ b/vendor/gix-config/src/file/section/mod.rs @@ -74,7 +74,7 @@ impl<'a> Section<'a> { /// Stream ourselves to the given `out`, in order to reproduce this section mostly losslessly /// as it was parsed. - pub fn write_to(&self, mut out: impl std::io::Write) -> std::io::Result<()> { + pub fn write_to(&self, mut out: &mut dyn std::io::Write) -> std::io::Result<()> { self.header.write_to(&mut out)?; if self.body.0.is_empty() { diff --git a/vendor/gix-config/src/file/write.rs b/vendor/gix-config/src/file/write.rs index 29024170d..772054f95 100644 --- a/vendor/gix-config/src/file/write.rs +++ b/vendor/gix-config/src/file/write.rs @@ -17,8 +17,8 @@ impl File<'_> { /// as it was parsed, while writing only sections for which `filter` returns true. pub fn write_to_filter( &self, - mut out: impl std::io::Write, - mut filter: impl FnMut(&Section<'_>) -> bool, + mut out: &mut dyn std::io::Write, + mut filter: &mut dyn FnMut(&Section<'_>) -> bool, ) -> std::io::Result<()> { let nl = self.detect_newline_style(); @@ -65,8 +65,8 @@ impl File<'_> { /// Stream ourselves to the given `out`, in order to reproduce this file mostly losslessly /// as it was parsed. - pub fn write_to(&self, out: impl std::io::Write) -> std::io::Result<()> { - self.write_to_filter(out, |_| true) + pub fn write_to(&self, out: &mut dyn std::io::Write) -> std::io::Result<()> { + self.write_to_filter(out, &mut |_| true) } } @@ -76,7 +76,7 @@ pub(crate) fn ends_with_newline(e: &[crate::parse::Event<'_>], nl: impl AsRef<[u } e.iter() .rev() - .take_while(|e| e.to_bstr_lossy().iter().all(|b| b.is_ascii_whitespace())) + .take_while(|e| e.to_bstr_lossy().iter().all(u8::is_ascii_whitespace)) .find_map(|e| e.to_bstr_lossy().contains_str(nl.as_ref()).then_some(true)) .unwrap_or(false) } diff --git a/vendor/gix-config/src/lib.rs b/vendor/gix-config/src/lib.rs index 9b2afd692..a62163ac3 100644 --- a/vendor/gix-config/src/lib.rs +++ b/vendor/gix-config/src/lib.rs @@ -1,7 +1,7 @@ //! # `gix_config` //! -//! This crate is a high performance `gix-config` file reader and writer. It -//! exposes a high level API to parse, read, and write [`gix-config` files]. +//! This crate is a high performance `git-config` file reader and writer. It +//! exposes a high level API to parse, read, and write [`git-config` files]. //! //! This crate has a few primary offerings and various accessory functions. The //! table below gives a brief explanation of all offerings, loosely in order @@ -10,8 +10,8 @@ //! | Offering | Description | Zero-copy? | //! | ------------- | --------------------------------------------------- | ----------------- | //! | [`File`] | Accelerated wrapper for reading and writing values. | On some reads[^1] | -//! | [`parse::State`] | Syntactic events for `gix-config` files. | Yes | -//! | value wrappers | Wrappers for `gix-config` value types. | Yes | +//! | [`parse::State`] | Syntactic events for `git-config` files. | Yes | +//! | value wrappers | Wrappers for `git-config` value types. | Yes | //! //! This crate also exposes efficient value normalization which unescapes //! characters and removes quotes through the `normalize_*` family of functions, @@ -24,7 +24,7 @@ //! //! [^1]: When read values do not need normalization and it wasn't parsed in 'owned' mode. //! -//! [`gix-config` files]: https://git-scm.com/docs/gix-config#_configuration_file +//! [`git-config` files]: https://git-scm.com/docs/git-config#_configuration_file //! [`File`]: crate::File //! [`parse::State`]: crate::parse::Events //! [`nom`]: https://github.com/Geal/nom diff --git a/vendor/gix-config/src/parse/event.rs b/vendor/gix-config/src/parse/event.rs index b7b96934d..f528e2077 100644 --- a/vendor/gix-config/src/parse/event.rs +++ b/vendor/gix-config/src/parse/event.rs @@ -33,7 +33,7 @@ impl Event<'_> { /// Stream ourselves to the given `out`, in order to reproduce this event mostly losslessly /// as it was parsed. - pub fn write_to(&self, mut out: impl std::io::Write) -> std::io::Result<()> { + pub fn write_to(&self, mut out: &mut dyn std::io::Write) -> std::io::Result<()> { match self { Self::ValueNotDone(e) => { out.write_all(e.as_ref())?; diff --git a/vendor/gix-config/src/parse/events.rs b/vendor/gix-config/src/parse/events.rs index 24bb45253..f3f527500 100644 --- a/vendor/gix-config/src/parse/events.rs +++ b/vendor/gix-config/src/parse/events.rs @@ -10,26 +10,26 @@ use crate::{ /// A type store without allocation all events that are typically preceding the first section. pub type FrontMatterEvents<'a> = SmallVec<[Event<'a>; 8]>; -/// A zero-copy `gix-config` file parser. +/// A zero-copy `git-config` file parser. /// -/// This is parser exposes low-level syntactic events from a `gix-config` file. +/// This is parser exposes low-level syntactic events from a `git-config` file. /// Generally speaking, you'll want to use [`File`] as it wraps -/// around the parser to provide a higher-level abstraction to a `gix-config` +/// around the parser to provide a higher-level abstraction to a `git-config` /// file, including querying, modifying, and updating values. /// /// This parser guarantees that the events emitted are sufficient to -/// reconstruct a `gix-config` file identical to the source `gix-config` +/// reconstruct a `git-config` file identical to the source `git-config` /// when writing it. /// /// # Differences between a `.ini` parser /// -/// While the `gix-config` format closely resembles the [`.ini` file format], +/// While the `git-config` format closely resembles the [`.ini` file format], /// there are subtle differences that make them incompatible. For one, the file /// format is not well defined, and there exists no formal specification to /// adhere to. /// /// For concrete examples, some notable differences are: -/// - `gix-config` sections permit subsections via either a quoted string +/// - `git-config` sections permit subsections via either a quoted string /// (`[some-section "subsection"]`) or via the deprecated dot notation /// (`[some-section.subsection]`). Successful parsing these section names is not /// well defined in typical `.ini` parsers. This parser will handle these cases @@ -45,7 +45,7 @@ pub type FrontMatterEvents<'a> = SmallVec<[Event<'a>; 8]>; /// which should be interpreted as `5hello world` after /// [normalization][crate::value::normalize()]. /// - Line continuations via a `\` character is supported (inside or outside of quotes) -/// - Whitespace handling similarly follows the `gix-config` specification as +/// - Whitespace handling similarly follows the `git-config` specification as /// closely as possible, where excess whitespace after a non-quoted value are /// trimmed, and line continuations onto a new line with excess spaces are kept. /// - Only equal signs (optionally padded by spaces) are valid name/value @@ -74,7 +74,7 @@ pub type FrontMatterEvents<'a> = SmallVec<[Event<'a>; 8]>; /// /// ## `Value` events do not immediately follow `Key` events /// -/// Consider the following `gix-config` example: +/// Consider the following `git-config` example: /// /// ```text /// [core] @@ -110,7 +110,7 @@ pub type FrontMatterEvents<'a> = SmallVec<[Event<'a>; 8]>; /// /// ## `KeyValueSeparator` event is not guaranteed to emit /// -/// Consider the following `gix-config` example: +/// Consider the following `git-config` example: /// /// ```text /// [core] @@ -139,7 +139,7 @@ pub type FrontMatterEvents<'a> = SmallVec<[Event<'a>; 8]>; /// /// ## Quoted values are not unquoted /// -/// Consider the following `gix-config` example: +/// Consider the following `git-config` example: /// /// ```text /// [core] @@ -175,7 +175,7 @@ pub type FrontMatterEvents<'a> = SmallVec<[Event<'a>; 8]>; /// /// ## Whitespace after line continuations are part of the value /// -/// Consider the following `gix-config` example: +/// Consider the following `git-config` example: /// /// ```text /// [some-section] @@ -183,7 +183,7 @@ pub type FrontMatterEvents<'a> = SmallVec<[Event<'a>; 8]>; /// c /// ``` /// -/// Because how `gix-config` treats continuations, the whitespace preceding `c` +/// Because how `git-config` treats continuations, the whitespace preceding `c` /// are in fact part of the value of `file`. The fully interpreted key/value /// pair is actually `file=a c`. As a result, the parser will provide this /// split value accordingly: @@ -208,7 +208,7 @@ pub type FrontMatterEvents<'a> = SmallVec<[Event<'a>; 8]>; /// /// [`File`]: crate::File /// [`.ini` file format]: https://en.wikipedia.org/wiki/INI_file -/// [`git`'s documentation]: https://git-scm.com/docs/gix-config#_configuration_file +/// [`git`'s documentation]: https://git-scm.com/docs/git-config#_configuration_file /// [`FromStr`]: std::str::FromStr /// [`From<&'_ str>`]: std::convert::From #[derive(Clone, Eq, PartialEq, Ord, PartialOrd, Hash, Debug, Default)] @@ -229,19 +229,19 @@ impl Events<'static> { input: &'a [u8], filter: Option<fn(&Event<'a>) -> bool>, ) -> Result<Events<'static>, parse::Error> { - from_bytes(input, |e| e.to_owned(), filter) + from_bytes(input, &|e| e.to_owned(), filter) } } impl<'a> Events<'a> { /// Attempt to zero-copy parse the provided bytes. On success, returns a /// [`Events`] that provides methods to accessing leading comments and sections - /// of a `gix-config` file and can be converted into an iterator of [`Event`] + /// of a `git-config` file and can be converted into an iterator of [`Event`] /// for higher level processing. /// /// Use `filter` to only include those events for which it returns true. pub fn from_bytes(input: &'a [u8], filter: Option<fn(&Event<'a>) -> bool>) -> Result<Events<'a>, parse::Error> { - from_bytes(input, std::convert::identity, filter) + from_bytes(input, &std::convert::identity, filter) } /// Attempt to zero-copy parse the provided `input` string. @@ -288,14 +288,14 @@ impl<'a> TryFrom<&'a [u8]> for Events<'a> { fn from_bytes<'a, 'b>( input: &'a [u8], - convert: impl Fn(Event<'a>) -> Event<'b>, + convert: &dyn Fn(Event<'a>) -> Event<'b>, filter: Option<fn(&Event<'a>) -> bool>, ) -> Result<Events<'b>, parse::Error> { let mut header = None; let mut events = section::Events::default(); let mut frontmatter = FrontMatterEvents::default(); let mut sections = Vec::new(); - parse::from_bytes(input, |e: Event<'_>| match e { + parse::from_bytes(input, &mut |e: Event<'_>| match e { Event::SectionHeader(next_header) => { match header.take() { None => { diff --git a/vendor/gix-config/src/parse/key.rs b/vendor/gix-config/src/parse/key.rs index b0e0376be..0ebb09e5f 100644 --- a/vendor/gix-config/src/parse/key.rs +++ b/vendor/gix-config/src/parse/key.rs @@ -14,8 +14,7 @@ pub struct Key<'a> { /// Parse `input` like `core.bare` or `remote.origin.url` as a `Key` to make its fields available, /// or `None` if there were not at least 2 tokens separated by `.`. /// Note that `input` isn't validated, and is `str` as ascii is a subset of UTF-8 which is required for any valid keys. -pub fn parse_unvalidated<'a>(input: impl Into<&'a BStr>) -> Option<Key<'a>> { - let input = input.into(); +pub fn parse_unvalidated(input: &BStr) -> Option<Key<'_>> { let mut tokens = input.splitn(2, |b| *b == b'.'); let section_name = tokens.next()?; let subsection_or_key = tokens.next()?; diff --git a/vendor/gix-config/src/parse/mod.rs b/vendor/gix-config/src/parse/mod.rs index e943a22b4..e11bbc1e3 100644 --- a/vendor/gix-config/src/parse/mod.rs +++ b/vendor/gix-config/src/parse/mod.rs @@ -1,4 +1,4 @@ -//! This module handles parsing a `gix-config` file. Generally speaking, you +//! This module handles parsing a `git-config` file. Generally speaking, you //! want to use a higher abstraction such as [`File`] unless you have some //! explicit reason to work with events instead. //! diff --git a/vendor/gix-config/src/parse/nom/mod.rs b/vendor/gix-config/src/parse/nom/mod.rs index 11d1dea6b..3ae45618d 100644 --- a/vendor/gix-config/src/parse/nom/mod.rs +++ b/vendor/gix-config/src/parse/nom/mod.rs @@ -1,38 +1,38 @@ use std::borrow::Cow; -use bstr::{BStr, BString, ByteSlice, ByteVec}; -use nom::{ - branch::alt, - bytes::complete::{tag, take_till, take_while}, - character::{ - complete::{char, one_of}, - is_space, - }, - combinator::{map, opt}, - error::{Error as NomError, ErrorKind}, - multi::{fold_many0, fold_many1}, - sequence::delimited, - IResult, +use bstr::{BStr, ByteSlice}; +use winnow::{ + combinator::{alt, delimited, fold_repeat, opt, preceded, repeat}, + error::{ErrorKind, InputError as NomError, ParserError as _}, + prelude::*, + stream::{Offset as _, Stream as _}, + token::{one_of, take_till0, take_while}, }; use crate::parse::{error::ParseNode, section, Comment, Error, Event}; /// Attempt to zero-copy parse the provided bytes, passing results to `dispatch`. -pub fn from_bytes<'a>(input: &'a [u8], mut dispatch: impl FnMut(Event<'a>)) -> Result<(), Error> { +pub fn from_bytes<'i>(mut input: &'i [u8], dispatch: &mut dyn FnMut(Event<'i>)) -> Result<(), Error> { + let start = input.checkpoint(); + let bom = unicode_bom::Bom::from(input); - let mut newlines = 0; - let (i, _) = fold_many0( + input.next_slice(bom.len()); + + fold_repeat( + 0.., alt(( - map(comment, Event::Comment), - map(take_spaces, |whitespace| Event::Whitespace(Cow::Borrowed(whitespace))), - map(take_newlines, |(newline, counter)| { - newlines += counter; - Event::Newline(Cow::Borrowed(newline)) - }), + comment.map(Event::Comment), + take_spaces1.map(|whitespace| Event::Whitespace(Cow::Borrowed(whitespace))), + |i: &mut &'i [u8]| { + let newline = take_newlines1.parse_next(i)?; + let o = Event::Newline(Cow::Borrowed(newline)); + Ok(o) + }, )), || (), |_acc, event| dispatch(event), - )(&input[bom.len()..]) + ) + .parse_next(&mut input) // I don't think this can panic. many0 errors if the child parser returns // a success where the input was not consumed, but alt will only return Ok // if one of its children succeed. However, all of it's children are @@ -40,108 +40,101 @@ pub fn from_bytes<'a>(input: &'a [u8], mut dispatch: impl FnMut(Event<'a>)) -> R // can never occur. .expect("many0(alt(...)) panicked. Likely a bug in one of the children parsers."); - if i.is_empty() { + if input.is_empty() { return Ok(()); } let mut node = ParseNode::SectionHeader; - let res = fold_many1( - |i| section(i, &mut node, &mut dispatch), - || (), - |_acc, additional_newlines| { - newlines += additional_newlines; - }, - )(i); - let (i, _) = res.map_err(|_| Error { - line_number: newlines, - last_attempted_parser: node, - parsed_until: i.as_bstr().into(), + let res = repeat(1.., |i: &mut &'i [u8]| section(i, &mut node, dispatch)) + .map(|()| ()) + .parse_next(&mut input); + res.map_err(|_| { + let newlines = newlines_from(input, start); + Error { + line_number: newlines, + last_attempted_parser: node, + parsed_until: input.as_bstr().into(), + } })?; // This needs to happen after we collect sections, otherwise the line number // will be off. - if !i.is_empty() { + if !input.is_empty() { + let newlines = newlines_from(input, start); return Err(Error { line_number: newlines, last_attempted_parser: node, - parsed_until: i.as_bstr().into(), + parsed_until: input.as_bstr().into(), }); } Ok(()) } -fn comment(i: &[u8]) -> IResult<&[u8], Comment<'_>> { - let (i, comment_tag) = one_of(";#")(i)?; - let (i, comment) = take_till(|c| c == b'\n')(i)?; - Ok(( - i, - Comment { - tag: comment_tag as u8, - text: Cow::Borrowed(comment.as_bstr()), - }, - )) +fn newlines_from(input: &[u8], start: winnow::stream::Checkpoint<&[u8]>) -> usize { + let offset = input.offset_from(&start); + let mut start_input = input; + start_input.reset(start); + start_input.next_slice(offset).iter().filter(|c| **c == b'\n').count() +} + +fn comment<'i>(i: &mut &'i [u8]) -> PResult<Comment<'i>, NomError<&'i [u8]>> { + ( + one_of([';', '#']), + take_till0(|c| c == b'\n').map(|text: &[u8]| Cow::Borrowed(text.as_bstr())), + ) + .map(|(tag, text)| Comment { tag, text }) + .parse_next(i) } #[cfg(test)] mod tests; -fn section<'a>(i: &'a [u8], node: &mut ParseNode, dispatch: &mut impl FnMut(Event<'a>)) -> IResult<&'a [u8], usize> { - let (mut i, header) = section_header(i)?; +fn section<'i>( + i: &mut &'i [u8], + node: &mut ParseNode, + dispatch: &mut dyn FnMut(Event<'i>), +) -> PResult<(), NomError<&'i [u8]>> { + let start = i.checkpoint(); + let header = section_header(i).map_err(|e| { + i.reset(start); + e + })?; dispatch(Event::SectionHeader(header)); - let mut newlines = 0; - // This would usually be a many0(alt(...)), the manual loop allows us to // optimize vec insertions loop { - let old_i = i; + let start = i.checkpoint(); - if let Ok((new_i, v)) = take_spaces(i) { - if old_i != new_i { - i = new_i; - dispatch(Event::Whitespace(Cow::Borrowed(v.as_bstr()))); - } + if let Some(v) = opt(take_spaces1).parse_next(i)? { + dispatch(Event::Whitespace(Cow::Borrowed(v.as_bstr()))); } - if let Ok((new_i, (v, new_newlines))) = take_newlines(i) { - if old_i != new_i { - i = new_i; - newlines += new_newlines; - dispatch(Event::Newline(Cow::Borrowed(v.as_bstr()))); - } + if let Some(v) = opt(take_newlines1).parse_next(i)? { + dispatch(Event::Newline(Cow::Borrowed(v.as_bstr()))); } - if let Ok((new_i, new_newlines)) = key_value_pair(i, node, dispatch) { - if old_i != new_i { - i = new_i; - newlines += new_newlines; - } - } + key_value_pair(i, node, dispatch)?; - if let Ok((new_i, comment)) = comment(i) { - if old_i != new_i { - i = new_i; - dispatch(Event::Comment(comment)); - } + if let Some(comment) = opt(comment).parse_next(i)? { + dispatch(Event::Comment(comment)); } - if old_i == i { + if i.offset_from(&start) == 0 { break; } } - Ok((i, newlines)) + Ok(()) } -fn section_header(i: &[u8]) -> IResult<&[u8], section::Header<'_>> { - let (i, _) = char('[')(i)?; +fn section_header<'i>(i: &mut &'i [u8]) -> PResult<section::Header<'i>, NomError<&'i [u8]>> { // No spaces must be between section name and section start - let (i, name) = take_while(|c: u8| c.is_ascii_alphanumeric() || c == b'-' || c == b'.')(i)?; + let name = preceded('[', take_while(1.., is_section_char).map(bstr::ByteSlice::as_bstr)).parse_next(i)?; - let name = name.as_bstr(); - if let Ok((i, _)) = char::<_, NomError<&[u8]>>(']')(i) { + if opt(one_of::<_, _, NomError<&[u8]>>(']')).parse_next(i)?.is_some() { // Either section does not have a subsection or using deprecated // subsection syntax at this point. let header = match memchr::memrchr(b'.', name.as_bytes()) { @@ -158,303 +151,226 @@ fn section_header(i: &[u8]) -> IResult<&[u8], section::Header<'_>> { }; if header.name.is_empty() { - return Err(nom::Err::Error(NomError { - input: i, - code: ErrorKind::NoneOf, - })); + return Err(winnow::error::ErrMode::from_error_kind(i, ErrorKind::Fail)); } - return Ok((i, header)); + return Ok(header); } // Section header must be using modern subsection syntax at this point. - - let (i, whitespace) = take_spaces(i)?; - let (i, subsection_name) = delimited(char('"'), opt(sub_section), tag("\"]"))(i)?; - - Ok(( - i, - section::Header { + (take_spaces1, delimited('"', opt(sub_section), "\"]")) + .map(|(whitespace, subsection_name)| section::Header { name: section::Name(Cow::Borrowed(name)), separator: Some(Cow::Borrowed(whitespace)), subsection_name, - }, - )) + }) + .parse_next(i) } -fn sub_section(i: &[u8]) -> IResult<&[u8], Cow<'_, BStr>> { - let (rest, (found_escape, consumed)) = sub_section_delegate(i, &mut |_| ())?; - if found_escape { - let mut buf = BString::default(); - sub_section_delegate(i, &mut |b| buf.push_byte(b)).map(|(i, _)| (i, buf.into())) - } else { - Ok((rest, i[..consumed].as_bstr().into())) - } +fn is_section_char(c: u8) -> bool { + c.is_ascii_alphanumeric() || c == b'-' || c == b'.' } -fn sub_section_delegate<'a>(i: &'a [u8], push_byte: &mut dyn FnMut(u8)) -> IResult<&'a [u8], (bool, usize)> { - let mut cursor = 0; - let mut bytes = i.iter().copied(); - let mut found_terminator = false; - let mut found_escape = false; - while let Some(mut b) = bytes.next() { - cursor += 1; - if b == b'\n' || b == 0 { - return Err(nom::Err::Error(NomError { - input: &i[cursor..], - code: ErrorKind::NonEmpty, - })); - } - if b == b'"' { - found_terminator = true; - break; - } - if b == b'\\' { - b = bytes.next().ok_or_else(|| { - nom::Err::Error(NomError { - input: &i[cursor..], - code: ErrorKind::NonEmpty, - }) - })?; - found_escape = true; - cursor += 1; - if b == b'\n' { - return Err(nom::Err::Error(NomError { - input: &i[cursor..], - code: ErrorKind::NonEmpty, - })); - } - } - push_byte(b); +fn sub_section<'i>(i: &mut &'i [u8]) -> PResult<Cow<'i, BStr>, NomError<&'i [u8]>> { + let mut output = Cow::Borrowed(Default::default()); + if let Some(sub) = opt(subsection_subset).parse_next(i)? { + output = Cow::Borrowed(sub.as_bstr()); } - - if !found_terminator { - return Err(nom::Err::Error(NomError { - input: &i[cursor..], - code: ErrorKind::NonEmpty, - })); + while let Some(sub) = opt(subsection_subset).parse_next(i)? { + output.to_mut().extend(sub); } - Ok((&i[cursor - 1..], (found_escape, cursor - 1))) + Ok(output) +} + +fn subsection_subset<'i>(i: &mut &'i [u8]) -> PResult<&'i [u8], NomError<&'i [u8]>> { + alt((subsection_unescaped, subsection_escaped_char)).parse_next(i) +} + +fn subsection_unescaped<'i>(i: &mut &'i [u8]) -> PResult<&'i [u8], NomError<&'i [u8]>> { + take_while(1.., is_subsection_unescaped_char).parse_next(i) +} + +fn subsection_escaped_char<'i>(i: &mut &'i [u8]) -> PResult<&'i [u8], NomError<&'i [u8]>> { + preceded('\\', one_of(is_subsection_escapeable_char).recognize()).parse_next(i) } -fn key_value_pair<'a>( - i: &'a [u8], +fn is_subsection_escapeable_char(c: u8) -> bool { + c != b'\n' +} + +fn is_subsection_unescaped_char(c: u8) -> bool { + c != b'"' && c != b'\\' && c != b'\n' && c != 0 +} + +fn key_value_pair<'i>( + i: &mut &'i [u8], node: &mut ParseNode, - dispatch: &mut impl FnMut(Event<'a>), -) -> IResult<&'a [u8], usize> { + dispatch: &mut dyn FnMut(Event<'i>), +) -> PResult<(), NomError<&'i [u8]>> { *node = ParseNode::Name; - let (i, name) = config_name(i)?; + if let Some(name) = opt(config_name).parse_next(i)? { + dispatch(Event::SectionKey(section::Key(Cow::Borrowed(name)))); - dispatch(Event::SectionKey(section::Key(Cow::Borrowed(name)))); + if let Some(whitespace) = opt(take_spaces1).parse_next(i)? { + dispatch(Event::Whitespace(Cow::Borrowed(whitespace))); + } - let (i, whitespace) = opt(take_spaces)(i)?; - if let Some(whitespace) = whitespace { - dispatch(Event::Whitespace(Cow::Borrowed(whitespace))); + *node = ParseNode::Value; + config_value(i, dispatch) + } else { + Ok(()) } - - *node = ParseNode::Value; - let (i, newlines) = config_value(i, dispatch)?; - Ok((i, newlines)) } /// Parses the config name of a config pair. Assumes the input has already been /// trimmed of any leading whitespace. -fn config_name(i: &[u8]) -> IResult<&[u8], &BStr> { - if i.is_empty() { - return Err(nom::Err::Error(NomError { - input: i, - code: ErrorKind::NonEmpty, - })); - } - - if !i[0].is_ascii_alphabetic() { - return Err(nom::Err::Error(NomError { - input: i, - code: ErrorKind::Alpha, - })); - } - - let (i, name) = take_while(|c: u8| c.is_ascii_alphanumeric() || c == b'-')(i)?; - Ok((i, name.as_bstr())) +fn config_name<'i>(i: &mut &'i [u8]) -> PResult<&'i BStr, NomError<&'i [u8]>> { + ( + one_of(|c: u8| c.is_ascii_alphabetic()), + take_while(0.., |c: u8| c.is_ascii_alphanumeric() || c == b'-'), + ) + .recognize() + .map(bstr::ByteSlice::as_bstr) + .parse_next(i) } -fn config_value<'a>(i: &'a [u8], dispatch: &mut impl FnMut(Event<'a>)) -> IResult<&'a [u8], usize> { - if let (i, Some(_)) = opt(char('='))(i)? { +fn config_value<'i>(i: &mut &'i [u8], dispatch: &mut dyn FnMut(Event<'i>)) -> PResult<(), NomError<&'i [u8]>> { + if opt('=').parse_next(i)?.is_some() { dispatch(Event::KeyValueSeparator); - let (i, whitespace) = opt(take_spaces)(i)?; - if let Some(whitespace) = whitespace { + if let Some(whitespace) = opt(take_spaces1).parse_next(i)? { dispatch(Event::Whitespace(Cow::Borrowed(whitespace))); } - let (i, newlines) = value_impl(i, dispatch)?; - Ok((i, newlines)) + value_impl(i, dispatch) } else { // This is a special way of denoting 'empty' values which a lot of code depends on. // Hence, rather to fix this everywhere else, leave it here and fix it where it matters, namely // when it's about differentiating between a missing key-value separator, and one followed by emptiness. dispatch(Event::Value(Cow::Borrowed("".into()))); - Ok((i, 0)) + Ok(()) } } /// Handles parsing of known-to-be values. This function handles both single /// line values as well as values that are continuations. -fn value_impl<'a>(i: &'a [u8], dispatch: &mut impl FnMut(Event<'a>)) -> IResult<&'a [u8], usize> { - let (i, value_end, newlines, mut dispatch) = { - let new_err = |code| nom::Err::Error(NomError { input: i, code }); - let mut value_end = None::<usize>; - let mut value_start: usize = 0; - let mut newlines = 0; - - let mut prev_char_was_backslash = false; - // This is required to ignore comment markers if they're in a quote. - let mut is_in_quotes = false; - // Used to determine if we return a Value or Value{Not,}Done - let mut partial_value_found = false; - let mut last_value_index: usize = 0; - - let mut bytes = i.iter(); - while let Some(mut c) = bytes.next() { - if prev_char_was_backslash { - prev_char_was_backslash = false; - let mut consumed = 1; - if *c == b'\r' { - c = bytes.next().ok_or_else(|| new_err(ErrorKind::Escaped))?; - if *c != b'\n' { - return Err(new_err(ErrorKind::Tag)); - } - consumed += 1; - } +fn value_impl<'i>(i: &mut &'i [u8], dispatch: &mut dyn FnMut(Event<'i>)) -> PResult<(), NomError<&'i [u8]>> { + let start_checkpoint = i.checkpoint(); + let mut value_start_checkpoint = i.checkpoint(); + let mut value_end = None; - match c { - b'\n' => { - partial_value_found = true; - let backslash = 1; - dispatch(Event::ValueNotDone(Cow::Borrowed( - i[value_start..last_value_index - backslash].as_bstr(), - ))); - let nl_end = last_value_index + consumed; - dispatch(Event::Newline(Cow::Borrowed(i[last_value_index..nl_end].as_bstr()))); - value_start = nl_end; - value_end = None; - newlines += 1; - - last_value_index += consumed; - } - b'n' | b't' | b'\\' | b'b' | b'"' => { - last_value_index += 1; - } - _ => { - return Err(new_err(ErrorKind::Escaped)); - } + // This is required to ignore comment markers if they're in a quote. + let mut is_in_quotes = false; + // Used to determine if we return a Value or Value{Not,}Done + let mut partial_value_found = false; + + loop { + let _ = take_while(0.., |c| !matches!(c, b'\n' | b'\\' | b'"' | b';' | b'#')).parse_next(i)?; + if let Some(c) = i.next_token() { + match c { + b'\n' => { + value_end = Some(i.offset_from(&value_start_checkpoint) - 1); + break; } - } else { - match c { - b'\n' => { - value_end = last_value_index.into(); - break; - } - b';' | b'#' if !is_in_quotes => { - value_end = last_value_index.into(); - break; - } - b'\\' => prev_char_was_backslash = true, - b'"' => is_in_quotes = !is_in_quotes, - _ => {} + b';' | b'#' if !is_in_quotes => { + value_end = Some(i.offset_from(&value_start_checkpoint) - 1); + break; } - last_value_index += 1; - } - } + b'\\' => { + let escaped_index = i.offset_from(&value_start_checkpoint); + let escape_index = escaped_index - 1; + let Some(mut c) = i.next_token() else { + i.reset(start_checkpoint); + return Err(winnow::error::ErrMode::from_error_kind(i, ErrorKind::Token)); + }; + let mut consumed = 1; + if c == b'\r' { + c = i.next_token().ok_or_else(|| { + i.reset(start_checkpoint); + winnow::error::ErrMode::from_error_kind(i, ErrorKind::Token) + })?; + if c != b'\n' { + i.reset(start_checkpoint); + return Err(winnow::error::ErrMode::from_error_kind(i, ErrorKind::Slice)); + } + consumed += 1; + } - if prev_char_was_backslash { - return Err(new_err(ErrorKind::Escaped)); - } + match c { + b'\n' => { + partial_value_found = true; - if is_in_quotes { - return Err(new_err(ErrorKind::Tag)); - } + i.reset(value_start_checkpoint); + + let value = i.next_slice(escape_index).as_bstr(); + dispatch(Event::ValueNotDone(Cow::Borrowed(value))); + + i.next_token(); - let value_end = match value_end { - None => { - if last_value_index == 0 { - dispatch(Event::Value(Cow::Borrowed("".into()))); - return Ok((&i[0..], newlines)); - } else { - i.len() + let nl = i.next_slice(consumed).as_bstr(); + dispatch(Event::Newline(Cow::Borrowed(nl))); + + value_start_checkpoint = i.checkpoint(); + value_end = None; + } + b'n' | b't' | b'\\' | b'b' | b'"' => {} + _ => { + i.reset(start_checkpoint); + return Err(winnow::error::ErrMode::from_error_kind(i, ErrorKind::Token)); + } + } } + b'"' => is_in_quotes = !is_in_quotes, + _ => {} } - Some(idx) => idx, - }; + } else { + break; + } + } + if is_in_quotes { + i.reset(start_checkpoint); + return Err(winnow::error::ErrMode::from_error_kind(i, ErrorKind::Slice)); + } - let dispatch = move |value: &'a [u8]| { - if partial_value_found { - dispatch(Event::ValueDone(Cow::Borrowed(value.as_bstr()))); + let value_end = match value_end { + None => { + let last_value_index = i.offset_from(&value_start_checkpoint); + if last_value_index == 0 { + dispatch(Event::Value(Cow::Borrowed("".into()))); + return Ok(()); } else { - dispatch(Event::Value(Cow::Borrowed(value.as_bstr()))); + last_value_index } - }; - (&i[value_start..], value_end - value_start, newlines, dispatch) - }; - - let (i, remainder_value) = { - let value_end_no_trailing_whitespace = i[..value_end] - .iter() - .enumerate() - .rev() - .find_map(|(idx, b)| (!b.is_ascii_whitespace()).then_some(idx + 1)) - .unwrap_or(0); - ( - &i[value_end_no_trailing_whitespace..], - &i[..value_end_no_trailing_whitespace], - ) + } + Some(idx) => idx, }; - dispatch(remainder_value); + i.reset(value_start_checkpoint); + let value_end_no_trailing_whitespace = i[..value_end] + .iter() + .enumerate() + .rev() + .find_map(|(idx, b)| (!b.is_ascii_whitespace()).then_some(idx + 1)) + .unwrap_or(0); + let remainder_value = i.next_slice(value_end_no_trailing_whitespace); + + if partial_value_found { + dispatch(Event::ValueDone(Cow::Borrowed(remainder_value.as_bstr()))); + } else { + dispatch(Event::Value(Cow::Borrowed(remainder_value.as_bstr()))); + } - Ok((i, newlines)) + Ok(()) } -fn take_spaces(i: &[u8]) -> IResult<&[u8], &BStr> { - let (i, v) = take_while(|c: u8| c.is_ascii() && is_space(c))(i)?; - if v.is_empty() { - Err(nom::Err::Error(NomError { - input: i, - code: ErrorKind::Eof, - })) - } else { - Ok((i, v.as_bstr())) - } +fn take_spaces1<'i>(i: &mut &'i [u8]) -> PResult<&'i BStr, NomError<&'i [u8]>> { + take_while(1.., winnow::stream::AsChar::is_space) + .map(bstr::ByteSlice::as_bstr) + .parse_next(i) } -fn take_newlines(i: &[u8]) -> IResult<&[u8], (&BStr, usize)> { - let mut counter = 0; - let mut consumed_bytes = 0; - let mut next_must_be_newline = false; - for b in i.iter().copied() { - if !b.is_ascii() { - break; - }; - if b == b'\r' { - if next_must_be_newline { - break; - } - next_must_be_newline = true; - continue; - }; - if b == b'\n' { - counter += 1; - consumed_bytes += if next_must_be_newline { 2 } else { 1 }; - next_must_be_newline = false; - } else { - break; - } - } - let (v, i) = i.split_at(consumed_bytes); - if v.is_empty() { - Err(nom::Err::Error(NomError { - input: i, - code: ErrorKind::Eof, - })) - } else { - Ok((i, (v.as_bstr(), counter))) - } +fn take_newlines1<'i>(i: &mut &'i [u8]) -> PResult<&'i BStr, NomError<&'i [u8]>> { + repeat(1.., alt(("\r\n", "\n"))) + .map(|()| ()) + .recognize() + .map(bstr::ByteSlice::as_bstr) + .parse_next(i) } diff --git a/vendor/gix-config/src/parse/nom/tests.rs b/vendor/gix-config/src/parse/nom/tests.rs index f6e8c3d92..d9679222f 100644 --- a/vendor/gix-config/src/parse/nom/tests.rs +++ b/vendor/gix-config/src/parse/nom/tests.rs @@ -1,13 +1,15 @@ use super::*; mod section_headers { + use winnow::prelude::*; + use super::section_header; use crate::parse::tests::util::{fully_consumed, section_header as parsed_section_header}; #[test] fn no_subsection() { assert_eq!( - section_header(b"[hello]").unwrap(), + section_header.parse_peek(b"[hello]").unwrap(), fully_consumed(parsed_section_header("hello", None)), ); } @@ -15,7 +17,7 @@ mod section_headers { #[test] fn modern_subsection() { assert_eq!( - section_header(br#"[hello "world"]"#).unwrap(), + section_header.parse_peek(br#"[hello "world"]"#).unwrap(), fully_consumed(parsed_section_header("hello", (" ", "world"))), ); } @@ -23,7 +25,7 @@ mod section_headers { #[test] fn escaped_subsection() { assert_eq!( - section_header(br#"[hello "foo\\bar\""]"#).unwrap(), + section_header.parse_peek(br#"[hello "foo\\bar\""]"#).unwrap(), fully_consumed(parsed_section_header("hello", (" ", r#"foo\bar""#))), ); } @@ -31,11 +33,11 @@ mod section_headers { #[test] fn deprecated_subsection() { assert_eq!( - section_header(br#"[hello.world]"#).unwrap(), + section_header.parse_peek(br#"[hello.world]"#).unwrap(), fully_consumed(parsed_section_header("hello", (".", "world"))) ); assert_eq!( - section_header(br#"[Hello.World]"#).unwrap(), + section_header.parse_peek(br#"[Hello.World]"#).unwrap(), fully_consumed(parsed_section_header("Hello", (".", "World"))) ); } @@ -43,7 +45,7 @@ mod section_headers { #[test] fn empty_legacy_subsection_name() { assert_eq!( - section_header(br#"[hello-world.]"#).unwrap(), + section_header.parse_peek(br#"[hello-world.]"#).unwrap(), fully_consumed(parsed_section_header("hello-world", (".", ""))) ); } @@ -51,7 +53,7 @@ mod section_headers { #[test] fn empty_modern_subsection_name() { assert_eq!( - section_header(br#"[hello ""]"#).unwrap(), + section_header.parse_peek(br#"[hello ""]"#).unwrap(), fully_consumed(parsed_section_header("hello", (" ", ""))) ); } @@ -59,55 +61,55 @@ mod section_headers { #[test] fn backslashes_in_subsections_do_not_escape_newlines_or_tabs() { assert_eq!( - section_header(br#"[hello "single \ \\ \t \n \0"]"#).unwrap(), - fully_consumed(parsed_section_header("hello", (" ", r#"single \ t n 0"#))) + section_header.parse_peek(br#"[hello "single \ \\ \t \n \0"]"#).unwrap(), + fully_consumed(parsed_section_header("hello", (" ", r"single \ t n 0"))) ); } #[test] fn newline_in_header() { - assert!(section_header(b"[hello\n]").is_err()); + assert!(section_header.parse_peek(b"[hello\n]").is_err()); } #[test] fn newline_in_sub_section() { - assert!(section_header(b"[hello \"hello\n\"]").is_err()); + assert!(section_header.parse_peek(b"[hello \"hello\n\"]").is_err()); } #[test] fn null_byt_in_sub_section() { - assert!(section_header(b"[hello \"hello\0\"]").is_err()); + assert!(section_header.parse_peek(b"[hello \"hello\0\"]").is_err()); } #[test] fn escaped_newline_in_sub_section() { - assert!(section_header(b"[hello \"hello\\\n\"]").is_err()); + assert!(section_header.parse_peek(b"[hello \"hello\\\n\"]").is_err()); } #[test] fn eof_after_escape_in_sub_section() { - assert!(section_header(b"[hello \"hello\\").is_err()); + assert!(section_header.parse_peek(b"[hello \"hello\\").is_err()); } #[test] fn null_byte_in_header() { - assert!(section_header(b"[hello\0]").is_err()); + assert!(section_header.parse_peek(b"[hello\0]").is_err()); } #[test] fn invalid_characters_in_section() { - assert!(section_header(b"[$]").is_err()); + assert!(section_header.parse_peek(b"[$]").is_err()); } #[test] fn invalid_characters_in_legacy_sub_section() { - assert!(section_header(b"[hello.$]").is_err()); - assert!(section_header(b"[hello. world]").is_err()); + assert!(section_header.parse_peek(b"[hello.$]").is_err()); + assert!(section_header.parse_peek(b"[hello. world]").is_err()); } #[test] fn right_brace_in_subsection_name() { assert_eq!( - section_header(br#"[hello "]"]"#).unwrap(), + section_header.parse_peek(br#"[hello "]"]"#).unwrap(), fully_consumed(parsed_section_header("hello", (" ", "]"))) ); } @@ -116,49 +118,51 @@ mod section_headers { mod sub_section { use std::borrow::Cow; + use winnow::prelude::*; + use super::sub_section; #[test] fn zero_copy_simple() { - let actual = sub_section(b"name\"").unwrap().1; + let actual = sub_section.parse_peek(b"name\"").unwrap().1; assert_eq!(actual.as_ref(), "name"); assert!(matches!(actual, Cow::Borrowed(_))); } #[test] fn escapes_need_allocation() { - let actual = sub_section(br#"\x\t\n\0\\\"""#).unwrap().1; + let actual = sub_section.parse_peek(br#"\x\t\n\0\\\"""#).unwrap().1; assert_eq!(actual.as_ref(), r#"xtn0\""#); assert!(matches!(actual, Cow::Owned(_))); } } mod config_name { - use nom::combinator::all_consuming; + use winnow::prelude::*; use super::config_name; use crate::parse::tests::util::fully_consumed; #[test] fn just_name() { - assert_eq!(config_name(b"name").unwrap(), fully_consumed("name".into())); + assert_eq!(config_name.parse_peek(b"name").unwrap(), fully_consumed("name".into())); } #[test] fn must_start_with_alphabetic() { - assert!(config_name(b"4aaa").is_err()); - assert!(config_name(b"-aaa").is_err()); + assert!(config_name.parse_peek(b"4aaa").is_err()); + assert!(config_name.parse_peek(b"-aaa").is_err()); } #[test] fn only_a_subset_of_characters_is_allowed() { - assert!(all_consuming(config_name)(b"Name$_").is_err()); - assert!(all_consuming(config_name)(b"other#").is_err()); + assert!(config_name.parse(b"Name$_").is_err()); + assert!(config_name.parse(b"other#").is_err()); } #[test] fn cannot_be_empty() { - assert!(config_name(b"").is_err()); + assert!(config_name.parse_peek(b"").is_err()); } } @@ -174,28 +178,25 @@ mod section { Event, Section, }; - fn section<'a>(i: &'a [u8], node: &mut ParseNode) -> nom::IResult<&'a [u8], (Section<'a>, usize)> { + fn section<'a>(mut i: &'a [u8], node: &mut ParseNode) -> winnow::IResult<&'a [u8], Section<'a>> { let mut header = None; let mut events = section::Events::default(); - super::section(i, node, &mut |e| match &header { + super::section(&mut i, node, &mut |e| match &header { None => { header = Some(e); } Some(_) => events.push(e), }) - .map(|(i, o)| { + .map(|_| { ( i, - ( - Section { - header: match header.expect("header set") { - Event::SectionHeader(header) => header, - _ => unreachable!("unexpected"), - }, - events, + Section { + header: match header.expect("header set") { + Event::SectionHeader(header) => header, + _ => unreachable!("unexpected"), }, - o, - ), + events, + }, ) }) } @@ -205,22 +206,19 @@ mod section { let mut node = ParseNode::SectionHeader; assert_eq!( section(b"[a] k = \r\n", &mut node).unwrap(), - fully_consumed(( - Section { - header: parsed_section_header("a", None), - events: vec![ - whitespace_event(" "), - name_event("k"), - whitespace_event(" "), - Event::KeyValueSeparator, - whitespace_event(" "), - value_event(""), - newline_custom_event("\r\n") - ] - .into(), - }, - 1 - )), + fully_consumed(Section { + header: parsed_section_header("a", None), + events: vec![ + whitespace_event(" "), + name_event("k"), + whitespace_event(" "), + Event::KeyValueSeparator, + whitespace_event(" "), + value_event(""), + newline_custom_event("\r\n") + ] + .into(), + }), ); } @@ -229,41 +227,35 @@ mod section { let mut node = ParseNode::SectionHeader; assert_eq!( section(b"[a] k = v\r\n", &mut node).unwrap(), - fully_consumed(( - Section { - header: parsed_section_header("a", None), - events: vec![ - whitespace_event(" "), - name_event("k"), - whitespace_event(" "), - Event::KeyValueSeparator, - whitespace_event(" "), - value_event("v"), - newline_custom_event("\r\n") - ] - .into(), - }, - 1 - )), + fully_consumed(Section { + header: parsed_section_header("a", None), + events: vec![ + whitespace_event(" "), + name_event("k"), + whitespace_event(" "), + Event::KeyValueSeparator, + whitespace_event(" "), + value_event("v"), + newline_custom_event("\r\n") + ] + .into(), + }), ); assert_eq!( section(b"[a] k = \r\n", &mut node).unwrap(), - fully_consumed(( - Section { - header: parsed_section_header("a", None), - events: vec![ - whitespace_event(" "), - name_event("k"), - whitespace_event(" "), - Event::KeyValueSeparator, - whitespace_event(" "), - value_event(""), - newline_custom_event("\r\n") - ] - .into(), - }, - 1 - )), + fully_consumed(Section { + header: parsed_section_header("a", None), + events: vec![ + whitespace_event(" "), + name_event("k"), + whitespace_event(" "), + Event::KeyValueSeparator, + whitespace_event(" "), + value_event(""), + newline_custom_event("\r\n") + ] + .into(), + }), ); } @@ -272,13 +264,10 @@ mod section { let mut node = ParseNode::SectionHeader; assert_eq!( section(b"[test]", &mut node).unwrap(), - fully_consumed(( - Section { - header: parsed_section_header("test", None), - events: Default::default() - }, - 0 - )), + fully_consumed(Section { + header: parsed_section_header("test", None), + events: Default::default() + }), ); } @@ -291,33 +280,30 @@ mod section { d = "lol""#; assert_eq!( section(section_data, &mut node).unwrap(), - fully_consumed(( - Section { - header: parsed_section_header("hello", None), - events: vec![ - newline_event(), - whitespace_event(" "), - name_event("a"), - whitespace_event(" "), - Event::KeyValueSeparator, - whitespace_event(" "), - value_event("b"), - newline_event(), - whitespace_event(" "), - name_event("c"), - value_event(""), - newline_event(), - whitespace_event(" "), - name_event("d"), - whitespace_event(" "), - Event::KeyValueSeparator, - whitespace_event(" "), - value_event("\"lol\"") - ] - .into() - }, - 3 - )) + fully_consumed(Section { + header: parsed_section_header("hello", None), + events: vec![ + newline_event(), + whitespace_event(" "), + name_event("a"), + whitespace_event(" "), + Event::KeyValueSeparator, + whitespace_event(" "), + value_event("b"), + newline_event(), + whitespace_event(" "), + name_event("c"), + value_event(""), + newline_event(), + whitespace_event(" "), + name_event("d"), + whitespace_event(" "), + Event::KeyValueSeparator, + whitespace_event(" "), + value_event("\"lol\"") + ] + .into() + }) ); } @@ -327,38 +313,32 @@ mod section { let section_data = b"[a] k="; assert_eq!( section(section_data, &mut node).unwrap(), - fully_consumed(( - Section { - header: parsed_section_header("a", None), - events: vec![ - whitespace_event(" "), - name_event("k"), - Event::KeyValueSeparator, - value_event(""), - ] - .into() - }, - 0 - )) + fully_consumed(Section { + header: parsed_section_header("a", None), + events: vec![ + whitespace_event(" "), + name_event("k"), + Event::KeyValueSeparator, + value_event(""), + ] + .into() + }) ); let section_data = b"[a] k=\n"; assert_eq!( section(section_data, &mut node).unwrap(), - fully_consumed(( - Section { - header: parsed_section_header("a", None), - events: vec![ - whitespace_event(" "), - name_event("k"), - Event::KeyValueSeparator, - value_event(""), - newline_event(), - ] - .into() - }, - 1 - )) + fully_consumed(Section { + header: parsed_section_header("a", None), + events: vec![ + whitespace_event(" "), + name_event("k"), + Event::KeyValueSeparator, + value_event(""), + newline_event(), + ] + .into() + }) ); } @@ -371,34 +351,31 @@ mod section { d = "lol""#; assert_eq!( section(section_data, &mut node).unwrap(), - fully_consumed(( - Section { - header: parsed_section_header("hello", None), - events: vec![ - newline_event(), - whitespace_event(" "), - name_event("a"), - whitespace_event(" "), - Event::KeyValueSeparator, - whitespace_event(" "), - value_event("b"), - newline_event(), - whitespace_event(" "), - name_event("c"), - Event::KeyValueSeparator, - value_event(""), - newline_event(), - whitespace_event(" "), - name_event("d"), - whitespace_event(" "), - Event::KeyValueSeparator, - whitespace_event(" "), - value_event("\"lol\"") - ] - .into() - }, - 3 - )) + fully_consumed(Section { + header: parsed_section_header("hello", None), + events: vec![ + newline_event(), + whitespace_event(" "), + name_event("a"), + whitespace_event(" "), + Event::KeyValueSeparator, + whitespace_event(" "), + value_event("b"), + newline_event(), + whitespace_event(" "), + name_event("c"), + Event::KeyValueSeparator, + value_event(""), + newline_event(), + whitespace_event(" "), + name_event("d"), + whitespace_event(" "), + Event::KeyValueSeparator, + whitespace_event(" "), + value_event("\"lol\"") + ] + .into() + }) ); } @@ -407,32 +384,26 @@ mod section { let mut node = ParseNode::SectionHeader; assert_eq!( section(b"[hello] c", &mut node).unwrap(), - fully_consumed(( - Section { - header: parsed_section_header("hello", None), - events: vec![whitespace_event(" "), name_event("c"), value_event("")].into() - }, - 0 - )) + fully_consumed(Section { + header: parsed_section_header("hello", None), + events: vec![whitespace_event(" "), name_event("c"), value_event("")].into() + }) ); assert_eq!( section(b"[hello] c\nd", &mut node).unwrap(), - fully_consumed(( - Section { - header: parsed_section_header("hello", None), - events: vec![ - whitespace_event(" "), - name_event("c"), - value_event(""), - newline_event(), - name_event("d"), - value_event("") - ] - .into() - }, - 1 - )) + fully_consumed(Section { + header: parsed_section_header("hello", None), + events: vec![ + whitespace_event(" "), + name_event("c"), + value_event(""), + newline_event(), + name_event("d"), + value_event("") + ] + .into() + }) ); } @@ -446,39 +417,36 @@ mod section { c = d"#; assert_eq!( section(section_data, &mut node).unwrap(), - fully_consumed(( - Section { - header: parsed_section_header("hello", None), - events: vec![ - whitespace_event(" "), - comment_event(';', " commentA"), - newline_event(), - whitespace_event(" "), - name_event("a"), - whitespace_event(" "), - Event::KeyValueSeparator, - whitespace_event(" "), - value_event("b"), - whitespace_event(" "), - comment_event('#', " commentB"), - newline_event(), - whitespace_event(" "), - comment_event(';', " commentC"), - newline_event(), - whitespace_event(" "), - comment_event(';', " commentD"), - newline_event(), - whitespace_event(" "), - name_event("c"), - whitespace_event(" "), - Event::KeyValueSeparator, - whitespace_event(" "), - value_event("d"), - ] - .into() - }, - 4 - )) + fully_consumed(Section { + header: parsed_section_header("hello", None), + events: vec![ + whitespace_event(" "), + comment_event(';', " commentA"), + newline_event(), + whitespace_event(" "), + name_event("a"), + whitespace_event(" "), + Event::KeyValueSeparator, + whitespace_event(" "), + value_event("b"), + whitespace_event(" "), + comment_event('#', " commentB"), + newline_event(), + whitespace_event(" "), + comment_event(';', " commentC"), + newline_event(), + whitespace_event(" "), + comment_event(';', " commentD"), + newline_event(), + whitespace_event(" "), + name_event("c"), + whitespace_event(" "), + Event::KeyValueSeparator, + whitespace_event(" "), + value_event("d"), + ] + .into() + }) ); } @@ -488,27 +456,24 @@ mod section { // This test is absolute hell. Good luck if this fails. assert_eq!( section(b"[section] a = 1 \"\\\"\\\na ; e \"\\\"\\\nd # \"b\t ; c", &mut node).unwrap(), - fully_consumed(( - Section { - header: parsed_section_header("section", None), - events: vec![ - whitespace_event(" "), - name_event("a"), - whitespace_event(" "), - Event::KeyValueSeparator, - whitespace_event(" "), - value_not_done_event(r#"1 "\""#), - newline_event(), - value_not_done_event(r#"a ; e "\""#), - newline_event(), - value_done_event("d"), - whitespace_event(" "), - comment_event('#', " \"b\t ; c"), - ] - .into() - }, - 2 - )) + fully_consumed(Section { + header: parsed_section_header("section", None), + events: vec![ + whitespace_event(" "), + name_event("a"), + whitespace_event(" "), + Event::KeyValueSeparator, + whitespace_event(" "), + value_not_done_event(r#"1 "\""#), + newline_event(), + value_not_done_event(r#"a ; e "\""#), + newline_event(), + value_done_event("d"), + whitespace_event(" "), + comment_event('#', " \"b\t ; c"), + ] + .into() + }) ); } @@ -517,23 +482,20 @@ mod section { let mut node = ParseNode::SectionHeader; assert_eq!( section(b"[section \"a\"] b =\"\\\n;\";a", &mut node).unwrap(), - fully_consumed(( - Section { - header: parsed_section_header("section", (" ", "a")), - events: vec![ - whitespace_event(" "), - name_event("b"), - whitespace_event(" "), - Event::KeyValueSeparator, - value_not_done_event("\""), - newline_event(), - value_done_event(";\""), - comment_event(';', "a"), - ] - .into() - }, - 1 - )) + fully_consumed(Section { + header: parsed_section_header("section", (" ", "a")), + events: vec![ + whitespace_event(" "), + name_event("b"), + whitespace_event(" "), + Event::KeyValueSeparator, + value_not_done_event("\""), + newline_event(), + value_done_event(";\""), + comment_event(';', "a"), + ] + .into() + }) ); } @@ -542,19 +504,16 @@ mod section { let mut node = ParseNode::SectionHeader; assert_eq!( section(b"[s]hello #world", &mut node).unwrap(), - fully_consumed(( - Section { - header: parsed_section_header("s", None), - events: vec![ - name_event("hello"), - whitespace_event(" "), - value_event(""), - comment_event('#', "world"), - ] - .into() - }, - 0 - )) + fully_consumed(Section { + header: parsed_section_header("s", None), + events: vec![ + name_event("hello"), + whitespace_event(" "), + value_event(""), + comment_event('#', "world"), + ] + .into() + }) ); } } @@ -567,8 +526,8 @@ mod value_continuation { tests::util::{into_events, newline_custom_event, newline_event, value_done_event, value_not_done_event}, }; - pub fn value_impl<'a>(i: &'a [u8], events: &mut section::Events<'a>) -> nom::IResult<&'a [u8], ()> { - super::value_impl(i, &mut |e| events.push(e)).map(|t| (t.0, ())) + pub fn value_impl<'a>(mut i: &'a [u8], events: &mut section::Events<'a>) -> winnow::IResult<&'a [u8], ()> { + super::value_impl(&mut i, &mut |e| events.push(e)).map(|_| (i, ())) } #[test] @@ -797,6 +756,7 @@ mod value_no_continuation { } #[test] + #[allow(clippy::needless_raw_string_hashes)] fn trans_escaped_comment_marker_not_consumed() { let mut events = section::Events::default(); assert_eq!(value_impl(br##"hello"#"world; a"##, &mut events).unwrap().0, b"; a"); @@ -817,7 +777,7 @@ mod value_no_continuation { #[test] fn invalid_escape() { - assert!(value_impl(br#"\x"#, &mut Default::default()).is_err()); + assert!(value_impl(br"\x", &mut Default::default()).is_err()); } #[test] @@ -827,7 +787,7 @@ mod value_no_continuation { #[test] fn incomplete_escape() { - assert!(value_impl(br#"hello world\"#, &mut Default::default()).is_err()); + assert!(value_impl(br"hello world\", &mut Default::default()).is_err()); } } @@ -840,18 +800,25 @@ mod key_value_pair { }; fn key_value<'a>( - i: &'a [u8], + mut i: &'a [u8], node: &mut ParseNode, events: &mut section::Events<'a>, - ) -> nom::IResult<&'a [u8], ()> { - super::key_value_pair(i, node, &mut |e| events.push(e)).map(|t| (t.0, ())) + ) -> winnow::IResult<&'a [u8], ()> { + super::key_value_pair(&mut i, node, &mut |e| events.push(e)).map(|_| (i, ())) } #[test] fn nonascii_is_allowed_for_values_but_not_for_keys() { let mut node = ParseNode::SectionHeader; let mut vec = Default::default(); - assert!(key_value("你好".as_bytes(), &mut node, &mut vec).is_err()); + assert!( + key_value("你好".as_bytes(), &mut node, &mut vec).is_ok(), + "Verifying `is_ok` because bad keys get ignored, the caller parser handles this as error" + ); + assert_eq!(vec, into_events(vec![])); + + let mut node = ParseNode::SectionHeader; + let mut vec = Default::default(); assert!(key_value("a = 你好 ".as_bytes(), &mut node, &mut vec).is_ok()); assert_eq!( vec, @@ -895,13 +862,15 @@ mod key_value_pair { } mod comment { + use winnow::prelude::*; + use super::comment; use crate::parse::tests::util::{comment as parsed_comment, fully_consumed}; #[test] fn semicolon() { assert_eq!( - comment(b"; this is a semicolon comment").unwrap(), + comment.parse_peek(b"; this is a semicolon comment").unwrap(), fully_consumed(parsed_comment(';', " this is a semicolon comment")), ); } @@ -909,7 +878,7 @@ mod comment { #[test] fn octothorpe() { assert_eq!( - comment(b"# this is an octothorpe comment").unwrap(), + comment.parse_peek(b"# this is an octothorpe comment").unwrap(), fully_consumed(parsed_comment('#', " this is an octothorpe comment")), ); } @@ -917,7 +886,7 @@ mod comment { #[test] fn multiple_markers() { assert_eq!( - comment(b"###### this is an octothorpe comment").unwrap(), + comment.parse_peek(b"###### this is an octothorpe comment").unwrap(), fully_consumed(parsed_comment('#', "##### this is an octothorpe comment")), ); } diff --git a/vendor/gix-config/src/parse/section/header.rs b/vendor/gix-config/src/parse/section/header.rs index 341edcdd5..14c2519cf 100644 --- a/vendor/gix-config/src/parse/section/header.rs +++ b/vendor/gix-config/src/parse/section/header.rs @@ -147,7 +147,7 @@ fn escape_subsection(name: &BStr) -> Cow<'_, BStr> { let mut buf = Vec::with_capacity(name.len()); for b in name.iter().copied() { match b { - b'\\' => buf.push_str(br#"\\"#), + b'\\' => buf.push_str(br"\\"), b'"' => buf.push_str(br#"\""#), _ => buf.push(b), } diff --git a/vendor/gix-config/src/types.rs b/vendor/gix-config/src/types.rs index 7110906b8..5abd48785 100644 --- a/vendor/gix-config/src/types.rs +++ b/vendor/gix-config/src/types.rs @@ -47,10 +47,10 @@ pub enum Source { EnvOverride, } -/// High level `gix-config` reader and writer. +/// High level `git-config` reader and writer. /// /// This is the full-featured implementation that can deserialize, serialize, -/// and edit `gix-config` files without loss of whitespace or comments. +/// and edit `git-config` files without loss of whitespace or comments. /// /// # 'multivar' behavior /// @@ -88,8 +88,8 @@ pub enum Source { /// ``` /// # use std::borrow::Cow; /// # use std::convert::TryFrom; -/// # let gix_config = gix_config::File::try_from("[core]a=b\n[core]\na=c\na=d").unwrap(); -/// assert_eq!(gix_config.raw_value("core", None, "a").unwrap().as_ref(), "d"); +/// # let git_config = gix_config::File::try_from("[core]a=b\n[core]\na=c\na=d").unwrap(); +/// assert_eq!(git_config.raw_value("core", None, "a").unwrap().as_ref(), "d"); /// ``` /// /// Consider the `multi` variants of the methods instead, if you want to work @@ -104,7 +104,7 @@ pub enum Source { #[derive(Eq, Clone, Debug, Default)] pub struct File<'event> { /// The list of events that occur before any section. Since a - /// `gix-config` file prohibits global values, this vec is limited to only + /// `git-config` file prohibits global values, this vec is limited to only /// comment, newline, and whitespace events. pub(crate) frontmatter_events: crate::parse::FrontMatterEvents<'event>, /// Frontmatter events to be placed after the given section. @@ -113,7 +113,7 @@ pub struct File<'event> { /// variant of `SectionBodyIds`. pub(crate) section_lookup_tree: HashMap<section::Name<'event>, Vec<SectionBodyIdsLut<'event>>>, /// This indirection with the SectionId as the key is critical to flexibly - /// supporting `gix-config` sections, as duplicated keys are permitted. + /// supporting `git-config` sections, as duplicated keys are permitted. pub(crate) sections: HashMap<SectionId, file::Section<'event>>, /// Internal monotonically increasing counter for section ids. pub(crate) section_id_counter: usize, |