diff options
author | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-05-04 12:41:41 +0000 |
---|---|---|
committer | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-05-04 12:41:41 +0000 |
commit | 10ee2acdd26a7f1298c6f6d6b7af9b469fe29b87 (patch) | |
tree | bdffd5d80c26cf4a7a518281a204be1ace85b4c1 /vendor/gix-config-value | |
parent | Releasing progress-linux version 1.70.0+dfsg1-9~progress7.99u1. (diff) | |
download | rustc-10ee2acdd26a7f1298c6f6d6b7af9b469fe29b87.tar.xz rustc-10ee2acdd26a7f1298c6f6d6b7af9b469fe29b87.zip |
Merging upstream version 1.70.0+dfsg2.
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'vendor/gix-config-value')
-rw-r--r-- | vendor/gix-config-value/.cargo-checksum.json | 1 | ||||
-rw-r--r-- | vendor/gix-config-value/CHANGELOG.md | 224 | ||||
-rw-r--r-- | vendor/gix-config-value/Cargo.toml | 62 | ||||
-rw-r--r-- | vendor/gix-config-value/src/boolean.rs | 99 | ||||
-rw-r--r-- | vendor/gix-config-value/src/color.rs | 346 | ||||
-rw-r--r-- | vendor/gix-config-value/src/integer.rs | 156 | ||||
-rw-r--r-- | vendor/gix-config-value/src/lib.rs | 47 | ||||
-rw-r--r-- | vendor/gix-config-value/src/path.rs | 195 | ||||
-rw-r--r-- | vendor/gix-config-value/src/types.rs | 48 | ||||
-rw-r--r-- | vendor/gix-config-value/tests/value/boolean.rs | 42 | ||||
-rw-r--r-- | vendor/gix-config-value/tests/value/color.rs | 199 | ||||
-rw-r--r-- | vendor/gix-config-value/tests/value/integer.rs | 74 | ||||
-rw-r--r-- | vendor/gix-config-value/tests/value/main.rs | 17 | ||||
-rw-r--r-- | vendor/gix-config-value/tests/value/path.rs | 129 |
14 files changed, 1639 insertions, 0 deletions
diff --git a/vendor/gix-config-value/.cargo-checksum.json b/vendor/gix-config-value/.cargo-checksum.json new file mode 100644 index 000000000..b8e695dec --- /dev/null +++ b/vendor/gix-config-value/.cargo-checksum.json @@ -0,0 +1 @@ +{"files":{"CHANGELOG.md":"d2d50cd8d923495354119d4dbcf3943f8bbfb91fff4d77deb893805c56ae9bbe","Cargo.toml":"8339f883c0a0d7144b5cdd01983ce1b2cc3f7fa54aa630f92252d018b251adf4","src/boolean.rs":"77a8302108c63f85e276408aeda80ffad98fa85ea5ce06b732b1fccba4118f0c","src/color.rs":"528e78fbe1e38171143013ff2fddeb1b8acc3f8f0d71427b99779311e263cdf3","src/integer.rs":"ab6288d4e2cf8ae3185f08697b38a2ea684e47f470614031d6deada7280dc010","src/lib.rs":"bbeff9e2bf6a037c9c6cdf9c15b9fc60cb58565602b80fccca0e977c46f302e5","src/path.rs":"3d44a4d2a3ac026cca91521d36e06b13de07bc21c32dcdde0f797eb0769a6c1a","src/types.rs":"990211343908621c6bb8c1d5dedd4402c490348744c047c45de58c1fbe979e9b","tests/value/boolean.rs":"105356f72445fae217444949a9dadf7d487682998bc3a37f8eb636c5c15da602","tests/value/color.rs":"6d8b93e13e689c2ffd96ad9f42d498a9fe9dfc5f1ae472bb4aa5fc9c63f7fefa","tests/value/integer.rs":"961e700fd2b3511d404471f91f46760a9e0fa7d70663055be476a15eded8a2ac","tests/value/main.rs":"f488f0fd4e508e45b83d81a191b0a932940b5ee6e8df9395f30d1b8d03b6f359","tests/value/path.rs":"253f1b73338c9d41b2b2cf280cd8a59f591c1296aecc96eeede4db4c0e0b63c9"},"package":"693d4a4ba0531e46fe558459557a5b29fb86c3e4b2666c1c0861d93c7c678331"}
\ No newline at end of file diff --git a/vendor/gix-config-value/CHANGELOG.md b/vendor/gix-config-value/CHANGELOG.md new file mode 100644 index 000000000..6e9d0068a --- /dev/null +++ b/vendor/gix-config-value/CHANGELOG.md @@ -0,0 +1,224 @@ +# Changelog + +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.10.2 (2023-02-17) + +### Bug Fixes + + - <csr-id-e14dc7d475373d2c266e84ff8f1826c68a34ab92/> note that crates have been renamed from `git-*` to `gix-*`. + This also means that the `git-*` prefixed crates of the `gitoxide` project + are effectively unmaintained. + Use the crates with the `gix-*` prefix instead. + + If you were using `git-repository`, then `gix` is its substitute. + +## 0.10.1 (2023-02-17) + +<csr-id-4ebe2ac05dc8bef3bc1783afca3fcfdc565c2aae/> + +### New Features (BREAKING) + + - <csr-id-3d8fa8fef9800b1576beab8a5bc39b821157a5ed/> upgrade edition to 2021 in most crates. + MSRV for this is 1.56, and we are now at 1.60 so should be compatible. + This isn't more than a patch release as it should break nobody + who is adhering to the MSRV, but let's be careful and mark it + breaking. + + Note that `git-features` and `git-pack` are still on edition 2018 + as they make use of a workaround to support (safe) mutable access + to non-overlapping entries in a slice which doesn't work anymore + in edition 2021. + +### Changed (BREAKING) + + - <csr-id-99905bacace8aed42b16d43f0f04cae996cb971c/> upgrade `bstr` to `1.0.1` + +### Other + + - <csr-id-4ebe2ac05dc8bef3bc1783afca3fcfdc565c2aae/> Actively discourage using `Boolean::try_from("")` explicitly. + Use `config.boolean(…)` instead. + +### Bug Fixes + + - <csr-id-38b92ba9615f9c90cfeed5bd050007168fa6df94/> build error on Android + +### New Features + + - <csr-id-3577aefc68d9aec149e0a0f4192f06d6de9ff531/> `Default` implementation for `Boolean` and `Integer` + - <csr-id-5f675d387e52a75ff7bd17a38516ce9778ea6b7e/> `Boolean::try_from(OsString)` + This makes getting booleans from the environment easier. + +### Changed + + - <csr-id-5ad296577d837b0699b4718fa2be3d0978c4e342/> `git-config` now uses `git-config-value`. + +### Documentation + + - <csr-id-39ed9eda62b7718d5109135e5ad406fb1fe2978c/> fix typos + +### Commit Statistics + +<csr-read-only-do-not-edit/> + + - 83 commits contributed to the release over the course of 172 calendar days. + - 8 commits were understood as [conventional](https://www.conventionalcommits.org). + - 3 unique issues were worked on: [#450](https://github.com/Byron/gitoxide/issues/450), [#470](https://github.com/Byron/gitoxide/issues/470), [#691](https://github.com/Byron/gitoxide/issues/691) + +### Thanks Clippy + +<csr-read-only-do-not-edit/> + +[Clippy](https://github.com/rust-lang/rust-clippy) helped 2 times to make code idiomatic. + +### Commit Details + +<csr-read-only-do-not-edit/> + +<details><summary>view details</summary> + + * **[#450](https://github.com/Byron/gitoxide/issues/450)** + - upgrade `bstr` to `1.0.1` ([`99905ba`](https://github.com/Byron/gitoxide/commit/99905bacace8aed42b16d43f0f04cae996cb971c)) + - `Boolean::try_from(OsString)` ([`5f675d3`](https://github.com/Byron/gitoxide/commit/5f675d387e52a75ff7bd17a38516ce9778ea6b7e)) + - fix windows tests ([`0f11a6d`](https://github.com/Byron/gitoxide/commit/0f11a6dea937903d40833037d063bb82e224d66d)) + - add changelog ([`c396ba1`](https://github.com/Byron/gitoxide/commit/c396ba17f3f674c3af7460534860fc0dc462d401)) + - `git-config` now uses `git-config-value`. ([`5ad2965`](https://github.com/Byron/gitoxide/commit/5ad296577d837b0699b4718fa2be3d0978c4e342)) + - port tests over as well ([`9b28df2`](https://github.com/Byron/gitoxide/commit/9b28df22b858b6f1c9ca9b07a5a1c0cc300b50f0)) + - copy all value code from git-config to the dedicated crate ([`edb1162`](https://github.com/Byron/gitoxide/commit/edb1162e284e343e2c575980854b8292de9c968f)) + - add new git-config-value crate ([`f87edf2`](https://github.com/Byron/gitoxide/commit/f87edf26c1cb795142fbe95e12c0dfc1166e4233)) + * **[#470](https://github.com/Byron/gitoxide/issues/470)** + - update changelogs prior to release ([`caa7a1b`](https://github.com/Byron/gitoxide/commit/caa7a1bdef74d7d3166a7e38127a59f5ab3cfbdd)) + * **[#691](https://github.com/Byron/gitoxide/issues/691)** + - set `rust-version` to 1.64 ([`55066ce`](https://github.com/Byron/gitoxide/commit/55066ce5fd71209abb5d84da2998b903504584bb)) + * **Uncategorized** + - Release gix-features v0.26.4, gix-actor v0.17.1, gix-glob v0.5.3, gix-path v0.7.1, gix-quote v0.4.1, gix-attributes v0.8.2, gix-config-value v0.10.1, gix-tempfile v3.0.2, gix-lock v3.0.2, gix-validate v0.7.2, gix-object v0.26.1, gix-ref v0.24.0, gix-sec v0.6.2, gix-config v0.16.1, gix-command v0.2.3, gix-prompt v0.3.2, gix-url v0.13.2, gix-credentials v0.9.1, gix-diff v0.26.1, gix-discover v0.13.0, gix-hashtable v0.1.1, gix-bitmap v0.2.1, gix-traverse v0.22.1, gix-index v0.12.3, gix-mailmap v0.9.2, gix-chunk v0.4.1, gix-pack v0.30.2, gix-odb v0.40.2, gix-packetline v0.14.2, gix-transport v0.25.4, gix-protocol v0.26.3, gix-revision v0.10.3, gix-refspec v0.7.2, gix-worktree v0.12.2, gix v0.36.0 ([`6efd0d3`](https://github.com/Byron/gitoxide/commit/6efd0d31fbeca31ab7319aa2ac97bb31dc4ce055)) + - Release gix-date v0.4.2, gix-hash v0.10.2, gix-features v0.26.4, gix-actor v0.17.1, gix-glob v0.5.3, gix-path v0.7.1, gix-quote v0.4.1, gix-attributes v0.8.2, gix-config-value v0.10.1, gix-tempfile v3.0.2, gix-lock v3.0.2, gix-validate v0.7.2, gix-object v0.26.1, gix-ref v0.24.0, gix-sec v0.6.2, gix-config v0.16.1, gix-command v0.2.3, gix-prompt v0.3.2, gix-url v0.13.2, gix-credentials v0.9.1, gix-diff v0.26.1, gix-discover v0.13.0, gix-hashtable v0.1.1, gix-bitmap v0.2.1, gix-traverse v0.22.1, gix-index v0.12.3, gix-mailmap v0.9.2, gix-chunk v0.4.1, gix-pack v0.30.2, gix-odb v0.40.2, gix-packetline v0.14.2, gix-transport v0.25.4, gix-protocol v0.26.3, gix-revision v0.10.3, gix-refspec v0.7.2, gix-worktree v0.12.2, gix v0.36.0 ([`6ccc88a`](https://github.com/Byron/gitoxide/commit/6ccc88a8e4a56973b1a358cf72dc012ee3c75d56)) + - Merge branch 'rename-crates' into inform-about-gix-rename ([`c9275b9`](https://github.com/Byron/gitoxide/commit/c9275b99ea43949306d93775d9d78c98fb86cfb1)) + - rename `git-testtools` to `gix-testtools` ([`b65c33d`](https://github.com/Byron/gitoxide/commit/b65c33d256cfed65d11adeff41132e3e58754089)) + - adjust to renaming of `git-pack` to `gix-pack` ([`1ee81ad`](https://github.com/Byron/gitoxide/commit/1ee81ad310285ee4aa118118a2be3810dbace574)) + - adjust to renaming of `git-odb` to `gix-odb` ([`476e2ad`](https://github.com/Byron/gitoxide/commit/476e2ad1a64e9e3f0d7c8651d5bcbee36cd78241)) + - adjust to renaming of `git-index` to `gix-index` ([`86db5e0`](https://github.com/Byron/gitoxide/commit/86db5e09fc58ce66b252dc13b8d7e2c48e4d5062)) + - adjust to renaming of `git-diff` to `gix-diff` ([`49a163e`](https://github.com/Byron/gitoxide/commit/49a163ec8b18f0e5fcd05a315de16d5d8be7650e)) + - adjust to renaming of `git-commitgraph` to `gix-commitgraph` ([`f1dd0a3`](https://github.com/Byron/gitoxide/commit/f1dd0a3366e31259af029da73228e8af2f414244)) + - adjust to renaming of `git-mailmap` to `gix-mailmap` ([`2e28c56`](https://github.com/Byron/gitoxide/commit/2e28c56bb9f70de6f97439818118d3a25859698f)) + - adjust to renaming of `git-discover` to `gix-discover` ([`53adfe1`](https://github.com/Byron/gitoxide/commit/53adfe1c34e9ea3b27067a97b5e7ac80b351c441)) + - adjust to renaming of `git-chunk` to `gix-chunk` ([`59194e3`](https://github.com/Byron/gitoxide/commit/59194e3a07853eae0624ebc4907478d1de4f7599)) + - adjust to renaming of `git-bitmap` to `gix-bitmap` ([`75f2a07`](https://github.com/Byron/gitoxide/commit/75f2a079b17489f62bc43e1f1d932307375c4f9d)) + - adjust to renaming for `git-protocol` to `gix-protocol` ([`823795a`](https://github.com/Byron/gitoxide/commit/823795addea3810243cab7936cd8ec0137cbc224)) + - adjust to renaming of `git-refspec` to `gix-refspec` ([`c958802`](https://github.com/Byron/gitoxide/commit/c9588020561577736faa065e7e5b5bb486ca8fe1)) + - adjust to renaming of `git-revision` to `gix-revision` ([`ee0ee84`](https://github.com/Byron/gitoxide/commit/ee0ee84607c2ffe11ee75f27a31903db68afed02)) + - adjust to renaming of `git-transport` to `gix-transport` ([`b2ccf71`](https://github.com/Byron/gitoxide/commit/b2ccf716dc4425bb96651d4d58806a3cc2da219e)) + - adjust to renaming of `git-credentials` to `gix-credentials` ([`6b18abc`](https://github.com/Byron/gitoxide/commit/6b18abcf2856f02ab938d535a65e51ac282bf94a)) + - adjust to renaming of `git-prompt` to `gix-prompt` ([`6a4654e`](https://github.com/Byron/gitoxide/commit/6a4654e0d10ab773dd219cb4b731c0fc1471c36d)) + - adjust to renaming of `git-command` to `gix-command` ([`d26b8e0`](https://github.com/Byron/gitoxide/commit/d26b8e046496894ae06b0bbfdba77196976cd975)) + - adjust to renaming of `git-packetline` to `gix-packetline` ([`5cbd22c`](https://github.com/Byron/gitoxide/commit/5cbd22cf42efb760058561c6c3bbcd4dab8c8be1)) + - adjust to renaming of `git-worktree` to `gix-worktree` ([`73a1282`](https://github.com/Byron/gitoxide/commit/73a12821b3d9b66ec1714d07dd27eb7a73e3a544)) + - adjust to renamining of `git-worktree` to `gix-worktree` ([`108bb1a`](https://github.com/Byron/gitoxide/commit/108bb1a634f4828853fb590e9fc125f79441dd38)) + - adjust to renaming of `git-url` to `gix-url` ([`b50817a`](https://github.com/Byron/gitoxide/commit/b50817aadb143e19f61f64e19b19ec1107d980c6)) + - adjust to renaming of `git-date` to `gix-date` ([`9a79ff2`](https://github.com/Byron/gitoxide/commit/9a79ff2d5cc74c1efad9f41e21095ae498cce00b)) + - adjust to renamining of `git-attributes` to `gix-attributes` ([`4a8b3b8`](https://github.com/Byron/gitoxide/commit/4a8b3b812ac26f2a2aee8ce8ca81591273383c84)) + - adjust to renaminig of `git-quote` to `gix-quote` ([`648025b`](https://github.com/Byron/gitoxide/commit/648025b7ca94411fdd0d90c53e5faede5fde6c8d)) + - adjust to renaming of `git-config` to `gix-config` ([`3a861c8`](https://github.com/Byron/gitoxide/commit/3a861c8f049f6502d3bcbdac752659aa1aeda46a)) + - adjust to renaming of `git-ref` to `gix-ref` ([`1f5f695`](https://github.com/Byron/gitoxide/commit/1f5f695407b034377d94b172465ff573562b3fc3)) + - adjust to renaming of `git-lock` to `gix-lock` ([`2028e78`](https://github.com/Byron/gitoxide/commit/2028e7884ae1821edeec81612f501e88e4722b17)) + - adjust to renaming of `git-tempfile` to `gix-tempfile` ([`b6cc3eb`](https://github.com/Byron/gitoxide/commit/b6cc3ebb5137084a6327af16a7d9364d8f092cc9)) + - adjust to renaming of `git-object` to `gix-object` ([`fc86a1e`](https://github.com/Byron/gitoxide/commit/fc86a1e710ad7bf076c25cc6f028ddcf1a5a4311)) + - adjust to renaming of `git-actor` to `gix-actor` ([`4dc9b44`](https://github.com/Byron/gitoxide/commit/4dc9b44dc52f2486ffa2040585c6897c1bf55df4)) + - adjust to renaming of `git-validate` to `gix-validate` ([`5e40ad0`](https://github.com/Byron/gitoxide/commit/5e40ad078af3d08cbc2ca81ce755c0ed8a065b4f)) + - adjust to renaming of `git-hash` to `gix-hash` ([`4a9d025`](https://github.com/Byron/gitoxide/commit/4a9d0257110c3efa61d08c8457c4545b200226d1)) + - adjust to renaming of `git-features` to `gix-features` ([`e2dd68a`](https://github.com/Byron/gitoxide/commit/e2dd68a417aad229e194ff20dbbfd77668096ec6)) + - adjust to renaming of `git-glob` to `gix-glob` ([`35b2a3a`](https://github.com/Byron/gitoxide/commit/35b2a3acbc8f2a03f151bc0a3863163844e0ca86)) + - adjust to renaming of `git-sec` to `gix-sec` ([`eabbb92`](https://github.com/Byron/gitoxide/commit/eabbb923bd5a32fc80fa80f96cfdc2ab7bb2ed17)) + - adapt to renaming of `git-path` to `gix-path` ([`d3bbcfc`](https://github.com/Byron/gitoxide/commit/d3bbcfccad80fc44ea8e7bf819f23adaca06ba2d)) + - adjust to rename of `git-config-value` to `gix-config-value` ([`622b3e1`](https://github.com/Byron/gitoxide/commit/622b3e1d0bffa0f8db73697960f9712024fac430)) + - rename gix-config-values to `gix-config-values` ([`df3f4b3`](https://github.com/Byron/gitoxide/commit/df3f4b3f923935b1a45e04cdaa457bd0352958da)) + - Release git-date v0.4.2, git-hash v0.10.2, git-features v0.26.2, git-actor v0.17.1, git-glob v0.5.3, git-path v0.7.1, git-quote v0.4.1, git-attributes v0.8.2, git-config-value v0.10.1, git-tempfile v3.0.2, git-lock v3.0.2, git-validate v0.7.2, git-object v0.26.1, git-ref v0.24.0, git-sec v0.6.2, git-config v0.16.0, git-command v0.2.3, git-prompt v0.3.2, git-url v0.13.2, git-credentials v0.9.1, git-diff v0.26.1, git-discover v0.13.0, git-hashtable v0.1.1, git-bitmap v0.2.1, git-traverse v0.22.1, git-index v0.12.3, git-mailmap v0.9.2, git-chunk v0.4.1, git-pack v0.30.2, git-odb v0.40.2, git-packetline v0.14.2, git-transport v0.25.4, git-protocol v0.26.3, git-revision v0.10.2, git-refspec v0.7.2, git-worktree v0.12.2, git-repository v0.34.0, safety bump 3 crates ([`c196d20`](https://github.com/Byron/gitoxide/commit/c196d206d57a310b1ce974a1cf0e7e6d6db5c4d6)) + - prepare changelogs prior to release ([`7c846d2`](https://github.com/Byron/gitoxide/commit/7c846d2102dc767366771925212712ef8cc9bf07)) + - Merge branch 'Lioness100/main' ([`1e544e8`](https://github.com/Byron/gitoxide/commit/1e544e82455bf9ecb5e3c2146280eaf7ecd81f16)) + - fix typos ([`39ed9ed`](https://github.com/Byron/gitoxide/commit/39ed9eda62b7718d5109135e5ad406fb1fe2978c)) + - thanks clippy ([`bac57dd`](https://github.com/Byron/gitoxide/commit/bac57dd05ea2d5a4ee45ef9350fa3f2e19474bc0)) + - Release git-date v0.3.1, git-features v0.25.0, git-actor v0.15.0, git-glob v0.5.1, git-path v0.7.0, git-attributes v0.7.0, git-config-value v0.10.0, git-lock v3.0.1, git-validate v0.7.1, git-object v0.24.0, git-ref v0.21.0, git-sec v0.6.0, git-config v0.13.0, git-prompt v0.3.0, git-url v0.12.0, git-credentials v0.8.0, git-diff v0.24.0, git-discover v0.10.0, git-traverse v0.20.0, git-index v0.10.0, git-mailmap v0.7.0, git-pack v0.28.0, git-odb v0.38.0, git-packetline v0.14.1, git-transport v0.24.0, git-protocol v0.25.0, git-revision v0.8.0, git-refspec v0.5.0, git-worktree v0.10.0, git-repository v0.30.0, safety bump 26 crates ([`e6b9906`](https://github.com/Byron/gitoxide/commit/e6b9906c486b11057936da16ed6e0ec450a0fb83)) + - prepare chnagelogs prior to git-repository release ([`7114bbb`](https://github.com/Byron/gitoxide/commit/7114bbb6732aa8571d4ab74f28ed3e26e9fbe4d0)) + - Actively discourage using `Boolean::try_from("")` explicitly. ([`4ebe2ac`](https://github.com/Byron/gitoxide/commit/4ebe2ac05dc8bef3bc1783afca3fcfdc565c2aae)) + - Merge branch 'main' into http-config ([`bcd9654`](https://github.com/Byron/gitoxide/commit/bcd9654e56169799eb706646da6ee1f4ef2021a9)) + - Release git-hash v0.10.0, git-features v0.24.0, git-date v0.3.0, git-actor v0.14.0, git-glob v0.5.0, git-path v0.6.0, git-quote v0.4.0, git-attributes v0.6.0, git-config-value v0.9.0, git-tempfile v3.0.0, git-lock v3.0.0, git-validate v0.7.0, git-object v0.23.0, git-ref v0.20.0, git-sec v0.5.0, git-config v0.12.0, git-command v0.2.0, git-prompt v0.2.0, git-url v0.11.0, git-credentials v0.7.0, git-diff v0.23.0, git-discover v0.9.0, git-bitmap v0.2.0, git-traverse v0.19.0, git-index v0.9.0, git-mailmap v0.6.0, git-chunk v0.4.0, git-pack v0.27.0, git-odb v0.37.0, git-packetline v0.14.0, git-transport v0.23.0, git-protocol v0.24.0, git-revision v0.7.0, git-refspec v0.4.0, git-worktree v0.9.0, git-repository v0.29.0, git-commitgraph v0.11.0, gitoxide-core v0.21.0, gitoxide v0.19.0, safety bump 28 crates ([`b2c301e`](https://github.com/Byron/gitoxide/commit/b2c301ef131ffe1871314e19f387cf10a8d2ac16)) + - prepare changelogs prior to release ([`e4648f8`](https://github.com/Byron/gitoxide/commit/e4648f827c97e9d13636d1bbdc83dd63436e6e5c)) + - Merge branch 'version2021' ([`0e4462d`](https://github.com/Byron/gitoxide/commit/0e4462df7a5166fe85c23a779462cdca8ee013e8)) + - upgrade edition to 2021 in most crates. ([`3d8fa8f`](https://github.com/Byron/gitoxide/commit/3d8fa8fef9800b1576beab8a5bc39b821157a5ed)) + - Release git-glob v0.4.2, git-config-value v0.8.2, git-lock v2.2.0, git-ref v0.19.0, git-config v0.11.0, git-discover v0.8.0, git-index v0.8.0, git-transport v0.22.0, git-protocol v0.23.0, git-worktree v0.8.0, git-repository v0.28.0, gitoxide-core v0.20.0, gitoxide v0.18.0, safety bump 9 crates ([`0c253b1`](https://github.com/Byron/gitoxide/commit/0c253b15143dcedfe4c66d64ab1ea6e097030651)) + - prepare changelogs prior to release ([`fe5721f`](https://github.com/Byron/gitoxide/commit/fe5721f888c64c79fe9a734a9e33b94a282f8d97)) + - Merge branch 'http-config' ([`665b53e`](https://github.com/Byron/gitoxide/commit/665b53e1c2e1de65fafa28b669f58977868bbc81)) + - `Default` implementation for `Boolean` and `Integer` ([`3577aef`](https://github.com/Byron/gitoxide/commit/3577aefc68d9aec149e0a0f4192f06d6de9ff531)) + - Release git-features v0.23.1, git-glob v0.4.1, git-config-value v0.8.1, git-tempfile v2.0.6, git-object v0.22.1, git-ref v0.18.0, git-sec v0.4.2, git-config v0.10.0, git-prompt v0.1.1, git-url v0.10.1, git-credentials v0.6.1, git-diff v0.21.0, git-discover v0.7.0, git-index v0.7.0, git-pack v0.25.0, git-odb v0.35.0, git-transport v0.21.1, git-protocol v0.22.0, git-refspec v0.3.1, git-worktree v0.7.0, git-repository v0.26.0, git-commitgraph v0.10.0, gitoxide-core v0.19.0, gitoxide v0.17.0, safety bump 9 crates ([`d071583`](https://github.com/Byron/gitoxide/commit/d071583c5576fdf5f7717765ffed5681792aa81f)) + - prepare changelogs prior to release ([`423af90`](https://github.com/Byron/gitoxide/commit/423af90c8202d62dc1ea4a76a0df6421d1f0aa06)) + - Merge branch 'main' into write-sparse-index (upgrade to Rust 1.65) ([`5406630`](https://github.com/Byron/gitoxide/commit/5406630466145990b5adbdadb59151036993060d)) + - thanks clippy ([`04cfa63`](https://github.com/Byron/gitoxide/commit/04cfa635a65ae34ad6d22391f2febd2ca7eabca9)) + - Merge branch 'main' into write-sparse-index ([`70963f5`](https://github.com/Byron/gitoxide/commit/70963f5d8e3b59ce6fe8bcc1844218ac717f3390)) + - Merge branch 'main' into gix-clone ([`64f81d7`](https://github.com/Byron/gitoxide/commit/64f81d78ae75a0e5914f431bbdc385a6d40f8835)) + - Merge branch 'fix/android_build' ([`8f64ecd`](https://github.com/Byron/gitoxide/commit/8f64ecdeb5345f6c1f4adcc7948f44bf1379e823)) + - build error on Android ([`38b92ba`](https://github.com/Byron/gitoxide/commit/38b92ba9615f9c90cfeed5bd050007168fa6df94)) + - Merge branch 'diff' ([`25a7726`](https://github.com/Byron/gitoxide/commit/25a7726377fbe400ea3c4927d04e9dec99802b7b)) + - Release git-hash v0.9.10, git-features v0.22.5, git-date v0.2.0, git-actor v0.12.0, git-glob v0.4.0, git-path v0.5.0, git-quote v0.3.0, git-attributes v0.4.0, git-config-value v0.8.0, git-tempfile v2.0.5, git-validate v0.6.0, git-object v0.21.0, git-ref v0.16.0, git-sec v0.4.0, git-config v0.8.0, git-discover v0.5.0, git-traverse v0.17.0, git-index v0.5.0, git-worktree v0.5.0, git-testtools v0.9.0, git-command v0.1.0, git-prompt v0.1.0, git-url v0.9.0, git-credentials v0.5.0, git-diff v0.19.0, git-mailmap v0.4.0, git-chunk v0.3.2, git-pack v0.23.0, git-odb v0.33.0, git-packetline v0.13.0, git-transport v0.20.0, git-protocol v0.20.0, git-revision v0.5.0, git-refspec v0.2.0, git-repository v0.24.0, git-commitgraph v0.9.0, gitoxide-core v0.18.0, gitoxide v0.16.0, safety bump 28 crates ([`29a043b`](https://github.com/Byron/gitoxide/commit/29a043be6808a3e9199a9b26bd076fe843afe4f4)) + - Merge branch 'filter-refs' ([`fd14489`](https://github.com/Byron/gitoxide/commit/fd14489f729172d615d0fa1e8dbd605e9eacf69d)) + - make fmt ([`535e967`](https://github.com/Byron/gitoxide/commit/535e967666c6da657ff1b7eff7c64ab27cafb182)) + - Merge branch 'filter-refs-by-spec' ([`5c05198`](https://github.com/Byron/gitoxide/commit/5c051986bd89590a9287d85d84c713d83dfab83a)) + - Release git-config-value v0.7.0 ([`21c0ab9`](https://github.com/Byron/gitoxide/commit/21c0ab9c60ee317f574633081354351b0c7e5d0e)) + - Release git-path v0.4.2, git-config-value v0.7.0 ([`c48fb31`](https://github.com/Byron/gitoxide/commit/c48fb3107d29f9a06868b0c6de40567063a656d1)) +</details> + +## 0.10.0 (2022-12-19) + +<csr-id-4ebe2ac05dc8bef3bc1783afca3fcfdc565c2aae/> + +### Other + + - <csr-id-4ebe2ac05dc8bef3bc1783afca3fcfdc565c2aae/> Actively discourage using `Boolean::try_from("")` explicitly. + Use `config.boolean(…)` instead. + +## 0.9.0 (2022-11-21) + +### New Features (BREAKING) + + - <csr-id-3d8fa8fef9800b1576beab8a5bc39b821157a5ed/> upgrade edition to 2021 in most crates. + MSRV for this is 1.56, and we are now at 1.60 so should be compatible. + This isn't more than a patch release as it should break nobody + who is adhering to the MSRV, but let's be careful and mark it + breaking. + + Note that `gix-features` and `gix-pack` are still on edition 2018 + as they make use of a workaround to support (safe) mutable access + to non-overlapping entries in a slice which doesn't work anymore + in edition 2021. + +## 0.8.2 (2022-11-17) + +### New Features + + - <csr-id-3577aefc68d9aec149e0a0f4192f06d6de9ff531/> `Default` implementation for `Boolean` and `Integer` + +## 0.8.1 (2022-11-06) + +### Bug Fixes + + - <csr-id-38b92ba9615f9c90cfeed5bd050007168fa6df94/> build error on Android + +## 0.8.0 (2022-09-20) + +### New Features + + - <csr-id-5f675d387e52a75ff7bd17a38516ce9778ea6b7e/> `Boolean::try_from(OsString)` + This makes getting booleans from the environment easier. + +### Changed (BREAKING) + + - <csr-id-99905bacace8aed42b16d43f0f04cae996cb971c/> upgrade `bstr` to `1.0.1` + +## v0.7.0 (2022-08-29) + +### Changed + + - <csr-id-5ad296577d837b0699b4718fa2be3d0978c4e342/> `gix-config` now uses `gix-config-value`. + diff --git a/vendor/gix-config-value/Cargo.toml b/vendor/gix-config-value/Cargo.toml new file mode 100644 index 000000000..d05e41b2b --- /dev/null +++ b/vendor/gix-config-value/Cargo.toml @@ -0,0 +1,62 @@ +# THIS FILE IS AUTOMATICALLY GENERATED BY CARGO +# +# When uploading crates to the registry Cargo will automatically +# "normalize" Cargo.toml files for maximal compatibility +# with all versions of Cargo and also rewrite `path` dependencies +# to registry (e.g., crates.io) dependencies. +# +# If you are reading this file be aware that the original Cargo.toml +# will likely look very different (and much more reasonable). +# See Cargo.toml.orig for the original contents. + +[package] +edition = "2021" +rust-version = "1.64" +name = "gix-config-value" +version = "0.10.1" +authors = ["Sebastian Thiel <sebastian.thiel@icloud.com>"] +description = "A crate of the gitoxide project providing gix-config value parsing" +license = "MIT/Apache-2.0" +repository = "https://github.com/Byron/gitoxide" + +[package.metadata.docs.rs] +all-features = true +features = ["document-features"] +rustdoc-args = [ + "--cfg", + "docsrs", +] + +[lib] +doctest = false + +[dependencies.bitflags] +version = "1.3.2" + +[dependencies.bstr] +version = "1.0.1" + +[dependencies.document-features] +version = "0.2.0" +optional = true + +[dependencies.gix-path] +version = "^0.7.1" + +[dependencies.serde] +version = "1.0.114" +features = ["derive"] +optional = true +default-features = false + +[dependencies.thiserror] +version = "1.0.32" + +[features] +serde1 = [ + "serde", + "bstr/serde", +] + +[target."cfg(not(windows))".dependencies.libc] +version = "0.2" diff --git a/vendor/gix-config-value/src/boolean.rs b/vendor/gix-config-value/src/boolean.rs new file mode 100644 index 000000000..908e11a30 --- /dev/null +++ b/vendor/gix-config-value/src/boolean.rs @@ -0,0 +1,99 @@ +use std::{borrow::Cow, convert::TryFrom, ffi::OsString, fmt::Display}; + +use bstr::{BStr, BString, ByteSlice}; + +use crate::{Boolean, Error}; + +fn bool_err(input: impl Into<BString>) -> Error { + Error::new( + "Booleans need to be 'no', 'off', 'false', '' or 'yes', 'on', 'true' or any number", + input, + ) +} + +impl TryFrom<OsString> for Boolean { + type Error = Error; + + fn try_from(value: OsString) -> Result<Self, Self::Error> { + let value = gix_path::os_str_into_bstr(&value) + .map_err(|_| Error::new("Illformed UTF-8", std::path::Path::new(&value).display().to_string()))?; + Self::try_from(value) + } +} + +/// # Warning +/// +/// The direct usage of `try_from("string")` is discouraged as it will produce the wrong result for values +/// obtained from `core.bool-implicit-true`, which have no separator and are implicitly true. +/// This method chooses to work correctly for `core.bool-empty=`, which is an empty string and resolves +/// to being `false`. +/// +/// Instead of this, obtain booleans with `config.boolean(…)`, which handles the case were no separator is +/// present correctly. +impl TryFrom<&BStr> for Boolean { + type Error = Error; + + fn try_from(value: &BStr) -> Result<Self, Self::Error> { + if parse_true(value) { + Ok(Boolean(true)) + } else if parse_false(value) { + Ok(Boolean(false)) + } else { + use std::str::FromStr; + if let Some(integer) = value.to_str().ok().and_then(|s| i64::from_str(s).ok()) { + Ok(Boolean(integer != 0)) + } else { + Err(bool_err(value)) + } + } + } +} + +impl Boolean { + /// Return true if the boolean is a true value. + /// + /// Note that the inner value is accessible directly as well. + pub fn is_true(self) -> bool { + self.0 + } +} + +impl TryFrom<Cow<'_, BStr>> for Boolean { + type Error = Error; + fn try_from(c: Cow<'_, BStr>) -> Result<Self, Self::Error> { + Self::try_from(c.as_ref()) + } +} + +impl Display for Boolean { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + self.0.fmt(f) + } +} + +impl From<Boolean> for bool { + fn from(b: Boolean) -> Self { + b.0 + } +} + +#[cfg(feature = "serde")] +impl serde::Serialize for Boolean { + fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error> + where + S: serde::Serializer, + { + serializer.serialize_bool(self.0) + } +} + +fn parse_true(value: &BStr) -> bool { + value.eq_ignore_ascii_case(b"yes") || value.eq_ignore_ascii_case(b"on") || value.eq_ignore_ascii_case(b"true") +} + +fn parse_false(value: &BStr) -> bool { + value.eq_ignore_ascii_case(b"no") + || value.eq_ignore_ascii_case(b"off") + || value.eq_ignore_ascii_case(b"false") + || value.is_empty() +} diff --git a/vendor/gix-config-value/src/color.rs b/vendor/gix-config-value/src/color.rs new file mode 100644 index 000000000..74e0dd4ac --- /dev/null +++ b/vendor/gix-config-value/src/color.rs @@ -0,0 +1,346 @@ +#![allow(missing_docs)] +use std::{borrow::Cow, convert::TryFrom, fmt::Display, str::FromStr}; + +use bstr::{BStr, BString}; + +use crate::{Color, Error}; + +impl Display for Color { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + let mut write_space = None; + if let Some(fg) = self.foreground { + fg.fmt(f)?; + write_space = Some(()); + } + + if let Some(bg) = self.background { + if write_space.take().is_some() { + write!(f, " ")?; + } + bg.fmt(f)?; + write_space = Some(()) + } + + if !self.attributes.is_empty() { + if write_space.take().is_some() { + write!(f, " ")?; + } + self.attributes.fmt(f)?; + } + Ok(()) + } +} + +fn color_err(input: impl Into<BString>) -> Error { + Error::new( + "Colors are specific color values and their attributes, like 'brightred', or 'blue'", + input, + ) +} + +impl TryFrom<&BStr> for Color { + type Error = Error; + + fn try_from(s: &BStr) -> Result<Self, Self::Error> { + let s = std::str::from_utf8(s).map_err(|err| color_err(s).with_err(err))?; + enum ColorItem { + Value(Name), + Attr(Attribute), + } + + let items = s.split_whitespace().filter_map(|s| { + if s.is_empty() { + return None; + } + + Some( + Name::from_str(s) + .map(ColorItem::Value) + .or_else(|_| Attribute::from_str(s).map(ColorItem::Attr)), + ) + }); + + let mut foreground = None; + let mut background = None; + let mut attributes = Attribute::empty(); + for item in items { + match item { + Ok(item) => match item { + ColorItem::Value(v) => { + if foreground.is_none() { + foreground = Some(v); + } else if background.is_none() { + background = Some(v); + } else { + return Err(color_err(s)); + } + } + ColorItem::Attr(a) => attributes |= a, + }, + Err(_) => return Err(color_err(s)), + } + } + + Ok(Color { + foreground, + background, + attributes, + }) + } +} + +impl TryFrom<Cow<'_, BStr>> for Color { + type Error = Error; + + fn try_from(c: Cow<'_, BStr>) -> Result<Self, Self::Error> { + Self::try_from(c.as_ref()) + } +} + +/// Discriminating enum for names of [`Color`] values. +/// +/// `gix-config` supports the eight standard colors, their bright variants, an +/// ANSI color code, or a 24-bit hex value prefixed with an octothorpe/hash. +#[derive(Copy, Clone, Eq, PartialEq, Ord, PartialOrd, Hash, Debug)] +#[allow(missing_docs)] +pub enum Name { + Normal, + Default, + Black, + BrightBlack, + Red, + BrightRed, + Green, + BrightGreen, + Yellow, + BrightYellow, + Blue, + BrightBlue, + Magenta, + BrightMagenta, + Cyan, + BrightCyan, + White, + BrightWhite, + Ansi(u8), + Rgb(u8, u8, u8), +} + +impl Display for Name { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + match self { + Self::Normal => write!(f, "normal"), + Self::Default => write!(f, "default"), + Self::Black => write!(f, "black"), + Self::BrightBlack => write!(f, "brightblack"), + Self::Red => write!(f, "red"), + Self::BrightRed => write!(f, "brightred"), + Self::Green => write!(f, "green"), + Self::BrightGreen => write!(f, "brightgreen"), + Self::Yellow => write!(f, "yellow"), + Self::BrightYellow => write!(f, "brightyellow"), + Self::Blue => write!(f, "blue"), + Self::BrightBlue => write!(f, "brightblue"), + Self::Magenta => write!(f, "magenta"), + Self::BrightMagenta => write!(f, "brightmagenta"), + Self::Cyan => write!(f, "cyan"), + Self::BrightCyan => write!(f, "brightcyan"), + Self::White => write!(f, "white"), + Self::BrightWhite => write!(f, "brightwhite"), + Self::Ansi(num) => num.fmt(f), + Self::Rgb(r, g, b) => write!(f, "#{r:02x}{g:02x}{b:02x}"), + } + } +} + +#[cfg(feature = "serde")] +impl serde::Serialize for Name { + fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error> + where + S: serde::Serializer, + { + serializer.serialize_str(&self.to_string()) + } +} + +impl FromStr for Name { + type Err = Error; + + fn from_str(mut s: &str) -> Result<Self, Self::Err> { + let bright = if let Some(rest) = s.strip_prefix("bright") { + s = rest; + true + } else { + false + }; + + match s { + "normal" if !bright => return Ok(Self::Normal), + "-1" if !bright => return Ok(Self::Normal), + "normal" if bright => return Err(color_err(s)), + "default" if !bright => return Ok(Self::Default), + "default" if bright => return Err(color_err(s)), + "black" if !bright => return Ok(Self::Black), + "black" if bright => return Ok(Self::BrightBlack), + "red" if !bright => return Ok(Self::Red), + "red" if bright => return Ok(Self::BrightRed), + "green" if !bright => return Ok(Self::Green), + "green" if bright => return Ok(Self::BrightGreen), + "yellow" if !bright => return Ok(Self::Yellow), + "yellow" if bright => return Ok(Self::BrightYellow), + "blue" if !bright => return Ok(Self::Blue), + "blue" if bright => return Ok(Self::BrightBlue), + "magenta" if !bright => return Ok(Self::Magenta), + "magenta" if bright => return Ok(Self::BrightMagenta), + "cyan" if !bright => return Ok(Self::Cyan), + "cyan" if bright => return Ok(Self::BrightCyan), + "white" if !bright => return Ok(Self::White), + "white" if bright => return Ok(Self::BrightWhite), + _ => (), + } + + if let Ok(v) = u8::from_str(s) { + return Ok(Self::Ansi(v)); + } + + if let Some(s) = s.strip_prefix('#') { + if s.len() == 6 { + let rgb = ( + u8::from_str_radix(&s[..2], 16), + u8::from_str_radix(&s[2..4], 16), + u8::from_str_radix(&s[4..], 16), + ); + + if let (Ok(r), Ok(g), Ok(b)) = rgb { + return Ok(Self::Rgb(r, g, b)); + } + } + } + + Err(color_err(s)) + } +} + +impl TryFrom<&BStr> for Name { + type Error = Error; + + fn try_from(s: &BStr) -> Result<Self, Self::Error> { + Self::from_str(std::str::from_utf8(s).map_err(|err| color_err(s).with_err(err))?) + } +} + +bitflags::bitflags! { + /// Discriminating enum for [`Color`] attributes. + /// + /// `gix-config` supports modifiers and their negators. The negating color + /// attributes are equivalent to having a `no` or `no-` prefix to the normal + /// variant. + #[derive(Default)] + pub struct Attribute: u32 { + const BOLD = 1 << 1; + const DIM = 1 << 2; + const ITALIC = 1 << 3; + const UL = 1 << 4; + const BLINK = 1 << 5; + const REVERSE = 1 << 6; + const STRIKE = 1 << 7; + /// Reset is special as we have to be able to parse it, without git actually doing anything with it + const RESET = 1 << 8; + + const NO_DIM = 1 << 21; + const NO_BOLD = 1 << 22; + const NO_ITALIC = 1 << 23; + const NO_UL = 1 << 24; + const NO_BLINK = 1 << 25; + const NO_REVERSE = 1 << 26; + const NO_STRIKE = 1 << 27; + } +} + +impl Display for Attribute { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + let mut write_space = None; + for bit in 1..std::mem::size_of::<Attribute>() * 8 { + let attr = match Attribute::from_bits(1 << bit) { + Some(attr) => attr, + None => continue, + }; + if self.contains(attr) { + if write_space.take().is_some() { + write!(f, " ")? + } + match attr { + Attribute::RESET => write!(f, "reset"), + Attribute::BOLD => write!(f, "bold"), + Attribute::NO_BOLD => write!(f, "nobold"), + Attribute::DIM => write!(f, "dim"), + Attribute::NO_DIM => write!(f, "nodim"), + Attribute::UL => write!(f, "ul"), + Attribute::NO_UL => write!(f, "noul"), + Attribute::BLINK => write!(f, "blink"), + Attribute::NO_BLINK => write!(f, "noblink"), + Attribute::REVERSE => write!(f, "reverse"), + Attribute::NO_REVERSE => write!(f, "noreverse"), + Attribute::ITALIC => write!(f, "italic"), + Attribute::NO_ITALIC => write!(f, "noitalic"), + Attribute::STRIKE => write!(f, "strike"), + Attribute::NO_STRIKE => write!(f, "nostrike"), + _ => unreachable!("BUG: add new attribute flag"), + }?; + write_space = Some(()); + } + } + Ok(()) + } +} + +#[cfg(feature = "serde")] +impl serde::Serialize for Attribute { + fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error> + where + S: serde::Serializer, + { + serializer.serialize_str(&self.to_string()) + } +} + +impl FromStr for Attribute { + type Err = Error; + + fn from_str(mut s: &str) -> Result<Self, Self::Err> { + let inverted = if let Some(rest) = s.strip_prefix("no-").or_else(|| s.strip_prefix("no")) { + s = rest; + true + } else { + false + }; + + match s { + "reset" if !inverted => Ok(Attribute::RESET), + "reset" if inverted => Err(color_err(s)), + "bold" if !inverted => Ok(Attribute::BOLD), + "bold" if inverted => Ok(Attribute::NO_BOLD), + "dim" if !inverted => Ok(Attribute::DIM), + "dim" if inverted => Ok(Attribute::NO_DIM), + "ul" if !inverted => Ok(Attribute::UL), + "ul" if inverted => Ok(Attribute::NO_UL), + "blink" if !inverted => Ok(Attribute::BLINK), + "blink" if inverted => Ok(Attribute::NO_BLINK), + "reverse" if !inverted => Ok(Attribute::REVERSE), + "reverse" if inverted => Ok(Attribute::NO_REVERSE), + "italic" if !inverted => Ok(Attribute::ITALIC), + "italic" if inverted => Ok(Attribute::NO_ITALIC), + "strike" if !inverted => Ok(Attribute::STRIKE), + "strike" if inverted => Ok(Attribute::NO_STRIKE), + _ => Err(color_err(s)), + } + } +} + +impl TryFrom<&BStr> for Attribute { + type Error = Error; + + fn try_from(s: &BStr) -> Result<Self, Self::Error> { + Self::from_str(std::str::from_utf8(s).map_err(|err| color_err(s).with_err(err))?) + } +} diff --git a/vendor/gix-config-value/src/integer.rs b/vendor/gix-config-value/src/integer.rs new file mode 100644 index 000000000..b287899ec --- /dev/null +++ b/vendor/gix-config-value/src/integer.rs @@ -0,0 +1,156 @@ +use std::{borrow::Cow, convert::TryFrom, fmt::Display, str::FromStr}; + +use bstr::{BStr, BString}; + +use crate::{Error, Integer}; + +impl Integer { + /// Canonicalize values as simple decimal numbers. + /// An optional suffix of k, m, or g (case-insensitive), will cause the + /// value to be multiplied by 1024 (k), 1048576 (m), or 1073741824 (g) respectively. + /// + /// Returns the result if there is no multiplication overflow. + pub fn to_decimal(&self) -> Option<i64> { + match self.suffix { + None => Some(self.value), + Some(suffix) => match suffix { + Suffix::Kibi => self.value.checked_mul(1024), + Suffix::Mebi => self.value.checked_mul(1024 * 1024), + Suffix::Gibi => self.value.checked_mul(1024 * 1024 * 1024), + }, + } + } +} + +impl Display for Integer { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + write!(f, "{}", self.value)?; + if let Some(suffix) = self.suffix { + write!(f, "{suffix}") + } else { + Ok(()) + } + } +} + +#[cfg(feature = "serde")] +impl serde::Serialize for Integer { + fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error> + where + S: serde::Serializer, + { + if let Some(suffix) = self.suffix { + serializer.serialize_i64(self.value << suffix.bitwise_offset()) + } else { + serializer.serialize_i64(self.value) + } + } +} + +fn int_err(input: impl Into<BString>) -> Error { + Error::new( + "Integers needs to be positive or negative numbers which may have a suffix like 1k, 42, or 50G", + input, + ) +} + +impl TryFrom<&BStr> for Integer { + type Error = Error; + + fn try_from(s: &BStr) -> Result<Self, Self::Error> { + let s = std::str::from_utf8(s).map_err(|err| int_err(s).with_err(err))?; + if let Ok(value) = s.parse() { + return Ok(Self { value, suffix: None }); + } + + if s.len() <= 1 { + return Err(int_err(s)); + } + + let (number, suffix) = s.split_at(s.len() - 1); + if let (Ok(value), Ok(suffix)) = (number.parse(), suffix.parse()) { + Ok(Self { + value, + suffix: Some(suffix), + }) + } else { + Err(int_err(s)) + } + } +} + +impl TryFrom<Cow<'_, BStr>> for Integer { + type Error = Error; + + fn try_from(c: Cow<'_, BStr>) -> Result<Self, Self::Error> { + Self::try_from(c.as_ref()) + } +} + +/// Integer suffixes that are supported by `gix-config`. +/// +/// These values are base-2 unit of measurements, not the base-10 variants. +#[derive(Copy, Clone, Eq, PartialEq, Ord, PartialOrd, Hash, Debug)] +#[allow(missing_docs)] +pub enum Suffix { + Kibi, + Mebi, + Gibi, +} + +impl Suffix { + /// Returns the number of bits that the suffix shifts left by. + #[must_use] + pub const fn bitwise_offset(self) -> usize { + match self { + Self::Kibi => 10, + Self::Mebi => 20, + Self::Gibi => 30, + } + } +} + +impl Display for Suffix { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + match self { + Self::Kibi => write!(f, "k"), + Self::Mebi => write!(f, "m"), + Self::Gibi => write!(f, "g"), + } + } +} + +#[cfg(feature = "serde")] +impl serde::Serialize for Suffix { + fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error> + where + S: serde::Serializer, + { + serializer.serialize_str(match self { + Self::Kibi => "k", + Self::Mebi => "m", + Self::Gibi => "g", + }) + } +} + +impl FromStr for Suffix { + type Err = (); + + fn from_str(s: &str) -> Result<Self, Self::Err> { + match s { + "k" | "K" => Ok(Self::Kibi), + "m" | "M" => Ok(Self::Mebi), + "g" | "G" => Ok(Self::Gibi), + _ => Err(()), + } + } +} + +impl TryFrom<&BStr> for Suffix { + type Error = (); + + fn try_from(s: &BStr) -> Result<Self, Self::Error> { + Self::from_str(std::str::from_utf8(s).map_err(|_| ())?) + } +} diff --git a/vendor/gix-config-value/src/lib.rs b/vendor/gix-config-value/src/lib.rs new file mode 100644 index 000000000..130674e5a --- /dev/null +++ b/vendor/gix-config-value/src/lib.rs @@ -0,0 +1,47 @@ +//! Parsing for data types used in `gix-config` files to allow their use from environment variables and other sources. +//! +//! ## Feature Flags +#![cfg_attr( + feature = "document-features", + cfg_attr(doc, doc = ::document_features::document_features!()) +)] +#![cfg_attr(docsrs, feature(doc_cfg, doc_auto_cfg))] +#![deny(missing_docs, rust_2018_idioms, unsafe_code)] + +/// The error returned when any config value couldn't be instantiated due to malformed input. +#[derive(Debug, thiserror::Error, Eq, PartialEq)] +#[allow(missing_docs)] +#[error("Could not decode '{input}': {message}")] +pub struct Error { + pub message: &'static str, + pub input: bstr::BString, + #[source] + pub utf8_err: Option<std::str::Utf8Error>, +} + +impl Error { + /// Create a new value error from `message`, with `input` being what's causing the error. + pub fn new(message: &'static str, input: impl Into<bstr::BString>) -> Self { + Error { + message, + input: input.into(), + utf8_err: None, + } + } + + pub(crate) fn with_err(mut self, err: std::str::Utf8Error) -> Self { + self.utf8_err = Some(err); + self + } +} + +mod boolean; +/// +pub mod color; +/// +pub mod integer; +/// +pub mod path; + +mod types; +pub use types::{Boolean, Color, Integer, Path}; diff --git a/vendor/gix-config-value/src/path.rs b/vendor/gix-config-value/src/path.rs new file mode 100644 index 000000000..99ee5cf2e --- /dev/null +++ b/vendor/gix-config-value/src/path.rs @@ -0,0 +1,195 @@ +use std::{borrow::Cow, path::PathBuf}; + +use bstr::BStr; + +use crate::Path; + +/// +pub mod interpolate { + use std::path::PathBuf; + + /// Options for interpolating paths with [`Path::interpolate()`][crate::Path::interpolate()]. + #[derive(Clone, Copy)] + pub struct Context<'a> { + /// The location where gitoxide or git is installed. If `None`, `%(prefix)` in paths will cause an error. + pub git_install_dir: Option<&'a std::path::Path>, + /// The home directory of the current user. If `None`, `~/` in paths will cause an error. + pub home_dir: Option<&'a std::path::Path>, + /// A function returning the home directory of a given user. If `None`, `~name/` in paths will cause an error. + pub home_for_user: Option<fn(&str) -> Option<PathBuf>>, + } + + impl Default for Context<'_> { + fn default() -> Self { + Context { + git_install_dir: None, + home_dir: None, + home_for_user: Some(home_for_user), + } + } + } + + /// The error returned by [`Path::interpolate()`][crate::Path::interpolate()]. + #[derive(Debug, thiserror::Error)] + #[allow(missing_docs)] + pub enum Error { + #[error("{} is missing", .what)] + Missing { what: &'static str }, + #[error("Ill-formed UTF-8 in {}", .what)] + Utf8Conversion { + what: &'static str, + #[source] + err: gix_path::Utf8Error, + }, + #[error("Ill-formed UTF-8 in username")] + UsernameConversion(#[from] std::str::Utf8Error), + #[error("User interpolation is not available on this platform")] + UserInterpolationUnsupported, + } + + /// Obtain the home directory for the given user `name` or return `None` if the user wasn't found + /// or any other error occurred. + /// It can be used as `home_for_user` parameter in [`Path::interpolate()`][crate::Path::interpolate()]. + #[cfg_attr(windows, allow(unused_variables))] + pub fn home_for_user(name: &str) -> Option<PathBuf> { + #[cfg(not(any(target_os = "android", target_os = "windows")))] + { + let cname = std::ffi::CString::new(name).ok()?; + // SAFETY: calling this in a threaded program that modifies the pw database is not actually safe. + // TODO: use the `*_r` version, but it's much harder to use. + #[allow(unsafe_code)] + let pwd = unsafe { libc::getpwnam(cname.as_ptr()) }; + if pwd.is_null() { + None + } else { + use std::os::unix::ffi::OsStrExt; + // SAFETY: pw_dir is a cstr and it lives as long as… well, we hope nobody changes the pw database while we are at it + // from another thread. Otherwise it lives long enough. + #[allow(unsafe_code)] + let cstr = unsafe { std::ffi::CStr::from_ptr((*pwd).pw_dir) }; + Some(std::ffi::OsStr::from_bytes(cstr.to_bytes()).into()) + } + } + #[cfg(any(target_os = "android", target_os = "windows"))] + { + None + } + } +} + +impl<'a> std::ops::Deref for Path<'a> { + type Target = BStr; + + fn deref(&self) -> &Self::Target { + self.value.as_ref() + } +} + +impl<'a> AsRef<[u8]> for Path<'a> { + fn as_ref(&self) -> &[u8] { + self.value.as_ref() + } +} + +impl<'a> AsRef<BStr> for Path<'a> { + fn as_ref(&self) -> &BStr { + self.value.as_ref() + } +} + +impl<'a> From<Cow<'a, BStr>> for Path<'a> { + fn from(value: Cow<'a, BStr>) -> Self { + Path { value } + } +} + +impl<'a> Path<'a> { + /// Interpolates this path into a path usable on the file system. + /// + /// If this path starts with `~/` or `~user/` or `%(prefix)/` + /// - `~/` is expanded to the value of `home_dir`. The caller can use the [dirs](https://crates.io/crates/dirs) crate to obtain it. + /// It it is required but not set, an error is produced. + /// - `~user/` to the specified user’s home directory, e.g `~alice` might get expanded to `/home/alice` on linux, but requires + /// the `home_for_user` function to be provided. + /// The interpolation uses `getpwnam` sys call and is therefore not available on windows. + /// - `%(prefix)/` is expanded to the location where `gitoxide` is installed. + /// This location is not known at compile time and therefore need to be + /// optionally provided by the caller through `git_install_dir`. + /// + /// Any other, non-empty path value is returned unchanged and error is returned in case of an empty path value or if required input + /// wasn't provided. + pub fn interpolate( + self, + interpolate::Context { + git_install_dir, + home_dir, + home_for_user, + }: interpolate::Context<'_>, + ) -> Result<Cow<'a, std::path::Path>, interpolate::Error> { + if self.is_empty() { + return Err(interpolate::Error::Missing { what: "path" }); + } + + const PREFIX: &[u8] = b"%(prefix)/"; + const USER_HOME: &[u8] = b"~/"; + if self.starts_with(PREFIX) { + let git_install_dir = git_install_dir.ok_or(interpolate::Error::Missing { + what: "git install dir", + })?; + let (_prefix, path_without_trailing_slash) = self.split_at(PREFIX.len()); + let path_without_trailing_slash = + gix_path::try_from_bstring(path_without_trailing_slash).map_err(|err| { + interpolate::Error::Utf8Conversion { + what: "path past %(prefix)", + err, + } + })?; + Ok(git_install_dir.join(path_without_trailing_slash).into()) + } else if self.starts_with(USER_HOME) { + let home_path = home_dir.ok_or(interpolate::Error::Missing { what: "home dir" })?; + let (_prefix, val) = self.split_at(USER_HOME.len()); + let val = gix_path::try_from_byte_slice(val).map_err(|err| interpolate::Error::Utf8Conversion { + what: "path past ~/", + err, + })?; + Ok(home_path.join(val).into()) + } else if self.starts_with(b"~") && self.contains(&b'/') { + self.interpolate_user(home_for_user.ok_or(interpolate::Error::Missing { + what: "home for user lookup", + })?) + } else { + Ok(gix_path::from_bstr(self.value)) + } + } + + #[cfg(any(target_os = "windows", target_os = "android"))] + fn interpolate_user( + self, + _home_for_user: fn(&str) -> Option<PathBuf>, + ) -> Result<Cow<'a, std::path::Path>, interpolate::Error> { + Err(interpolate::Error::UserInterpolationUnsupported) + } + + #[cfg(not(any(target_os = "windows", target_os = "android")))] + fn interpolate_user( + self, + home_for_user: fn(&str) -> Option<PathBuf>, + ) -> Result<Cow<'a, std::path::Path>, interpolate::Error> { + let (_prefix, val) = self.split_at("/".len()); + let i = val + .iter() + .position(|&e| e == b'/') + .ok_or(interpolate::Error::Missing { what: "/" })?; + let (username, path_with_leading_slash) = val.split_at(i); + let username = std::str::from_utf8(username)?; + let home = home_for_user(username).ok_or(interpolate::Error::Missing { what: "pwd user info" })?; + let path_past_user_prefix = + gix_path::try_from_byte_slice(&path_with_leading_slash["/".len()..]).map_err(|err| { + interpolate::Error::Utf8Conversion { + what: "path past ~user/", + err, + } + })?; + Ok(home.join(path_past_user_prefix).into()) + } +} diff --git a/vendor/gix-config-value/src/types.rs b/vendor/gix-config-value/src/types.rs new file mode 100644 index 000000000..ac3911dfd --- /dev/null +++ b/vendor/gix-config-value/src/types.rs @@ -0,0 +1,48 @@ +use crate::{color, integer}; + +/// Any value that may contain a foreground color, background color, a +/// collection of color (text) modifiers, or a combination of any of the +/// aforementioned values, like `red` or `brightgreen`. +/// +/// Note that `gix-config` allows color values to simply be a collection of +/// [`color::Attribute`]s, and does not require a [`color::Name`] for either the +/// foreground or background color. +#[derive(Clone, Eq, PartialEq, Ord, PartialOrd, Hash, Debug, Default)] +pub struct Color { + /// A provided foreground color + pub foreground: Option<color::Name>, + /// A provided background color + pub background: Option<color::Name>, + /// A potentially empty set of text attributes + pub attributes: color::Attribute, +} + +/// Any value that can be interpreted as an integer. +/// +/// This supports any numeric value that can fit in a [`i64`], excluding the +/// suffix. The suffix is parsed separately from the value itself, so if you +/// wish to obtain the true value of the integer, you must account for the +/// suffix after fetching the value. [`integer::Suffix`] provides +/// [`bitwise_offset()`][integer::Suffix::bitwise_offset] to help with the +/// math, or [to_decimal()][Integer::to_decimal()] for obtaining a usable value in one step. +#[derive(Default, Copy, Clone, Eq, PartialEq, Ord, PartialOrd, Hash, Debug)] +pub struct Integer { + /// The value, without any suffix modification + pub value: i64, + /// A provided suffix, if any. + pub suffix: Option<integer::Suffix>, +} + +/// Any value that can be interpreted as a boolean. +#[derive(Default, Copy, Clone, Eq, PartialEq, Ord, PartialOrd, Hash, Debug)] +#[allow(missing_docs)] +pub struct Boolean(pub bool); + +/// Any value that can be interpreted as a path to a resource on disk. +/// +/// Git represents file paths as byte arrays, modeled here as owned or borrowed byte sequences. +#[derive(Clone, Eq, PartialEq, Ord, PartialOrd, Hash, Debug)] +pub struct Path<'a> { + /// The path string, un-interpolated + pub value: std::borrow::Cow<'a, bstr::BStr>, +} diff --git a/vendor/gix-config-value/tests/value/boolean.rs b/vendor/gix-config-value/tests/value/boolean.rs new file mode 100644 index 000000000..8fe8b43f0 --- /dev/null +++ b/vendor/gix-config-value/tests/value/boolean.rs @@ -0,0 +1,42 @@ +use std::convert::TryFrom; + +use gix_config_value::Boolean; + +use crate::b; + +#[test] +fn from_str_false() -> crate::Result { + assert!(!Boolean::try_from(b("no"))?.0); + assert!(!Boolean::try_from(b("off"))?.0); + assert!(!Boolean::try_from(b("false"))?.0); + assert!(!Boolean::try_from(b("0"))?.0); + assert!(!Boolean::try_from(b(""))?.0); + Ok(()) +} + +#[test] +fn from_str_true() -> crate::Result { + assert_eq!(Boolean::try_from(b("yes")).map(Into::into), Ok(true)); + assert_eq!(Boolean::try_from(b("on")), Ok(Boolean(true))); + assert_eq!(Boolean::try_from(b("true")), Ok(Boolean(true))); + assert!(Boolean::try_from(b("1"))?.0); + assert!(Boolean::try_from(b("+10"))?.0); + assert!(Boolean::try_from(b("-1"))?.0); + Ok(()) +} + +#[test] +fn ignores_case() { + // Random subset + for word in &["no", "yes", "on", "off", "true", "false"] { + let first: bool = Boolean::try_from(b(word)).unwrap().into(); + let second: bool = Boolean::try_from(b(&word.to_uppercase())).unwrap().into(); + assert_eq!(first, second); + } +} + +#[test] +fn from_str_err() { + assert!(Boolean::try_from(b("yesn't")).is_err()); + assert!(Boolean::try_from(b("yesno")).is_err()); +} diff --git a/vendor/gix-config-value/tests/value/color.rs b/vendor/gix-config-value/tests/value/color.rs new file mode 100644 index 000000000..1db7fe2e0 --- /dev/null +++ b/vendor/gix-config-value/tests/value/color.rs @@ -0,0 +1,199 @@ +mod name { + use std::str::FromStr; + + use gix_config_value::color::Name; + + #[test] + fn non_bright() { + assert_eq!(Name::from_str("normal"), Ok(Name::Normal)); + assert_eq!(Name::from_str("-1"), Ok(Name::Normal)); + assert_eq!(Name::from_str("default"), Ok(Name::Default)); + assert_eq!(Name::from_str("black"), Ok(Name::Black)); + assert_eq!(Name::from_str("red"), Ok(Name::Red)); + assert_eq!(Name::from_str("green"), Ok(Name::Green)); + assert_eq!(Name::from_str("yellow"), Ok(Name::Yellow)); + assert_eq!(Name::from_str("blue"), Ok(Name::Blue)); + assert_eq!(Name::from_str("magenta"), Ok(Name::Magenta)); + assert_eq!(Name::from_str("cyan"), Ok(Name::Cyan)); + assert_eq!(Name::from_str("white"), Ok(Name::White)); + } + + #[test] + fn bright() { + assert_eq!(Name::from_str("brightblack"), Ok(Name::BrightBlack)); + assert_eq!(Name::from_str("brightred"), Ok(Name::BrightRed)); + assert_eq!(Name::from_str("brightgreen"), Ok(Name::BrightGreen)); + assert_eq!(Name::from_str("brightyellow"), Ok(Name::BrightYellow)); + assert_eq!(Name::from_str("brightblue"), Ok(Name::BrightBlue)); + assert_eq!(Name::from_str("brightmagenta"), Ok(Name::BrightMagenta)); + assert_eq!(Name::from_str("brightcyan"), Ok(Name::BrightCyan)); + assert_eq!(Name::from_str("brightwhite"), Ok(Name::BrightWhite)); + } + + #[test] + fn ansi() { + assert_eq!(Name::from_str("255"), Ok(Name::Ansi(255))); + assert_eq!(Name::from_str("0"), Ok(Name::Ansi(0))); + } + + #[test] + fn hex() { + assert_eq!(Name::from_str("#ff0010"), Ok(Name::Rgb(255, 0, 16))); + assert_eq!(Name::from_str("#ffffff"), Ok(Name::Rgb(255, 255, 255))); + assert_eq!(Name::from_str("#000000"), Ok(Name::Rgb(0, 0, 0))); + } + + #[test] + fn invalid() { + assert!(Name::from_str("-2").is_err()); + assert!(Name::from_str("brightnormal").is_err()); + assert!(Name::from_str("brightdefault").is_err()); + assert!(Name::from_str("").is_err()); + assert!(Name::from_str("bright").is_err()); + assert!(Name::from_str("256").is_err()); + assert!(Name::from_str("#").is_err()); + assert!(Name::from_str("#fff").is_err()); + assert!(Name::from_str("#gggggg").is_err()); + } +} + +mod attribute { + use std::str::FromStr; + + use gix_config_value::color::Attribute; + + #[test] + fn non_inverted() { + assert_eq!(Attribute::from_str("reset"), Ok(Attribute::RESET)); + assert_eq!(Attribute::from_str("bold"), Ok(Attribute::BOLD)); + assert_eq!(Attribute::from_str("dim"), Ok(Attribute::DIM)); + assert_eq!(Attribute::from_str("ul"), Ok(Attribute::UL)); + assert_eq!(Attribute::from_str("blink"), Ok(Attribute::BLINK)); + assert_eq!(Attribute::from_str("reverse"), Ok(Attribute::REVERSE)); + assert_eq!(Attribute::from_str("italic"), Ok(Attribute::ITALIC)); + assert_eq!(Attribute::from_str("strike"), Ok(Attribute::STRIKE)); + } + + #[test] + fn inverted_no_dash() { + assert_eq!(Attribute::from_str("nobold"), Ok(Attribute::NO_BOLD)); + assert_eq!(Attribute::from_str("nodim"), Ok(Attribute::NO_DIM)); + assert_eq!(Attribute::from_str("noul"), Ok(Attribute::NO_UL)); + assert_eq!(Attribute::from_str("noblink"), Ok(Attribute::NO_BLINK)); + assert_eq!(Attribute::from_str("noreverse"), Ok(Attribute::NO_REVERSE)); + assert_eq!(Attribute::from_str("noitalic"), Ok(Attribute::NO_ITALIC)); + assert_eq!(Attribute::from_str("nostrike"), Ok(Attribute::NO_STRIKE)); + } + + #[test] + fn inverted_dashed() { + assert_eq!(Attribute::from_str("no-bold"), Ok(Attribute::NO_BOLD)); + assert_eq!(Attribute::from_str("no-dim"), Ok(Attribute::NO_DIM)); + assert_eq!(Attribute::from_str("no-ul"), Ok(Attribute::NO_UL)); + assert_eq!(Attribute::from_str("no-blink"), Ok(Attribute::NO_BLINK)); + assert_eq!(Attribute::from_str("no-reverse"), Ok(Attribute::NO_REVERSE)); + assert_eq!(Attribute::from_str("no-italic"), Ok(Attribute::NO_ITALIC)); + assert_eq!(Attribute::from_str("no-strike"), Ok(Attribute::NO_STRIKE)); + } + + #[test] + fn invalid() { + assert!(Attribute::from_str("no-reset").is_err()); + assert!(Attribute::from_str("noreset").is_err()); + assert!(Attribute::from_str("a").is_err()); + assert!(Attribute::from_str("no bold").is_err()); + assert!(Attribute::from_str("").is_err()); + assert!(Attribute::from_str("no").is_err()); + assert!(Attribute::from_str("no-").is_err()); + } +} + +mod from_git { + use std::convert::TryFrom; + + use bstr::BStr; + use gix_config_value::Color; + + #[test] + fn reset() { + assert_eq!(color("reset"), "reset"); + } + + #[test] + fn empty() { + assert_eq!(color(""), ""); + } + + #[test] + fn at_most_two_colors() { + assert!(try_color("red green blue").is_err()); + } + + #[test] + fn attribute_before_color_name() { + assert_eq!(color("bold red"), "red bold"); + } + + #[test] + fn color_name_before_attribute() { + assert_eq!(color("red bold"), "red bold"); + } + + #[test] + fn attribute_fg_bg() { + assert_eq!(color("ul blue red"), "blue red ul"); + } + + #[test] + fn fg_bg_attribute() { + assert_eq!(color("blue red ul"), "blue red ul"); + } + + #[test] + fn multiple_attributes() { + assert_eq!( + color("blue bold dim ul blink reverse"), + "blue bold dim ul blink reverse" + ); + } + + #[test] + fn reset_then_multiple_attributes() { + assert_eq!( + color("blue bold dim ul blink reverse reset"), + "blue bold dim ul blink reverse reset" + ); + } + + #[test] + fn long_color_spec() { + assert_eq!( + color("254 255 bold dim ul blink reverse"), + "254 255 bold dim ul blink reverse" + ); + let input = "#ffffff #ffffff bold nobold dim nodim italic noitalic ul noul blink noblink reverse noreverse strike nostrike"; + let expected = "#ffffff #ffffff bold dim italic ul blink reverse strike nodim nobold noitalic noul noblink noreverse nostrike"; + assert_eq!(color(input), expected); + } + + #[test] + fn normal_default_can_clear_backgrounds() { + assert_eq!(color("normal default"), "normal default"); + } + + #[test] + fn default_can_combine_with_attributes() { + assert_eq!( + color("default default no-reverse bold"), + "default default bold noreverse" + ); + } + + fn color<'a>(name: impl Into<&'a BStr>) -> String { + try_color(name).expect("input color is expected to be valid") + } + + fn try_color<'a>(name: impl Into<&'a BStr>) -> crate::Result<String> { + Ok(Color::try_from(name.into())?.to_string()) + } +} diff --git a/vendor/gix-config-value/tests/value/integer.rs b/vendor/gix-config-value/tests/value/integer.rs new file mode 100644 index 000000000..9de2ab1ca --- /dev/null +++ b/vendor/gix-config-value/tests/value/integer.rs @@ -0,0 +1,74 @@ +use std::convert::TryFrom; + +use gix_config_value::{integer::Suffix, Integer}; + +use crate::b; + +#[test] +fn from_str_no_suffix() { + assert_eq!(Integer::try_from(b("1")).unwrap(), Integer { value: 1, suffix: None }); + + assert_eq!( + Integer::try_from(b("-1")).unwrap(), + Integer { + value: -1, + suffix: None + } + ); +} + +#[test] +fn from_str_with_suffix() { + assert_eq!( + Integer::try_from(b("1k")).unwrap(), + Integer { + value: 1, + suffix: Some(Suffix::Kibi), + } + ); + + assert_eq!( + Integer::try_from(b("1m")).unwrap(), + Integer { + value: 1, + suffix: Some(Suffix::Mebi), + } + ); + + assert_eq!( + Integer::try_from(b("1g")).unwrap(), + Integer { + value: 1, + suffix: Some(Suffix::Gibi), + } + ); +} + +#[test] +fn invalid_from_str() { + assert!(Integer::try_from(b("")).is_err()); + assert!(Integer::try_from(b("-")).is_err()); + assert!(Integer::try_from(b("k")).is_err()); + assert!(Integer::try_from(b("m")).is_err()); + assert!(Integer::try_from(b("g")).is_err()); + assert!(Integer::try_from(b("123123123123123123123123")).is_err()); + assert!(Integer::try_from(b("gg")).is_err()); +} + +#[test] +fn as_decimal() { + fn decimal(input: &str) -> Option<i64> { + Integer::try_from(b(input)).unwrap().to_decimal() + } + + assert_eq!(decimal("12"), Some(12), "works without suffix"); + assert_eq!(decimal("13k"), Some(13 * 1024), "works with kilobyte suffix"); + assert_eq!(decimal("13K"), Some(13 * 1024), "works with Kilobyte suffix"); + assert_eq!(decimal("14m"), Some(14 * 1_048_576), "works with megabyte suffix"); + assert_eq!(decimal("14M"), Some(14 * 1_048_576), "works with Megabyte suffix"); + assert_eq!(decimal("15g"), Some(15 * 1_073_741_824), "works with gigabyte suffix"); + assert_eq!(decimal("15G"), Some(15 * 1_073_741_824), "works with Gigabyte suffix"); + + assert_eq!(decimal(&format!("{}g", i64::MAX)), None, "overflow results in None"); + assert_eq!(decimal(&format!("{}g", i64::MIN)), None, "underflow results in None"); +} diff --git a/vendor/gix-config-value/tests/value/main.rs b/vendor/gix-config-value/tests/value/main.rs new file mode 100644 index 000000000..13a33c9d8 --- /dev/null +++ b/vendor/gix-config-value/tests/value/main.rs @@ -0,0 +1,17 @@ +use std::borrow::Cow; + +use bstr::{BStr, ByteSlice}; + +type Result<T = ()> = std::result::Result<T, Box<dyn std::error::Error>>; +fn b(s: &str) -> &bstr::BStr { + s.into() +} + +pub fn cow_str(s: &str) -> Cow<'_, BStr> { + Cow::Borrowed(s.as_bytes().as_bstr()) +} + +mod boolean; +mod color; +mod integer; +mod path; diff --git a/vendor/gix-config-value/tests/value/path.rs b/vendor/gix-config-value/tests/value/path.rs new file mode 100644 index 000000000..10970296d --- /dev/null +++ b/vendor/gix-config-value/tests/value/path.rs @@ -0,0 +1,129 @@ +mod interpolate { + use std::{ + borrow::Cow, + path::{Path, PathBuf}, + }; + + use gix_config_value::path; + + use crate::{b, cow_str}; + + #[test] + fn backslash_is_not_special_and_they_are_not_escaping_anything() -> crate::Result { + for path in ["C:\\foo\\bar", "/foo/bar"] { + let actual = gix_config_value::Path::from(Cow::Borrowed(b(path))).interpolate(Default::default())?; + assert_eq!(actual, Path::new(path)); + assert!( + matches!(actual, Cow::Borrowed(_)), + "it does not unnecessarily copy values" + ); + } + Ok(()) + } + + #[test] + fn empty_path_is_error() { + assert!(matches!( + interpolate_without_context(""), + Err(path::interpolate::Error::Missing { what: "path" }) + )); + } + + #[test] + fn prefix_substitutes_git_install_dir() { + for git_install_dir in &["/tmp/git", "C:\\git"] { + for (val, expected) in &[("%(prefix)/foo/bar", "foo/bar"), ("%(prefix)/foo\\bar", "foo\\bar")] { + let expected = + std::path::PathBuf::from(format!("{}{}{}", git_install_dir, std::path::MAIN_SEPARATOR, expected)); + assert_eq!( + gix_config_value::Path::from(cow_str(val)) + .interpolate(path::interpolate::Context { + git_install_dir: Path::new(git_install_dir).into(), + ..Default::default() + }) + .unwrap(), + expected, + "prefix interpolation keeps separators as they are" + ); + } + } + } + + #[test] + fn prefix_substitution_skipped_with_dot_slash() { + let path = "./%(prefix)/foo/bar"; + let git_install_dir = "/tmp/git"; + assert_eq!( + gix_config_value::Path::from(Cow::Borrowed(b(path))) + .interpolate(path::interpolate::Context { + git_install_dir: Path::new(git_install_dir).into(), + ..Default::default() + }) + .unwrap(), + Path::new(path) + ); + } + + #[test] + fn tilde_alone_does_not_interpolate() -> crate::Result { + assert_eq!(interpolate_without_context("~")?, Path::new("~")); + Ok(()) + } + + #[test] + fn tilde_slash_substitutes_current_user() -> crate::Result { + let path = "~/user/bar"; + let home = std::env::current_dir()?; + let expected = home.join("user").join("bar"); + assert_eq!( + gix_config_value::Path::from(cow_str(path)) + .interpolate(path::interpolate::Context { + home_dir: Some(&home), + home_for_user: Some(home_for_user), + ..Default::default() + }) + .unwrap() + .as_ref(), + expected + ); + Ok(()) + } + + #[cfg(windows)] + #[test] + fn tilde_with_given_user_is_unsupported_on_windows() { + assert!(matches!( + interpolate_without_context("~baz/foo/bar"), + Err(gix_config_value::path::interpolate::Error::UserInterpolationUnsupported) + )); + } + + #[cfg(not(windows))] + #[test] + fn tilde_with_given_user() -> crate::Result { + let home = std::env::current_dir()?; + + for path_suffix in &["foo/bar", "foo\\bar", ""] { + let path = format!("~user{}{}", std::path::MAIN_SEPARATOR, path_suffix); + let expected = home.join("user").join(path_suffix); + + assert_eq!(interpolate_without_context(path)?, expected); + } + Ok(()) + } + + fn interpolate_without_context( + path: impl AsRef<str>, + ) -> Result<Cow<'static, Path>, gix_config_value::path::interpolate::Error> { + gix_config_value::Path::from(Cow::Owned(path.as_ref().to_owned().into())).interpolate( + path::interpolate::Context { + home_for_user: Some(home_for_user), + ..Default::default() + }, + ) + } + + fn home_for_user(name: &str) -> Option<PathBuf> { + std::env::current_dir().unwrap().join(name).into() + } +} |