difftreelog
style fix clippy warnings
in: master
19 files changed
Cargo.lockdiffbeforeafterboth--- a/Cargo.lock
+++ b/Cargo.lock
@@ -41,9 +41,9 @@
[[package]]
name = "anstream"
-version = "0.6.14"
+version = "0.6.15"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "418c75fa768af9c03be99d17643f93f79bbba589895012a80e3452a19ddda15b"
+checksum = "64e15c1ab1f89faffbf04a634d5e1962e9074f2741eef6d97f3c4e322426d526"
dependencies = [
"anstyle",
"anstyle-parse",
@@ -56,36 +56,36 @@
[[package]]
name = "anstyle"
-version = "1.0.7"
+version = "1.0.8"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "038dfcf04a5feb68e9c60b21c9625a54c2c0616e79b72b0fd87075a056ae1d1b"
+checksum = "1bec1de6f59aedf83baf9ff929c98f2ad654b97c9510f4e70cf6f661d49fd5b1"
[[package]]
name = "anstyle-parse"
-version = "0.2.4"
+version = "0.2.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "c03a11a9034d92058ceb6ee011ce58af4a9bf61491aa7e1e59ecd24bd40d22d4"
+checksum = "eb47de1e80c2b463c735db5b217a0ddc39d612e7ac9e2e96a5aed1f57616c1cb"
dependencies = [
"utf8parse",
]
[[package]]
name = "anstyle-query"
-version = "1.0.3"
+version = "1.1.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "a64c907d4e79225ac72e2a354c9ce84d50ebb4586dee56c82b3ee73004f537f5"
+checksum = "6d36fc52c7f6c869915e99412912f22093507da8d9e942ceaf66fe4b7c14422a"
dependencies = [
- "windows-sys",
+ "windows-sys 0.52.0",
]
[[package]]
name = "anstyle-wincon"
-version = "3.0.3"
+version = "3.0.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "61a38449feb7068f52bb06c12759005cf459ee52bb4adc1d5a7c4322d716fb19"
+checksum = "5bf74e1b6e971609db8ca7a9ce79fd5768ab6ae46441c572e46cf596f59e57f8"
dependencies = [
"anstyle",
- "windows-sys",
+ "windows-sys 0.52.0",
]
[[package]]
@@ -114,9 +114,9 @@
[[package]]
name = "bitflags"
-version = "2.5.0"
+version = "2.6.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "cf4b9d6a944f767f8e5e0db018570623c85f3d925ac718db4e06d0187adb21c1"
+checksum = "b048fb63fd8b5923fc5aa7b340d8e156aec7ec02f0c78fa8a6ddc2613f6f71de"
[[package]]
name = "block-buffer"
@@ -134,10 +134,19 @@
checksum = "79296716171880943b8470b5f8d03aa55eb2e645a4874bdbb28adb49162e012c"
[[package]]
+name = "byteorder"
+version = "1.5.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "1fd0f2584146f6f2ef48085050886acf353beff7305ebd1ae69500e27c67f64b"
+
+[[package]]
name = "cc"
-version = "1.0.97"
+version = "1.1.14"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "099a5357d84c4c61eb35fc8eafa9a79a902c2f76911e5747ced4e032edd8d9b4"
+checksum = "50d2eb3cd3d1bf4529e31c215ee6f93ec5a3d536d9f578f93d9d33ee19562932"
+dependencies = [
+ "shlex",
+]
[[package]]
name = "cfg-if"
@@ -147,9 +156,9 @@
[[package]]
name = "clap"
-version = "4.5.4"
+version = "4.5.16"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "90bc066a67923782aa8515dbaea16946c5bcc5addbd668bb80af688e53e548a0"
+checksum = "ed6719fffa43d0d87e5fd8caeab59be1554fb028cd30edc88fc4369b17971019"
dependencies = [
"clap_builder",
"clap_derive",
@@ -157,9 +166,9 @@
[[package]]
name = "clap_builder"
-version = "4.5.2"
+version = "4.5.15"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "ae129e2e766ae0ec03484e609954119f123cc1fe650337e155d03b022f24f7b4"
+checksum = "216aec2b177652e3846684cbfe25c9964d18ec45234f0f5da5157b207ed1aab6"
dependencies = [
"anstream",
"anstyle",
@@ -169,36 +178,36 @@
[[package]]
name = "clap_complete"
-version = "4.5.2"
+version = "4.5.23"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "dd79504325bf38b10165b02e89b4347300f855f273c4cb30c4a3209e6583275e"
+checksum = "531d7959c5bbb6e266cecdd0f20213639c3a5c3e4d615f97db87661745f781ff"
dependencies = [
"clap",
]
[[package]]
name = "clap_derive"
-version = "4.5.4"
+version = "4.5.13"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "528131438037fd55894f62d6e9f068b8f45ac57ffa77517819645d10aed04f64"
+checksum = "501d359d5f3dcaf6ecdeee48833ae73ec6e42723a1e52419c79abf9507eec0a0"
dependencies = [
"heck",
"proc-macro2",
"quote",
- "syn 2.0.64",
+ "syn 2.0.76",
]
[[package]]
name = "clap_lex"
-version = "0.7.0"
+version = "0.7.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "98cc8fbded0c607b7ba9dd60cd98df59af97e84d24e49c8557331cfc26d301ce"
+checksum = "1462739cb27611015575c0c11df5df7601141071f07518d56fcc1be504cbec97"
[[package]]
name = "colorchoice"
-version = "1.0.1"
+version = "1.0.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "0b6a852b24ab71dffc585bcb46eaf7959d175cb865a7152e35b348d1b2960422"
+checksum = "d3fd119d74b830634cea2a0f58bbd0d54540518a14397557951e79340abc28c0"
[[package]]
name = "console"
@@ -209,7 +218,7 @@
"encode_unicode",
"lazy_static",
"libc",
- "windows-sys",
+ "windows-sys 0.52.0",
]
[[package]]
@@ -220,9 +229,9 @@
[[package]]
name = "cpufeatures"
-version = "0.2.12"
+version = "0.2.13"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "53fe5e26ff1b7aef8bca9c6080520cfb8d9333c7568e1829cef191a9723e5504"
+checksum = "51e852e6dc9a5bed1fae92dd2375037bf2b768725bf3be87811edee3249d09ad"
dependencies = [
"libc",
]
@@ -272,7 +281,7 @@
dependencies = [
"anyhow",
"bumpalo",
- "indexmap 2.2.6",
+ "indexmap 2.4.0",
"rustc-hash",
"serde",
"unicode-width",
@@ -286,9 +295,9 @@
[[package]]
name = "either"
-version = "1.12.0"
+version = "1.13.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "3dca9240753cf90908d7e4aac30f630662b02aebaa1b58a3cadabdb23385b58b"
+checksum = "60b1af1c220855b6ceac025d3f6ecdd2b7c4894bfe9cd9bda4fbb4bc7c0d4cf0"
[[package]]
name = "encode_unicode"
@@ -309,14 +318,14 @@
checksum = "534c5cf6194dfab3db3242765c03bbe257cf92f22b38f6bc0c58d59108a820ba"
dependencies = [
"libc",
- "windows-sys",
+ "windows-sys 0.52.0",
]
[[package]]
name = "fastrand"
-version = "2.1.0"
+version = "2.1.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "9fc0510504f03c51ada170672ac806f1f105a88aa97a5281117e1ddc3368e51a"
+checksum = "e8c02a5121d4ea3eb16a80748c74f5549a5665e4c21333c6098f283870fbdea6"
[[package]]
name = "fnv"
@@ -392,9 +401,9 @@
[[package]]
name = "indexmap"
-version = "2.2.6"
+version = "2.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "168fb715dda47215e360912c096649d23d58bf392ac62f73919e831745e40f26"
+checksum = "93ead53efc7ea8ed3cfb0c79fc8023fbb782a5432b52830b6518941cebe6505c"
dependencies = [
"equivalent",
"hashbrown 0.14.5",
@@ -421,9 +430,9 @@
[[package]]
name = "is_terminal_polyfill"
-version = "1.70.0"
+version = "1.70.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "f8478577c03552c21db0e2724ffb8986a5ce7af88107e6be5d2ee6e158c12800"
+checksum = "7943c866cc5cd64cbc25b2e01621d07fa8eb2a1a23160ee81ce38704e97b8ecf"
[[package]]
name = "itertools"
@@ -524,7 +533,7 @@
dependencies = [
"proc-macro2",
"quote",
- "syn 2.0.64",
+ "syn 2.0.76",
]
[[package]]
@@ -542,7 +551,8 @@
dependencies = [
"proc-macro2",
"quote",
- "syn 2.0.64",
+ "syn 2.0.76",
+ "syn-dissect-closure",
]
[[package]]
@@ -620,15 +630,15 @@
[[package]]
name = "lazy_static"
-version = "1.4.0"
+version = "1.5.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646"
+checksum = "bbd2bcb4c963f2ddae06a2efc7e9f3591312473c50c6685e1f298068316e66fe"
[[package]]
name = "libc"
-version = "0.2.155"
+version = "0.2.158"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "97b3888a4aecf77e811145cadf6eef5901f4782c53886191b2f693f24761847c"
+checksum = "d8adc4bb1803a324070e64a98ae98f38934d91957a99cfb3a43dcbc01bc56439"
[[package]]
name = "libjsonnet"
@@ -665,18 +675,18 @@
[[package]]
name = "logos"
-version = "0.14.0"
+version = "0.14.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "161971eb88a0da7ae0c333e1063467c5b5727e7fb6b710b8db4814eade3a42e8"
+checksum = "ff1ceb190eb9bdeecdd8f1ad6a71d6d632a50905948771718741b5461fb01e13"
dependencies = [
"logos-derive",
]
[[package]]
name = "logos-codegen"
-version = "0.14.0"
+version = "0.14.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "8e31badd9de5131fdf4921f6473d457e3dd85b11b7f091ceb50e4df7c3eeb12a"
+checksum = "90be66cb7bd40cb5cc2e9cfaf2d1133b04a3d93b72344267715010a466e0915a"
dependencies = [
"beef",
"fnv",
@@ -684,23 +694,23 @@
"proc-macro2",
"quote",
"regex-syntax",
- "syn 2.0.64",
+ "syn 2.0.76",
]
[[package]]
name = "logos-derive"
-version = "0.14.0"
+version = "0.14.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "1c2a69b3eb68d5bd595107c9ee58d7e07fe2bb5e360cc85b0f084dedac80de0a"
+checksum = "45154231e8e96586b39494029e58f12f8ffcb5ecf80333a603a13aa205ea8cbd"
dependencies = [
"logos-codegen",
]
[[package]]
name = "lru"
-version = "0.12.3"
+version = "0.12.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "d3262e75e648fce39813cb56ac41f3c3e3f65217ebf3844d818d1f9398cfb0dc"
+checksum = "37ee39891760e7d94734f6f63fedc29a2e4a152f836120753a72503f09fcf904"
dependencies = [
"hashbrown 0.14.5",
]
@@ -713,18 +723,9 @@
[[package]]
name = "memchr"
-version = "2.7.2"
+version = "2.7.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "6c8640c5d730cb13ebd907d8d04b52f55ac9a2eec55b440c8892f40d56c76c1d"
-
-[[package]]
-name = "memoffset"
-version = "0.9.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "488016bfae457b036d996092f6cb448677611ce4449e970ceaf42695203f218a"
-dependencies = [
- "autocfg",
-]
+checksum = "78ca9ab1a0babb1e7d5695e3530886289c18cf2f87ec19a575a0abdce112e3a3"
[[package]]
name = "mimalloc-sys"
@@ -747,9 +748,9 @@
[[package]]
name = "num-bigint"
-version = "0.4.5"
+version = "0.4.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "c165a9ab64cf766f73521c0dd2cfdff64f488b8f0b3e621face3462d3db536d7"
+checksum = "a5e44f723f1133c9deac646763579fdb3ac745e418f2a7af9cd0c431da1f20b9"
dependencies = [
"num-integer",
"num-traits",
@@ -811,9 +812,9 @@
[[package]]
name = "peg"
-version = "0.8.3"
+version = "0.8.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "8a625d12ad770914cbf7eff6f9314c3ef803bfe364a1b20bc36ddf56673e71e5"
+checksum = "295283b02df346d1ef66052a757869b2876ac29a6bb0ac3f5f7cd44aebe40e8f"
dependencies = [
"peg-macros",
"peg-runtime",
@@ -821,9 +822,9 @@
[[package]]
name = "peg-macros"
-version = "0.8.3"
+version = "0.8.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "f241d42067ed3ab6a4fece1db720838e1418f36d868585a27931f95d6bc03582"
+checksum = "bdad6a1d9cf116a059582ce415d5f5566aabcd4008646779dab7fdc2a9a9d426"
dependencies = [
"peg-runtime",
"proc-macro2",
@@ -838,15 +839,18 @@
[[package]]
name = "ppv-lite86"
-version = "0.2.17"
+version = "0.2.20"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "5b40af805b3121feab8a3c29f04d8ad262fa8e0561883e7653e024ae4479e6de"
+checksum = "77957b295656769bb8ad2b6a6b09d897d94f05c41b069aede1fcdaa675eaea04"
+dependencies = [
+ "zerocopy",
+]
[[package]]
name = "proc-macro2"
-version = "1.0.82"
+version = "1.0.86"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "8ad3d49ab951a01fbaafe34f2ec74122942fe18a3f9814c3268f1bb72042131b"
+checksum = "5e719e8df665df0d1c8fbfd238015744736151d4445ec0836b8e628aae103b77"
dependencies = [
"unicode-ident",
]
@@ -862,9 +866,9 @@
[[package]]
name = "quote"
-version = "1.0.36"
+version = "1.0.37"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "0fa76aaf39101c457836aec0ce2316dbdc3ab723cdda1c6bd4e6ad4208acaca7"
+checksum = "b5b9d34b8991d19d98081b46eacdd8eb58c6f2b201139f7c5f643cc155a633af"
dependencies = [
"proc-macro2",
]
@@ -919,18 +923,18 @@
[[package]]
name = "redox_syscall"
-version = "0.5.1"
+version = "0.5.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "469052894dcb553421e483e4209ee581a45100d31b4018de03e5a7ad86374a7e"
+checksum = "2a908a6e00f1fdd0dfd9c0eb08ce85126f6d8bbda50017e74bc4a4b7d4a926a4"
dependencies = [
"bitflags",
]
[[package]]
name = "regex"
-version = "1.10.4"
+version = "1.10.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "c117dbdfde9c8308975b6a18d71f3f385c89461f7b3fb054288ecf2a2058ba4c"
+checksum = "4219d74c6b67a3654a9fbebc4b419e22126d13d2f3c4a07ee0cb61ff79a79619"
dependencies = [
"aho-corasick",
"memchr",
@@ -940,9 +944,9 @@
[[package]]
name = "regex-automata"
-version = "0.4.6"
+version = "0.4.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "86b83b8b9847f9bf95ef68afb0b8e6cdb80f498442f5179a29fad448fcc1eaea"
+checksum = "38caf58cc5ef2fed281f89292ef23f6365465ed9a41b7a7754eb4e26496c92df"
dependencies = [
"aho-corasick",
"memchr",
@@ -951,19 +955,18 @@
[[package]]
name = "regex-syntax"
-version = "0.8.3"
+version = "0.8.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "adad44e29e4c806119491a7f06f03de4d1af22c3a680dd47f1e6e179439d1f56"
+checksum = "7a66a03ae7c801facd77a29370b4faec201768915ac14a721ba36f20bc9c209b"
[[package]]
name = "rowan"
-version = "0.15.15"
+version = "0.15.16"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "32a58fa8a7ccff2aec4f39cc45bf5f985cec7125ab271cf681c279fd00192b49"
+checksum = "0a542b0253fa46e632d27a1dc5cf7b930de4df8659dc6e720b647fc72147ae3d"
dependencies = [
"countme",
"hashbrown 0.14.5",
- "memoffset",
"rustc-hash",
"text-size",
]
@@ -984,7 +987,7 @@
"errno",
"libc",
"linux-raw-sys",
- "windows-sys",
+ "windows-sys 0.52.0",
]
[[package]]
@@ -1001,31 +1004,32 @@
[[package]]
name = "serde"
-version = "1.0.202"
+version = "1.0.209"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "226b61a0d411b2ba5ff6d7f73a476ac4f8bb900373459cd00fab8512828ba395"
+checksum = "99fce0ffe7310761ca6bf9faf5115afbc19688edd00171d81b1bb1b116c63e09"
dependencies = [
"serde_derive",
]
[[package]]
name = "serde_derive"
-version = "1.0.202"
+version = "1.0.209"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "6048858004bcff69094cd972ed40a32500f153bd3be9f716b2eed2e8217c4838"
+checksum = "a5831b979fd7b5439637af1752d535ff49f4860c0f341d1baeb6faf0f4242170"
dependencies = [
"proc-macro2",
"quote",
- "syn 2.0.64",
+ "syn 2.0.76",
]
[[package]]
name = "serde_json"
-version = "1.0.117"
+version = "1.0.127"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "455182ea6142b14f93f4bc5320a2b31c1f266b66a4a5c858b013302a5d8cbfc3"
+checksum = "8043c06d9f82bd7271361ed64f415fe5e12a77fdb52e573e7f06a516dea329ad"
dependencies = [
"itoa",
+ "memchr",
"ryu",
"serde",
]
@@ -1075,10 +1079,16 @@
]
[[package]]
+name = "shlex"
+version = "1.3.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "0fda2ff0d084019ba4d7c6f371c95d8fd75ce3524c3cb8fb653a3023f6323e64"
+
+[[package]]
name = "similar"
-version = "2.5.0"
+version = "2.6.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "fa42c91313f1d05da9b26f267f931cf178d4aba455b4c4622dd7355eb80c6640"
+checksum = "1de1d4f81173b03af4c0cbed3c898f6bff5b870e4a7f5d6f4057d62a7a4b686e"
[[package]]
name = "smallvec"
@@ -1088,15 +1098,15 @@
[[package]]
name = "stacker"
-version = "0.1.15"
+version = "0.1.16"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "c886bd4480155fd3ef527d45e9ac8dd7118a898a46530b7b94c3e21866259fce"
+checksum = "95a5daa25ea337c85ed954c0496e3bdd2c7308cc3b24cf7b50d04876654c579f"
dependencies = [
"cc",
"cfg-if",
"libc",
"psm",
- "winapi",
+ "windows-sys 0.36.1",
]
[[package]]
@@ -1124,9 +1134,9 @@
[[package]]
name = "syn"
-version = "2.0.64"
+version = "2.0.76"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "7ad3dee41f36859875573074334c200d1add8e4a87bb37113ebd31d926b7b11f"
+checksum = "578e081a14e0cefc3279b0472138c513f37b41a08d5a3cca9b6e4e8ceb6cd525"
dependencies = [
"proc-macro2",
"quote",
@@ -1134,15 +1144,27 @@
]
[[package]]
+name = "syn-dissect-closure"
+version = "0.1.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "343bae741672e4b94421cbe93f9794ba9a061434272f7e3a29ff43be26be3ac9"
+dependencies = [
+ "proc-macro2",
+ "quote",
+ "syn 2.0.76",
+]
+
+[[package]]
name = "tempfile"
-version = "3.10.1"
+version = "3.12.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "85b77fafb263dd9d05cbeac119526425676db3784113aa9295c88498cbf8bff1"
+checksum = "04cbcdd0c794ebb0d4cf35e88edd2f7d2c4c3e9a5a6dab322839b321c6a87a64"
dependencies = [
"cfg-if",
"fastrand",
+ "once_cell",
"rustix",
- "windows-sys",
+ "windows-sys 0.59.0",
]
[[package]]
@@ -1165,22 +1187,22 @@
[[package]]
name = "thiserror"
-version = "1.0.61"
+version = "1.0.63"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "c546c80d6be4bc6a00c0f01730c08df82eaa7a7a61f11d656526506112cc1709"
+checksum = "c0342370b38b6a11b6cc11d6a805569958d54cfa061a29969c3b5ce2ea405724"
dependencies = [
"thiserror-impl",
]
[[package]]
name = "thiserror-impl"
-version = "1.0.61"
+version = "1.0.63"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "46c3384250002a6d5af4d114f2845d37b57521033f30d5c3f46c4d70e1197533"
+checksum = "a4558b58466b9ad7ca0f102865eccc95938dca1a74a856f2b57b6629050da261"
dependencies = [
"proc-macro2",
"quote",
- "syn 2.0.64",
+ "syn 2.0.76",
]
[[package]]
@@ -1203,21 +1225,21 @@
[[package]]
name = "unicode-width"
-version = "0.1.12"
+version = "0.1.13"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "68f5e5f3158ecfd4b8ff6fe086db7c8467a2dfdac97fe420f2b7c4aa97af66d6"
+checksum = "0336d538f7abc86d282a4189614dfaa90810dfc2c6f6427eaf88e16311dd225d"
[[package]]
name = "utf8parse"
-version = "0.2.1"
+version = "0.2.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "711b9620af191e0cdc7468a8d14e709c3dcdb115b36f838e601583af800a370a"
+checksum = "06abde3611657adf66d383f00b093d7faecc7fa57071cce2578660c9f1010821"
[[package]]
name = "version_check"
-version = "0.9.4"
+version = "0.9.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "49874b5167b65d7193b8aba1567f5c7d93d001cafc34600cee003eda787e483f"
+checksum = "0b928f33d975fc6ad9f86c8f283853ad26bdd5b10b7f1542aa2fa15e2289105a"
[[package]]
name = "wasi"
@@ -1226,99 +1248,129 @@
checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423"
[[package]]
-name = "winapi"
-version = "0.3.9"
+name = "windows-sys"
+version = "0.36.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "5c839a674fcd7a98952e593242ea400abe93992746761e38641405d28b00f419"
+checksum = "ea04155a16a59f9eab786fe12a4a450e75cdb175f9e0d80da1e17db09f55b8d2"
dependencies = [
- "winapi-i686-pc-windows-gnu",
- "winapi-x86_64-pc-windows-gnu",
+ "windows_aarch64_msvc 0.36.1",
+ "windows_i686_gnu 0.36.1",
+ "windows_i686_msvc 0.36.1",
+ "windows_x86_64_gnu 0.36.1",
+ "windows_x86_64_msvc 0.36.1",
]
[[package]]
-name = "winapi-i686-pc-windows-gnu"
-version = "0.4.0"
+name = "windows-sys"
+version = "0.52.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6"
-
-[[package]]
-name = "winapi-x86_64-pc-windows-gnu"
-version = "0.4.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f"
+checksum = "282be5f36a8ce781fad8c8ae18fa3f9beff57ec1b52cb3de0789201425d9a33d"
+dependencies = [
+ "windows-targets",
+]
[[package]]
name = "windows-sys"
-version = "0.52.0"
+version = "0.59.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "282be5f36a8ce781fad8c8ae18fa3f9beff57ec1b52cb3de0789201425d9a33d"
+checksum = "1e38bc4d79ed67fd075bcc251a1c39b32a1776bbe92e5bef1f0bf1f8c531853b"
dependencies = [
"windows-targets",
]
[[package]]
name = "windows-targets"
-version = "0.52.5"
+version = "0.52.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "6f0713a46559409d202e70e28227288446bf7841d3211583a4b53e3f6d96e7eb"
+checksum = "9b724f72796e036ab90c1021d4780d4d3d648aca59e491e6b98e725b84e99973"
dependencies = [
"windows_aarch64_gnullvm",
- "windows_aarch64_msvc",
- "windows_i686_gnu",
+ "windows_aarch64_msvc 0.52.6",
+ "windows_i686_gnu 0.52.6",
"windows_i686_gnullvm",
- "windows_i686_msvc",
- "windows_x86_64_gnu",
+ "windows_i686_msvc 0.52.6",
+ "windows_x86_64_gnu 0.52.6",
"windows_x86_64_gnullvm",
- "windows_x86_64_msvc",
+ "windows_x86_64_msvc 0.52.6",
]
[[package]]
name = "windows_aarch64_gnullvm"
-version = "0.52.5"
+version = "0.52.6"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "32a4622180e7a0ec044bb555404c800bc9fd9ec262ec147edd5989ccd0c02cd3"
+
+[[package]]
+name = "windows_aarch64_msvc"
+version = "0.36.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "7088eed71e8b8dda258ecc8bac5fb1153c5cffaf2578fc8ff5d61e23578d3263"
+checksum = "9bb8c3fd39ade2d67e9874ac4f3db21f0d710bee00fe7cab16949ec184eeaa47"
[[package]]
name = "windows_aarch64_msvc"
-version = "0.52.5"
+version = "0.52.6"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "09ec2a7bb152e2252b53fa7803150007879548bc709c039df7627cabbd05d469"
+
+[[package]]
+name = "windows_i686_gnu"
+version = "0.36.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "9985fd1504e250c615ca5f281c3f7a6da76213ebd5ccc9561496568a2752afb6"
+checksum = "180e6ccf01daf4c426b846dfc66db1fc518f074baa793aa7d9b9aaeffad6a3b6"
[[package]]
name = "windows_i686_gnu"
-version = "0.52.5"
+version = "0.52.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "88ba073cf16d5372720ec942a8ccbf61626074c6d4dd2e745299726ce8b89670"
+checksum = "8e9b5ad5ab802e97eb8e295ac6720e509ee4c243f69d781394014ebfe8bbfa0b"
[[package]]
name = "windows_i686_gnullvm"
-version = "0.52.5"
+version = "0.52.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "87f4261229030a858f36b459e748ae97545d6f1ec60e5e0d6a3d32e0dc232ee9"
+checksum = "0eee52d38c090b3caa76c563b86c3a4bd71ef1a819287c19d586d7334ae8ed66"
[[package]]
name = "windows_i686_msvc"
-version = "0.52.5"
+version = "0.36.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "e2e7917148b2812d1eeafaeb22a97e4813dfa60a3f8f78ebe204bcc88f12f024"
+
+[[package]]
+name = "windows_i686_msvc"
+version = "0.52.6"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "240948bc05c5e7c6dabba28bf89d89ffce3e303022809e73deaefe4f6ec56c66"
+
+[[package]]
+name = "windows_x86_64_gnu"
+version = "0.36.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "db3c2bf3d13d5b658be73463284eaf12830ac9a26a90c717b7f771dfe97487bf"
+checksum = "4dcd171b8776c41b97521e5da127a2d86ad280114807d0b2ab1e462bc764d9e1"
[[package]]
name = "windows_x86_64_gnu"
-version = "0.52.5"
+version = "0.52.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "4e4246f76bdeff09eb48875a0fd3e2af6aada79d409d33011886d3e1581517d9"
+checksum = "147a5c80aabfbf0c7d901cb5895d1de30ef2907eb21fbbab29ca94c5b08b1a78"
[[package]]
name = "windows_x86_64_gnullvm"
-version = "0.52.5"
+version = "0.52.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "852298e482cd67c356ddd9570386e2862b5673c85bd5f88df9ab6802b334c596"
+checksum = "24d5b23dc417412679681396f2b49f3de8c1473deb516bd34410872eff51ed0d"
+
+[[package]]
+name = "windows_x86_64_msvc"
+version = "0.36.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "c811ca4a8c853ef420abd8592ba53ddbbac90410fab6903b3e79972a631f7680"
[[package]]
name = "windows_x86_64_msvc"
-version = "0.52.5"
+version = "0.52.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "bec47e5bfd1bff0eeaf6d8b485cc1074891a197ab4225d504cb7a1ab88b02bf0"
+checksum = "589f6da84c646204747d1270a2a5661ea66ed1cced2631d546fdfb155959f9ec"
[[package]]
name = "xshell"
@@ -1341,7 +1393,7 @@
dependencies = [
"anyhow",
"clap",
- "indexmap 2.2.6",
+ "indexmap 2.4.0",
"itertools",
"proc-macro2",
"quote",
@@ -1360,20 +1412,21 @@
[[package]]
name = "zerocopy"
-version = "0.7.34"
+version = "0.7.35"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "ae87e3fcd617500e5d106f0380cf7b77f3c6092aae37191433159dda23cfb087"
+checksum = "1b9b4fd18abc82b8136838da5d50bae7bdea537c574d8dc1a34ed098d6c166f0"
dependencies = [
+ "byteorder",
"zerocopy-derive",
]
[[package]]
name = "zerocopy-derive"
-version = "0.7.34"
+version = "0.7.35"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "15e934569e47891f7d9411f1a451d947a60e000ab3bd24fbb970f000387d1b3b"
+checksum = "fa4f8080344d4671fb4e831a13ad1e68092748387dfc4f55e356242fae12ce3e"
dependencies = [
"proc-macro2",
"quote",
- "syn 2.0.64",
+ "syn 2.0.76",
]
Cargo.tomldiffbeforeafterboth--- a/Cargo.toml
+++ b/Cargo.toml
@@ -89,6 +89,7 @@
lru = "0.12.3"
json-structural-diff = "0.1.0"
+syn-dissect-closure = "0.1.0"
[workspace.lints.rust]
unsafe_op_in_unsafe_fn = "deny"
@@ -107,9 +108,9 @@
all = "warn"
[workspace.lints.clippy]
-all = "warn"
-nursery = "warn"
-pedantic = "warn"
+all = { level = "warn", priority = -1 }
+nursery = { level = "warn", priority = -1 }
+pedantic = { level = "warn", priority = -1 }
ptr_arg = "allow"
# Too verbose
bindings/jsonnet/src/native.rsdiffbeforeafterboth--- a/bindings/jsonnet/src/native.rs
+++ b/bindings/jsonnet/src/native.rs
@@ -20,6 +20,7 @@
/// - `ctx` User pointer, given in `jsonnet_native_callback`.
/// - `argv` Array of arguments from Jsonnet code.
/// - `param` success Set this byref param to 1 to indicate success and 0 for failure.
+///
/// Returns the content of the imported file, or an error message.
type JsonnetNativeCallback = unsafe extern "C" fn(
ctx: *const c_void,
cmds/jrsonnet-fmt/src/comments.rsdiffbeforeafterboth--- a/cmds/jrsonnet-fmt/src/comments.rs
+++ b/cmds/jrsonnet-fmt/src/comments.rs
@@ -20,7 +20,7 @@
let Ok(c) = c else {
let mut text = c.as_ref().unwrap_err() as &str;
while !text.is_empty() {
- let pos = text.find(|c| c == '\n' || c == '\t').unwrap_or(text.len());
+ let pos = text.find(['\n', '\t']).unwrap_or(text.len());
let sliced = &text[..pos];
p!(out, string(sliced.to_string()));
text = &text[pos..];
cmds/jrsonnet-fmt/src/tests.rsdiffbeforeafterboth--- a/cmds/jrsonnet-fmt/src/tests.rs
+++ b/cmds/jrsonnet-fmt/src/tests.rs
@@ -75,5 +75,5 @@
b: '',
},
}"
- )))
+ )));
}
crates/jrsonnet-evaluator/src/function/arglike.rsdiffbeforeafterboth--- a/crates/jrsonnet-evaluator/src/function/arglike.rs
+++ b/crates/jrsonnet-evaluator/src/function/arglike.rs
@@ -91,6 +91,7 @@
handler: &mut dyn FnMut(&IStr, Thunk<Val>) -> Result<()>,
) -> Result<()>;
fn named_names(&self, handler: &mut dyn FnMut(&IStr));
+ fn is_empty(&self) -> bool;
}
impl ArgsLike for Vec<Val> {
@@ -117,6 +118,9 @@
Ok(())
}
fn named_names(&self, _handler: &mut dyn FnMut(&IStr)) {}
+ fn is_empty(&self) -> bool {
+ self.is_empty()
+ }
}
impl ArgsLike for ArgsDesc {
@@ -173,6 +177,10 @@
handler(name);
}
}
+
+ fn is_empty(&self) -> bool {
+ self.unnamed.is_empty() && self.named.is_empty()
+ }
}
impl<V: ArgLike, S> ArgsLike for HashMap<IStr, V, S> {
@@ -206,6 +214,10 @@
handler(name);
}
}
+
+ fn is_empty(&self) -> bool {
+ self.is_empty()
+ }
}
impl<V, S> OptionalContext for HashMap<IStr, V, S> where V: ArgLike + OptionalContext {}
@@ -235,6 +247,10 @@
fn named_names(&self, handler: &mut dyn FnMut(&IStr)) {
self.0.named_names(handler);
}
+
+ fn is_empty(&self) -> bool {
+ self.0.is_empty()
+ }
}
macro_rules! impl_args_like {
@@ -267,43 +283,13 @@
Ok(())
}
fn named_names(&self, _handler: &mut dyn FnMut(&IStr)) {}
- }
- impl<$($gen: ArgLike,)*> OptionalContext for ($($gen,)*) where $($gen: OptionalContext),* {}
- impl<$($gen: ArgLike,)*> ArgsLike for ($((IStr, $gen),)*) {
- fn unnamed_len(&self) -> usize {
- 0
- }
- fn unnamed_iter(
- &self,
- _ctx: Context,
- _tailstrict: bool,
- _handler: &mut dyn FnMut(usize, Thunk<Val>) -> Result<()>,
- ) -> Result<()> {
- Ok(())
- }
- #[allow(non_snake_case)]
- fn named_iter(
- &self,
- ctx: Context,
- tailstrict: bool,
- handler: &mut dyn FnMut(&IStr, Thunk<Val>) -> Result<()>,
- ) -> Result<()> {
- let ($($gen,)*) = self;
- $(
- handler(&$gen.0, $gen.1.evaluate_arg(ctx.clone(), tailstrict)?)?;
- )*
- Ok(())
- }
- #[allow(non_snake_case)]
- fn named_names(&self, handler: &mut dyn FnMut(&IStr)) {
- let ($($gen,)*) = self;
- $(
- handler(&$gen.0);
- )*
+ fn is_empty(&self) -> bool {
+ // impl_args_like only implements non-empty tuples.
+ false
}
}
- impl<$($gen: ArgLike,)*> OptionalContext for ($((IStr, $gen),)*) where $($gen: OptionalContext),* {}
+ impl<$($gen: ArgLike,)*> OptionalContext for ($($gen,)*) where $($gen: OptionalContext),* {}
};
($count:expr; $($cur:ident)* @ $c:ident $($rest:ident)*) => {
impl_args_like!($count; $($cur)*);
@@ -342,5 +328,8 @@
}
fn named_names(&self, _handler: &mut dyn FnMut(&IStr)) {}
+ fn is_empty(&self) -> bool {
+ true
+ }
}
impl OptionalContext for () {}
crates/jrsonnet-evaluator/src/function/mod.rsdiffbeforeafterboth--- a/crates/jrsonnet-evaluator/src/function/mod.rs
+++ b/crates/jrsonnet-evaluator/src/function/mod.rs
@@ -12,7 +12,10 @@
native::NativeDesc,
parse::{parse_default_function_call, parse_function_call},
};
-use crate::{evaluate, evaluate_trivial, gc::TraceBox, tb, Context, ContextBuilder, Result, Val};
+use crate::{
+ bail, error::ErrorKind::*, evaluate, evaluate_trivial, gc::TraceBox, tb, Context,
+ ContextBuilder, Result, Thunk, Val,
+};
pub mod arglike;
pub mod builtin;
@@ -94,6 +97,8 @@
Id,
/// Plain function implemented in jsonnet.
Normal(Cc<FuncDesc>),
+ /// Function without arguments works just as a fancy thunk value.
+ Thunk(Thunk<Val>),
/// Standard library function.
StaticBuiltin(#[trace(skip)] &'static dyn StaticBuiltin),
/// User-provided function.
@@ -104,6 +109,7 @@
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
match self {
Self::Id => f.debug_tuple("Id").finish(),
+ Self::Thunk(arg0) => f.debug_tuple("Thunk").field(arg0).finish(),
Self::Normal(arg0) => f.debug_tuple("Normal").field(arg0).finish(),
Self::StaticBuiltin(arg0) => {
f.debug_tuple("StaticBuiltin").field(&arg0.name()).finish()
@@ -146,6 +152,7 @@
)
})
.collect(),
+ Self::Thunk(_) => vec![],
}
}
/// Amount of non-default required arguments
@@ -155,6 +162,7 @@
Self::Normal(n) => n.params.iter().filter(|p| p.1.is_none()).count(),
Self::StaticBuiltin(i) => i.params().iter().filter(|p| !p.has_default()).count(),
Self::Builtin(i) => i.params().iter().filter(|p| !p.has_default()).count(),
+ Self::Thunk(_) => 0,
}
}
/// Function name, as defined in code.
@@ -164,6 +172,7 @@
Self::Normal(normal) => normal.name.clone(),
Self::StaticBuiltin(builtin) => builtin.name().into(),
Self::Builtin(builtin) => builtin.name().into(),
+ Self::Thunk(_) => "thunk".into(),
}
}
/// Call function using arguments evaluated in specified `call_ctx` [`Context`].
@@ -182,6 +191,12 @@
let body_ctx = func.call_body_context(call_ctx, args, tailstrict)?;
evaluate(body_ctx, &func.body)
}
+ Self::Thunk(thunk) => {
+ if args.is_empty() {
+ bail!(TooManyArgsFunctionHas(0, vec![],))
+ }
+ thunk.evaluate()
+ }
Self::StaticBuiltin(b) => b.call(call_ctx, loc, args),
Self::Builtin(b) => b.call(call_ctx, loc, args),
}
crates/jrsonnet-evaluator/src/stdlib/format.rsdiffbeforeafterboth1//! faster std.format impl2#![allow(clippy::too_many_arguments)]34use jrsonnet_gcmodule::Trace;5use jrsonnet_interner::IStr;6use jrsonnet_types::ValType;7use thiserror::Error;89use crate::{10 bail,11 error::{format_found, suggest_object_fields, ErrorKind::*},12 typed::Typed,13 Error, ObjValue, Result, Val,14};1516#[derive(Debug, Clone, Error, Trace)]17pub enum FormatError {18 #[error("truncated format code")]19 TruncatedFormatCode,20 #[error("unrecognized conversion type: {0}")]21 UnrecognizedConversionType(char),2223 #[error("not enough values")]24 NotEnoughValues,2526 #[error("cannot use * width with object")]27 CannotUseStarWidthWithObject,28 #[error("mapping keys required")]29 MappingKeysRequired,30 #[error("no such format field: {0}")]31 NoSuchFormatField(IStr),3233 #[error("expected subfield <{0}> to be an object, got {1} instead")]34 SubfieldDidntYieldAnObject(IStr, ValType),35 #[error("subfield not found: <[{full}]{current}>{}", format_found(.found, "subfield"))]36 SubfieldNotFound {37 current: IStr,38 full: IStr,39 found: Box<Vec<IStr>>,40 },41}4243impl From<FormatError> for Error {44 fn from(e: FormatError) -> Self {45 Self::new(Format(e))46 }47}4849use FormatError::*;5051type ParseResult<'t, T> = std::result::Result<(T, &'t str), FormatError>;5253pub fn try_parse_mapping_key(str: &str) -> ParseResult<'_, &str> {54 if str.is_empty() {55 return Err(TruncatedFormatCode);56 }57 let bytes = str.as_bytes();58 if bytes[0] == b'(' {59 let mut i = 1;60 while i < bytes.len() {61 if bytes[i] == b')' {62 return Ok((&str[1..i], &str[i + 1..]));63 }64 i += 1;65 }66 Err(TruncatedFormatCode)67 } else {68 Ok(("", str))69 }70}7172#[cfg(test)]73pub mod tests_key {74 use super::*;7576 #[test]77 fn parse_key() {78 assert_eq!(79 try_parse_mapping_key("(hello ) world").unwrap(),80 ("hello ", " world")81 );82 assert_eq!(try_parse_mapping_key("() world").unwrap(), ("", " world"));83 assert_eq!(try_parse_mapping_key(" world").unwrap(), ("", " world"));84 assert_eq!(85 try_parse_mapping_key(" () world").unwrap(),86 ("", " () world")87 );88 }8990 #[test]91 #[should_panic = "TruncatedFormatCode"]92 fn parse_key_missing_start() {93 try_parse_mapping_key("").unwrap();94 }9596 #[test]97 #[should_panic = "TruncatedFormatCode"]98 fn parse_key_missing_end() {99 try_parse_mapping_key("( ").unwrap();100 }101}102103#[allow(clippy::struct_excessive_bools)]104#[derive(Default, Debug)]105pub struct CFlags {106 pub alt: bool,107 pub zero: bool,108 pub left: bool,109 pub blank: bool,110 pub sign: bool,111}112113pub fn try_parse_cflags(str: &str) -> ParseResult<'_, CFlags> {114 if str.is_empty() {115 return Err(TruncatedFormatCode);116 }117 let bytes = str.as_bytes();118 let mut i = 0;119 let mut out = CFlags::default();120 loop {121 if bytes.len() == i {122 return Err(TruncatedFormatCode);123 }124 match bytes[i] {125 b'#' => out.alt = true,126 b'0' => out.zero = true,127 b'-' => out.left = true,128 b' ' => out.blank = true,129 b'+' => out.sign = true,130 _ => break,131 }132 i += 1;133 }134 Ok((out, &str[i..]))135}136137#[derive(Debug, PartialEq, Eq)]138pub enum Width {139 Star,140 Fixed(usize),141}142pub fn try_parse_field_width(str: &str) -> ParseResult<'_, Width> {143 if str.is_empty() {144 return Err(TruncatedFormatCode);145 }146 let bytes = str.as_bytes();147 if bytes[0] == b'*' {148 return Ok((Width::Star, &str[1..]));149 }150 let mut out: usize = 0;151 let mut digits = 0;152 while let Some(digit) = (bytes[digits] as char).to_digit(10) {153 out *= 10;154 out += digit as usize;155 digits += 1;156 if digits == bytes.len() {157 return Err(TruncatedFormatCode);158 }159 }160 Ok((Width::Fixed(out), &str[digits..]))161}162163pub fn try_parse_precision(str: &str) -> ParseResult<'_, Option<Width>> {164 if str.is_empty() {165 return Err(TruncatedFormatCode);166 }167 let bytes = str.as_bytes();168 if bytes[0] == b'.' {169 try_parse_field_width(&str[1..]).map(|(r, s)| (Some(r), s))170 } else {171 Ok((None, str))172 }173}174175// Only skips176pub fn try_parse_length_modifier(str: &str) -> ParseResult<'_, ()> {177 if str.is_empty() {178 return Err(TruncatedFormatCode);179 }180 let bytes = str.as_bytes();181 let mut idx = 0;182 while bytes[idx] == b'h' || bytes[idx] == b'l' || bytes[idx] == b'L' {183 idx += 1;184 if bytes.len() == idx {185 return Err(TruncatedFormatCode);186 }187 }188 Ok(((), &str[idx..]))189}190191#[derive(Debug, PartialEq, Eq)]192pub enum ConvTypeV {193 Decimal,194 Octal,195 Hexadecimal,196 Scientific,197 Float,198 Shorter,199 Char,200 String,201 Percent,202}203pub struct ConvType {204 v: ConvTypeV,205 caps: bool,206}207208pub fn parse_conversion_type(str: &str) -> ParseResult<'_, ConvType> {209 if str.is_empty() {210 return Err(TruncatedFormatCode);211 }212213 let code = str.as_bytes()[0];214 let v: (ConvTypeV, bool) = match code {215 b'd' | b'i' | b'u' => (ConvTypeV::Decimal, false),216 b'o' => (ConvTypeV::Octal, false),217 b'x' => (ConvTypeV::Hexadecimal, false),218 b'X' => (ConvTypeV::Hexadecimal, true),219 b'e' => (ConvTypeV::Scientific, false),220 b'E' => (ConvTypeV::Scientific, true),221 b'f' => (ConvTypeV::Float, false),222 b'F' => (ConvTypeV::Float, true),223 b'g' => (ConvTypeV::Shorter, false),224 b'G' => (ConvTypeV::Shorter, true),225 b'c' => (ConvTypeV::Char, false),226 b's' => (ConvTypeV::String, false),227 b'%' => (ConvTypeV::Percent, false),228 c => return Err(UnrecognizedConversionType(c as char)),229 };230231 Ok((ConvType { v: v.0, caps: v.1 }, &str[1..]))232}233234#[derive(Debug)]235pub struct Code<'s> {236 mkey: &'s str,237 cflags: CFlags,238 width: Width,239 precision: Option<Width>,240 convtype: ConvTypeV,241 caps: bool,242}243pub fn parse_code(str: &str) -> ParseResult<'_, Code<'_>> {244 if str.is_empty() {245 return Err(TruncatedFormatCode);246 }247 let (mkey, str) = try_parse_mapping_key(str)?;248 let (cflags, str) = try_parse_cflags(str)?;249 let (width, str) = try_parse_field_width(str)?;250 let (precision, str) = try_parse_precision(str)?;251 let ((), str) = try_parse_length_modifier(str)?;252 let (convtype, str) = parse_conversion_type(str)?;253254 Ok((255 Code {256 mkey,257 cflags,258 width,259 precision,260 convtype: convtype.v,261 caps: convtype.caps,262 },263 str,264 ))265}266267#[derive(Debug)]268pub enum Element<'s> {269 String(&'s str),270 Code(Code<'s>),271}272pub fn parse_codes(mut str: &str) -> Result<Vec<Element<'_>>> {273 let mut bytes = str.as_bytes();274 let mut out = vec![];275 let mut offset = 0;276277 loop {278 while offset != bytes.len() && bytes[offset] != b'%' {279 offset += 1;280 }281 if offset != 0 {282 out.push(Element::String(&str[0..offset]));283 }284 if offset == bytes.len() {285 return Ok(out);286 }287 str = &str[offset + 1..];288 let code;289 (code, str) = parse_code(str)?;290 bytes = str.as_bytes();291 offset = 0;292293 out.push(Element::Code(code));294 }295}296297const NUMBERS: &[u8] = b"0123456789abcdefghijklmnopqrstuvwxyz";298299#[inline]300pub fn render_integer(301 out: &mut String,302 iv: f64,303 padding: usize,304 precision: usize,305 blank: bool,306 sign: bool,307 radix: i64,308 prefix: &str,309 caps: bool,310) {311 let radix = radix as f64;312 let iv = iv.floor();313 // Digit char indexes in reverse order, i.e314 // for radix = 16 and n = 12f: [15, 2, 1]315 let digits = if iv == 0.0 {316 vec![0u8]317 } else {318 let mut v = iv.abs();319 let mut nums = Vec::with_capacity(1);320 while v != 0.0 {321 nums.push((v % radix) as u8);322 v = (v / radix).floor();323 }324 nums325 };326 let neg = iv < 0.0;327 #[allow(clippy::bool_to_int_with_if)]328 let zp = padding.saturating_sub(if neg || blank || sign { 1 } else { 0 });329 let zp2 = zp330 .max(precision)331 .saturating_sub(prefix.len() + digits.len());332333 if neg {334 out.push('-');335 } else if sign {336 out.push('+');337 } else if blank {338 out.push(' ');339 }340341 out.reserve(zp2);342 for _ in 0..zp2 {343 out.push('0');344 }345 out.push_str(prefix);346347 for digit in digits.into_iter().rev() {348 let ch = NUMBERS[digit as usize] as char;349 out.push(if caps { ch.to_ascii_uppercase() } else { ch });350 }351}352353pub fn render_decimal(354 out: &mut String,355 iv: f64,356 padding: usize,357 precision: usize,358 blank: bool,359 sign: bool,360) {361 render_integer(out, iv, padding, precision, blank, sign, 10, "", false);362}363pub fn render_octal(364 out: &mut String,365 iv: f64,366 padding: usize,367 precision: usize,368 alt: bool,369 blank: bool,370 sign: bool,371) {372 render_integer(373 out,374 iv,375 padding,376 precision,377 blank,378 sign,379 8,380 if alt && iv != 0.0 { "0" } else { "" },381 false,382 );383}384385#[allow(clippy::fn_params_excessive_bools)]386pub fn render_hexadecimal(387 out: &mut String,388 iv: f64,389 padding: usize,390 precision: usize,391 alt: bool,392 blank: bool,393 sign: bool,394 caps: bool,395) {396 render_integer(397 out,398 iv,399 padding,400 precision,401 blank,402 sign,403 16,404 match (alt, caps) {405 (true, true) => "0X",406 (true, false) => "0x",407 (false, _) => "",408 },409 caps,410 );411}412413#[allow(clippy::fn_params_excessive_bools)]414pub fn render_float(415 out: &mut String,416 n: f64,417 mut padding: usize,418 precision: usize,419 blank: bool,420 sign: bool,421 ensure_pt: bool,422 trailing: bool,423) {424 #[allow(clippy::bool_to_int_with_if)]425 let dot_size = if precision == 0 && !ensure_pt { 0 } else { 1 };426 padding = padding.saturating_sub(dot_size + precision);427 render_decimal(out, n.floor(), padding, 0, blank, sign);428 if precision == 0 {429 if ensure_pt {430 out.push('.');431 }432 return;433 }434 let frac = n435 .fract()436 .mul_add(10.0_f64.powf(precision as f64), 0.5)437 .floor();438 if trailing || frac > 0.0 {439 out.push('.');440 let mut frac_str = String::new();441 render_decimal(&mut frac_str, frac, precision, 0, false, false);442 let mut trim = frac_str.len();443 if !trailing {444 for b in frac_str.as_bytes().iter().rev() {445 if *b == b'0' {446 trim -= 1;447 } else {448 break;449 }450 }451 }452 out.push_str(&frac_str[..trim]);453 } else if ensure_pt {454 out.push('.');455 }456}457458#[allow(clippy::fn_params_excessive_bools)]459pub fn render_float_sci(460 out: &mut String,461 n: f64,462 mut padding: usize,463 precision: usize,464 blank: bool,465 sign: bool,466 ensure_pt: bool,467 trailing: bool,468 caps: bool,469) {470 let exponent = n.log10().floor();471 let mantissa = if exponent as i16 == -324 {472 n * 10.0 / 10.0_f64.powf(exponent + 1.0)473 } else {474 n / 10.0_f64.powf(exponent)475 };476 let mut exponent_str = String::new();477 render_decimal(&mut exponent_str, exponent, 3, 0, false, true);478479 // +1 for e480 padding = padding.saturating_sub(exponent_str.len() + 1);481482 render_float(483 out, mantissa, padding, precision, blank, sign, ensure_pt, trailing,484 );485 out.push(if caps { 'E' } else { 'e' });486 out.push_str(&exponent_str);487}488489#[allow(clippy::too_many_lines)]490pub fn format_code(491 out: &mut String,492 value: &Val,493 code: &Code<'_>,494 width: usize,495 precision: Option<usize>,496) -> Result<()> {497 let clfags = &code.cflags;498 let (fpprec, iprec) = precision.map_or((6, 0), |v| (v, v));499 let padding = if clfags.zero && !clfags.left {500 width501 } else {502 0503 };504505 // TODO: If left padded, can optimize by writing directly to out506 let mut tmp_out = String::new();507508 match code.convtype {509 ConvTypeV::String => tmp_out.push_str(&value.clone().to_string()?),510 ConvTypeV::Decimal => {511 let value = f64::from_untyped(value.clone())?;512 render_decimal(513 &mut tmp_out,514 value,515 padding,516 iprec,517 clfags.blank,518 clfags.sign,519 );520 }521 ConvTypeV::Octal => {522 let value = f64::from_untyped(value.clone())?;523 render_octal(524 &mut tmp_out,525 value,526 padding,527 iprec,528 clfags.alt,529 clfags.blank,530 clfags.sign,531 );532 }533 ConvTypeV::Hexadecimal => {534 let value = f64::from_untyped(value.clone())?;535 render_hexadecimal(536 &mut tmp_out,537 value,538 padding,539 iprec,540 clfags.alt,541 clfags.blank,542 clfags.sign,543 code.caps,544 );545 }546 ConvTypeV::Scientific => {547 let value = f64::from_untyped(value.clone())?;548 render_float_sci(549 &mut tmp_out,550 value,551 padding,552 fpprec,553 clfags.blank,554 clfags.sign,555 clfags.alt,556 true,557 code.caps,558 );559 }560 ConvTypeV::Float => {561 let value = f64::from_untyped(value.clone())?;562 render_float(563 &mut tmp_out,564 value,565 padding,566 fpprec,567 clfags.blank,568 clfags.sign,569 clfags.alt,570 true,571 );572 }573 ConvTypeV::Shorter => {574 let value = f64::from_untyped(value.clone())?;575 let exponent = if value == 0.0 {576 0.0577 } else {578 value.abs().log10().floor()579 };580 if exponent < -4.0 || exponent >= fpprec as f64 {581 render_float_sci(582 &mut tmp_out,583 value,584 padding,585 fpprec - 1,586 clfags.blank,587 clfags.sign,588 clfags.alt,589 clfags.alt,590 code.caps,591 );592 } else {593 let digits_before_pt = 1.max(exponent as usize + 1);594 render_float(595 &mut tmp_out,596 value,597 padding,598 fpprec - digits_before_pt,599 clfags.blank,600 clfags.sign,601 clfags.alt,602 clfags.alt,603 );604 }605 }606 ConvTypeV::Char => match value.clone() {607 Val::Num(n) => {608 let n = n.get();609 tmp_out.push(610 std::char::from_u32(n as u32)611 .ok_or_else(|| InvalidUnicodeCodepointGot(n as u32))?,612 );613 }614 Val::Str(s) => {615 let s = s.into_flat();616 if s.chars().count() != 1 {617 bail!("%c expected 1 char string, got {}", s.chars().count());618 }619 tmp_out.push_str(&s);620 }621 _ => {622 bail!(TypeMismatch(623 "%c requires number/string",624 vec![ValType::Num, ValType::Str],625 value.value_type(),626 ));627 }628 },629 ConvTypeV::Percent => tmp_out.push('%'),630 };631632 let padding = width.saturating_sub(tmp_out.len());633634 if !clfags.left {635 for _ in 0..padding {636 out.push(' ');637 }638 }639 out.push_str(&tmp_out);640 if clfags.left {641 for _ in 0..padding {642 out.push(' ');643 }644 }645646 Ok(())647}648649pub fn format_arr(str: &str, mut values: &[Val]) -> Result<String> {650 let codes = parse_codes(str)?;651 let mut out = String::new();652 let value_count = values.len();653654 for code in codes {655 match code {656 Element::String(s) => {657 out.push_str(s);658 }659 Element::Code(c) => {660 let width = match c.width {661 Width::Star => {662 if values.is_empty() {663 bail!(NotEnoughValues);664 }665 let value = &values[0];666 values = &values[1..];667 usize::from_untyped(value.clone())?668 }669 Width::Fixed(n) => n,670 };671 let precision = match c.precision {672 Some(Width::Star) => {673 if values.is_empty() {674 bail!(NotEnoughValues);675 }676 let value = &values[0];677 values = &values[1..];678 Some(usize::from_untyped(value.clone())?)679 }680 Some(Width::Fixed(n)) => Some(n),681 None => None,682 };683684 // %% should not consume a value685 let value = if c.convtype == ConvTypeV::Percent {686 &Val::Null687 } else {688 if values.is_empty() {689 bail!(NotEnoughValues);690 }691 let value = &values[0];692 values = &values[1..];693 value694 };695696 format_code(&mut out, value, &c, width, precision)?;697 }698 }699 }700701 if !values.is_empty() {702 bail!(703 "too many values to format, expected {value_count}, got {}",704 value_count + values.len()705 )706 }707708 Ok(out)709}710711fn get_dotted_field(obj: ObjValue, field: &str) -> Result<Val> {712 let mut current = Val::Obj(obj);713 let mut name_offset = 0;714 for component in field.split('.') {715 let end_offset = name_offset + component.len();716 current = if let Val::Obj(obj) = current {717 if let Some(value) = obj.get(component.into())? {718 value719 } else {720 let current = &field[name_offset..end_offset];721 let full = &field[..name_offset];722 let found = Box::new(suggest_object_fields(&obj, current.into()));723 bail!(SubfieldNotFound {724 current: current.into(),725 full: full.into(),726 found,727 })728 }729 } else {730 // No underflow may happen, initially we always start with an object731 let subfield = &field[..name_offset - 1];732 bail!(SubfieldDidntYieldAnObject(733 subfield.into(),734 current.value_type()735 ));736 };737 name_offset = end_offset + 1;738 }739 Ok(current)740}741742pub fn format_obj(str: &str, values: &ObjValue) -> Result<String> {743 let codes = parse_codes(str)?;744 let mut out = String::new();745746 for code in codes {747 match code {748 Element::String(s) => {749 out.push_str(s);750 }751 Element::Code(c) => {752 // TODO: Operate on ref753 let f: IStr = c.mkey.into();754 let width = match c.width {755 Width::Star => {756 bail!(CannotUseStarWidthWithObject);757 }758 Width::Fixed(n) => n,759 };760 let precision = match c.precision {761 Some(Width::Star) => {762 bail!(CannotUseStarWidthWithObject);763 }764 Some(Width::Fixed(n)) => Some(n),765 None => None,766 };767768 let value = if c.convtype == ConvTypeV::Percent {769 Val::Null770 } else {771 if f.is_empty() {772 bail!(MappingKeysRequired);773 }774 if let Some(v) = values.get(f.clone())? {775 v776 } else {777 get_dotted_field(values.clone(), &f)?778 }779 };780781 format_code(&mut out, &value, &c, width, precision)?;782 }783 }784 }785786 Ok(out)787}788789#[cfg(test)]790pub mod test_format {791 use super::*;792 use crate::val::NumValue;793794 #[test]795 fn parse() {796 assert_eq!(797 parse_codes(798 "How much error budget is left looking at our %.3f%% availability gurantees?"799 )800 .unwrap()801 .len(),802 4803 );804 }805806 fn num(v: f64) -> Val {807 Val::Num(NumValue::new(v).expect("finite"))808 }809810 #[test]811 fn octals() {812 assert_eq!(format_arr("%#o", &[num(8.0)]).unwrap(), "010");813 assert_eq!(format_arr("%#4o", &[num(8.0)]).unwrap(), " 010");814 assert_eq!(format_arr("%4o", &[num(8.0)]).unwrap(), " 10");815 assert_eq!(format_arr("%04o", &[num(8.0)]).unwrap(), "0010");816 assert_eq!(format_arr("%+4o", &[num(8.0)]).unwrap(), " +10");817 assert_eq!(format_arr("%+04o", &[num(8.0)]).unwrap(), "+010");818 assert_eq!(format_arr("%-4o", &[num(8.0)]).unwrap(), "10 ");819 assert_eq!(format_arr("%+-4o", &[num(8.0)]).unwrap(), "+10 ");820 assert_eq!(format_arr("%+-04o", &[num(8.0)]).unwrap(), "+10 ");821 }822823 #[test]824 fn percent_doesnt_consumes_values() {825 assert_eq!(826 format_arr(827 "How much error budget is left looking at our %.3f%% availability gurantees?",828 &[num(4.0)]829 )830 .unwrap(),831 "How much error budget is left looking at our 4.000% availability gurantees?"832 );833 }834}1//! faster std.format impl2#![allow(clippy::too_many_arguments)]34use jrsonnet_gcmodule::Trace;5use jrsonnet_interner::IStr;6use jrsonnet_types::ValType;7use thiserror::Error;89use crate::{10 bail,11 error::{format_found, suggest_object_fields, ErrorKind::*},12 typed::Typed,13 Error, ObjValue, Result, Val,14};1516#[derive(Debug, Clone, Error, Trace)]17pub enum FormatError {18 #[error("truncated format code")]19 TruncatedFormatCode,20 #[error("unrecognized conversion type: {0}")]21 UnrecognizedConversionType(char),2223 #[error("not enough values")]24 NotEnoughValues,2526 #[error("cannot use * width with object")]27 CannotUseStarWidthWithObject,28 #[error("mapping keys required")]29 MappingKeysRequired,30 #[error("no such format field: {0}")]31 NoSuchFormatField(IStr),3233 #[error("expected subfield <{0}> to be an object, got {1} instead")]34 SubfieldDidntYieldAnObject(IStr, ValType),35 #[error("subfield not found: <[{full}]{current}>{}", format_found(.found, "subfield"))]36 SubfieldNotFound {37 current: IStr,38 full: IStr,39 found: Box<Vec<IStr>>,40 },41}4243impl From<FormatError> for Error {44 fn from(e: FormatError) -> Self {45 Self::new(Format(e))46 }47}4849use FormatError::*;5051type ParseResult<'t, T> = std::result::Result<(T, &'t str), FormatError>;5253pub fn try_parse_mapping_key(str: &str) -> ParseResult<'_, &str> {54 if str.is_empty() {55 return Err(TruncatedFormatCode);56 }57 let bytes = str.as_bytes();58 if bytes[0] == b'(' {59 let mut i = 1;60 while i < bytes.len() {61 if bytes[i] == b')' {62 return Ok((&str[1..i], &str[i + 1..]));63 }64 i += 1;65 }66 Err(TruncatedFormatCode)67 } else {68 Ok(("", str))69 }70}7172#[cfg(test)]73pub mod tests_key {74 use super::*;7576 #[test]77 fn parse_key() {78 assert_eq!(79 try_parse_mapping_key("(hello ) world").unwrap(),80 ("hello ", " world")81 );82 assert_eq!(try_parse_mapping_key("() world").unwrap(), ("", " world"));83 assert_eq!(try_parse_mapping_key(" world").unwrap(), ("", " world"));84 assert_eq!(85 try_parse_mapping_key(" () world").unwrap(),86 ("", " () world")87 );88 }8990 #[test]91 #[should_panic = "TruncatedFormatCode"]92 fn parse_key_missing_start() {93 try_parse_mapping_key("").unwrap();94 }9596 #[test]97 #[should_panic = "TruncatedFormatCode"]98 fn parse_key_missing_end() {99 try_parse_mapping_key("( ").unwrap();100 }101}102103#[allow(clippy::struct_excessive_bools)]104#[derive(Default, Debug)]105pub struct CFlags {106 pub alt: bool,107 pub zero: bool,108 pub left: bool,109 pub blank: bool,110 pub sign: bool,111}112113pub fn try_parse_cflags(str: &str) -> ParseResult<'_, CFlags> {114 if str.is_empty() {115 return Err(TruncatedFormatCode);116 }117 let bytes = str.as_bytes();118 let mut i = 0;119 let mut out = CFlags::default();120 loop {121 if bytes.len() == i {122 return Err(TruncatedFormatCode);123 }124 match bytes[i] {125 b'#' => out.alt = true,126 b'0' => out.zero = true,127 b'-' => out.left = true,128 b' ' => out.blank = true,129 b'+' => out.sign = true,130 _ => break,131 }132 i += 1;133 }134 Ok((out, &str[i..]))135}136137#[derive(Debug, PartialEq, Eq)]138pub enum Width {139 Star,140 Fixed(usize),141}142pub fn try_parse_field_width(str: &str) -> ParseResult<'_, Width> {143 if str.is_empty() {144 return Err(TruncatedFormatCode);145 }146 let bytes = str.as_bytes();147 if bytes[0] == b'*' {148 return Ok((Width::Star, &str[1..]));149 }150 let mut out: usize = 0;151 let mut digits = 0;152 while let Some(digit) = (bytes[digits] as char).to_digit(10) {153 out *= 10;154 out += digit as usize;155 digits += 1;156 if digits == bytes.len() {157 return Err(TruncatedFormatCode);158 }159 }160 Ok((Width::Fixed(out), &str[digits..]))161}162163pub fn try_parse_precision(str: &str) -> ParseResult<'_, Option<Width>> {164 if str.is_empty() {165 return Err(TruncatedFormatCode);166 }167 let bytes = str.as_bytes();168 if bytes[0] == b'.' {169 try_parse_field_width(&str[1..]).map(|(r, s)| (Some(r), s))170 } else {171 Ok((None, str))172 }173}174175// Only skips176pub fn try_parse_length_modifier(str: &str) -> ParseResult<'_, ()> {177 if str.is_empty() {178 return Err(TruncatedFormatCode);179 }180 let bytes = str.as_bytes();181 let mut idx = 0;182 while bytes[idx] == b'h' || bytes[idx] == b'l' || bytes[idx] == b'L' {183 idx += 1;184 if bytes.len() == idx {185 return Err(TruncatedFormatCode);186 }187 }188 Ok(((), &str[idx..]))189}190191#[derive(Debug, PartialEq, Eq)]192pub enum ConvTypeV {193 Decimal,194 Octal,195 Hexadecimal,196 Scientific,197 Float,198 Shorter,199 Char,200 String,201 Percent,202}203pub struct ConvType {204 v: ConvTypeV,205 caps: bool,206}207208pub fn parse_conversion_type(str: &str) -> ParseResult<'_, ConvType> {209 if str.is_empty() {210 return Err(TruncatedFormatCode);211 }212213 let code = str.as_bytes()[0];214 let v: (ConvTypeV, bool) = match code {215 b'd' | b'i' | b'u' => (ConvTypeV::Decimal, false),216 b'o' => (ConvTypeV::Octal, false),217 b'x' => (ConvTypeV::Hexadecimal, false),218 b'X' => (ConvTypeV::Hexadecimal, true),219 b'e' => (ConvTypeV::Scientific, false),220 b'E' => (ConvTypeV::Scientific, true),221 b'f' => (ConvTypeV::Float, false),222 b'F' => (ConvTypeV::Float, true),223 b'g' => (ConvTypeV::Shorter, false),224 b'G' => (ConvTypeV::Shorter, true),225 b'c' => (ConvTypeV::Char, false),226 b's' => (ConvTypeV::String, false),227 b'%' => (ConvTypeV::Percent, false),228 c => return Err(UnrecognizedConversionType(c as char)),229 };230231 Ok((ConvType { v: v.0, caps: v.1 }, &str[1..]))232}233234#[derive(Debug)]235pub struct Code<'s> {236 mkey: &'s str,237 cflags: CFlags,238 width: Width,239 precision: Option<Width>,240 convtype: ConvTypeV,241 caps: bool,242}243pub fn parse_code(str: &str) -> ParseResult<'_, Code<'_>> {244 if str.is_empty() {245 return Err(TruncatedFormatCode);246 }247 let (mkey, str) = try_parse_mapping_key(str)?;248 let (cflags, str) = try_parse_cflags(str)?;249 let (width, str) = try_parse_field_width(str)?;250 let (precision, str) = try_parse_precision(str)?;251 let ((), str) = try_parse_length_modifier(str)?;252 let (convtype, str) = parse_conversion_type(str)?;253254 Ok((255 Code {256 mkey,257 cflags,258 width,259 precision,260 convtype: convtype.v,261 caps: convtype.caps,262 },263 str,264 ))265}266267#[derive(Debug)]268pub enum Element<'s> {269 String(&'s str),270 Code(Code<'s>),271}272pub fn parse_codes(mut str: &str) -> Result<Vec<Element<'_>>> {273 let mut bytes = str.as_bytes();274 let mut out = vec![];275 let mut offset = 0;276277 loop {278 while offset != bytes.len() && bytes[offset] != b'%' {279 offset += 1;280 }281 if offset != 0 {282 out.push(Element::String(&str[0..offset]));283 }284 if offset == bytes.len() {285 return Ok(out);286 }287 str = &str[offset + 1..];288 let code;289 (code, str) = parse_code(str)?;290 bytes = str.as_bytes();291 offset = 0;292293 out.push(Element::Code(code));294 }295}296297const NUMBERS: &[u8] = b"0123456789abcdefghijklmnopqrstuvwxyz";298299#[inline]300pub fn render_integer(301 out: &mut String,302 iv: f64,303 padding: usize,304 precision: usize,305 blank: bool,306 sign: bool,307 radix: i64,308 prefix: &str,309 caps: bool,310) {311 let iv = iv.floor() as i64;312 // Digit char indexes in reverse order, i.e313 // for radix = 16 and n = 12f: [15, 2, 1]314 let digits = if iv == 0 {315 vec![0u8]316 } else {317 let mut v = iv.abs();318 let mut nums = Vec::with_capacity(1);319 while v != 0 {320 nums.push((v % radix) as u8);321 v /= radix;322 }323 nums324 };325 let neg = iv < 0;326 #[allow(clippy::bool_to_int_with_if)]327 let zp = padding.saturating_sub(if neg || blank || sign { 1 } else { 0 });328 let zp2 = zp329 .max(precision)330 .saturating_sub(prefix.len() + digits.len());331332 if neg {333 out.push('-');334 } else if sign {335 out.push('+');336 } else if blank {337 out.push(' ');338 }339340 out.reserve(zp2);341 for _ in 0..zp2 {342 out.push('0');343 }344 out.push_str(prefix);345346 for digit in digits.into_iter().rev() {347 let ch = NUMBERS[digit as usize] as char;348 out.push(if caps { ch.to_ascii_uppercase() } else { ch });349 }350}351352pub fn render_decimal(353 out: &mut String,354 iv: f64,355 padding: usize,356 precision: usize,357 blank: bool,358 sign: bool,359) {360 render_integer(out, iv, padding, precision, blank, sign, 10, "", false);361}362pub fn render_octal(363 out: &mut String,364 iv: f64,365 padding: usize,366 precision: usize,367 alt: bool,368 blank: bool,369 sign: bool,370) {371 render_integer(372 out,373 iv,374 padding,375 precision,376 blank,377 sign,378 8,379 if alt && iv != 0.0 { "0" } else { "" },380 false,381 );382}383384#[allow(clippy::fn_params_excessive_bools)]385pub fn render_hexadecimal(386 out: &mut String,387 iv: f64,388 padding: usize,389 precision: usize,390 alt: bool,391 blank: bool,392 sign: bool,393 caps: bool,394) {395 render_integer(396 out,397 iv,398 padding,399 precision,400 blank,401 sign,402 16,403 match (alt, caps) {404 (true, true) => "0X",405 (true, false) => "0x",406 (false, _) => "",407 },408 caps,409 );410}411412#[allow(clippy::fn_params_excessive_bools)]413pub fn render_float(414 out: &mut String,415 n: f64,416 mut padding: usize,417 precision: usize,418 blank: bool,419 sign: bool,420 ensure_pt: bool,421 trailing: bool,422) {423 #[allow(clippy::bool_to_int_with_if)]424 let dot_size = if precision == 0 && !ensure_pt { 0 } else { 1 };425 padding = padding.saturating_sub(dot_size + precision);426 render_decimal(out, n.floor(), padding, 0, blank, sign);427 if precision == 0 {428 if ensure_pt {429 out.push('.');430 }431 return;432 }433 let frac = n434 .fract()435 .mul_add(10.0_f64.powf(precision as f64), 0.5)436 .floor();437 if trailing || frac > 0.0 {438 out.push('.');439 let mut frac_str = String::new();440 render_decimal(&mut frac_str, frac, precision, 0, false, false);441 let mut trim = frac_str.len();442 if !trailing {443 for b in frac_str.as_bytes().iter().rev() {444 if *b == b'0' {445 trim -= 1;446 } else {447 break;448 }449 }450 }451 out.push_str(&frac_str[..trim]);452 } else if ensure_pt {453 out.push('.');454 }455}456457#[allow(clippy::fn_params_excessive_bools)]458pub fn render_float_sci(459 out: &mut String,460 n: f64,461 mut padding: usize,462 precision: usize,463 blank: bool,464 sign: bool,465 ensure_pt: bool,466 trailing: bool,467 caps: bool,468) {469 let exponent = n.log10().floor();470 let mantissa = if exponent as i16 == -324 {471 n * 10.0 / 10.0_f64.powf(exponent + 1.0)472 } else {473 n / 10.0_f64.powf(exponent)474 };475 let mut exponent_str = String::new();476 render_decimal(&mut exponent_str, exponent, 3, 0, false, true);477478 // +1 for e479 padding = padding.saturating_sub(exponent_str.len() + 1);480481 render_float(482 out, mantissa, padding, precision, blank, sign, ensure_pt, trailing,483 );484 out.push(if caps { 'E' } else { 'e' });485 out.push_str(&exponent_str);486}487488#[allow(clippy::too_many_lines)]489pub fn format_code(490 out: &mut String,491 value: &Val,492 code: &Code<'_>,493 width: usize,494 precision: Option<usize>,495) -> Result<()> {496 let clfags = &code.cflags;497 let (fpprec, iprec) = precision.map_or((6, 0), |v| (v, v));498 let padding = if clfags.zero && !clfags.left {499 width500 } else {501 0502 };503504 // TODO: If left padded, can optimize by writing directly to out505 let mut tmp_out = String::new();506507 match code.convtype {508 ConvTypeV::String => tmp_out.push_str(&value.clone().to_string()?),509 ConvTypeV::Decimal => {510 let value = f64::from_untyped(value.clone())?;511 render_decimal(512 &mut tmp_out,513 value,514 padding,515 iprec,516 clfags.blank,517 clfags.sign,518 );519 }520 ConvTypeV::Octal => {521 let value = f64::from_untyped(value.clone())?;522 render_octal(523 &mut tmp_out,524 value,525 padding,526 iprec,527 clfags.alt,528 clfags.blank,529 clfags.sign,530 );531 }532 ConvTypeV::Hexadecimal => {533 let value = f64::from_untyped(value.clone())?;534 render_hexadecimal(535 &mut tmp_out,536 value,537 padding,538 iprec,539 clfags.alt,540 clfags.blank,541 clfags.sign,542 code.caps,543 );544 }545 ConvTypeV::Scientific => {546 let value = f64::from_untyped(value.clone())?;547 render_float_sci(548 &mut tmp_out,549 value,550 padding,551 fpprec,552 clfags.blank,553 clfags.sign,554 clfags.alt,555 true,556 code.caps,557 );558 }559 ConvTypeV::Float => {560 let value = f64::from_untyped(value.clone())?;561 render_float(562 &mut tmp_out,563 value,564 padding,565 fpprec,566 clfags.blank,567 clfags.sign,568 clfags.alt,569 true,570 );571 }572 ConvTypeV::Shorter => {573 let value = f64::from_untyped(value.clone())?;574 let exponent = if value == 0.0 {575 0.0576 } else {577 value.abs().log10().floor()578 };579 if exponent < -4.0 || exponent >= fpprec as f64 {580 render_float_sci(581 &mut tmp_out,582 value,583 padding,584 fpprec - 1,585 clfags.blank,586 clfags.sign,587 clfags.alt,588 clfags.alt,589 code.caps,590 );591 } else {592 let digits_before_pt = 1.max(exponent as usize + 1);593 render_float(594 &mut tmp_out,595 value,596 padding,597 fpprec - digits_before_pt,598 clfags.blank,599 clfags.sign,600 clfags.alt,601 clfags.alt,602 );603 }604 }605 ConvTypeV::Char => match value.clone() {606 Val::Num(n) => {607 let n = n.get();608 tmp_out.push(609 std::char::from_u32(n as u32)610 .ok_or_else(|| InvalidUnicodeCodepointGot(n as u32))?,611 );612 }613 Val::Str(s) => {614 let s = s.into_flat();615 if s.chars().count() != 1 {616 bail!("%c expected 1 char string, got {}", s.chars().count());617 }618 tmp_out.push_str(&s);619 }620 _ => {621 bail!(TypeMismatch(622 "%c requires number/string",623 vec![ValType::Num, ValType::Str],624 value.value_type(),625 ));626 }627 },628 ConvTypeV::Percent => tmp_out.push('%'),629 };630631 let padding = width.saturating_sub(tmp_out.len());632633 if !clfags.left {634 for _ in 0..padding {635 out.push(' ');636 }637 }638 out.push_str(&tmp_out);639 if clfags.left {640 for _ in 0..padding {641 out.push(' ');642 }643 }644645 Ok(())646}647648pub fn format_arr(str: &str, mut values: &[Val]) -> Result<String> {649 let codes = parse_codes(str)?;650 let mut out = String::new();651 let value_count = values.len();652653 for code in codes {654 match code {655 Element::String(s) => {656 out.push_str(s);657 }658 Element::Code(c) => {659 let width = match c.width {660 Width::Star => {661 if values.is_empty() {662 bail!(NotEnoughValues);663 }664 let value = &values[0];665 values = &values[1..];666 usize::from_untyped(value.clone())?667 }668 Width::Fixed(n) => n,669 };670 let precision = match c.precision {671 Some(Width::Star) => {672 if values.is_empty() {673 bail!(NotEnoughValues);674 }675 let value = &values[0];676 values = &values[1..];677 Some(usize::from_untyped(value.clone())?)678 }679 Some(Width::Fixed(n)) => Some(n),680 None => None,681 };682683 // %% should not consume a value684 let value = if c.convtype == ConvTypeV::Percent {685 &Val::Null686 } else {687 if values.is_empty() {688 bail!(NotEnoughValues);689 }690 let value = &values[0];691 values = &values[1..];692 value693 };694695 format_code(&mut out, value, &c, width, precision)?;696 }697 }698 }699700 if !values.is_empty() {701 bail!(702 "too many values to format, expected {value_count}, got {}",703 value_count + values.len()704 )705 }706707 Ok(out)708}709710fn get_dotted_field(obj: ObjValue, field: &str) -> Result<Val> {711 let mut current = Val::Obj(obj);712 let mut name_offset = 0;713 for component in field.split('.') {714 let end_offset = name_offset + component.len();715 current = if let Val::Obj(obj) = current {716 if let Some(value) = obj.get(component.into())? {717 value718 } else {719 let current = &field[name_offset..end_offset];720 let full = &field[..name_offset];721 let found = Box::new(suggest_object_fields(&obj, current.into()));722 bail!(SubfieldNotFound {723 current: current.into(),724 full: full.into(),725 found,726 })727 }728 } else {729 // No underflow may happen, initially we always start with an object730 let subfield = &field[..name_offset - 1];731 bail!(SubfieldDidntYieldAnObject(732 subfield.into(),733 current.value_type()734 ));735 };736 name_offset = end_offset + 1;737 }738 Ok(current)739}740741pub fn format_obj(str: &str, values: &ObjValue) -> Result<String> {742 let codes = parse_codes(str)?;743 let mut out = String::new();744745 for code in codes {746 match code {747 Element::String(s) => {748 out.push_str(s);749 }750 Element::Code(c) => {751 // TODO: Operate on ref752 let f: IStr = c.mkey.into();753 let width = match c.width {754 Width::Star => {755 bail!(CannotUseStarWidthWithObject);756 }757 Width::Fixed(n) => n,758 };759 let precision = match c.precision {760 Some(Width::Star) => {761 bail!(CannotUseStarWidthWithObject);762 }763 Some(Width::Fixed(n)) => Some(n),764 None => None,765 };766767 let value = if c.convtype == ConvTypeV::Percent {768 Val::Null769 } else {770 if f.is_empty() {771 bail!(MappingKeysRequired);772 }773 if let Some(v) = values.get(f.clone())? {774 v775 } else {776 get_dotted_field(values.clone(), &f)?777 }778 };779780 format_code(&mut out, &value, &c, width, precision)?;781 }782 }783 }784785 Ok(out)786}787788#[cfg(test)]789pub mod test_format {790 use super::*;791 use crate::val::NumValue;792793 #[test]794 fn parse() {795 assert_eq!(796 parse_codes(797 "How much error budget is left looking at our %.3f%% availability gurantees?"798 )799 .unwrap()800 .len(),801 4802 );803 }804805 fn num(v: f64) -> Val {806 Val::Num(NumValue::new(v).expect("finite"))807 }808809 #[test]810 fn octals() {811 assert_eq!(format_arr("%#o", &[num(8.0)]).unwrap(), "010");812 assert_eq!(format_arr("%#4o", &[num(8.0)]).unwrap(), " 010");813 assert_eq!(format_arr("%4o", &[num(8.0)]).unwrap(), " 10");814 assert_eq!(format_arr("%04o", &[num(8.0)]).unwrap(), "0010");815 assert_eq!(format_arr("%+4o", &[num(8.0)]).unwrap(), " +10");816 assert_eq!(format_arr("%+04o", &[num(8.0)]).unwrap(), "+010");817 assert_eq!(format_arr("%-4o", &[num(8.0)]).unwrap(), "10 ");818 assert_eq!(format_arr("%+-4o", &[num(8.0)]).unwrap(), "+10 ");819 assert_eq!(format_arr("%+-04o", &[num(8.0)]).unwrap(), "+10 ");820 }821822 #[test]823 fn percent_doesnt_consumes_values() {824 assert_eq!(825 format_arr(826 "How much error budget is left looking at our %.3f%% availability gurantees?",827 &[num(4.0)]828 )829 .unwrap(),830 "How much error budget is left looking at our 4.000% availability gurantees?"831 );832 }833}crates/jrsonnet-rowan-parser/src/ast.rsdiffbeforeafterboth--- a/crates/jrsonnet-rowan-parser/src/ast.rs
+++ b/crates/jrsonnet-rowan-parser/src/ast.rs
@@ -16,12 +16,14 @@
Self: Sized;
fn syntax(&self) -> &SyntaxNode;
+ #[must_use]
fn clone_for_update(&self) -> Self
where
Self: Sized,
{
Self::cast(self.syntax().clone_for_update()).unwrap()
}
+ #[must_use]
fn clone_subtree(&self) -> Self
where
Self: Sized,
@@ -70,6 +72,8 @@
}
pub mod support {
+ use rowan::NodeOrToken;
+
use super::{AstChildren, AstNode, AstToken, SyntaxKind, SyntaxNode, SyntaxToken};
pub fn child<N: AstNode>(parent: &SyntaxNode) -> Option<N> {
@@ -89,7 +93,7 @@
pub fn token(parent: &SyntaxNode, kind: SyntaxKind) -> Option<SyntaxToken> {
parent
.children_with_tokens()
- .filter_map(|it| it.into_token())
+ .filter_map(NodeOrToken::into_token)
.find(|it| it.kind() == kind)
}
}
crates/jrsonnet-rowan-parser/src/event.rsdiffbeforeafterboth--- a/crates/jrsonnet-rowan-parser/src/event.rs
+++ b/crates/jrsonnet-rowan-parser/src/event.rs
@@ -26,7 +26,7 @@
// VirtualToken { kind: SyntaxKind },
/// Position of finished node
Finish {
- /// Same as forward_parent of Start, but for wrapping
+ /// Same as `forward_parent` of Start, but for wrapping
wrapper: Option<NonZeroUsize>,
error: Option<Box<SyntaxError>>,
},
@@ -57,13 +57,14 @@
if self.offset == 0 {
return 0.into();
};
- if let Some(lex) = self.lexemes.get(self.offset) {
- lex.range.start()
- } else if let Some(lex) = self.lexemes.get(self.offset - 1) {
- lex.range.end()
- } else {
- panic!("hard oob")
- }
+ self.lexemes.get(self.offset).map_or_else(
+ || {
+ self.lexemes
+ .get(self.offset - 1)
+ .map_or_else(|| panic!("hard oob"), |lex| lex.range.end())
+ },
+ |lex| lex.range.start(),
+ )
}
pub(super) fn finish(mut self) -> Parse {
@@ -139,7 +140,7 @@
self.errors.push(LocatedSyntaxError {
error: *error,
range: TextRange::new(range.0, range.1),
- })
+ });
}
self.builder.finish_node();
depth -= 1;
@@ -158,7 +159,7 @@
self.errors.push(LocatedSyntaxError {
error: *error,
range: TextRange::new(range.0, range.1),
- })
+ });
}
if depth == 1 {
crates/jrsonnet-stdlib/src/manifest/mod.rsdiffbeforeafterboth--- a/crates/jrsonnet-stdlib/src/manifest/mod.rs
+++ b/crates/jrsonnet-stdlib/src/manifest/mod.rs
@@ -98,6 +98,7 @@
}
#[builtin]
+#[allow(clippy::fn_params_excessive_bools)]
pub fn builtin_manifest_yaml_stream(
value: Val,
#[default(false)] indent_array_in_object: bool,
crates/jrsonnet-stdlib/src/manifest/yaml.rsdiffbeforeafterboth--- a/crates/jrsonnet-stdlib/src/manifest/yaml.rs
+++ b/crates/jrsonnet-stdlib/src/manifest/yaml.rs
@@ -76,7 +76,7 @@
string.is_empty()
|| need_quotes_spaces(string)
- || string.starts_with(|c| matches!(c, '&' | '*' | '?' | '|' | '-' | '<' | '>' | '=' | '!' | '%' | '@'))
+ || string.starts_with(['&' , '*' , '?' , '|' , '-' , '<' , '>' , '=' , '!' , '%' , '@'])
|| string.contains(|c| matches!(c, ':' | '{' | '}' | '[' | ']' | ',' | '#' | '`' | '\"' | '\'' | '\\' | '\0'..='\x06' | '\t' | '\n' | '\r' | '\x0e'..='\x1a' | '\x1c'..='\x1f'))
|| [
// http://yaml.org/type/bool.html
crates/jrsonnet-stdlib/src/strings.rsdiffbeforeafterboth--- a/crates/jrsonnet-stdlib/src/strings.rs
+++ b/crates/jrsonnet-stdlib/src/strings.rs
@@ -267,6 +267,7 @@
}
#[cfg(test)]
+#[allow(clippy::float_cmp)]
mod tests {
use super::*;
@@ -274,8 +275,8 @@
fn parse_nat_base_8() {
assert_eq!(parse_nat::<8>("0").unwrap(), 0.);
assert_eq!(parse_nat::<8>("5").unwrap(), 5.);
- assert_eq!(parse_nat::<8>("32").unwrap(), 0o32 as f64);
- assert_eq!(parse_nat::<8>("761").unwrap(), 0o761 as f64);
+ assert_eq!(parse_nat::<8>("32").unwrap(), f64::from(0o32));
+ assert_eq!(parse_nat::<8>("761").unwrap(), f64::from(0o761));
}
#[test]
@@ -290,7 +291,7 @@
fn parse_nat_base_16() {
assert_eq!(parse_nat::<16>("0").unwrap(), 0.);
assert_eq!(parse_nat::<16>("A").unwrap(), 10.);
- assert_eq!(parse_nat::<16>("a9").unwrap(), 0xA9 as f64);
- assert_eq!(parse_nat::<16>("BbC").unwrap(), 0xBBC as f64);
+ assert_eq!(parse_nat::<16>("a9").unwrap(), f64::from(0xA9));
+ assert_eq!(parse_nat::<16>("BbC").unwrap(), f64::from(0xBBC));
}
}
crates/jrsonnet-types/src/lib.rsdiffbeforeafterboth--- a/crates/jrsonnet-types/src/lib.rs
+++ b/crates/jrsonnet-types/src/lib.rs
@@ -4,84 +4,6 @@
use jrsonnet_gcmodule::Trace;
-#[macro_export]
-macro_rules! ty {
- ((Array<number>)) => {{
- $crate::ComplexValType::ArrayRef(&$crate::ComplexValType::Simple($crate::ValType::Num))
- }};
- ((Array<ubyte>)) => {{
- $crate::ComplexValType::ArrayRef(&$crate::ComplexValType::BoundedNumber(Some(0.0), Some(255.0)))
- }};
- (array) => {
- $crate::ComplexValType::Simple($crate::ValType::Arr)
- };
- (boolean) => {
- $crate::ComplexValType::Simple($crate::ValType::Bool)
- };
- (null) => {
- $crate::ComplexValType::Simple($crate::ValType::Null)
- };
- (string) => {
- $crate::ComplexValType::Simple($crate::ValType::Str)
- };
- (char) => {
- $crate::ComplexValType::Char
- };
- (number) => {
- $crate::ComplexValType::Simple($crate::ValType::Num)
- };
- (BoundedNumber<($min:expr), ($max:expr)>) => {{
- $crate::ComplexValType::BoundedNumber($min, $max)
- }};
- (object) => {
- $crate::ComplexValType::Simple($crate::ValType::Obj)
- };
- (any) => {
- $crate::ComplexValType::Any
- };
- (function) => {
- $crate::ComplexValType::Simple($crate::ValType::Func)
- };
- (($($a:tt) |+)) => {{
- static CONTENTS: &'static [&'static $crate::ComplexValType] = &[
- $(&ty!($a)),+
- ];
- $crate::ComplexValType::UnionRef(CONTENTS)
- }};
- (($($a:tt) &+)) => {{
- static CONTENTS: &'static [&'static $crate::ComplexValType] = &[
- $(&ty!($a)),+
- ];
- $crate::ComplexValType::SumRef(CONTENTS)
- }};
-}
-
-#[test]
-fn test() {
- assert_eq!(
- ty!((Array<number>)),
- ComplexValType::ArrayRef(&ComplexValType::Simple(ValType::Num))
- );
- assert_eq!(ty!(array), ComplexValType::Simple(ValType::Arr));
- assert_eq!(ty!(any), ComplexValType::Any);
- assert_eq!(
- ty!((string | number)),
- ComplexValType::UnionRef(&[
- &ComplexValType::Simple(ValType::Str),
- &ComplexValType::Simple(ValType::Num)
- ])
- );
- assert_eq!(
- format!("{}", ty!(((string & number) | (object & null)))),
- "string & number | object & null"
- );
- assert_eq!(format!("{}", ty!((string | array))), "string | array");
- assert_eq!(
- format!("{}", ty!(((string & number) | array))),
- "string & number | array"
- );
-}
-
#[derive(Debug, Clone, Copy, PartialEq, Eq, Trace)]
pub enum ValType {
Bool,
@@ -213,98 +135,5 @@
Self::Lazy(lazy) => write!(f, "Lazy<{lazy}>")?,
};
Ok(())
- }
-}
-
-peg::parser! {
-pub grammar parser() for str {
- rule number() -> f64
- = n:$(['0'..='9']+) { n.parse().unwrap() }
-
- rule any_ty() -> ComplexValType = "any" { ComplexValType::Any }
- rule char_ty() -> ComplexValType = "character" { ComplexValType::Char }
- rule bool_ty() -> ComplexValType = "boolean" { ComplexValType::Simple(ValType::Bool) }
- rule null_ty() -> ComplexValType = "null" { ComplexValType::Simple(ValType::Null) }
- rule str_ty() -> ComplexValType = "string" { ComplexValType::Simple(ValType::Str) }
- rule num_ty() -> ComplexValType = "number" { ComplexValType::Simple(ValType::Num) }
- rule simple_array_ty() -> ComplexValType = "array" { ComplexValType::Simple(ValType::Arr) }
- rule simple_object_ty() -> ComplexValType = "object" { ComplexValType::Simple(ValType::Obj) }
- rule simple_function_ty() -> ComplexValType = "function" { ComplexValType::Simple(ValType::Func) }
-
- rule array_ty() -> ComplexValType
- = "Array<" t:ty() ">" { ComplexValType::Array(Box::new(t)) }
-
- rule bounded_number_ty() -> ComplexValType
- = "BoundedNumber<" a:number() ", " b:number() ">" { ComplexValType::BoundedNumber(Some(a), Some(b)) }
-
- rule ty_basic() -> ComplexValType
- = any_ty()
- / char_ty()
- / bool_ty()
- / null_ty()
- / str_ty()
- / num_ty()
- / simple_array_ty()
- / simple_object_ty()
- / simple_function_ty()
- / array_ty()
- / bounded_number_ty()
-
- pub rule ty() -> ComplexValType
- = precedence! {
- a:(@) " | " b:@ {
- match a {
- ComplexValType::Union(mut a) => {
- a.push(b);
- ComplexValType::Union(a)
- }
- _ => ComplexValType::Union(vec![a, b]),
- }
- }
- --
- a:(@) " & " b:@ {
- match a {
- ComplexValType::Sum(mut a) => {
- a.push(b);
- ComplexValType::Sum(a)
- }
- _ => ComplexValType::Sum(vec![a, b]),
- }
- }
- --
- "(" t:ty() ")" { t }
- t:ty_basic() { t }
- }
-}
-}
-
-#[cfg(test)]
-pub mod tests {
- use super::parser;
-
- #[test]
- fn precedence() {
- assert_eq!(
- parser::ty("(any & any) | (any | any) & any")
- .unwrap()
- .to_string(),
- "any & any | (any | any) & any"
- );
- }
-
- #[test]
- fn array() {
- assert_eq!(parser::ty("Array<any>").unwrap().to_string(), "array");
- assert_eq!(
- parser::ty("Array<number>").unwrap().to_string(),
- "Array<number>"
- );
- }
- #[test]
- fn bounded_number() {
- assert_eq!(
- parser::ty("BoundedNumber<1, 2>").unwrap().to_string(),
- "BoundedNumber<1, 2>"
- );
}
}
flake.lockdiffbeforeafterboth--- a/flake.lock
+++ b/flake.lock
@@ -7,11 +7,11 @@
]
},
"locked": {
- "lastModified": 1715274763,
- "narHash": "sha256-3Iv1PGHJn9sV3HO4FlOVaaztOxa9uGLfOmUWrH7v7+A=",
+ "lastModified": 1724377159,
+ "narHash": "sha256-ixjje1JO8ucKT41hs6n2NCde1Vc0+Zc2p2gUbJpCsMw=",
"owner": "ipetkov",
"repo": "crane",
- "rev": "27025ab71bdca30e7ed0a16c88fd74c5970fc7f5",
+ "rev": "3e47b7a86c19142bd3675da49d6acef488b4dac1",
"type": "github"
},
"original": {
@@ -27,44 +27,26 @@
]
},
"locked": {
- "lastModified": 1717285511,
- "narHash": "sha256-iKzJcpdXih14qYVcZ9QC9XuZYnPc6T8YImb6dX166kw=",
+ "lastModified": 1722555600,
+ "narHash": "sha256-XOQkdLafnb/p9ij77byFQjDf5m5QYl9b2REiVClC+x4=",
"owner": "hercules-ci",
"repo": "flake-parts",
- "rev": "2a55567fcf15b1b1c7ed712a2c6fadaec7412ea8",
+ "rev": "8471fe90ad337a8074e957b69ca4d0089218391d",
"type": "github"
},
"original": {
"owner": "hercules-ci",
"repo": "flake-parts",
- "type": "github"
- }
- },
- "flake-utils": {
- "inputs": {
- "systems": "systems"
- },
- "locked": {
- "lastModified": 1710146030,
- "narHash": "sha256-SZ5L6eA7HJ/nmkzGG7/ISclqe6oZdOZTNoesiInkXPQ=",
- "owner": "numtide",
- "repo": "flake-utils",
- "rev": "b1d9ab70662946ef0850d488da1c9019f3a9752a",
- "type": "github"
- },
- "original": {
- "owner": "numtide",
- "repo": "flake-utils",
"type": "github"
}
},
"nixpkgs": {
"locked": {
- "lastModified": 1715551360,
- "narHash": "sha256-fGYt2XnTYUS4Q0eH8tVu3ki1+m9YTgZ+NjlfkMKzko0=",
+ "lastModified": 1724519568,
+ "narHash": "sha256-CmfrenY4cEi/mIslKy8XOGdqxUUVgT6/qMzNcAN/7z8=",
"owner": "nixos",
"repo": "nixpkgs",
- "rev": "836306cd7bbb9e0f89c557b2ae14df09e573ee89",
+ "rev": "eb0e6df0cdd2641ec0651cd9802ff4cff3b3e915",
"type": "github"
},
"original": {
@@ -84,17 +66,16 @@
},
"rust-overlay": {
"inputs": {
- "flake-utils": "flake-utils",
"nixpkgs": [
"nixpkgs"
]
},
"locked": {
- "lastModified": 1715480255,
- "narHash": "sha256-gEZl8nYidQwqJhOigJ91JDjoBFoPEWVsd82AKnaE7Go=",
+ "lastModified": 1724466314,
+ "narHash": "sha256-ltKuK6shQ64uej1mYNtBsDYxttUNFiv9AcHqk0+0NQM=",
"owner": "oxalica",
"repo": "rust-overlay",
- "rev": "d690205a4f01ec0930303c4204e5063958e51255",
+ "rev": "2b5b3edd96ef336b00622dcabc13788fdef9e3ca",
"type": "github"
},
"original": {
@@ -123,21 +104,6 @@
"original": {
"owner": "CertainLach",
"repo": "shelly",
- "type": "github"
- }
- },
- "systems": {
- "locked": {
- "lastModified": 1681028828,
- "narHash": "sha256-Vy1rq5AaRuLzOxct8nz4T6wlgyUR7zLU309k9mBC768=",
- "owner": "nix-systems",
- "repo": "default",
- "rev": "da67096a3b9bf56a91d16901293e51ba5b49a27e",
- "type": "github"
- },
- "original": {
- "owner": "nix-systems",
- "repo": "default",
"type": "github"
}
}
rust-toolchain.tomldiffbeforeafterboth--- a/rust-toolchain.toml
+++ b/rust-toolchain.toml
@@ -1,3 +1,3 @@
[toolchain]
-channel = "nightly-2024-05-10"
+channel = "nightly-2024-08-20"
components = ["rustfmt", "clippy", "rust-analyzer", "rust-src"]
tests/tests/builtin.rsdiffbeforeafterboth--- a/tests/tests/builtin.rs
+++ b/tests/tests/builtin.rs
@@ -11,8 +11,8 @@
use jrsonnet_stdlib::ContextInitializer as StdContextInitializer;
#[builtin]
-fn a() -> Result<u32> {
- Ok(1)
+fn a() -> u32 {
+ 1
}
#[test]
@@ -29,8 +29,8 @@
}
#[builtin]
-fn native_add(a: u32, b: u32) -> Result<u32> {
- Ok(a + b)
+fn native_add(a: u32, b: u32) -> u32 {
+ a + b
}
#[derive(Trace)]
struct NativeAddContextInitializer;
@@ -72,13 +72,13 @@
#[builtin(fields(
a: u32
))]
-fn curried_add(this: &curried_add, b: u32) -> Result<u32> {
- Ok(this.a + b)
+fn curried_add(this: &curried_add, b: u32) -> u32 {
+ this.a + b
}
#[builtin]
-fn curry_add(a: u32) -> Result<FuncVal> {
- Ok(FuncVal::builtin(curried_add { a }))
+fn curry_add(a: u32) -> FuncVal {
+ FuncVal::builtin(curried_add { a })
}
#[derive(Trace)]
struct CurryAddContextInitializer;
tests/tests/common.rsdiffbeforeafterboth--- a/tests/tests/common.rs
+++ b/tests/tests/common.rs
@@ -73,6 +73,7 @@
.iter()
.map(|p| p.name().as_str().unwrap_or("<unnamed>").to_string())
.collect(),
+ FuncVal::Thunk(_) => vec![],
}
}
tests/tests/golden.rsdiffbeforeafterboth--- a/tests/tests/golden.rs
+++ b/tests/tests/golden.rs
@@ -32,7 +32,7 @@
Err(e) => return trace_format.format(&e).unwrap(),
};
match v.manifest(JsonFormat::default()) {
- Ok(v) => v.to_string(),
+ Ok(v) => v,
Err(e) => trace_format.format(&e).unwrap(),
}
}
@@ -57,45 +57,46 @@
if !golden_path.exists() {
fs::write(golden_path, &result)?;
- } else {
- let golden = fs::read_to_string(golden_path)?;
+ continue;
+ }
- match (serde_json::from_str(&result), serde_json::from_str(&golden)) {
- (Err(_), Ok(_)) => assert_eq!(
- result,
- golden,
- "unexpected error for golden {}",
- entry.path().display()
- ),
- (Ok(_), Err(_)) => assert_eq!(
- result,
- golden,
- "expected error for golden {}",
- entry.path().display()
- ),
- (Ok(result), Ok(golden)) => {
- // Show diff relative to golden`.
- let diff = JsonDiff::diff_string(&golden, &result, false);
- if let Some(diff) = diff {
- panic!(
- "Result \n{result:#}\n\
- and golden \n{golden:#}\n\
- did not match structurally:\n{diff:#}\n\
- for golden {}",
- entry.path().display()
- );
- }
- }
- (Err(_), Err(_)) => {}
- };
+ let golden = fs::read_to_string(golden_path)?;
- assert_eq!(
+ match (serde_json::from_str(&result), serde_json::from_str(&golden)) {
+ (Err(_), Ok(_)) => assert_eq!(
result,
golden,
- "golden didn't match for {}",
+ "unexpected error for golden {}",
+ entry.path().display()
+ ),
+ (Ok(_), Err(_)) => assert_eq!(
+ result,
+ golden,
+ "expected error for golden {}",
entry.path().display()
- )
- }
+ ),
+ (Ok(result), Ok(golden)) => {
+ // Show diff relative to golden`.
+ let diff = JsonDiff::diff_string(&golden, &result, false);
+ if let Some(diff) = diff {
+ panic!(
+ "Result \n{result:#}\n\
+ and golden \n{golden:#}\n\
+ did not match structurally:\n{diff:#}\n\
+ for golden {}",
+ entry.path().display()
+ );
+ }
+ }
+ (Err(_), Err(_)) => {}
+ };
+
+ assert_eq!(
+ result,
+ golden,
+ "golden didn't match for {}",
+ entry.path().display()
+ );
}
Ok(())