diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 619ff1e9ae..5aec3f923a 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -168,7 +168,7 @@ jobs: # Using macOS 13 runner because 14 is based on the M1 and has half as much RAM (7 GB, # instead of 14 GB) which is too little for us right now. # - # Failure occuring with clippy for rust 1.77.2 + # Failure occurring with clippy for rust 1.77.2 platform: [windows-latest, macos-13, ubuntu-20.04] runs-on: ${{ matrix.platform }} diff --git a/Cargo.lock b/Cargo.lock index 2d232ffd1e..d8841e688b 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -72,10 +72,19 @@ dependencies = [ ] [[package]] -name = "allocator-api2" -version = "0.2.16" +name = "alloca" +version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0942ffc6dcaadf03badf6e6a2d0228460359d5e34b57ccdc720b7382dfbd5ec5" +checksum = "e5a7d05ea6aea7e9e64d25b9156ba2fee3fdd659e34e41063cd2fc7cd020d7f4" +dependencies = [ + "cc", +] + +[[package]] +name = "allocator-api2" +version = "0.2.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5c6cb57a04249c6480766f7f7cef5467412af1490f8d1e243141daddada3264f" [[package]] name = "alphanumeric-sort" @@ -119,47 +128,48 @@ dependencies = [ [[package]] name = "anstream" -version = "0.6.13" +version = "0.6.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d96bd03f33fe50a863e394ee9718a706f988b9079b20c3784fb726e7678b62fb" +checksum = "418c75fa768af9c03be99d17643f93f79bbba589895012a80e3452a19ddda15b" dependencies = [ "anstyle", "anstyle-parse", "anstyle-query", "anstyle-wincon", "colorchoice", + "is_terminal_polyfill", "utf8parse", ] [[package]] name = "anstyle" -version = "1.0.6" +version = "1.0.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8901269c6307e8d93993578286ac0edf7f195079ffff5ebdeea6a59ffb7e36bc" +checksum = "038dfcf04a5feb68e9c60b21c9625a54c2c0616e79b72b0fd87075a056ae1d1b" [[package]] name = "anstyle-parse" -version = "0.2.3" +version = "0.2.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c75ac65da39e5fe5ab759307499ddad880d724eed2f6ce5b5e8a26f4f387928c" +checksum = "c03a11a9034d92058ceb6ee011ce58af4a9bf61491aa7e1e59ecd24bd40d22d4" dependencies = [ "utf8parse", ] [[package]] name = "anstyle-query" -version = "1.0.2" +version = "1.0.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e28923312444cdd728e4738b3f9c9cac739500909bb3d3c94b43551b16517648" +checksum = "a64c907d4e79225ac72e2a354c9ce84d50ebb4586dee56c82b3ee73004f537f5" dependencies = [ "windows-sys 0.52.0", ] [[package]] name = "anstyle-wincon" -version = "3.0.2" +version = "3.0.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1cd54b81ec8d6180e24654d0b371ad22fc3dd083b6ff8ba325b72e00c87660a7" +checksum = "61a38449feb7068f52bb06c12759005cf459ee52bb4adc1d5a7c4322d716fb19" dependencies = [ "anstyle", "windows-sys 0.52.0", @@ -173,17 +183,16 @@ checksum = "f538837af36e6f6a9be0faa67f9a314f8119e4e4b5867c6ab40ed60360142519" [[package]] name = "arboard" -version = "3.3.2" +version = "3.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a2041f1943049c7978768d84e6d0fd95de98b76d6c4727b09e78ec253d29fa58" +checksum = "9fb4009533e8ff8f1450a5bcbc30f4242a1d34442221f72314bea1f5dc9c7f89" dependencies = [ "clipboard-win", "log", - "objc", - "objc-foundation", - "objc_id", + "objc2", + "objc2-app-kit", + "objc2-foundation", "parking_lot", - "thiserror", "wl-clipboard-rs", "x11rb", ] @@ -259,18 +268,18 @@ checksum = "16e62a023e7c117e27523144c5d2459f4397fcc3cab0085af8e2224f643a0193" dependencies = [ "proc-macro2", "quote", - "syn 2.0.58", + "syn 2.0.60", ] [[package]] name = "async-trait" -version = "0.1.79" +version = "0.1.80" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a507401cad91ec6a857ed5513a2073c82a9b9048762b885bb98655b306964681" +checksum = "c6fa2087f2753a7da8cc1c0dbfcf89579dd57458e36769de5ac750b4671737ca" dependencies = [ "proc-macro2", "quote", - "syn 2.0.58", + "syn 2.0.60", ] [[package]] @@ -346,9 +355,9 @@ checksum = "9d297deb1925b89f2ccc13d7635fa0714f12c87adce1c75356b39ca9b7178567" [[package]] name = "base64" -version = "0.22.0" +version = "0.22.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9475866fec1451be56a3c2400fd081ff546538961565ccb5b7142cbd22bc7a51" +checksum = "72b3254f16251a8381aa12e40e3c4d2f0199f8c6508fbecb9d91f575e0fbb8c6" [[package]] name = "bincode" @@ -376,7 +385,7 @@ dependencies = [ "regex", "rustc-hash", "shlex", - "syn 2.0.58", + "syn 2.0.60", ] [[package]] @@ -421,12 +430,6 @@ dependencies = [ "wyz", ] -[[package]] -name = "block" -version = "0.1.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0d8c1fef690941d3e7788d328517591fecc684c084084702d6ff1641e993699a" - [[package]] name = "block-buffer" version = "0.10.4" @@ -437,10 +440,19 @@ dependencies = [ ] [[package]] -name = "borsh" -version = "1.4.0" +name = "block2" +version = "0.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0901fc8eb0aca4c83be0106d6f2db17d86a08dfc2c25f0e84464bf381158add6" +checksum = "43ff7d91d3c1d568065b06c899777d1e48dcf76103a672a0adbc238a7f247f1e" +dependencies = [ + "objc2", +] + +[[package]] +name = "borsh" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dbe5b10e214954177fb1dc9fbd20a1a2608fe99e6c832033bdc7cea287a20d77" dependencies = [ "borsh-derive", "cfg_aliases", @@ -448,15 +460,15 @@ dependencies = [ [[package]] name = "borsh-derive" -version = "1.4.0" +version = "1.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "51670c3aa053938b0ee3bd67c3817e471e626151131b934038e83c5bf8de48f5" +checksum = "d7a8646f94ab393e43e8b35a2558b1624bed28b97ee09c5d15456e3c9463f46d" dependencies = [ "once_cell", "proc-macro-crate", "proc-macro2", "quote", - "syn 2.0.58", + "syn 2.0.60", "syn_derive", ] @@ -560,9 +572,9 @@ dependencies = [ [[package]] name = "bytecount" -version = "0.6.7" +version = "0.6.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e1e5f035d16fc623ae5f74981db80a439803888314e3a555fd6f04acd51a3205" +checksum = "5ce89b21cab1437276d2650d57e971f9d548a2d9037cc231abdc0562b97498ce" [[package]] name = "bytemuck" @@ -581,7 +593,7 @@ checksum = "4da9a32f3fed317401fa3c862968128267c3106685286e15d5aaa3d7389c2f60" dependencies = [ "proc-macro2", "quote", - "syn 2.0.58", + "syn 2.0.60", ] [[package]] @@ -636,12 +648,13 @@ dependencies = [ [[package]] name = "cc" -version = "1.0.92" +version = "1.0.96" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2678b2e3449475e95b0aa6f9b506a28e61b3dc8996592b983695e8ebb58a8b41" +checksum = "065a29261d53ba54260972629f9ca6bffa69bac13cd1fed61420f7fa68b9f8bd" dependencies = [ "jobserver", "libc", + "once_cell", ] [[package]] @@ -688,9 +701,9 @@ dependencies = [ [[package]] name = "chrono" -version = "0.4.37" +version = "0.4.38" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8a0d04d43504c61aa6c7531f1871dd0d418d91130162063b789da00fd7057a5e" +checksum = "a21f936df1771bf62b77f047b726c4625ff2e8aa607c01ec06e5a05bd8463401" dependencies = [ "android-tzdata", "iana-time-zone", @@ -699,7 +712,7 @@ dependencies = [ "pure-rust-locales", "serde", "wasm-bindgen", - "windows-targets 0.52.4", + "windows-targets 0.52.5", ] [[package]] @@ -761,7 +774,7 @@ version = "0.9.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8eebd66744a15ded14960ab4ccdbfb51ad3b81f51f3f04a80adac98c985396c9" dependencies = [ - "hashbrown 0.14.3", + "hashbrown 0.14.5", "stacker", ] @@ -783,6 +796,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "90bc066a67923782aa8515dbaea16946c5bcc5addbd668bb80af688e53e548a0" dependencies = [ "clap_builder", + "clap_derive", ] [[package]] @@ -798,6 +812,18 @@ dependencies = [ "terminal_size", ] +[[package]] +name = "clap_derive" +version = "4.5.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "528131438037fd55894f62d6e9f068b8f45ac57ffa77517819645d10aed04f64" +dependencies = [ + "heck 0.5.0", + "proc-macro2", + "quote", + "syn 2.0.60", +] + [[package]] name = "clap_lex" version = "0.7.0" @@ -806,9 +832,9 @@ checksum = "98cc8fbded0c607b7ba9dd60cd98df59af97e84d24e49c8557331cfc26d301ce" [[package]] name = "clipboard-win" -version = "5.3.0" +version = "5.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d517d4b86184dbb111d3556a10f1c8a04da7428d2987bf1081602bf11c3aa9ee" +checksum = "79f4473f5144e20d9aceaf2972478f06ddf687831eafeeb434fbaf0acc4144ad" dependencies = [ "error-code", ] @@ -824,9 +850,18 @@ dependencies = [ [[package]] name = "colorchoice" -version = "1.0.0" +version = "1.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "acbf1af155f9b9ef647e42cdc158db4b64a1b61f743629225fde6f3e0be2a7c7" +checksum = "0b6a852b24ab71dffc585bcb46eaf7959d175cb865a7152e35b348d1b2960422" + +[[package]] +name = "colorz" +version = "1.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bc2a5df6ee18d52a36920c93a7736761c6fcffa72b9d960fd9133dd8d57c5184" +dependencies = [ + "supports-color 2.1.0", +] [[package]] name = "comfy-table" @@ -853,12 +888,6 @@ dependencies = [ "static_assertions", ] -[[package]] -name = "condtype" -version = "1.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "baf0a07a401f374238ab8e2f11a104d2851bf9ce711ec69804834de8af45c7af" - [[package]] name = "console" version = "0.15.8" @@ -1066,7 +1095,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "13b588ba4ac1a99f7f2964d24b3d896ddc6bf847ee3855dbd4366f058cfcd331" dependencies = [ "quote", - "syn 2.0.58", + "syn 2.0.60", ] [[package]] @@ -1117,7 +1146,7 @@ checksum = "d150dea618e920167e5973d70ae6ece4385b7164e0d799fe7c122dd0a5d912ad" dependencies = [ "proc-macro2", "quote", - "syn 2.0.58", + "syn 2.0.60", ] [[package]] @@ -1186,31 +1215,6 @@ dependencies = [ "winapi", ] -[[package]] -name = "divan" -version = "0.1.14" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a0d567df2c9c2870a43f3f2bd65aaeb18dbce1c18f217c3e564b4fbaeb3ee56c" -dependencies = [ - "cfg-if", - "clap", - "condtype", - "divan-macros", - "libc", - "regex-lite", -] - -[[package]] -name = "divan-macros" -version = "0.1.14" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "27540baf49be0d484d8f0130d7d8da3011c32a44d4fc873368154f1510e574a2" -dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.58", -] - [[package]] name = "dlib" version = "0.5.2" @@ -1297,9 +1301,9 @@ checksum = "3a68a4904193147e0a8dec3314640e6db742afd5f6e634f428a6af230d9b3591" [[package]] name = "either" -version = "1.10.0" +version = "1.11.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "11157ac094ffbdde99aa67b23417ebdd801842852b500e395a45a9c0aac03e4a" +checksum = "a47c1c47d2f5964e29c61246e81db715514cd532db6b5116a25ea3c03d6780a2" [[package]] name = "eml-parser" @@ -1319,9 +1323,9 @@ checksum = "a357d28ed41a50f9c765dbfe56cbc04a64e53e5fc58ba79fbc34c10ef3df831f" [[package]] name = "encoding_rs" -version = "0.8.33" +version = "0.8.34" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7268b386296a025e474d5140678f75d6de9493ae55a5d709eeb9dd08149945e1" +checksum = "b45de904aa0b010bce2ab45264d0631681847fa7b6f2eaa7dab7619943bc4f59" dependencies = [ "cfg-if", ] @@ -1335,7 +1339,7 @@ dependencies = [ "once_cell", "proc-macro2", "quote", - "syn 2.0.58", + "syn 2.0.60", ] [[package]] @@ -1416,9 +1420,9 @@ checksum = "95765f67b4b18863968b4a1bd5bb576f732b29a4a28c7cd84c09fa3e2875f33c" [[package]] name = "fastrand" -version = "2.0.2" +version = "2.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "658bd65b1cf4c852a3cc96f18a8ce7b5640f6b703f905c7d74532294c2a63984" +checksum = "9fc0510504f03c51ada170672ac806f1f105a88aa97a5281117e1ddc3368e51a" [[package]] name = "fd-lock" @@ -1457,7 +1461,7 @@ checksum = "1ee447700ac8aa0b2f2bd7bc4462ad686ba06baa6727ac149a2d6277f0d240fd" dependencies = [ "cfg-if", "libc", - "redox_syscall", + "redox_syscall 0.4.1", "windows-sys 0.52.0", ] @@ -1469,9 +1473,9 @@ checksum = "0ce7134b9999ecaf8bcd65542e436736ef32ddca1b3e06094cb6ec5755203b80" [[package]] name = "flate2" -version = "1.0.28" +version = "1.0.30" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "46303f565772937ffe1d394a4fac6f411c6013172fadde9dcdb1e147a086940e" +checksum = "5f54427cfd1c7829e2a139fcefea601bf088ebca651d2bf53ebc600eac295dae" dependencies = [ "crc32fast", "miniz_oxide", @@ -1609,7 +1613,7 @@ checksum = "87750cf4b7a4c0625b1529e4c543c2182106e4dedc60a2a6455e00d212c489ac" dependencies = [ "proc-macro2", "quote", - "syn 2.0.58", + "syn 2.0.60", ] [[package]] @@ -1726,6 +1730,23 @@ version = "0.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d2fabcfbdc87f4758337ca535fb41a6d701b65693ce38287d856d1674551ec9b" +[[package]] +name = "glob-match" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9985c9503b412198aa4197559e9a318524ebc4519c229bfa05a535828c950b9d" + +[[package]] +name = "goblin" +version = "0.7.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f27c1b4369c2cd341b5de549380158b105a04c331be5db9110eef7b6d2742134" +dependencies = [ + "log", + "plain", + "scroll", +] + [[package]] name = "h2" version = "0.3.26" @@ -1751,7 +1772,7 @@ version = "0.2.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8588661a8607108a5ca69cab034063441a0413a0b041c13618a7dd348021ef6f" dependencies = [ - "hashbrown 0.14.3", + "hashbrown 0.14.5", "serde", ] @@ -1775,9 +1796,9 @@ dependencies = [ [[package]] name = "hashbrown" -version = "0.14.3" +version = "0.14.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "290f1a1d9242c78d09ce40a5e87e7554ee637af1351968159f4952f028f75604" +checksum = "e5274423e17b7c9fc20b6e7e208532f9b19825d82dfd615708b70edd83df41f1" dependencies = [ "ahash 0.8.11", "allocator-api2", @@ -1790,7 +1811,7 @@ version = "0.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "692eaaf7f7607518dd3cef090f1474b61edc5301d8012f09579920df68b725ee" dependencies = [ - "hashbrown 0.14.3", + "hashbrown 0.14.5", ] [[package]] @@ -1968,7 +1989,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "168fb715dda47215e360912c096649d23d58bf392ac62f73919e831745e40f26" dependencies = [ "equivalent", - "hashbrown 0.14.3", + "hashbrown 0.14.5", "serde", ] @@ -2022,9 +2043,9 @@ dependencies = [ [[package]] name = "interprocess" -version = "2.0.0" +version = "2.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6d5f0e3c218e7a86a6712fd3adc84672304f9e839402b866685b9117a077c37f" +checksum = "7c7fb8583fab9503654385e2bafda123376445a77027a1b106dd7e44cf51122f" dependencies = [ "libc", "recvmsg", @@ -2047,6 +2068,17 @@ dependencies = [ "once_cell", ] +[[package]] +name = "is-terminal" +version = "0.4.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f23ff5ef2b80d608d61efee834934d862cd92461afc0560dedf493e4c033738b" +dependencies = [ + "hermit-abi", + "libc", + "windows-sys 0.52.0", +] + [[package]] name = "is-wsl" version = "0.4.0" @@ -2078,6 +2110,12 @@ dependencies = [ "winapi", ] +[[package]] +name = "is_terminal_polyfill" +version = "1.70.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f8478577c03552c21db0e2724ffb8986a5ce7af88107e6be5d2ee6e158c12800" + [[package]] name = "itertools" version = "0.11.0" @@ -2110,9 +2148,9 @@ checksum = "9028f49264629065d057f340a86acb84867925865f73bbf8d47b4d149a7e88b8" [[package]] name = "jobserver" -version = "0.1.28" +version = "0.1.31" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ab46a6e9526ddef3ae7f787c06f0f2600639ba80ea3eade3d8e670a2230f51d6" +checksum = "d2b099aaa34a9751c5bf0878add70444e1ed2dd73f347be99003d4577277de6e" dependencies = [ "libc", ] @@ -2241,9 +2279,9 @@ dependencies = [ [[package]] name = "libc" -version = "0.2.153" +version = "0.2.154" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9c198f91728a82281a64e1f4f9eeb25d82cb32a5de251c6bd1b5154d63a8e7bd" +checksum = "ae743338b92ff9146ce83992f766a31066a91a8c84a45e0e9f21e7cf6de6d346" [[package]] name = "libflate" @@ -2286,7 +2324,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0c2a198fb6b0eada2a8df47933734e6d35d350665a33a3593d7164fa52c75c19" dependencies = [ "cfg-if", - "windows-targets 0.52.4", + "windows-targets 0.52.5", ] [[package]] @@ -2297,9 +2335,9 @@ checksum = "4ec2a862134d2a7d32d7983ddcdd1c4923530833c9f2ea1a44fc5fa473989058" [[package]] name = "libmimalloc-sys" -version = "0.1.35" +version = "0.1.37" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3979b5c37ece694f1f5e51e7ecc871fdb0f517ed04ee45f88d15d6d553cb9664" +checksum = "81eb4061c0582dedea1cbc7aff2240300dd6982e0239d1c99e65c1dbf4a30ba7" dependencies = [ "cc", "libc", @@ -2307,9 +2345,9 @@ dependencies = [ [[package]] name = "libproc" -version = "0.14.6" +version = "0.14.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8eb6497078a4c9c2aca63df56d8dce6eb4381d53a960f781a3a748f7ea97436d" +checksum = "ae9ea4b75e1a81675429dafe43441df1caea70081e82246a8cccf514884a88bb" dependencies = [ "bindgen", "errno", @@ -2380,9 +2418,9 @@ checksum = "01cda141df6706de531b6c46c3a33ecca755538219bd484262fa09410c13539c" [[package]] name = "lock_api" -version = "0.4.11" +version = "0.4.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3c168f8615b12bc01f9c17e2eb0cc07dcae1940121185446edc3744920e8ef45" +checksum = "07af8b9cdd281b7915f413fa73f29ebd5d55d0d3f0155584dade1ff18cea1b17" dependencies = [ "autocfg", "scopeguard", @@ -2400,7 +2438,7 @@ version = "0.12.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d3262e75e648fce39813cb56ac41f3c3e3f65217ebf3844d818d1f9398cfb0dc" dependencies = [ - "hashbrown 0.14.3", + "hashbrown 0.14.5", ] [[package]] @@ -2531,7 +2569,7 @@ dependencies = [ "cfg-if", "miette-derive", "owo-colors", - "supports-color", + "supports-color 3.0.0", "supports-hyperlinks", "supports-unicode", "terminal_size", @@ -2548,14 +2586,14 @@ checksum = "dcf09caffaac8068c346b6df2a7fc27a177fd20b39421a39ce0a211bde679a6c" dependencies = [ "proc-macro2", "quote", - "syn 2.0.58", + "syn 2.0.60", ] [[package]] name = "mimalloc" -version = "0.1.39" +version = "0.1.41" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fa01922b5ea280a911e323e4d2fd24b7fe5cc4042e0d2cda3c40775cdc4bdc9c" +checksum = "9f41a2280ded0da56c8cf898babb86e8f10651a34adcfff190ae9a1159c6908d" dependencies = [ "libmimalloc-sys", ] @@ -2747,7 +2785,6 @@ dependencies = [ "crossterm", "ctrlc", "dirs-next", - "divan", "log", "miette", "mimalloc", @@ -2779,6 +2816,7 @@ dependencies = [ "serde_json", "serial_test", "simplelog", + "tango-bench", "tempfile", "time", "winresource", @@ -2928,7 +2966,7 @@ name = "nu-command" version = "0.93.1" dependencies = [ "alphanumeric-sort", - "base64 0.22.0", + "base64 0.22.1", "bracoxide", "brotli 5.0.0", "byteorder", @@ -3022,7 +3060,7 @@ dependencies = [ "uu_mv", "uu_uname", "uu_whoami", - "uucore", + "uucore 0.0.25", "uuid", "v_htmlescape", "wax", @@ -3424,9 +3462,9 @@ dependencies = [ [[package]] name = "num" -version = "0.4.1" +version = "0.4.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b05180d69e3da0e530ba2a1dae5110317e49e3b7f3d41be227dc5f92e49ee7af" +checksum = "3135b08af27d103b0a51f2ae0f8632117b7b185ccf931445affa8df530576a41" dependencies = [ "num-bigint", "num-complex", @@ -3561,23 +3599,58 @@ dependencies = [ ] [[package]] -name = "objc-foundation" -version = "0.1.1" +name = "objc-sys" +version = "0.3.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1add1b659e36c9607c7aab864a76c7a4c2760cd0cd2e120f3fb8b952c7e22bf9" +checksum = "da284c198fb9b7b0603f8635185e85fbd5b64ee154b1ed406d489077de2d6d60" + +[[package]] +name = "objc2" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b4b25e1034d0e636cd84707ccdaa9f81243d399196b8a773946dcffec0401659" dependencies = [ - "block", - "objc", - "objc_id", + "objc-sys", + "objc2-encode", ] [[package]] -name = "objc_id" -version = "0.1.1" +name = "objc2-app-kit" +version = "0.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c92d4ddb4bd7b50d730c215ff871754d0da6b2178849f8a2a2ab69712d0c073b" +checksum = "fb79768a710a9a1798848179edb186d1af7e8a8679f369e4b8d201dd2a034047" dependencies = [ - "objc", + "block2", + "objc2", + "objc2-core-data", + "objc2-foundation", +] + +[[package]] +name = "objc2-core-data" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6e092bc42eaf30a08844e6a076938c60751225ec81431ab89f5d1ccd9f958d6c" +dependencies = [ + "block2", + "objc2", + "objc2-foundation", +] + +[[package]] +name = "objc2-encode" +version = "4.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "88658da63e4cc2c8adb1262902cd6af51094df0488b760d6fd27194269c0950a" + +[[package]] +name = "objc2-foundation" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cfaefe14254871ea16c7d88968c0ff14ba554712a20d76421eec52f0a7fb8904" +dependencies = [ + "block2", + "objc2", ] [[package]] @@ -3635,7 +3708,7 @@ checksum = "a948666b637a0f465e8564c73e89d4dde00d72d4d473cc972f390fc3dcee7d9c" dependencies = [ "proc-macro2", "quote", - "syn 2.0.58", + "syn 2.0.60", ] [[package]] @@ -3673,7 +3746,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "49203cdcae0030493bad186b28da2fa25645fa276a51b6fec8010d281e02ef79" dependencies = [ "dlv-list", - "hashbrown 0.14.3", + "hashbrown 0.14.5", ] [[package]] @@ -3716,9 +3789,9 @@ dependencies = [ [[package]] name = "parking_lot" -version = "0.12.1" +version = "0.12.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3742b2c103b9f06bc9fff0a37ff4912935851bee6d36f3c02bcc755bcfec228f" +checksum = "7e4af0ca4f6caed20e900d564c242b8e5d4903fdacf31d3daf527b66fe6f42fb" dependencies = [ "lock_api", "parking_lot_core", @@ -3726,15 +3799,15 @@ dependencies = [ [[package]] name = "parking_lot_core" -version = "0.9.9" +version = "0.9.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4c42a9226546d68acdd9c0a280d17ce19bfe27a46bf68784e4066115788d008e" +checksum = "1e401f977ab385c9e4e3ab30627d6f26d00e2c73eef317493c4ec6d468726cf8" dependencies = [ "cfg-if", "libc", - "redox_syscall", + "redox_syscall 0.5.1", "smallvec", - "windows-targets 0.48.5", + "windows-targets 0.52.5", ] [[package]] @@ -3749,9 +3822,9 @@ dependencies = [ [[package]] name = "parse-zoneinfo" -version = "0.3.0" +version = "0.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c705f256449c60da65e11ff6626e0c16a0a0b96aaa348de61376b249bc340f41" +checksum = "1f2a05b18d44e2957b88f96ba460715e295bc1d7510468a2f3d3b44535d26c24" dependencies = [ "regex", ] @@ -3782,9 +3855,9 @@ checksum = "f658886ed52e196e850cfbbfddab9eaa7f6d90dd0929e264c31e5cec07e09e57" [[package]] name = "pest" -version = "2.7.9" +version = "2.7.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "311fb059dee1a7b802f036316d790138c613a4e8b180c822e3925a662e9f0c95" +checksum = "560131c633294438da9f7c4b08189194b20946c8274c6b9e38881a7874dc8ee8" dependencies = [ "memchr", "thiserror", @@ -3793,9 +3866,9 @@ dependencies = [ [[package]] name = "pest_derive" -version = "2.7.9" +version = "2.7.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f73541b156d32197eecda1a4014d7f868fd2bcb3c550d5386087cfba442bf69c" +checksum = "26293c9193fbca7b1a3bf9b79dc1e388e927e6cacaa78b4a3ab705a1d3d41459" dependencies = [ "pest", "pest_generator", @@ -3803,22 +3876,22 @@ dependencies = [ [[package]] name = "pest_generator" -version = "2.7.9" +version = "2.7.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c35eeed0a3fab112f75165fdc026b3913f4183133f19b49be773ac9ea966e8bd" +checksum = "3ec22af7d3fb470a85dd2ca96b7c577a1eb4ef6f1683a9fe9a8c16e136c04687" dependencies = [ "pest", "pest_meta", "proc-macro2", "quote", - "syn 2.0.58", + "syn 2.0.60", ] [[package]] name = "pest_meta" -version = "2.7.9" +version = "2.7.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2adbf29bb9776f28caece835398781ab24435585fe0d4dc1374a61db5accedca" +checksum = "d7a240022f37c361ec1878d646fc5b7d7c4d28d5946e1a80ad5a7a4f4ca0bdcd" dependencies = [ "once_cell", "pest", @@ -3904,7 +3977,7 @@ dependencies = [ "phf_shared 0.11.2", "proc-macro2", "quote", - "syn 2.0.58", + "syn 2.0.60", ] [[package]] @@ -3943,6 +4016,12 @@ version = "0.3.30" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d231b230927b5e4ad203db57bbcbee2802f6bce620b1e4a9024a07d94e2907ec" +[[package]] +name = "plain" +version = "0.2.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b4596b6d070b27117e987119b4dac604f3c58cfb0b191112e24771b2faeac1a6" + [[package]] name = "planus" version = "0.3.1" @@ -3954,9 +4033,9 @@ dependencies = [ [[package]] name = "platform-info" -version = "2.0.2" +version = "2.0.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d6259c4860e53bf665016f1b2f46a8859cadfa717581dc9d597ae4069de6300f" +checksum = "d5ff316b9c4642feda973c18f0decd6c8b0919d4722566f6e4337cce0dd88217" dependencies = [ "libc", "winapi", @@ -3964,9 +4043,9 @@ dependencies = [ [[package]] name = "polars" -version = "0.39.1" +version = "0.39.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1c352aaa0399c0863eecd879f2cbe585c9026c5cafe432f029025e4bec3adf43" +checksum = "0ea21b858b16b9c0e17a12db2800d11aa5b4bd182be6b3022eb537bbfc1f2db5" dependencies = [ "getrandom", "polars-arrow", @@ -3984,9 +4063,9 @@ dependencies = [ [[package]] name = "polars-arrow" -version = "0.39.1" +version = "0.39.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f88d3cfc6b500f106f03a5f4d37f700deef38c5b58a2e843edb3ec31f5a0ec19" +checksum = "725b09f2b5ef31279b66e27bbab63c58d49d8f6696b66b1f46c7eaab95e80f75" dependencies = [ "ahash 0.8.11", "atoi", @@ -4002,7 +4081,7 @@ dependencies = [ "foreign_vec", "futures", "getrandom", - "hashbrown 0.14.3", + "hashbrown 0.14.5", "itoa", "itoap", "lz4", @@ -4032,9 +4111,9 @@ dependencies = [ [[package]] name = "polars-compute" -version = "0.39.1" +version = "0.39.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cf264bfb632aaeba859fe19a87fa051d850e72542c36177ccea71fd9cae84079" +checksum = "a796945b14b14fbb79b91ef0406e6fddca2be636e889f81ea5d6ee7d36efb4fe" dependencies = [ "bytemuck", "either", @@ -4048,9 +4127,9 @@ dependencies = [ [[package]] name = "polars-core" -version = "0.39.1" +version = "0.39.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "85cb72917958e82f29d604429ab55851f561c7cd336f7744a7360f9e50b9ac88" +checksum = "465f70d3e96b6d0b1a43c358ba451286b8c8bd56696feff020d65702aa33e35c" dependencies = [ "ahash 0.8.11", "bitflags 2.5.0", @@ -4059,7 +4138,7 @@ dependencies = [ "chrono-tz 0.8.6", "comfy-table", "either", - "hashbrown 0.14.3", + "hashbrown 0.14.5", "indexmap", "num-traits", "once_cell", @@ -4082,9 +4161,9 @@ dependencies = [ [[package]] name = "polars-error" -version = "0.39.1" +version = "0.39.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c18ef81979a6d9e9fdbd25ad3bf1591cbd5c474489f785af44604cf591cd636d" +checksum = "5224d5d05e6b8a6f78b75951ae1b5f82c8ab1979e11ffaf5fd41941e3d5b0757" dependencies = [ "avro-schema", "polars-arrow-format", @@ -4095,9 +4174,9 @@ dependencies = [ [[package]] name = "polars-io" -version = "0.39.1" +version = "0.39.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4d47f2cdd8e2a2bfc71b0d30444d4c378ddc0d6f80826746fc3c731c06251b42" +checksum = "b2c8589e418cbe4a48228d64b2a8a40284a82ec3c98817c0c2bcc0267701338b" dependencies = [ "ahash 0.8.11", "async-trait", @@ -4136,14 +4215,14 @@ dependencies = [ [[package]] name = "polars-json" -version = "0.39.1" +version = "0.39.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "af22dcdf6f94894bbedb0b0b11fbffbb1905cc6e2a43bdb3e15355f3d4cf874a" +checksum = "81224492a649a12b668480c0cf219d703f432509765d2717e72fe32ad16fc701" dependencies = [ "ahash 0.8.11", "chrono", "fallible-streaming-iterator", - "hashbrown 0.14.3", + "hashbrown 0.14.5", "indexmap", "itoa", "num-traits", @@ -4157,9 +4236,9 @@ dependencies = [ [[package]] name = "polars-lazy" -version = "0.39.1" +version = "0.39.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ee5683b551f5e2bb004468edec0f87fd585f436c2e5f89b292c2bfee1b6f5d4f" +checksum = "89b2632b1af668e2058d5f8f916d8fbde3cac63d03ae29a705f598e41dcfeb7f" dependencies = [ "ahash 0.8.11", "bitflags 2.5.0", @@ -4181,9 +4260,9 @@ dependencies = [ [[package]] name = "polars-ops" -version = "0.39.1" +version = "0.39.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f311543e0e110d385867df25f47c1c740ee0cc854feead54262a24b0246383bb" +checksum = "efdbdb4d9a92109bc2e0ce8e17af5ae8ab643bb5b7ee9d1d74f0aeffd1fbc95f" dependencies = [ "ahash 0.8.11", "argminmax", @@ -4192,7 +4271,7 @@ dependencies = [ "chrono", "chrono-tz 0.8.6", "either", - "hashbrown 0.14.3", + "hashbrown 0.14.5", "hex", "indexmap", "jsonpath_lib_polars_vendor", @@ -4217,9 +4296,9 @@ dependencies = [ [[package]] name = "polars-parquet" -version = "0.39.1" +version = "0.39.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a41cd1f445fea8377350dfa2bd216785839ce97c826299c7e0e9557c1dbe887f" +checksum = "b421d2196f786fdfe162db614c8485f8308fe41575d4de634a39bbe460d1eb6a" dependencies = [ "ahash 0.8.11", "async-stream", @@ -4243,14 +4322,14 @@ dependencies = [ [[package]] name = "polars-pipe" -version = "0.39.1" +version = "0.39.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "58f57de92c0ca9851e89cf9374cd88029f9bb2197937c34d571ec2a7ac45cca3" +checksum = "48700f1d5bd56a15451e581f465c09541492750360f18637b196f995470a015c" dependencies = [ "crossbeam-channel", "crossbeam-queue", "enum_dispatch", - "hashbrown 0.14.3", + "hashbrown 0.14.5", "num-traits", "polars-arrow", "polars-compute", @@ -4268,14 +4347,14 @@ dependencies = [ [[package]] name = "polars-plan" -version = "0.39.1" +version = "0.39.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4c509bc273c402a8b1fbfa63df2b2e90ca10d30decab698c7739003817de67e1" +checksum = "2fb8e2302e20c44defd5be8cad9c96e75face63c3a5f609aced8c4ec3b3ac97d" dependencies = [ "ahash 0.8.11", "bytemuck", "chrono-tz 0.8.6", - "hashbrown 0.14.3", + "hashbrown 0.14.5", "once_cell", "percent-encoding", "polars-arrow", @@ -4297,9 +4376,9 @@ dependencies = [ [[package]] name = "polars-row" -version = "0.39.1" +version = "0.39.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "695a9954f5aa273e44c497c19f806177f787ccf87cd4b3044c96a5057266a861" +checksum = "a515bdc68c2ae3702e3de70d89601f3b71ca8137e282a226dddb53ee4bacfa2e" dependencies = [ "bytemuck", "polars-arrow", @@ -4309,9 +4388,9 @@ dependencies = [ [[package]] name = "polars-sql" -version = "0.39.1" +version = "0.39.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f7cdf3b41bda70004ed3ec78652eb690aec3db5d99dfac03fbf9995fe76a7e26" +checksum = "7b4bb7cc1c04c3023d1953b2f1dec50515e8fd8169a5a2bf4967b3b082232db7" dependencies = [ "hex", "polars-arrow", @@ -4327,9 +4406,9 @@ dependencies = [ [[package]] name = "polars-time" -version = "0.39.1" +version = "0.39.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5bdc956b63e99a5ad1dabd9d397ce9ce50f703e503a5039c972968683a953d0c" +checksum = "efc18e3ad92eec55db89d88f16c22d436559ba7030cf76f86f6ed7a754b673f1" dependencies = [ "atoi", "chrono", @@ -4348,13 +4427,13 @@ dependencies = [ [[package]] name = "polars-utils" -version = "0.39.1" +version = "0.39.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "355b126757b4a87da5248ae6eb644e99b5583a11ffc2d42e13b2b856d43e84be" +checksum = "c760b6c698cfe2fbbbd93d6cfb408db14ececfe1d92445dae2229ce1b5b21ae8" dependencies = [ "ahash 0.8.11", "bytemuck", - "hashbrown 0.14.3", + "hashbrown 0.14.5", "indexmap", "num-traits", "once_cell", @@ -4480,9 +4559,9 @@ dependencies = [ [[package]] name = "proc-macro2" -version = "1.0.79" +version = "1.0.81" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e835ff2298f5721608eb1a980ecaee1aef2c132bf95ecc026a11b7bf3c01c02e" +checksum = "3d1597b0c024618f09a9c3b8655b7e430397a36d23fdafec26d6965e9eec3eba" dependencies = [ "unicode-ident", ] @@ -4604,9 +4683,9 @@ dependencies = [ [[package]] name = "quote" -version = "1.0.35" +version = "1.0.36" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "291ec9ab5efd934aaf503a6466c5d5251535d108ee747472c3977cc5acc868ef" +checksum = "0fa76aaf39101c457836aec0ce2316dbdc3ab723cdda1c6bd4e6ad4208acaca7" dependencies = [ "proc-macro2", ] @@ -4685,9 +4764,9 @@ dependencies = [ [[package]] name = "raw-cpuid" -version = "11.0.1" +version = "11.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9d86a7c4638d42c44551f4791a20e687dbb4c3de1f33c43dd71e355cd429def1" +checksum = "e29830cbb1290e404f24c73af91c5d8d631ce7e128691e9477556b540cd01ecd" dependencies = [ "bitflags 2.5.0", ] @@ -4729,7 +4808,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "76009fbe0614077fc1a2ce255e3a1881a2e3a3527097d5dc6d8212c585e7e38b" dependencies = [ "quote", - "syn 2.0.58", + "syn 2.0.60", ] [[package]] @@ -4747,6 +4826,15 @@ dependencies = [ "bitflags 1.3.2", ] +[[package]] +name = "redox_syscall" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "469052894dcb553421e483e4209ee581a45100d31b4018de03e5a7ad86374a7e" +dependencies = [ + "bitflags 2.5.0", +] + [[package]] name = "redox_users" version = "0.4.5" @@ -4798,7 +4886,7 @@ checksum = "5fddb4f8d99b0a2ebafc65a87a69a7b9875e4b1ae1f00db265d300ef7f28bccc" dependencies = [ "proc-macro2", "quote", - "syn 2.0.58", + "syn 2.0.60", ] [[package]] @@ -4824,12 +4912,6 @@ dependencies = [ "regex-syntax", ] -[[package]] -name = "regex-lite" -version = "0.1.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "30b661b2f27137bdbc16f00eda72866a92bb28af1753ffbd56744fb6e2e9cd8e" - [[package]] name = "regex-syntax" version = "0.8.3" @@ -4961,7 +5043,7 @@ dependencies = [ "regex", "relative-path", "rustc_version", - "syn 2.0.58", + "syn 2.0.60", "unicode-ident", ] @@ -5000,7 +5082,7 @@ dependencies = [ "proc-macro2", "quote", "rust-embed-utils", - "syn 2.0.58", + "syn 2.0.60", "walkdir", ] @@ -5064,9 +5146,9 @@ dependencies = [ [[package]] name = "rustix" -version = "0.38.32" +version = "0.38.34" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "65e04861e65f21776e67888bfbea442b3642beaa0138fdb1dd7a84a52dffdb89" +checksum = "70dc5ec042f7a43c4a73241207cecc9873a06d45debb38b329f8541d85c2730f" dependencies = [ "bitflags 2.5.0", "errno", @@ -5141,6 +5223,26 @@ dependencies = [ "tendril", ] +[[package]] +name = "scroll" +version = "0.11.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "04c565b551bafbef4157586fa379538366e4385d42082f255bfd96e4fe8519da" +dependencies = [ + "scroll_derive", +] + +[[package]] +name = "scroll_derive" +version = "0.11.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1db149f81d46d2deba7cd3c50772474707729550221e69588478ebf9ada425ae" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.60", +] + [[package]] name = "sdd" version = "0.2.0" @@ -5209,29 +5311,29 @@ checksum = "a3f0bf26fd526d2a95683cd0f87bf103b8539e2ca1ef48ce002d67aad59aa0b4" [[package]] name = "serde" -version = "1.0.197" +version = "1.0.200" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3fb1c873e1b9b056a4dc4c0c198b24c3ffa059243875552b2bd0933b1aee4ce2" +checksum = "ddc6f9cc94d67c0e21aaf7eda3a010fd3af78ebf6e096aa6e2e13c79749cce4f" dependencies = [ "serde_derive", ] [[package]] name = "serde_derive" -version = "1.0.197" +version = "1.0.200" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7eb0b34b42edc17f6b7cac84a52a1c5f0e1bb2227e997ca9011ea3dd34e8610b" +checksum = "856f046b9400cee3c8c94ed572ecdb752444c24528c035cd35882aad6f492bcb" dependencies = [ "proc-macro2", "quote", - "syn 2.0.58", + "syn 2.0.60", ] [[package]] name = "serde_json" -version = "1.0.115" +version = "1.0.116" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "12dc5c46daa8e9fdf4f5e71b6cf9a53f2487da0e86e55808e2d35539666497dd" +checksum = "3e17db7126d17feb94eb3fad46bf1a96b034e8aacbc2e775fe81505f8b0b2813" dependencies = [ "indexmap", "itoa", @@ -5247,7 +5349,7 @@ checksum = "6c64451ba24fc7a6a2d60fc75dd9c83c90903b19028d4eff35e88fc1e86564e9" dependencies = [ "proc-macro2", "quote", - "syn 2.0.58", + "syn 2.0.60", ] [[package]] @@ -5286,9 +5388,9 @@ dependencies = [ [[package]] name = "serial_test" -version = "3.1.0" +version = "3.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "adb86f9315df5df6a70eae0cc22395a44e544a0d8897586820770a35ede74449" +checksum = "4b4b487fe2acf240a021cf57c6b2b4903b1e78ca0ecd862a71b71d2a51fed77d" dependencies = [ "futures", "log", @@ -5300,13 +5402,13 @@ dependencies = [ [[package]] name = "serial_test_derive" -version = "3.1.0" +version = "3.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a9bb72430492e9549b0c4596725c0f82729bff861c45aa8099c0a8e67fc3b721" +checksum = "82fe9db325bcef1fbcde82e078a5cc4efdf787e96b3b9cf45b50b529f2083d67" dependencies = [ "proc-macro2", "quote", - "syn 2.0.58", + "syn 2.0.60", ] [[package]] @@ -5375,18 +5477,18 @@ dependencies = [ [[package]] name = "signal-hook-registry" -version = "1.4.1" +version = "1.4.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d8229b473baa5980ac72ef434c4415e70c4b5e71b423043adb4ba059f89c99a1" +checksum = "a9e9e0b4211b72e7b8b6e85c807d36c212bdb33ea8587f7569562a84df5465b1" dependencies = [ "libc", ] [[package]] name = "simd-json" -version = "0.13.9" +version = "0.13.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b0b84c23a1066e1d650ebc99aa8fb9f8ed0ab96fd36e2e836173c92fc9fb29bc" +checksum = "570c430b3d902ea083097e853263ae782dfe40857d93db019a12356c8e8143fa" dependencies = [ "ahash 0.8.11", "getrandom", @@ -5470,9 +5572,9 @@ checksum = "1b6b67fb9a61334225b5b790716f609cd58395f895b3fe8b328786812a40bc3b" [[package]] name = "socket2" -version = "0.5.6" +version = "0.5.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "05ffd9c0a93b7543e062e759284fcf5f5e3b098501104bfbdde4d404db792871" +checksum = "ce305eb0b4296696835b71df73eb912e0f1ffd2556a501fcede6e0c50349191c" dependencies = [ "libc", "windows-sys 0.52.0", @@ -5503,7 +5605,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2ff9eaf853dec4c8802325d8b6d3dffa86cc707fd7a1a4cdbf416e13b061787a" dependencies = [ "quote", - "syn 2.0.58", + "syn 2.0.60", ] [[package]] @@ -5618,7 +5720,7 @@ dependencies = [ "proc-macro2", "quote", "rustversion", - "syn 2.0.58", + "syn 2.0.60", ] [[package]] @@ -5631,7 +5733,17 @@ dependencies = [ "proc-macro2", "quote", "rustversion", - "syn 2.0.58", + "syn 2.0.60", +] + +[[package]] +name = "supports-color" +version = "2.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d6398cde53adc3c4557306a96ce67b302968513830a77a95b2b17305d9719a89" +dependencies = [ + "is-terminal", + "is_ci", ] [[package]] @@ -5689,9 +5801,9 @@ dependencies = [ [[package]] name = "syn" -version = "2.0.58" +version = "2.0.60" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "44cfb93f38070beee36b3fef7d4f5a16f27751d94b187b666a5cc5e9b0d30687" +checksum = "909518bc7b1c9b779f1bbf07f2929d35af9f0f37e47c6e9ef7f9dddc1e1821f3" dependencies = [ "proc-macro2", "quote", @@ -5707,7 +5819,7 @@ dependencies = [ "proc-macro-error", "proc-macro2", "quote", - "syn 2.0.58", + "syn 2.0.60", ] [[package]] @@ -5721,9 +5833,9 @@ dependencies = [ [[package]] name = "sysinfo" -version = "0.30.9" +version = "0.30.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e9a84fe4cfc513b41cb2596b624e561ec9e7e1c4b46328e496ed56a53514ef2a" +checksum = "87341a165d73787554941cd5ef55ad728011566fe714e987d1b976c15dbc3a83" dependencies = [ "cfg-if", "core-foundation-sys", @@ -5746,6 +5858,27 @@ dependencies = [ "unicode-width", ] +[[package]] +name = "tango-bench" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3e79d9e491b718fb52bb2052726a0e66fe89a31cc6979fe58c72c73f058c279e" +dependencies = [ + "alloca", + "anyhow", + "clap", + "colorz", + "glob-match", + "goblin", + "libloading", + "log", + "num-traits", + "rand", + "scroll", + "tempfile", + "thiserror", +] + [[package]] name = "tap" version = "1.0.1" @@ -5819,22 +5952,22 @@ dependencies = [ [[package]] name = "thiserror" -version = "1.0.58" +version = "1.0.59" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "03468839009160513471e86a034bb2c5c0e4baae3b43f79ffc55c4a5427b3297" +checksum = "f0126ad08bff79f29fc3ae6a55cc72352056dfff61e3ff8bb7129476d44b23aa" dependencies = [ "thiserror-impl", ] [[package]] name = "thiserror-impl" -version = "1.0.58" +version = "1.0.59" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c61f3ba182994efc43764a46c018c347bc492c79f024e705f46567b418f6d4f7" +checksum = "d1cd413b5d558b4c5bf3680e324a6fa5014e7b7c067a51e69dbdf47eb7148b66" dependencies = [ "proc-macro2", "quote", - "syn 2.0.58", + "syn 2.0.60", ] [[package]] @@ -5849,9 +5982,9 @@ dependencies = [ [[package]] name = "time" -version = "0.3.34" +version = "0.3.36" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c8248b6521bb14bc45b4067159b9b6ad792e2d6d754d6c41fb50e29fefe38749" +checksum = "5dfd88e563464686c916c7e46e623e520ddc6d79fa6641390f2e3fa86e83e885" dependencies = [ "deranged", "itoa", @@ -5872,9 +6005,9 @@ checksum = "ef927ca75afb808a4d64dd374f00a2adf8d0fcff8e7b184af886c3c87ec4a3f3" [[package]] name = "time-macros" -version = "0.2.17" +version = "0.2.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7ba3a3ef41e6672a2f0f001392bb5dcd3ff0a9992d618ca761a11c3121547774" +checksum = "3f252a68540fde3a3877aeea552b832b40ab9a69e318efd078774a01ddee1ccf" dependencies = [ "num-conv", "time-core", @@ -5967,7 +6100,7 @@ dependencies = [ "serde", "serde_spanned", "toml_datetime", - "toml_edit 0.22.9", + "toml_edit 0.22.12", ] [[package]] @@ -6005,15 +6138,15 @@ dependencies = [ [[package]] name = "toml_edit" -version = "0.22.9" +version = "0.22.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8e40bb779c5187258fd7aad0eb68cb8706a0a81fa712fbea808ab43c4b8374c4" +checksum = "d3328d4f68a705b2a4498da1d580585d39a6510f98318a2cec3018a7ec61ddef" dependencies = [ "indexmap", "serde", "serde_spanned", "toml_datetime", - "winnow 0.6.5", + "winnow 0.6.7", ] [[package]] @@ -6116,7 +6249,7 @@ checksum = "ac73887f47b9312552aa90ef477927ff014d63d1920ca8037c6c1951eab64bb1" dependencies = [ "proc-macro2", "quote", - "syn 2.0.58", + "syn 2.0.60", ] [[package]] @@ -6187,9 +6320,9 @@ checksum = "d4c87d22b6e3f4a18d4d40ef354e97c90fcb14dd91d7dc0aa9d8a1172ebf7202" [[package]] name = "unicode-width" -version = "0.1.11" +version = "0.1.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e51733f11c9c4f72aa0c160008246859e340b00807569a0da0e7a1079b27ba85" +checksum = "68f5e5f3158ecfd4b8ff6fe086db7c8467a2dfdac97fe420f2b7c4aa97af66d6" [[package]] name = "unicode-xid" @@ -6205,11 +6338,11 @@ checksum = "673aac59facbab8a9007c7f6108d11f63b603f7cabff99fabf650fea5c32b861" [[package]] name = "ureq" -version = "2.9.6" +version = "2.9.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "11f214ce18d8b2cbe84ed3aa6486ed3f5b285cf8d8fbdbce9f3f767a724adc35" +checksum = "d11a831e3c0b56e438a28308e7c810799e3c118417f342d30ecec080105395cd" dependencies = [ - "base64 0.21.7", + "base64 0.22.1", "encoding_rs", "flate2", "log", @@ -6261,7 +6394,7 @@ dependencies = [ "indicatif", "libc", "quick-error 2.0.1", - "uucore", + "uucore 0.0.26", "walkdir", "xattr", ] @@ -6273,7 +6406,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "040aa4584036b2f65e05387b0ea9ac468afce1db325743ce5f350689fd9ce4ae" dependencies = [ "clap", - "uucore", + "uucore 0.0.26", ] [[package]] @@ -6285,7 +6418,7 @@ dependencies = [ "clap", "rand", "tempfile", - "uucore", + "uucore 0.0.26", ] [[package]] @@ -6297,7 +6430,7 @@ dependencies = [ "clap", "fs_extra", "indicatif", - "uucore", + "uucore 0.0.26", ] [[package]] @@ -6308,7 +6441,7 @@ checksum = "5951832d73199636bde6c0d61cf960932b3c4450142c290375bc10c7abed6db5" dependencies = [ "clap", "platform-info", - "uucore", + "uucore 0.0.26", ] [[package]] @@ -6319,7 +6452,7 @@ checksum = "e3b44166eb6335aeac42744ea368cc4c32d3f2287a4ff765a5ce44d927ab8bb4" dependencies = [ "clap", "libc", - "uucore", + "uucore 0.0.26", "windows-sys 0.48.0", ] @@ -6328,12 +6461,29 @@ name = "uucore" version = "0.0.25" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "23994a722acb43dbc56877e271c9723f167ae42c4c089f909b2d7dd106c3a9b4" +dependencies = [ + "clap", + "glob", + "libc", + "nix", + "once_cell", + "os_display", + "uucore_procs", + "wild", +] + +[[package]] +name = "uucore" +version = "0.0.26" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fb2ea2f77699e5ff5c7e001af588ceb34cae8b5f9af5496bea5a6476aaa8e780" dependencies = [ "clap", "dunce", "glob", "libc", "nix", + "number_prefix", "once_cell", "os_display", "uucore_procs", @@ -6346,9 +6496,9 @@ dependencies = [ [[package]] name = "uucore_procs" -version = "0.0.25" +version = "0.0.26" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f7f51594832e53b11811446b1cd3567722e2906a589a5b19622c5c4720977309" +checksum = "1a233a488da42f3ddb0aaa8a9f75a969e3f37e4de7e909d2d23f6aa3ee401d20" dependencies = [ "proc-macro2", "quote", @@ -6357,9 +6507,9 @@ dependencies = [ [[package]] name = "uuhelp_parser" -version = "0.0.25" +version = "0.0.26" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ac7a6832a5add86204d5a8d0ef41c5a11e3ddf61c0f1a508f69e7e3e1bf04e3f" +checksum = "425a23c7b7145bc7620c9c445817c37b1f78b6790aee9f208133f3c028975b60" [[package]] name = "uuid" @@ -6487,7 +6637,7 @@ dependencies = [ "once_cell", "proc-macro2", "quote", - "syn 2.0.58", + "syn 2.0.60", "wasm-bindgen-shared", ] @@ -6509,7 +6659,7 @@ checksum = "e94f17b526d0a461a191c78ea52bbce64071ed5c04c9ffe424dcb38f74171bb7" dependencies = [ "proc-macro2", "quote", - "syn 2.0.58", + "syn 2.0.60", "wasm-bindgen-backend", "wasm-bindgen-shared", ] @@ -6653,11 +6803,11 @@ checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6" [[package]] name = "winapi-util" -version = "0.1.6" +version = "0.1.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f29e6f9198ba0d26b4c9f07dbe6f9ed633e1f3d5b8b414090084349e46a52596" +checksum = "4d4cc384e1e73b93bafa6fb4f1df8c41695c8a91cf9c4c64358067d15a7b6c6b" dependencies = [ - "winapi", + "windows-sys 0.52.0", ] [[package]] @@ -6682,7 +6832,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e48a53791691ab099e5e2ad123536d0fff50652600abaf43bbf952894110d0be" dependencies = [ "windows-core 0.52.0", - "windows-targets 0.52.4", + "windows-targets 0.52.5", ] [[package]] @@ -6692,7 +6842,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9252e5725dbed82865af151df558e754e4a3c2c30818359eb17465f1346a1b49" dependencies = [ "windows-core 0.54.0", - "windows-targets 0.52.4", + "windows-targets 0.52.5", ] [[package]] @@ -6701,7 +6851,7 @@ version = "0.52.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "33ab640c8d7e35bf8ba19b884ba838ceb4fba93a4e8c65a9059d08afcfc683d9" dependencies = [ - "windows-targets 0.52.4", + "windows-targets 0.52.5", ] [[package]] @@ -6711,16 +6861,16 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "12661b9c89351d684a50a8a643ce5f608e20243b9fb84687800163429f161d65" dependencies = [ "windows-result", - "windows-targets 0.52.4", + "windows-targets 0.52.5", ] [[package]] name = "windows-result" -version = "0.1.0" +version = "0.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cd19df78e5168dfb0aedc343d1d1b8d422ab2db6756d2dc3fef75035402a3f64" +checksum = "749f0da9cc72d82e600d8d2e44cadd0b9eedb9038f71a1c58556ac1c5791813b" dependencies = [ - "windows-targets 0.52.4", + "windows-targets 0.52.5", ] [[package]] @@ -6738,7 +6888,7 @@ version = "0.52.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "282be5f36a8ce781fad8c8ae18fa3f9beff57ec1b52cb3de0789201425d9a33d" dependencies = [ - "windows-targets 0.52.4", + "windows-targets 0.52.5", ] [[package]] @@ -6773,17 +6923,18 @@ dependencies = [ [[package]] name = "windows-targets" -version = "0.52.4" +version = "0.52.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7dd37b7e5ab9018759f893a1952c9420d060016fc19a472b4bb20d1bdd694d1b" +checksum = "6f0713a46559409d202e70e28227288446bf7841d3211583a4b53e3f6d96e7eb" dependencies = [ - "windows_aarch64_gnullvm 0.52.4", - "windows_aarch64_msvc 0.52.4", - "windows_i686_gnu 0.52.4", - "windows_i686_msvc 0.52.4", - "windows_x86_64_gnu 0.52.4", - "windows_x86_64_gnullvm 0.52.4", - "windows_x86_64_msvc 0.52.4", + "windows_aarch64_gnullvm 0.52.5", + "windows_aarch64_msvc 0.52.5", + "windows_i686_gnu 0.52.5", + "windows_i686_gnullvm", + "windows_i686_msvc 0.52.5", + "windows_x86_64_gnu 0.52.5", + "windows_x86_64_gnullvm 0.52.5", + "windows_x86_64_msvc 0.52.5", ] [[package]] @@ -6800,9 +6951,9 @@ checksum = "2b38e32f0abccf9987a4e3079dfb67dcd799fb61361e53e2882c3cbaf0d905d8" [[package]] name = "windows_aarch64_gnullvm" -version = "0.52.4" +version = "0.52.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bcf46cf4c365c6f2d1cc93ce535f2c8b244591df96ceee75d8e83deb70a9cac9" +checksum = "7088eed71e8b8dda258ecc8bac5fb1153c5cffaf2578fc8ff5d61e23578d3263" [[package]] name = "windows_aarch64_msvc" @@ -6818,9 +6969,9 @@ checksum = "dc35310971f3b2dbbf3f0690a219f40e2d9afcf64f9ab7cc1be722937c26b4bc" [[package]] name = "windows_aarch64_msvc" -version = "0.52.4" +version = "0.52.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "da9f259dd3bcf6990b55bffd094c4f7235817ba4ceebde8e6d11cd0c5633b675" +checksum = "9985fd1504e250c615ca5f281c3f7a6da76213ebd5ccc9561496568a2752afb6" [[package]] name = "windows_i686_gnu" @@ -6836,9 +6987,15 @@ checksum = "a75915e7def60c94dcef72200b9a8e58e5091744960da64ec734a6c6e9b3743e" [[package]] name = "windows_i686_gnu" -version = "0.52.4" +version = "0.52.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b474d8268f99e0995f25b9f095bc7434632601028cf86590aea5c8a5cb7801d3" +checksum = "88ba073cf16d5372720ec942a8ccbf61626074c6d4dd2e745299726ce8b89670" + +[[package]] +name = "windows_i686_gnullvm" +version = "0.52.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "87f4261229030a858f36b459e748ae97545d6f1ec60e5e0d6a3d32e0dc232ee9" [[package]] name = "windows_i686_msvc" @@ -6854,9 +7011,9 @@ checksum = "8f55c233f70c4b27f66c523580f78f1004e8b5a8b659e05a4eb49d4166cca406" [[package]] name = "windows_i686_msvc" -version = "0.52.4" +version = "0.52.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1515e9a29e5bed743cb4415a9ecf5dfca648ce85ee42e15873c3cd8610ff8e02" +checksum = "db3c2bf3d13d5b658be73463284eaf12830ac9a26a90c717b7f771dfe97487bf" [[package]] name = "windows_x86_64_gnu" @@ -6872,9 +7029,9 @@ checksum = "53d40abd2583d23e4718fddf1ebec84dbff8381c07cae67ff7768bbf19c6718e" [[package]] name = "windows_x86_64_gnu" -version = "0.52.4" +version = "0.52.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5eee091590e89cc02ad514ffe3ead9eb6b660aedca2183455434b93546371a03" +checksum = "4e4246f76bdeff09eb48875a0fd3e2af6aada79d409d33011886d3e1581517d9" [[package]] name = "windows_x86_64_gnullvm" @@ -6890,9 +7047,9 @@ checksum = "0b7b52767868a23d5bab768e390dc5f5c55825b6d30b86c844ff2dc7414044cc" [[package]] name = "windows_x86_64_gnullvm" -version = "0.52.4" +version = "0.52.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "77ca79f2451b49fa9e2af39f0747fe999fcda4f5e241b2898624dca97a1f2177" +checksum = "852298e482cd67c356ddd9570386e2862b5673c85bd5f88df9ab6802b334c596" [[package]] name = "windows_x86_64_msvc" @@ -6908,9 +7065,9 @@ checksum = "ed94fce61571a4006852b7389a063ab983c02eb1bb37b47f8272ce92d06d9538" [[package]] name = "windows_x86_64_msvc" -version = "0.52.4" +version = "0.52.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "32b752e52a2da0ddfbdbcc6fceadfeede4c939ed16d13e648833a61dfb611ed8" +checksum = "bec47e5bfd1bff0eeaf6d8b485cc1074891a197ab4225d504cb7a1ab88b02bf0" [[package]] name = "winnow" @@ -6923,9 +7080,9 @@ dependencies = [ [[package]] name = "winnow" -version = "0.6.5" +version = "0.6.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dffa400e67ed5a4dd237983829e66475f0a4a26938c4b04c21baede6262215b8" +checksum = "14b9415ee827af173ebb3f15f9083df5a122eb93572ec28741fb153356ea2578" dependencies = [ "memchr", ] @@ -6987,9 +7144,9 @@ dependencies = [ [[package]] name = "x11rb" -version = "0.13.0" +version = "0.13.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f8f25ead8c7e4cba123243a6367da5d3990e0d3affa708ea19dce96356bd9f1a" +checksum = "5d91ffca73ee7f68ce055750bf9f6eca0780b8c85eff9bc046a3b0da41755e12" dependencies = [ "gethostname", "rustix", @@ -6998,9 +7155,9 @@ dependencies = [ [[package]] name = "x11rb-protocol" -version = "0.13.0" +version = "0.13.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e63e71c4b8bd9ffec2c963173a4dc4cbde9ee96961d4fcb4429db9929b606c34" +checksum = "ec107c4503ea0b4a98ef47356329af139c0a4f7750e621cf2973cd3385ebcb3d" [[package]] name = "xattr" @@ -7042,7 +7199,7 @@ checksum = "9ce1b18ccd8e73a9321186f97e46f9f04b778851177567b1975109d26a08d2a6" dependencies = [ "proc-macro2", "quote", - "syn 2.0.58", + "syn 2.0.60", ] [[package]] diff --git a/Cargo.toml b/Cargo.toml index 7fbc95a239..beabd26e20 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -65,14 +65,14 @@ members = [ alphanumeric-sort = "1.5" ansi-str = "0.8" anyhow = "1.0.82" -base64 = "0.22" +base64 = "0.22.1" bracoxide = "0.1.2" brotli = "5.0" byteorder = "1.5" bytesize = "1.3" calamine = "0.24.0" chardetng = "0.1.17" -chrono = { default-features = false, version = "0.4" } +chrono = { default-features = false, version = "0.4.34" } chrono-humanize = "0.2.3" chrono-tz = "0.8" crossbeam-channel = "0.5.8" @@ -94,7 +94,7 @@ heck = "0.5.0" human-date-parser = "0.1.1" indexmap = "2.2" indicatif = "0.17" -interprocess = "2.0.0" +interprocess = "2.0.1" is_executable = "1.0" itertools = "0.12" libc = "0.2" @@ -227,7 +227,7 @@ nu-plugin-protocol = { path = "./crates/nu-plugin-protocol", version = "0.93.1" nu-plugin-core = { path = "./crates/nu-plugin-core", version = "0.93.1" } assert_cmd = "2.0" dirs-next = { workspace = true } -divan = "0.1.14" +tango-bench = "0.5" pretty_assertions = { workspace = true } rstest = { workspace = true, default-features = false } serial_test = "3.1" diff --git a/benches/benchmarks.rs b/benches/benchmarks.rs index e6bec2e163..859e3e2d2d 100644 --- a/benches/benchmarks.rs +++ b/benches/benchmarks.rs @@ -1,7 +1,7 @@ use nu_cli::{eval_source, evaluate_commands}; -use nu_parser::parse; use nu_plugin_core::{Encoder, EncodingType}; use nu_plugin_protocol::{PluginCallResponse, PluginOutput}; + use nu_protocol::{ engine::{EngineState, Stack}, eval_const::create_nu_constant, @@ -9,12 +9,14 @@ use nu_protocol::{ }; use nu_std::load_standard_library; use nu_utils::{get_default_config, get_default_env}; -use std::path::{Path, PathBuf}; +use std::{ + path::{Path, PathBuf}, + rc::Rc, +}; -fn main() { - // Run registered benchmarks. - divan::main(); -} +use std::hint::black_box; + +use tango_bench::{benchmark_fn, tango_benchmarks, tango_main, IntoBenchmarks}; fn load_bench_commands() -> EngineState { nu_command::add_shell_command_context(nu_cmd_lang::create_default_context()) @@ -57,42 +59,6 @@ fn setup_engine() -> EngineState { engine_state } -fn bench_command(bencher: divan::Bencher, scaled_command: String) { - bench_command_with_custom_stack_and_engine( - bencher, - scaled_command, - Stack::new(), - setup_engine(), - ) -} - -fn bench_command_with_custom_stack_and_engine( - bencher: divan::Bencher, - scaled_command: String, - stack: nu_protocol::engine::Stack, - mut engine: EngineState, -) { - load_standard_library(&mut engine).unwrap(); - let commands = Spanned { - span: Span::unknown(), - item: scaled_command, - }; - - bencher - .with_inputs(|| engine.clone()) - .bench_values(|mut engine| { - evaluate_commands( - &commands, - &mut engine, - &mut stack.clone(), - PipelineData::empty(), - None, - false, - ) - .unwrap(); - }) -} - fn setup_stack_and_engine_from_command(command: &str) -> (Stack, EngineState) { let mut engine = setup_engine(); let commands = Spanned { @@ -114,261 +80,6 @@ fn setup_stack_and_engine_from_command(command: &str) -> (Stack, EngineState) { (stack, engine) } -// FIXME: All benchmarks live in this 1 file to speed up build times when benchmarking. -// When the *_benchmarks functions were in different files, `cargo bench` would build -// an executable for every single one - incredibly slowly. Would be nice to figure out -// a way to split things up again. - -#[divan::bench] -fn load_standard_lib(bencher: divan::Bencher) { - let engine = setup_engine(); - bencher - .with_inputs(|| engine.clone()) - .bench_values(|mut engine| { - load_standard_library(&mut engine).unwrap(); - }) -} - -#[divan::bench_group] -mod record { - - use super::*; - - fn create_flat_record_string(n: i32) -> String { - let mut s = String::from("let record = {"); - for i in 0..n { - s.push_str(&format!("col_{}: {}", i, i)); - if i < n - 1 { - s.push_str(", "); - } - } - s.push('}'); - s - } - - fn create_nested_record_string(depth: i32) -> String { - let mut s = String::from("let record = {"); - for _ in 0..depth { - s.push_str("col: {"); - } - s.push_str("col_final: 0"); - for _ in 0..depth { - s.push('}'); - } - s.push('}'); - s - } - - #[divan::bench(args = [1, 10, 100, 1000])] - fn create(bencher: divan::Bencher, n: i32) { - bench_command(bencher, create_flat_record_string(n)); - } - - #[divan::bench(args = [1, 10, 100, 1000])] - fn flat_access(bencher: divan::Bencher, n: i32) { - let (stack, engine) = setup_stack_and_engine_from_command(&create_flat_record_string(n)); - bench_command_with_custom_stack_and_engine( - bencher, - "$record.col_0 | ignore".to_string(), - stack, - engine, - ); - } - - #[divan::bench(args = [1, 2, 4, 8, 16, 32, 64, 128])] - fn nest_access(bencher: divan::Bencher, depth: i32) { - let (stack, engine) = - setup_stack_and_engine_from_command(&create_nested_record_string(depth)); - let nested_access = ".col".repeat(depth as usize); - bench_command_with_custom_stack_and_engine( - bencher, - format!("$record{} | ignore", nested_access), - stack, - engine, - ); - } -} - -#[divan::bench_group] -mod table { - - use super::*; - - fn create_example_table_nrows(n: i32) -> String { - let mut s = String::from("let table = [[foo bar baz]; "); - for i in 0..n { - s.push_str(&format!("[0, 1, {i}]")); - if i < n - 1 { - s.push_str(", "); - } - } - s.push(']'); - s - } - - #[divan::bench(args = [1, 10, 100, 1000])] - fn create(bencher: divan::Bencher, n: i32) { - bench_command(bencher, create_example_table_nrows(n)); - } - - #[divan::bench(args = [1, 10, 100, 1000])] - fn get(bencher: divan::Bencher, n: i32) { - let (stack, engine) = setup_stack_and_engine_from_command(&create_example_table_nrows(n)); - bench_command_with_custom_stack_and_engine( - bencher, - "$table | get bar | math sum | ignore".to_string(), - stack, - engine, - ); - } - - #[divan::bench(args = [1, 10, 100, 1000])] - fn select(bencher: divan::Bencher, n: i32) { - let (stack, engine) = setup_stack_and_engine_from_command(&create_example_table_nrows(n)); - bench_command_with_custom_stack_and_engine( - bencher, - "$table | select foo baz | ignore".to_string(), - stack, - engine, - ); - } -} - -#[divan::bench_group] -mod eval_commands { - use super::*; - - #[divan::bench(args = [100, 1_000, 10_000])] - fn interleave(bencher: divan::Bencher, n: i32) { - bench_command( - bencher, - format!("seq 1 {n} | wrap a | interleave {{ seq 1 {n} | wrap b }} | ignore"), - ) - } - - #[divan::bench(args = [100, 1_000, 10_000])] - fn interleave_with_ctrlc(bencher: divan::Bencher, n: i32) { - let mut engine = setup_engine(); - engine.ctrlc = Some(std::sync::Arc::new(std::sync::atomic::AtomicBool::new( - false, - ))); - load_standard_library(&mut engine).unwrap(); - let commands = Spanned { - span: Span::unknown(), - item: format!("seq 1 {n} | wrap a | interleave {{ seq 1 {n} | wrap b }} | ignore"), - }; - - bencher - .with_inputs(|| engine.clone()) - .bench_values(|mut engine| { - evaluate_commands( - &commands, - &mut engine, - &mut nu_protocol::engine::Stack::new(), - PipelineData::empty(), - None, - false, - ) - .unwrap(); - }) - } - - #[divan::bench(args = [1, 5, 10, 100, 1_000])] - fn for_range(bencher: divan::Bencher, n: i32) { - bench_command(bencher, format!("(for $x in (1..{}) {{ sleep 50ns }})", n)) - } - - #[divan::bench(args = [1, 5, 10, 100, 1_000])] - fn each(bencher: divan::Bencher, n: i32) { - bench_command( - bencher, - format!("(1..{}) | each {{|_| sleep 50ns }} | ignore", n), - ) - } - - #[divan::bench(args = [1, 5, 10, 100, 1_000])] - fn par_each_1t(bencher: divan::Bencher, n: i32) { - bench_command( - bencher, - format!("(1..{}) | par-each -t 1 {{|_| sleep 50ns }} | ignore", n), - ) - } - - #[divan::bench(args = [1, 5, 10, 100, 1_000])] - fn par_each_2t(bencher: divan::Bencher, n: i32) { - bench_command( - bencher, - format!("(1..{}) | par-each -t 2 {{|_| sleep 50ns }} | ignore", n), - ) - } -} - -#[divan::bench_group()] -mod parser_benchmarks { - use super::*; - - #[divan::bench()] - fn parse_default_config_file(bencher: divan::Bencher) { - let engine_state = setup_engine(); - let default_env = get_default_config().as_bytes(); - - bencher - .with_inputs(|| nu_protocol::engine::StateWorkingSet::new(&engine_state)) - .bench_refs(|working_set| parse(working_set, None, default_env, false)) - } - - #[divan::bench()] - fn parse_default_env_file(bencher: divan::Bencher) { - let engine_state = setup_engine(); - let default_env = get_default_env().as_bytes(); - - bencher - .with_inputs(|| nu_protocol::engine::StateWorkingSet::new(&engine_state)) - .bench_refs(|working_set| parse(working_set, None, default_env, false)) - } -} - -#[divan::bench_group()] -mod eval_benchmarks { - use super::*; - - #[divan::bench()] - fn eval_default_env(bencher: divan::Bencher) { - let default_env = get_default_env().as_bytes(); - let fname = "default_env.nu"; - bencher - .with_inputs(|| (setup_engine(), nu_protocol::engine::Stack::new())) - .bench_values(|(mut engine_state, mut stack)| { - eval_source( - &mut engine_state, - &mut stack, - default_env, - fname, - PipelineData::empty(), - false, - ) - }) - } - - #[divan::bench()] - fn eval_default_config(bencher: divan::Bencher) { - let default_env = get_default_config().as_bytes(); - let fname = "default_config.nu"; - bencher - .with_inputs(|| (setup_engine(), nu_protocol::engine::Stack::new())) - .bench_values(|(mut engine_state, mut stack)| { - eval_source( - &mut engine_state, - &mut stack, - default_env, - fname, - PipelineData::empty(), - false, - ) - }) - } -} - // generate a new table data with `row_cnt` rows, `col_cnt` columns. fn encoding_test_data(row_cnt: usize, col_cnt: usize) -> Value { let record = Value::test_record( @@ -380,76 +91,423 @@ fn encoding_test_data(row_cnt: usize, col_cnt: usize) -> Value { Value::list(vec![record; row_cnt], Span::test_data()) } -#[divan::bench_group()] -mod encoding_benchmarks { - use super::*; - - #[divan::bench(args = [(100, 5), (10000, 15)])] - fn json_encode(bencher: divan::Bencher, (row_cnt, col_cnt): (usize, usize)) { - let test_data = PluginOutput::CallResponse( - 0, - PluginCallResponse::value(encoding_test_data(row_cnt, col_cnt)), - ); - let encoder = EncodingType::try_from_bytes(b"json").unwrap(); - bencher - .with_inputs(Vec::new) - .bench_values(|mut res| encoder.encode(&test_data, &mut res)) - } - - #[divan::bench(args = [(100, 5), (10000, 15)])] - fn msgpack_encode(bencher: divan::Bencher, (row_cnt, col_cnt): (usize, usize)) { - let test_data = PluginOutput::CallResponse( - 0, - PluginCallResponse::value(encoding_test_data(row_cnt, col_cnt)), - ); - let encoder = EncodingType::try_from_bytes(b"msgpack").unwrap(); - bencher - .with_inputs(Vec::new) - .bench_values(|mut res| encoder.encode(&test_data, &mut res)) - } +fn bench_command( + name: &str, + command: &str, + stack: Stack, + engine: EngineState, +) -> impl IntoBenchmarks { + let commands = Spanned { + span: Span::unknown(), + item: command.to_string(), + }; + [benchmark_fn(name, move |b| { + let commands = commands.clone(); + let stack = stack.clone(); + let engine = engine.clone(); + b.iter(move || { + let mut stack = stack.clone(); + let mut engine = engine.clone(); + black_box( + evaluate_commands( + &commands, + &mut engine, + &mut stack, + PipelineData::empty(), + None, + false, + ) + .unwrap(), + ); + }) + })] } -#[divan::bench_group()] -mod decoding_benchmarks { - use super::*; - - #[divan::bench(args = [(100, 5), (10000, 15)])] - fn json_decode(bencher: divan::Bencher, (row_cnt, col_cnt): (usize, usize)) { - let test_data = PluginOutput::CallResponse( - 0, - PluginCallResponse::value(encoding_test_data(row_cnt, col_cnt)), - ); - let encoder = EncodingType::try_from_bytes(b"json").unwrap(); - let mut res = vec![]; - encoder.encode(&test_data, &mut res).unwrap(); - bencher - .with_inputs(|| { - let mut binary_data = std::io::Cursor::new(res.clone()); - binary_data.set_position(0); - binary_data - }) - .bench_values(|mut binary_data| -> Result, _> { - encoder.decode(&mut binary_data) - }) - } - - #[divan::bench(args = [(100, 5), (10000, 15)])] - fn msgpack_decode(bencher: divan::Bencher, (row_cnt, col_cnt): (usize, usize)) { - let test_data = PluginOutput::CallResponse( - 0, - PluginCallResponse::value(encoding_test_data(row_cnt, col_cnt)), - ); - let encoder = EncodingType::try_from_bytes(b"msgpack").unwrap(); - let mut res = vec![]; - encoder.encode(&test_data, &mut res).unwrap(); - bencher - .with_inputs(|| { - let mut binary_data = std::io::Cursor::new(res.clone()); - binary_data.set_position(0); - binary_data - }) - .bench_values(|mut binary_data| -> Result, _> { - encoder.decode(&mut binary_data) - }) - } +fn bench_eval_source( + name: &str, + fname: String, + source: Vec, + stack: Stack, + engine: EngineState, +) -> impl IntoBenchmarks { + [benchmark_fn(name, move |b| { + let stack = stack.clone(); + let engine = engine.clone(); + let fname = fname.clone(); + let source = source.clone(); + b.iter(move || { + let mut stack = stack.clone(); + let mut engine = engine.clone(); + let fname: &str = &fname.clone(); + let source: &[u8] = &source.clone(); + black_box(eval_source( + &mut engine, + &mut stack, + source, + fname, + PipelineData::empty(), + false, + )); + }) + })] } + +/// Load the standard library into the engine. +fn bench_load_standard_lib() -> impl IntoBenchmarks { + [benchmark_fn("load_standard_lib", move |b| { + let engine = setup_engine(); + b.iter(move || { + let mut engine = engine.clone(); + load_standard_library(&mut engine) + }) + })] +} + +fn create_flat_record_string(n: i32) -> String { + let mut s = String::from("let record = {"); + for i in 0..n { + s.push_str(&format!("col_{}: {}", i, i)); + if i < n - 1 { + s.push_str(", "); + } + } + s.push('}'); + s +} + +fn create_nested_record_string(depth: i32) -> String { + let mut s = String::from("let record = {"); + for _ in 0..depth { + s.push_str("col: {"); + } + s.push_str("col_final: 0"); + for _ in 0..depth { + s.push('}'); + } + s.push('}'); + s +} + +fn create_example_table_nrows(n: i32) -> String { + let mut s = String::from("let table = [[foo bar baz]; "); + for i in 0..n { + s.push_str(&format!("[0, 1, {i}]")); + if i < n - 1 { + s.push_str(", "); + } + } + s.push(']'); + s +} + +fn bench_record_create(n: i32) -> impl IntoBenchmarks { + bench_command( + &format!("record_create_{n}"), + &create_flat_record_string(n), + Stack::new(), + setup_engine(), + ) +} + +fn bench_record_flat_access(n: i32) -> impl IntoBenchmarks { + let setup_command = create_flat_record_string(n); + let (stack, engine) = setup_stack_and_engine_from_command(&setup_command); + bench_command( + &format!("record_flat_access_{n}"), + "$record.col_0 | ignore", + stack, + engine, + ) +} + +fn bench_record_nested_access(n: i32) -> impl IntoBenchmarks { + let setup_command = create_nested_record_string(n); + let (stack, engine) = setup_stack_and_engine_from_command(&setup_command); + let nested_access = ".col".repeat(n as usize); + bench_command( + &format!("record_nested_access_{n}"), + &format!("$record{} | ignore", nested_access), + stack, + engine, + ) +} + +fn bench_table_create(n: i32) -> impl IntoBenchmarks { + bench_command( + &format!("table_create_{n}"), + &create_example_table_nrows(n), + Stack::new(), + setup_engine(), + ) +} + +fn bench_table_get(n: i32) -> impl IntoBenchmarks { + let setup_command = create_example_table_nrows(n); + let (stack, engine) = setup_stack_and_engine_from_command(&setup_command); + bench_command( + &format!("table_get_{n}"), + "$table | get bar | math sum | ignore", + stack, + engine, + ) +} + +fn bench_table_select(n: i32) -> impl IntoBenchmarks { + let setup_command = create_example_table_nrows(n); + let (stack, engine) = setup_stack_and_engine_from_command(&setup_command); + bench_command( + &format!("table_select_{n}"), + "$table | select foo baz | ignore", + stack, + engine, + ) +} + +fn bench_eval_interleave(n: i32) -> impl IntoBenchmarks { + let engine = setup_engine(); + let stack = Stack::new(); + bench_command( + &format!("eval_interleave_{n}"), + &format!("seq 1 {n} | wrap a | interleave {{ seq 1 {n} | wrap b }} | ignore"), + stack, + engine, + ) +} + +fn bench_eval_interleave_with_ctrlc(n: i32) -> impl IntoBenchmarks { + let mut engine = setup_engine(); + engine.ctrlc = Some(std::sync::Arc::new(std::sync::atomic::AtomicBool::new( + false, + ))); + let stack = Stack::new(); + bench_command( + &format!("eval_interleave_with_ctrlc_{n}"), + &format!("seq 1 {n} | wrap a | interleave {{ seq 1 {n} | wrap b }} | ignore"), + stack, + engine, + ) +} + +fn bench_eval_for(n: i32) -> impl IntoBenchmarks { + let engine = setup_engine(); + let stack = Stack::new(); + bench_command( + &format!("eval_for_{n}"), + &format!("(for $x in (1..{n}) {{ 1 }}) | ignore"), + stack, + engine, + ) +} + +fn bench_eval_each(n: i32) -> impl IntoBenchmarks { + let engine = setup_engine(); + let stack = Stack::new(); + bench_command( + &format!("eval_each_{n}"), + &format!("(1..{n}) | each {{|_| 1 }} | ignore"), + stack, + engine, + ) +} + +fn bench_eval_par_each(n: i32) -> impl IntoBenchmarks { + let engine = setup_engine(); + let stack = Stack::new(); + bench_command( + &format!("eval_par_each_{n}"), + &format!("(1..{}) | par-each -t 2 {{|_| 1 }} | ignore", n), + stack, + engine, + ) +} + +fn bench_eval_default_config() -> impl IntoBenchmarks { + let default_env = get_default_config().as_bytes().to_vec(); + let fname = "default_config.nu".to_string(); + bench_eval_source( + "eval_default_config", + fname, + default_env, + Stack::new(), + setup_engine(), + ) +} + +fn bench_eval_default_env() -> impl IntoBenchmarks { + let default_env = get_default_env().as_bytes().to_vec(); + let fname = "default_env.nu".to_string(); + bench_eval_source( + "eval_default_env", + fname, + default_env, + Stack::new(), + setup_engine(), + ) +} + +fn encode_json(row_cnt: usize, col_cnt: usize) -> impl IntoBenchmarks { + let test_data = Rc::new(PluginOutput::CallResponse( + 0, + PluginCallResponse::value(encoding_test_data(row_cnt, col_cnt)), + )); + let encoder = Rc::new(EncodingType::try_from_bytes(b"json").unwrap()); + + [benchmark_fn( + format!("encode_json_{}_{}", row_cnt, col_cnt), + move |b| { + let encoder = encoder.clone(); + let test_data = test_data.clone(); + b.iter(move || { + let mut res = Vec::new(); + encoder.encode(&*test_data, &mut res).unwrap(); + }) + }, + )] +} + +fn encode_msgpack(row_cnt: usize, col_cnt: usize) -> impl IntoBenchmarks { + let test_data = Rc::new(PluginOutput::CallResponse( + 0, + PluginCallResponse::value(encoding_test_data(row_cnt, col_cnt)), + )); + let encoder = Rc::new(EncodingType::try_from_bytes(b"msgpack").unwrap()); + + [benchmark_fn( + format!("encode_msgpack_{}_{}", row_cnt, col_cnt), + move |b| { + let encoder = encoder.clone(); + let test_data = test_data.clone(); + b.iter(move || { + let mut res = Vec::new(); + encoder.encode(&*test_data, &mut res).unwrap(); + }) + }, + )] +} + +fn decode_json(row_cnt: usize, col_cnt: usize) -> impl IntoBenchmarks { + let test_data = PluginOutput::CallResponse( + 0, + PluginCallResponse::value(encoding_test_data(row_cnt, col_cnt)), + ); + let encoder = EncodingType::try_from_bytes(b"json").unwrap(); + let mut res = vec![]; + encoder.encode(&test_data, &mut res).unwrap(); + + [benchmark_fn( + format!("decode_json_{}_{}", row_cnt, col_cnt), + move |b| { + let res = res.clone(); + b.iter(move || { + let mut binary_data = std::io::Cursor::new(res.clone()); + binary_data.set_position(0); + let _: Result, _> = + black_box(encoder.decode(&mut binary_data)); + }) + }, + )] +} + +fn decode_msgpack(row_cnt: usize, col_cnt: usize) -> impl IntoBenchmarks { + let test_data = PluginOutput::CallResponse( + 0, + PluginCallResponse::value(encoding_test_data(row_cnt, col_cnt)), + ); + let encoder = EncodingType::try_from_bytes(b"msgpack").unwrap(); + let mut res = vec![]; + encoder.encode(&test_data, &mut res).unwrap(); + + [benchmark_fn( + format!("decode_msgpack_{}_{}", row_cnt, col_cnt), + move |b| { + let res = res.clone(); + b.iter(move || { + let mut binary_data = std::io::Cursor::new(res.clone()); + binary_data.set_position(0); + let _: Result, _> = + black_box(encoder.decode(&mut binary_data)); + }) + }, + )] +} + +tango_benchmarks!( + bench_load_standard_lib(), + // Data types + // Record + bench_record_create(1), + bench_record_create(10), + bench_record_create(100), + bench_record_create(1_000), + bench_record_flat_access(1), + bench_record_flat_access(10), + bench_record_flat_access(100), + bench_record_flat_access(1_000), + bench_record_nested_access(1), + bench_record_nested_access(2), + bench_record_nested_access(4), + bench_record_nested_access(8), + bench_record_nested_access(16), + bench_record_nested_access(32), + bench_record_nested_access(64), + bench_record_nested_access(128), + // Table + bench_table_create(1), + bench_table_create(10), + bench_table_create(100), + bench_table_create(1_000), + bench_table_get(1), + bench_table_get(10), + bench_table_get(100), + bench_table_get(1_000), + bench_table_select(1), + bench_table_select(10), + bench_table_select(100), + bench_table_select(1_000), + // Eval + // Interleave + bench_eval_interleave(100), + bench_eval_interleave(1_000), + bench_eval_interleave(10_000), + bench_eval_interleave_with_ctrlc(100), + bench_eval_interleave_with_ctrlc(1_000), + bench_eval_interleave_with_ctrlc(10_000), + // For + bench_eval_for(1), + bench_eval_for(10), + bench_eval_for(100), + bench_eval_for(1_000), + bench_eval_for(10_000), + // Each + bench_eval_each(1), + bench_eval_each(10), + bench_eval_each(100), + bench_eval_each(1_000), + bench_eval_each(10_000), + // Par-Each + bench_eval_par_each(1), + bench_eval_par_each(10), + bench_eval_par_each(100), + bench_eval_par_each(1_000), + bench_eval_par_each(10_000), + // Config + bench_eval_default_config(), + // Env + bench_eval_default_env(), + // Encode + // Json + encode_json(100, 5), + encode_json(10000, 15), + // MsgPack + encode_msgpack(100, 5), + encode_msgpack(10000, 15), + // Decode + // Json + decode_json(100, 5), + decode_json(10000, 15), + // MsgPack + decode_msgpack(100, 5), + decode_msgpack(10000, 15) +); + +tango_main!(); diff --git a/crates/nu-cli/src/commands/history/history_.rs b/crates/nu-cli/src/commands/history/history_.rs index 4572aaba35..8b0714216e 100644 --- a/crates/nu-cli/src/commands/history/history_.rs +++ b/crates/nu-cli/src/commands/history/history_.rs @@ -107,7 +107,7 @@ impl Command for History { file: history_path.display().to_string(), span: head, })? - .into_pipeline_data(ctrlc)), + .into_pipeline_data(head, ctrlc)), HistoryFileFormat::Sqlite => Ok(history_reader .and_then(|h| { h.search(SearchQuery::everything(SearchDirection::Forward, None)) @@ -122,7 +122,7 @@ impl Command for History { file: history_path.display().to_string(), span: head, })? - .into_pipeline_data(ctrlc)), + .into_pipeline_data(head, ctrlc)), } } } else { diff --git a/crates/nu-cli/src/completions/completion_common.rs b/crates/nu-cli/src/completions/completion_common.rs index 5f927976a2..4a8b0d57ac 100644 --- a/crates/nu-cli/src/completions/completion_common.rs +++ b/crates/nu-cli/src/completions/completion_common.rs @@ -7,40 +7,65 @@ use nu_protocol::{ Span, }; use nu_utils::get_ls_colors; -use std::{ - ffi::OsStr, - path::{is_separator, Component, Path, PathBuf, MAIN_SEPARATOR as SEP}, +use std::path::{ + is_separator, Component, Path, PathBuf, MAIN_SEPARATOR as SEP, MAIN_SEPARATOR_STR, }; +#[derive(Clone, Default)] +pub struct PathBuiltFromString { + parts: Vec, + isdir: bool, +} + fn complete_rec( - partial: &[String], + partial: &[&str], + built: &PathBuiltFromString, cwd: &Path, options: &CompletionOptions, dir: bool, isdir: bool, -) -> Vec { +) -> Vec { let mut completions = vec![]; - if let Ok(result) = cwd.read_dir() { - for entry in result.filter_map(|e| e.ok()) { - let entry_name = entry.file_name().to_string_lossy().into_owned(); - let path = entry.path(); + if let Some((&base, rest)) = partial.split_first() { + if (base == "." || base == "..") && (isdir || !rest.is_empty()) { + let mut built = built.clone(); + built.parts.push(base.to_string()); + built.isdir = true; + return complete_rec(rest, &built, cwd, options, dir, isdir); + } + } - if !dir || path.is_dir() { - match partial.first() { - Some(base) if matches(base, &entry_name, options) => { - let partial = &partial[1..]; - if !partial.is_empty() || isdir { - completions.extend(complete_rec(partial, &path, options, dir, isdir)); - if entry_name.eq(base) { - break; - } + let mut built_path = cwd.to_path_buf(); + for part in &built.parts { + built_path.push(part); + } + + let Ok(result) = built_path.read_dir() else { + return completions; + }; + + for entry in result.filter_map(|e| e.ok()) { + let entry_name = entry.file_name().to_string_lossy().into_owned(); + let entry_isdir = entry.path().is_dir(); + let mut built = built.clone(); + built.parts.push(entry_name.clone()); + built.isdir = entry_isdir; + + if !dir || entry_isdir { + match partial.split_first() { + Some((base, rest)) => { + if matches(base, &entry_name, options) { + if !rest.is_empty() || isdir { + completions + .extend(complete_rec(rest, &built, cwd, options, dir, isdir)); } else { - completions.push(path) + completions.push(built); } } - None => completions.push(path), - _ => {} + } + None => { + completions.push(built); } } } @@ -48,33 +73,23 @@ fn complete_rec( completions } +#[derive(Debug)] enum OriginalCwd { None, - Home(PathBuf), - Some(PathBuf), - // referencing a single local file - Local(PathBuf), + Home, + Prefix(String), } impl OriginalCwd { - fn apply(&self, p: &Path) -> String { - let mut ret = match self { - Self::None => p.to_string_lossy().into_owned(), - Self::Some(base) => pathdiff::diff_paths(p, base) - .unwrap_or(p.to_path_buf()) - .to_string_lossy() - .into_owned(), - Self::Home(home) => match p.strip_prefix(home) { - Ok(suffix) => format!("~{}{}", SEP, suffix.to_string_lossy()), - _ => p.to_string_lossy().into_owned(), - }, - Self::Local(base) => Path::new(".") - .join(pathdiff::diff_paths(p, base).unwrap_or(p.to_path_buf())) - .to_string_lossy() - .into_owned(), + fn apply(&self, mut p: PathBuiltFromString) -> String { + match self { + Self::None => {} + Self::Home => p.parts.insert(0, "~".to_string()), + Self::Prefix(s) => p.parts.insert(0, s.clone()), }; - if p.is_dir() { + let mut ret = p.parts.join(MAIN_SEPARATOR_STR); + if p.isdir { ret.push(SEP); } ret @@ -116,79 +131,67 @@ pub fn complete_item( }; get_ls_colors(ls_colors_env_str) }); + + let mut cwd = cwd_pathbuf.clone(); + let mut prefix_len = 0; let mut original_cwd = OriginalCwd::None; - let mut components_vec: Vec = Path::new(&partial).components().collect(); - // Path components that end with a single "." get normalized away, - // so if the partial path ends in a literal "." we must add it back in manually - if partial.ends_with('.') && partial.len() > 1 { - components_vec.push(Component::Normal(OsStr::new("."))); - }; - let mut components = components_vec.into_iter().peekable(); - - let mut cwd = match components.peek().cloned() { + let mut components = Path::new(&partial).components().peekable(); + match components.peek().cloned() { Some(c @ Component::Prefix(..)) => { // windows only by definition components.next(); if let Some(Component::RootDir) = components.peek().cloned() { components.next(); }; - [c, Component::RootDir].iter().collect() + cwd = [c, Component::RootDir].iter().collect(); + prefix_len = c.as_os_str().len(); + original_cwd = OriginalCwd::Prefix(c.as_os_str().to_string_lossy().into_owned()); } Some(c @ Component::RootDir) => { components.next(); - PathBuf::from(c.as_os_str()) + // This is kind of a hack. When joining an empty string with the rest, + // we add the slash automagically + cwd = PathBuf::from(c.as_os_str()); + prefix_len = 1; + original_cwd = OriginalCwd::Prefix(String::new()); } Some(Component::Normal(home)) if home.to_string_lossy() == "~" => { components.next(); - original_cwd = OriginalCwd::Home(home_dir().unwrap_or(cwd_pathbuf.clone())); - home_dir().unwrap_or(cwd_pathbuf) - } - Some(Component::CurDir) => { - components.next(); - original_cwd = match components.peek().cloned() { - Some(Component::Normal(_)) | None => OriginalCwd::Local(cwd_pathbuf.clone()), - _ => OriginalCwd::Some(cwd_pathbuf.clone()), - }; - cwd_pathbuf - } - _ => { - original_cwd = OriginalCwd::Some(cwd_pathbuf.clone()); - cwd_pathbuf + cwd = home_dir().unwrap_or(cwd_pathbuf); + prefix_len = 1; + original_cwd = OriginalCwd::Home; } + _ => {} }; - let mut partial = vec![]; + let after_prefix = &partial[prefix_len..]; + let partial: Vec<_> = after_prefix + .strip_prefix(is_separator) + .unwrap_or(after_prefix) + .split(is_separator) + .filter(|s| !s.is_empty()) + .collect(); - for component in components { - match component { - Component::Prefix(..) => unreachable!(), - Component::RootDir => unreachable!(), - Component::CurDir => {} - Component::ParentDir => { - if partial.pop().is_none() { - cwd.pop(); - } - } - Component::Normal(c) => partial.push(c.to_string_lossy().into_owned()), - } - } - - complete_rec(partial.as_slice(), &cwd, options, want_directory, isdir) - .into_iter() - .map(|p| { - let path = original_cwd.apply(&p); - let style = ls_colors.as_ref().map(|lsc| { - lsc.style_for_path_with_metadata( - &path, - std::fs::symlink_metadata(&path).ok().as_ref(), - ) + complete_rec( + partial.as_slice(), + &PathBuiltFromString::default(), + &cwd, + options, + want_directory, + isdir, + ) + .into_iter() + .map(|p| { + let path = original_cwd.apply(p); + let style = ls_colors.as_ref().map(|lsc| { + lsc.style_for_path_with_metadata(&path, std::fs::symlink_metadata(&path).ok().as_ref()) .map(lscolors::Style::to_nu_ansi_term_style) .unwrap_or_default() - }); - (span, escape_path(path, want_directory), style) - }) - .collect() + }); + (span, escape_path(path, want_directory), style) + }) + .collect() } // Fix files or folders with quotes or hashes diff --git a/crates/nu-cli/src/syntax_highlight.rs b/crates/nu-cli/src/syntax_highlight.rs index d4bbb7db92..e296943af6 100644 --- a/crates/nu-cli/src/syntax_highlight.rs +++ b/crates/nu-cli/src/syntax_highlight.rs @@ -88,7 +88,7 @@ impl Highlighter for NuHighlighter { .to_string(); let mut add_colored_token = |shape: &FlatShape, text: String| { - output.push((get_shape_color(shape.to_string(), &self.config), text)); + output.push((get_shape_color(shape.as_str(), &self.config), text)); }; match shape.1 { @@ -128,7 +128,7 @@ impl Highlighter for NuHighlighter { let start = part.start - span.start; let end = part.end - span.start; let text = next_token[start..end].to_string(); - let mut style = get_shape_color(shape.to_string(), &self.config); + let mut style = get_shape_color(shape.as_str(), &self.config); if highlight { style = get_matching_brackets_style(style, &self.config); } diff --git a/crates/nu-cli/tests/completions.rs b/crates/nu-cli/tests/completions.rs index 611dbfd35e..a22d770010 100644 --- a/crates/nu-cli/tests/completions.rs +++ b/crates/nu-cli/tests/completions.rs @@ -334,7 +334,26 @@ fn partial_completions() { let suggestions = completer.complete(&target_dir, target_dir.len()); // Create the expected values - let expected_paths: Vec = vec![file(dir.join("final_partial").join("somefile"))]; + let expected_paths: Vec = vec![ + file( + dir.join("partial_a") + .join("..") + .join("final_partial") + .join("somefile"), + ), + file( + dir.join("partial_b") + .join("..") + .join("final_partial") + .join("somefile"), + ), + file( + dir.join("partial_c") + .join("..") + .join("final_partial") + .join("somefile"), + ), + ]; // Match the results match_suggestions(expected_paths, suggestions); diff --git a/crates/nu-cmd-extra/src/extra/filters/each_while.rs b/crates/nu-cmd-extra/src/extra/filters/each_while.rs index 4e9741ef92..2dda815d43 100644 --- a/crates/nu-cmd-extra/src/extra/filters/each_while.rs +++ b/crates/nu-cmd-extra/src/extra/filters/each_while.rs @@ -87,7 +87,7 @@ impl Command for EachWhile { Err(_) => None, }) .fuse() - .into_pipeline_data(engine_state.ctrlc.clone())) + .into_pipeline_data(head, engine_state.ctrlc.clone())) } PipelineData::ExternalStream { stdout: None, .. } => Ok(PipelineData::empty()), PipelineData::ExternalStream { @@ -108,7 +108,7 @@ impl Command for EachWhile { } }) .fuse() - .into_pipeline_data(engine_state.ctrlc.clone())) + .into_pipeline_data(head, engine_state.ctrlc.clone())) } // This match allows non-iterables to be accepted, // which is currently considered undesirable (Nov 2022). diff --git a/crates/nu-cmd-extra/src/extra/filters/update_cells.rs b/crates/nu-cmd-extra/src/extra/filters/update_cells.rs index 21d499790c..b35736370d 100644 --- a/crates/nu-cmd-extra/src/extra/filters/update_cells.rs +++ b/crates/nu-cmd-extra/src/extra/filters/update_cells.rs @@ -108,7 +108,7 @@ impl Command for UpdateCells { columns, span: head, } - .into_pipeline_data(engine_state.ctrlc.clone()) + .into_pipeline_data(head, engine_state.ctrlc.clone()) .set_metadata(metadata)) } } diff --git a/crates/nu-cmd-extra/src/extra/strings/format/command.rs b/crates/nu-cmd-extra/src/extra/strings/format/command.rs index 437bbc14c9..932b5ccb7f 100644 --- a/crates/nu-cmd-extra/src/extra/strings/format/command.rs +++ b/crates/nu-cmd-extra/src/extra/strings/format/command.rs @@ -238,10 +238,7 @@ fn format( } } - Ok(PipelineData::ListStream( - ListStream::from_stream(list.into_iter(), None), - None, - )) + Ok(ListStream::new(list.into_iter(), head_span, engine_state.ctrlc.clone()).into()) } // Unwrapping this ShellError is a bit unfortunate. // Ideally, its Span would be preserved. diff --git a/crates/nu-cmd-lang/src/core_commands/do_.rs b/crates/nu-cmd-lang/src/core_commands/do_.rs index c2b630e08d..b057880cf3 100644 --- a/crates/nu-cmd-lang/src/core_commands/do_.rs +++ b/crates/nu-cmd-lang/src/core_commands/do_.rs @@ -62,6 +62,7 @@ impl Command for Do { call: &Call, input: PipelineData, ) -> Result { + let head = call.head; let block: Closure = call.req(engine_state, caller_stack, 0)?; let rest: Vec = call.rest(engine_state, caller_stack, 1)?; let ignore_all_errors = call.has_flag(engine_state, caller_stack, "ignore-errors")?; @@ -75,7 +76,7 @@ impl Command for Do { let mut callee_stack = caller_stack.captures_to_stack_preserve_out_dest(block.captures); let block = engine_state.get_block(block.block_id); - bind_args_to(&mut callee_stack, &block.signature, rest, call.head)?; + bind_args_to(&mut callee_stack, &block.signature, rest, head)?; let eval_block_with_early_return = get_eval_block_with_early_return(engine_state); let result = eval_block_with_early_return(engine_state, &mut callee_stack, block, input); @@ -117,7 +118,7 @@ impl Command for Do { None, ) }) - .err_span(call.head) + .err_span(head) }) .transpose()?; @@ -148,13 +149,9 @@ impl Command for Do { None }; - let mut exit_code_ctrlc = None; let exit_code: Vec = match exit_code { None => vec![], - Some(exit_code_stream) => { - exit_code_ctrlc.clone_from(&exit_code_stream.ctrlc); - exit_code_stream.into_iter().collect() - } + Some(exit_code_stream) => exit_code_stream.into_iter().collect(), }; if let Some(Value::Int { val: code, .. }) = exit_code.last() { if *code != 0 { @@ -174,10 +171,7 @@ impl Command for Do { span, None, )), - exit_code: Some(ListStream::from_stream( - exit_code.into_iter(), - exit_code_ctrlc, - )), + exit_code: Some(ListStream::new(exit_code.into_iter(), span, None)), span, metadata, trim_end_newline, @@ -205,21 +199,15 @@ impl Command for Do { Ok(PipelineData::Value(Value::Error { .. }, ..)) | Err(_) if ignore_shell_errors => { Ok(PipelineData::empty()) } - Ok(PipelineData::ListStream(ls, metadata)) if ignore_shell_errors => { - // check if there is a `Value::Error` in given list stream first. - let mut values = vec![]; - let ctrlc = ls.ctrlc.clone(); - for v in ls { - if let Value::Error { .. } = v { - values.push(Value::nothing(call.head)); + Ok(PipelineData::ListStream(stream, metadata)) if ignore_shell_errors => { + let stream = stream.map(move |value| { + if let Value::Error { .. } = value { + Value::nothing(head) } else { - values.push(v) + value } - } - Ok(PipelineData::ListStream( - ListStream::from_stream(values.into_iter(), ctrlc), - metadata, - )) + }); + Ok(PipelineData::ListStream(stream, metadata)) } r => r, } diff --git a/crates/nu-cmd-lang/src/core_commands/for_.rs b/crates/nu-cmd-lang/src/core_commands/for_.rs index e4e15e74dc..64e6c0a6ba 100644 --- a/crates/nu-cmd-lang/src/core_commands/for_.rs +++ b/crates/nu-cmd-lang/src/core_commands/for_.rs @@ -1,5 +1,4 @@ use nu_engine::{command_prelude::*, get_eval_block, get_eval_expression}; -use nu_protocol::ListStream; #[derive(Clone)] pub struct For; @@ -88,7 +87,11 @@ impl Command for For { let span = value.span(); match value { Value::List { vals, .. } => { - for (idx, x) in ListStream::from_stream(vals.into_iter(), ctrlc).enumerate() { + for (idx, x) in vals.into_iter().enumerate() { + if nu_utils::ctrl_c::was_pressed(&ctrlc) { + break; + } + // with_env() is used here to ensure that each iteration uses // a different set of environment variables. // Hence, a 'cd' in the first loop won't affect the next loop. diff --git a/crates/nu-cmd-lang/src/core_commands/scope/aliases.rs b/crates/nu-cmd-lang/src/core_commands/scope/aliases.rs index 780d8d5a13..0b8d2d0200 100644 --- a/crates/nu-cmd-lang/src/core_commands/scope/aliases.rs +++ b/crates/nu-cmd-lang/src/core_commands/scope/aliases.rs @@ -26,13 +26,10 @@ impl Command for ScopeAliases { call: &Call, _input: PipelineData, ) -> Result { - let span = call.head; - let ctrlc = engine_state.ctrlc.clone(); - + let head = call.head; let mut scope_data = ScopeData::new(engine_state, stack); scope_data.populate_decls(); - - Ok(scope_data.collect_aliases(span).into_pipeline_data(ctrlc)) + Ok(Value::list(scope_data.collect_aliases(head), head).into_pipeline_data()) } fn examples(&self) -> Vec { diff --git a/crates/nu-cmd-lang/src/core_commands/scope/commands.rs b/crates/nu-cmd-lang/src/core_commands/scope/commands.rs index 5feed1a9ee..6ce0448f4e 100644 --- a/crates/nu-cmd-lang/src/core_commands/scope/commands.rs +++ b/crates/nu-cmd-lang/src/core_commands/scope/commands.rs @@ -26,13 +26,10 @@ impl Command for ScopeCommands { call: &Call, _input: PipelineData, ) -> Result { - let span = call.head; - let ctrlc = engine_state.ctrlc.clone(); - + let head = call.head; let mut scope_data = ScopeData::new(engine_state, stack); scope_data.populate_decls(); - - Ok(scope_data.collect_commands(span).into_pipeline_data(ctrlc)) + Ok(Value::list(scope_data.collect_commands(head), head).into_pipeline_data()) } fn examples(&self) -> Vec { diff --git a/crates/nu-cmd-lang/src/core_commands/scope/externs.rs b/crates/nu-cmd-lang/src/core_commands/scope/externs.rs index 30cdc53f26..187f90206d 100644 --- a/crates/nu-cmd-lang/src/core_commands/scope/externs.rs +++ b/crates/nu-cmd-lang/src/core_commands/scope/externs.rs @@ -26,13 +26,10 @@ impl Command for ScopeExterns { call: &Call, _input: PipelineData, ) -> Result { - let span = call.head; - let ctrlc = engine_state.ctrlc.clone(); - + let head = call.head; let mut scope_data = ScopeData::new(engine_state, stack); scope_data.populate_decls(); - - Ok(scope_data.collect_externs(span).into_pipeline_data(ctrlc)) + Ok(Value::list(scope_data.collect_externs(head), head).into_pipeline_data()) } fn examples(&self) -> Vec { diff --git a/crates/nu-cmd-lang/src/core_commands/scope/modules.rs b/crates/nu-cmd-lang/src/core_commands/scope/modules.rs index 6031121847..9d78f2a061 100644 --- a/crates/nu-cmd-lang/src/core_commands/scope/modules.rs +++ b/crates/nu-cmd-lang/src/core_commands/scope/modules.rs @@ -26,13 +26,10 @@ impl Command for ScopeModules { call: &Call, _input: PipelineData, ) -> Result { - let span = call.head; - let ctrlc = engine_state.ctrlc.clone(); - + let head = call.head; let mut scope_data = ScopeData::new(engine_state, stack); scope_data.populate_modules(); - - Ok(scope_data.collect_modules(span).into_pipeline_data(ctrlc)) + Ok(Value::list(scope_data.collect_modules(head), head).into_pipeline_data()) } fn examples(&self) -> Vec { diff --git a/crates/nu-cmd-lang/src/core_commands/scope/variables.rs b/crates/nu-cmd-lang/src/core_commands/scope/variables.rs index 7f44289fb4..6c9a695c71 100644 --- a/crates/nu-cmd-lang/src/core_commands/scope/variables.rs +++ b/crates/nu-cmd-lang/src/core_commands/scope/variables.rs @@ -26,13 +26,10 @@ impl Command for ScopeVariables { call: &Call, _input: PipelineData, ) -> Result { - let span = call.head; - let ctrlc = engine_state.ctrlc.clone(); - + let head = call.head; let mut scope_data = ScopeData::new(engine_state, stack); scope_data.populate_vars(); - - Ok(scope_data.collect_vars(span).into_pipeline_data(ctrlc)) + Ok(Value::list(scope_data.collect_vars(head), head).into_pipeline_data()) } fn examples(&self) -> Vec { diff --git a/crates/nu-cmd-plugin/src/commands/plugin/list.rs b/crates/nu-cmd-plugin/src/commands/plugin/list.rs index 1d630b67c0..6b715a0001 100644 --- a/crates/nu-cmd-plugin/src/commands/plugin/list.rs +++ b/crates/nu-cmd-plugin/src/commands/plugin/list.rs @@ -69,35 +69,47 @@ impl Command for PluginList { call: &Call, _input: PipelineData, ) -> Result { - let span = call.span(); + let head = call.head; + // Group plugin decls by plugin identity let decls = engine_state.plugin_decls().into_group_map_by(|decl| { decl.plugin_identity() .expect("plugin decl should have identity") }); + // Build plugins list let list = engine_state.plugins().iter().map(|plugin| { // Find commands that belong to the plugin let commands = decls.get(plugin.identity()) .into_iter() .flat_map(|decls| { - decls.iter().map(|decl| Value::string(decl.name(), span)) + decls.iter().map(|decl| Value::string(decl.name(), head)) }) .collect(); - Value::record(record! { - "name" => Value::string(plugin.identity().name(), span), - "is_running" => Value::bool(plugin.is_running(), span), - "pid" => plugin.pid() - .map(|p| Value::int(p as i64, span)) - .unwrap_or(Value::nothing(span)), - "filename" => Value::string(plugin.identity().filename().to_string_lossy(), span), - "shell" => plugin.identity().shell() - .map(|s| Value::string(s.to_string_lossy(), span)) - .unwrap_or(Value::nothing(span)), - "commands" => Value::list(commands, span), - }, span) - }).collect::>(); - Ok(list.into_pipeline_data(engine_state.ctrlc.clone())) + let pid = plugin + .pid() + .map(|p| Value::int(p as i64, head)) + .unwrap_or(Value::nothing(head)); + + let shell = plugin + .identity() + .shell() + .map(|s| Value::string(s.to_string_lossy(), head)) + .unwrap_or(Value::nothing(head)); + + let record = record! { + "name" => Value::string(plugin.identity().name(), head), + "is_running" => Value::bool(plugin.is_running(), head), + "pid" => pid, + "filename" => Value::string(plugin.identity().filename().to_string_lossy(), head), + "shell" => shell, + "commands" => Value::list(commands, head), + }; + + Value::record(record, head) + }).collect(); + + Ok(Value::list(list, head).into_pipeline_data()) } } diff --git a/crates/nu-color-config/src/color_config.rs b/crates/nu-color-config/src/color_config.rs index 8f25ada576..ad5040893a 100644 --- a/crates/nu-color-config/src/color_config.rs +++ b/crates/nu-color-config/src/color_config.rs @@ -13,7 +13,7 @@ pub fn lookup_ansi_color_style(s: &str) -> Style { .and_then(|c| c.map(|c| c.normal())) .unwrap_or_default() } else if s.starts_with('{') { - color_string_to_nustyle(s.to_string()) + color_string_to_nustyle(s) } else { lookup_style(s) } @@ -74,13 +74,13 @@ fn get_style_from_value(record: &Record) -> Option { } } -fn color_string_to_nustyle(color_string: String) -> Style { +fn color_string_to_nustyle(color_string: &str) -> Style { // eprintln!("color_string: {}", &color_string); if color_string.is_empty() { return Style::default(); } - let nu_style = match nu_json::from_str::(&color_string) { + let nu_style = match nu_json::from_str::(color_string) { Ok(s) => s, Err(_) => return Style::default(), }; @@ -97,13 +97,13 @@ mod tests { #[test] fn test_color_string_to_nustyle_empty_string() { let color_string = String::new(); - let style = color_string_to_nustyle(color_string); + let style = color_string_to_nustyle(&color_string); assert_eq!(style, Style::default()); } #[test] fn test_color_string_to_nustyle_valid_string() { - let color_string = r#"{"fg": "black", "bg": "white", "attr": "b"}"#.to_string(); + let color_string = r#"{"fg": "black", "bg": "white", "attr": "b"}"#; let style = color_string_to_nustyle(color_string); assert_eq!(style.foreground, Some(Color::Black)); assert_eq!(style.background, Some(Color::White)); @@ -112,7 +112,7 @@ mod tests { #[test] fn test_color_string_to_nustyle_invalid_string() { - let color_string = "invalid string".to_string(); + let color_string = "invalid string"; let style = color_string_to_nustyle(color_string); assert_eq!(style, Style::default()); } diff --git a/crates/nu-color-config/src/shape_color.rs b/crates/nu-color-config/src/shape_color.rs index cb896f2bfc..72cc955e0b 100644 --- a/crates/nu-color-config/src/shape_color.rs +++ b/crates/nu-color-config/src/shape_color.rs @@ -3,8 +3,8 @@ use nu_ansi_term::{Color, Style}; use nu_protocol::{Config, Value}; // The default colors for shapes, used when there is no config for them. -pub fn default_shape_color(shape: String) -> Style { - match shape.as_ref() { +pub fn default_shape_color(shape: &str) -> Style { + match shape { "shape_and" => Style::new().fg(Color::Purple).bold(), "shape_binary" => Style::new().fg(Color::Purple).bold(), "shape_block" => Style::new().fg(Color::Blue).bold(), @@ -45,8 +45,8 @@ pub fn default_shape_color(shape: String) -> Style { } } -pub fn get_shape_color(shape: String, conf: &Config) -> Style { - match conf.color_config.get(shape.as_str()) { +pub fn get_shape_color(shape: &str, conf: &Config) -> Style { + match conf.color_config.get(shape) { Some(int_color) => { // Shapes do not use color_config closures, currently. match int_color { diff --git a/crates/nu-command/src/conversions/into/cell_path.rs b/crates/nu-command/src/conversions/into/cell_path.rs index 039656e9d6..4faa6e83d6 100644 --- a/crates/nu-command/src/conversions/into/cell_path.rs +++ b/crates/nu-command/src/conversions/into/cell_path.rs @@ -98,7 +98,7 @@ fn into_cell_path(call: &Call, input: PipelineData) -> Result Ok(value_to_cell_path(&value, head)?.into_pipeline_data()), PipelineData::ListStream(stream, ..) => { - let list: Vec<_> = stream.collect(); + let list: Vec<_> = stream.into_iter().collect(); Ok(list_to_cell_path(&list, head)?.into_pipeline_data()) } PipelineData::ExternalStream { span, .. } => Err(ShellError::OnlySupportsThisInputType { diff --git a/crates/nu-command/src/conversions/into/datetime.rs b/crates/nu-command/src/conversions/into/datetime.rs index 157ae95079..af10732aea 100644 --- a/crates/nu-command/src/conversions/into/datetime.rs +++ b/crates/nu-command/src/conversions/into/datetime.rs @@ -39,7 +39,7 @@ impl Zone { Self::Error // Out of range } } - fn from_string(s: String) -> Self { + fn from_string(s: &str) -> Self { match s.to_ascii_lowercase().as_str() { "utc" | "u" => Self::Utc, "local" | "l" => Self::Local, @@ -126,7 +126,7 @@ impl Command for SubCommand { span: zone_offset.span, }), None => timezone.as_ref().map(|zone| Spanned { - item: Zone::from_string(zone.item.clone()), + item: Zone::from_string(&zone.item), span: zone.span, }), }; diff --git a/crates/nu-command/src/conversions/into/value.rs b/crates/nu-command/src/conversions/into/value.rs index c92afc3685..b867e8dae2 100644 --- a/crates/nu-command/src/conversions/into/value.rs +++ b/crates/nu-command/src/conversions/into/value.rs @@ -81,7 +81,7 @@ impl Command for IntoValue { display_as_filesizes, span, } - .into_pipeline_data(ctrlc) + .into_pipeline_data(span, ctrlc) .set_metadata(metadata)) } } diff --git a/crates/nu-command/src/database/commands/into_sqlite.rs b/crates/nu-command/src/database/commands/into_sqlite.rs index 1b4d0b8073..f3a2e3622a 100644 --- a/crates/nu-command/src/database/commands/into_sqlite.rs +++ b/crates/nu-command/src/database/commands/into_sqlite.rs @@ -203,8 +203,8 @@ fn action( ctrl_c: Option>, ) -> Result { match input { - PipelineData::ListStream(list_stream, _) => { - insert_in_transaction(list_stream.stream, span, table, ctrl_c) + PipelineData::ListStream(stream, _) => { + insert_in_transaction(stream.into_iter(), span, table, ctrl_c) } PipelineData::Value( Value::List { @@ -269,7 +269,8 @@ fn insert_in_transaction( let insert_statement = format!( "INSERT INTO [{}] ({}) VALUES ({})", table_name, - Itertools::intersperse(val.columns().map(String::as_str), ", ").collect::(), + Itertools::intersperse(val.columns().map(|c| format!("`{}`", c)), ", ".to_string()) + .collect::(), Itertools::intersperse(itertools::repeat_n("?", val.len()), ", ").collect::(), ); @@ -390,8 +391,12 @@ fn get_columns_with_sqlite_types( let mut columns: Vec<(String, &'static str)> = vec![]; for (c, v) in record { - if !columns.iter().any(|(name, _)| name == c) { - columns.push((c.clone(), nu_value_to_sqlite_type(v)?)); + if !columns + .iter() + .map(|name| (format!("`{}`", name.0), name.1)) + .any(|(name, _)| name == *c) + { + columns.push((format!("`{}`", c), nu_value_to_sqlite_type(v)?)); } } diff --git a/crates/nu-command/src/date/list_timezone.rs b/crates/nu-command/src/date/list_timezone.rs index bb56cb995d..6f9267947d 100644 --- a/crates/nu-command/src/date/list_timezone.rs +++ b/crates/nu-command/src/date/list_timezone.rs @@ -30,17 +30,17 @@ impl Command for SubCommand { call: &Call, _input: PipelineData, ) -> Result { - let span = call.head; + let head = call.head; Ok(TZ_VARIANTS .iter() .map(move |x| { Value::record( - record! { "timezone" => Value::string(x.name(), span) }, - span, + record! { "timezone" => Value::string(x.name(), head) }, + head, ) }) - .into_pipeline_data(engine_state.ctrlc.clone())) + .into_pipeline_data(head, engine_state.ctrlc.clone())) } fn examples(&self) -> Vec { diff --git a/crates/nu-command/src/date/utils.rs b/crates/nu-command/src/date/utils.rs index f58b2a517c..4616dc887b 100644 --- a/crates/nu-command/src/date/utils.rs +++ b/crates/nu-command/src/date/utils.rs @@ -8,7 +8,7 @@ pub(crate) fn parse_date_from_string( match dtparse::parse(input) { Ok((native_dt, fixed_offset)) => { let offset = match fixed_offset { - Some(fo) => fo, + Some(offset) => offset, None => *(Local::now().offset()), }; match offset.from_local_datetime(&native_dt) { diff --git a/crates/nu-command/src/debug/explain.rs b/crates/nu-command/src/debug/explain.rs index 0abd87b9a3..b451d6916a 100644 --- a/crates/nu-command/src/debug/explain.rs +++ b/crates/nu-command/src/debug/explain.rs @@ -34,16 +34,14 @@ impl Command for Explain { stack: &mut Stack, call: &Call, _input: PipelineData, - ) -> Result { + ) -> Result { + let head = call.head; // This was all delightfully stolen from benchmark :) let capture_block: Closure = call.req(engine_state, stack, 0)?; let block = engine_state.get_block(capture_block.block_id); - let ctrlc = engine_state.ctrlc.clone(); let mut stack = stack.captures_to_stack(capture_block.captures); - - let elements = get_pipeline_elements(engine_state, &mut stack, block, call.head); - - Ok(elements.into_pipeline_data(ctrlc)) + let elements = get_pipeline_elements(engine_state, &mut stack, block, head); + Ok(Value::list(elements, head).into_pipeline_data()) } fn examples(&self) -> Vec { diff --git a/crates/nu-command/src/debug/metadata_set.rs b/crates/nu-command/src/debug/metadata_set.rs index 29cb8ab0a2..6608827fda 100644 --- a/crates/nu-command/src/debug/metadata_set.rs +++ b/crates/nu-command/src/debug/metadata_set.rs @@ -47,13 +47,21 @@ impl Command for MetadataSet { let metadata = PipelineMetadata { data_source: DataSource::FilePath(path.into()), }; - Ok(input.into_pipeline_data_with_metadata(metadata, engine_state.ctrlc.clone())) + Ok(input.into_pipeline_data_with_metadata( + head, + engine_state.ctrlc.clone(), + metadata, + )) } (None, true) => { let metadata = PipelineMetadata { data_source: DataSource::Ls, }; - Ok(input.into_pipeline_data_with_metadata(metadata, engine_state.ctrlc.clone())) + Ok(input.into_pipeline_data_with_metadata( + head, + engine_state.ctrlc.clone(), + metadata, + )) } _ => Err(ShellError::IncorrectValue { msg: "Expected either --datasource-ls(-l) or --datasource-filepath(-f)".to_string(), diff --git a/crates/nu-command/src/env/config/config_env.rs b/crates/nu-command/src/env/config/config_env.rs index 2bcb3bc175..3c8dff487e 100644 --- a/crates/nu-command/src/env/config/config_env.rs +++ b/crates/nu-command/src/env/config/config_env.rs @@ -57,7 +57,7 @@ impl Command for ConfigEnv { let env_vars_str = env_to_strings(engine_state, stack)?; let nu_config = match engine_state.get_config_path("env-path") { - Some(path) => path.clone(), + Some(path) => path, None => { return Err(ShellError::GenericError { error: "Could not find $nu.env-path".into(), diff --git a/crates/nu-command/src/env/config/config_nu.rs b/crates/nu-command/src/env/config/config_nu.rs index 835926fa84..c43d8d0726 100644 --- a/crates/nu-command/src/env/config/config_nu.rs +++ b/crates/nu-command/src/env/config/config_nu.rs @@ -61,7 +61,7 @@ impl Command for ConfigNu { let env_vars_str = env_to_strings(engine_state, stack)?; let nu_config = match engine_state.get_config_path("config-path") { - Some(path) => path.clone(), + Some(path) => path, None => { return Err(ShellError::GenericError { error: "Could not find $nu.config-path".into(), diff --git a/crates/nu-command/src/env/config/utils.rs b/crates/nu-command/src/env/config/utils.rs index 63a323af7b..4b3ea43483 100644 --- a/crates/nu-command/src/env/config/utils.rs +++ b/crates/nu-command/src/env/config/utils.rs @@ -1,10 +1,10 @@ use crate::ExternalCommand; use nu_protocol::{OutDest, Span, Spanned}; -use std::{collections::HashMap, path::PathBuf}; +use std::{collections::HashMap, path::Path}; pub(crate) fn gen_command( span: Span, - config_path: PathBuf, + config_path: &Path, item: String, config_args: Vec, env_vars_str: HashMap, diff --git a/crates/nu-command/src/filesystem/cd.rs b/crates/nu-command/src/filesystem/cd.rs index 50ad0b35a1..f90e9bfd2a 100644 --- a/crates/nu-command/src/filesystem/cd.rs +++ b/crates/nu-command/src/filesystem/cd.rs @@ -100,6 +100,9 @@ impl Command for Cd { } }; + // Strip the trailing slash from the new path. This is required for PWD. + let path = nu_path::strip_trailing_slash(&path); + // Set OLDPWD. // We're using `Stack::get_env_var()` instead of `EngineState::cwd()` to avoid a conversion roundtrip. if let Some(oldpwd) = stack.get_env_var(engine_state, "PWD") { diff --git a/crates/nu-command/src/filesystem/du.rs b/crates/nu-command/src/filesystem/du.rs index adf648f732..c48a1f7ac1 100644 --- a/crates/nu-command/src/filesystem/du.rs +++ b/crates/nu-command/src/filesystem/du.rs @@ -121,7 +121,7 @@ impl Command for Du { }; Ok( du_for_one_pattern(args, ¤t_dir, tag, engine_state.ctrlc.clone())? - .into_pipeline_data(engine_state.ctrlc.clone()), + .into_pipeline_data(tag, engine_state.ctrlc.clone()), ) } Some(paths) => { @@ -147,7 +147,7 @@ impl Command for Du { Ok(result_iters .into_iter() .flatten() - .into_pipeline_data(engine_state.ctrlc.clone())) + .into_pipeline_data(tag, engine_state.ctrlc.clone())) } } } diff --git a/crates/nu-command/src/filesystem/glob.rs b/crates/nu-command/src/filesystem/glob.rs index 909dc36837..c5f4bc08b4 100644 --- a/crates/nu-command/src/filesystem/glob.rs +++ b/crates/nu-command/src/filesystem/glob.rs @@ -199,7 +199,7 @@ impl Command for Glob { } }; - Ok(if !not_patterns.is_empty() { + let result = if !not_patterns.is_empty() { let np: Vec<&str> = not_patterns.iter().map(|s| s as &str).collect(); let glob_results = glob .walk_with_behavior( @@ -218,10 +218,7 @@ impl Command for Glob { inner: vec![], })? .flatten(); - let result = glob_to_value(ctrlc, glob_results, no_dirs, no_files, no_symlinks, span)?; - result - .into_iter() - .into_pipeline_data(engine_state.ctrlc.clone()) + glob_to_value(ctrlc, glob_results, no_dirs, no_files, no_symlinks, span) } else { let glob_results = glob .walk_with_behavior( @@ -232,11 +229,12 @@ impl Command for Glob { }, ) .flatten(); - let result = glob_to_value(ctrlc, glob_results, no_dirs, no_files, no_symlinks, span)?; - result - .into_iter() - .into_pipeline_data(engine_state.ctrlc.clone()) - }) + glob_to_value(ctrlc, glob_results, no_dirs, no_files, no_symlinks, span) + }?; + + Ok(result + .into_iter() + .into_pipeline_data(span, engine_state.ctrlc.clone())) } } diff --git a/crates/nu-command/src/filesystem/ls.rs b/crates/nu-command/src/filesystem/ls.rs index 9d8db0a8c6..dd1b9770d2 100644 --- a/crates/nu-command/src/filesystem/ls.rs +++ b/crates/nu-command/src/filesystem/ls.rs @@ -115,10 +115,11 @@ impl Command for Ls { match input_pattern_arg { None => Ok(ls_for_one_pattern(None, args, ctrl_c.clone(), cwd)? .into_pipeline_data_with_metadata( + call_span, + ctrl_c, PipelineMetadata { data_source: DataSource::Ls, }, - ctrl_c, )), Some(pattern) => { let mut result_iters = vec![]; @@ -137,10 +138,11 @@ impl Command for Ls { .into_iter() .flatten() .into_pipeline_data_with_metadata( + call_span, + ctrl_c, PipelineMetadata { data_source: DataSource::Ls, }, - ctrl_c, )) } } diff --git a/crates/nu-command/src/filesystem/open.rs b/crates/nu-command/src/filesystem/open.rs index 63b6aa8f04..23664bb576 100644 --- a/crates/nu-command/src/filesystem/open.rs +++ b/crates/nu-command/src/filesystem/open.rs @@ -209,7 +209,10 @@ impl Command for Open { } else if output.len() == 1 { Ok(output.remove(0)) } else { - Ok(output.into_iter().flatten().into_pipeline_data(ctrlc)) + Ok(output + .into_iter() + .flatten() + .into_pipeline_data(call_span, ctrlc)) } } diff --git a/crates/nu-command/src/filesystem/rm.rs b/crates/nu-command/src/filesystem/rm.rs index fe14253982..9b9e88b5ff 100644 --- a/crates/nu-command/src/filesystem/rm.rs +++ b/crates/nu-command/src/filesystem/rm.rs @@ -465,7 +465,7 @@ fn rm( } }) .filter(|x| !matches!(x.get_type(), Type::Nothing)) - .into_pipeline_data(ctrlc) + .into_pipeline_data(span, ctrlc) .print_not_formatted(engine_state, false, true)?; Ok(PipelineData::empty()) diff --git a/crates/nu-command/src/filters/append.rs b/crates/nu-command/src/filters/append.rs index 2ad5c2dbe4..af5bd49283 100644 --- a/crates/nu-command/src/filters/append.rs +++ b/crates/nu-command/src/filters/append.rs @@ -116,7 +116,7 @@ only unwrap the outer list, and leave the variable's contents untouched."# Ok(input .into_iter() .chain(other.into_pipeline_data()) - .into_pipeline_data_with_metadata(metadata, engine_state.ctrlc.clone())) + .into_pipeline_data_with_metadata(call.head, engine_state.ctrlc.clone(), metadata)) } } diff --git a/crates/nu-command/src/filters/columns.rs b/crates/nu-command/src/filters/columns.rs index 165e881dd6..67c5fe98bd 100644 --- a/crates/nu-command/src/filters/columns.rs +++ b/crates/nu-command/src/filters/columns.rs @@ -62,72 +62,67 @@ impl Command for Columns { fn run( &self, - engine_state: &EngineState, + _engine_state: &EngineState, _stack: &mut Stack, call: &Call, input: PipelineData, ) -> Result { - let span = call.head; - getcol(engine_state, span, input) + getcol(call.head, input) } } -fn getcol( - engine_state: &EngineState, - head: Span, - input: PipelineData, -) -> Result { - let ctrlc = engine_state.ctrlc.clone(); +fn getcol(head: Span, input: PipelineData) -> Result { let metadata = input.metadata(); match input { PipelineData::Empty => Ok(PipelineData::Empty), PipelineData::Value(v, ..) => { let span = v.span(); - match v { + let cols = match v { Value::List { vals: input_vals, .. - } => { - let input_cols = get_columns(&input_vals); - Ok(input_cols - .into_iter() - .map(move |x| Value::string(x, span)) - .into_pipeline_data(ctrlc) - .set_metadata(metadata)) - } + } => get_columns(&input_vals) + .into_iter() + .map(move |x| Value::string(x, span)) + .collect(), Value::Custom { val, .. } => { // TODO: should we get CustomValue to expose columns in a more efficient way? // Would be nice to be able to get columns without generating the whole value let input_as_base_value = val.to_base_value(span)?; - let input_cols = get_columns(&[input_as_base_value]); - Ok(input_cols + get_columns(&[input_as_base_value]) .into_iter() .map(move |x| Value::string(x, span)) - .into_pipeline_data(ctrlc) - .set_metadata(metadata)) + .collect() } - Value::Record { val, .. } => Ok(val + Value::Record { val, .. } => val .into_iter() .map(move |(x, _)| Value::string(x, head)) - .into_pipeline_data(ctrlc) - .set_metadata(metadata)), + .collect(), // Propagate errors - Value::Error { error, .. } => Err(*error), - other => Err(ShellError::OnlySupportsThisInputType { - exp_input_type: "record or table".into(), - wrong_type: other.get_type().to_string(), - dst_span: head, - src_span: other.span(), - }), - } + Value::Error { error, .. } => return Err(*error), + other => { + return Err(ShellError::OnlySupportsThisInputType { + exp_input_type: "record or table".into(), + wrong_type: other.get_type().to_string(), + dst_span: head, + src_span: other.span(), + }) + } + }; + + Ok(Value::list(cols, head) + .into_pipeline_data() + .set_metadata(metadata)) } PipelineData::ListStream(stream, ..) => { - let v: Vec<_> = stream.into_iter().collect(); - let input_cols = get_columns(&v); - - Ok(input_cols + let values = stream.into_iter().collect::>(); + let cols = get_columns(&values) .into_iter() - .map(move |x| Value::string(x, head)) - .into_pipeline_data_with_metadata(metadata, ctrlc)) + .map(|s| Value::string(s, head)) + .collect(); + + Ok(Value::list(cols, head) + .into_pipeline_data() + .set_metadata(metadata)) } PipelineData::ExternalStream { .. } => Err(ShellError::OnlySupportsThisInputType { exp_input_type: "record or table".into(), diff --git a/crates/nu-command/src/filters/drop/column.rs b/crates/nu-command/src/filters/drop/column.rs index 436fa953a4..689a335923 100644 --- a/crates/nu-command/src/filters/drop/column.rs +++ b/crates/nu-command/src/filters/drop/column.rs @@ -90,7 +90,8 @@ fn drop_cols( // is displayed farther to the right. let metadata = input.metadata(); match input { - PipelineData::ListStream(mut stream, ..) => { + PipelineData::ListStream(stream, ..) => { + let mut stream = stream.into_iter(); if let Some(mut first) = stream.next() { let drop_cols = drop_cols_set(&mut first, head, columns)?; @@ -101,7 +102,7 @@ fn drop_cols( Err(e) => Value::error(e, head), } })) - .into_pipeline_data_with_metadata(metadata, engine_state.ctrlc.clone())) + .into_pipeline_data_with_metadata(head, engine_state.ctrlc.clone(), metadata)) } else { Ok(PipelineData::Empty) } diff --git a/crates/nu-command/src/filters/drop/nth.rs b/crates/nu-command/src/filters/drop/nth.rs index b0858b19cc..a530de5aa1 100644 --- a/crates/nu-command/src/filters/drop/nth.rs +++ b/crates/nu-command/src/filters/drop/nth.rs @@ -100,6 +100,7 @@ impl Command for DropNth { call: &Call, input: PipelineData, ) -> Result { + let head = call.head; let metadata = input.metadata(); let number_or_range = extract_int_or_range(engine_state, stack, call)?; @@ -115,7 +116,7 @@ impl Command for DropNth { return Err(ShellError::UnsupportedInput { msg: "float range".into(), input: "value originates from here".into(), - msg_span: call.head, + msg_span: head, input_span: number_or_range.span, }); } @@ -129,7 +130,7 @@ impl Command for DropNth { return Err(ShellError::UnsupportedInput { msg: "drop nth accepts only positive ints".into(), input: "value originates from here".into(), - msg_span: call.head, + msg_span: head, input_span: number_or_range.span, }); } @@ -139,7 +140,7 @@ impl Command for DropNth { msg: "The upper bound needs to be equal or larger to the lower bound" .into(), input: "value originates from here".into(), - msg_span: call.head, + msg_span: head, input_span: number_or_range.span, }); } @@ -154,8 +155,9 @@ impl Command for DropNth { .into_iter() .take(start) .into_pipeline_data_with_metadata( - metadata, + head, engine_state.ctrlc.clone(), + metadata, )) } }; @@ -175,7 +177,7 @@ impl Command for DropNth { rows, current: 0, } - .into_pipeline_data_with_metadata(metadata, engine_state.ctrlc.clone())) + .into_pipeline_data_with_metadata(head, engine_state.ctrlc.clone(), metadata)) } } diff --git a/crates/nu-command/src/filters/each.rs b/crates/nu-command/src/filters/each.rs index d0267b1fce..65d61fd3a8 100644 --- a/crates/nu-command/src/filters/each.rs +++ b/crates/nu-command/src/filters/each.rs @@ -138,7 +138,7 @@ with 'transpose' first."# } } }) - .into_pipeline_data(engine_state.ctrlc.clone())) + .into_pipeline_data(head, engine_state.ctrlc.clone())) } PipelineData::ExternalStream { stdout: None, .. } => Ok(PipelineData::empty()), PipelineData::ExternalStream { @@ -170,7 +170,7 @@ with 'transpose' first."# } } }) - .into_pipeline_data(engine_state.ctrlc.clone())) + .into_pipeline_data(head, engine_state.ctrlc.clone())) } // This match allows non-iterables to be accepted, // which is currently considered undesirable (Nov 2022). diff --git a/crates/nu-command/src/filters/empty.rs b/crates/nu-command/src/filters/empty.rs index e75700f26d..fd55921414 100644 --- a/crates/nu-command/src/filters/empty.rs +++ b/crates/nu-command/src/filters/empty.rs @@ -60,10 +60,11 @@ pub fn empty( } }, PipelineData::ListStream(s, ..) => { + let empty = s.into_iter().next().is_none(); if negate { - Ok(Value::bool(s.count() != 0, head).into_pipeline_data()) + Ok(Value::bool(!empty, head).into_pipeline_data()) } else { - Ok(Value::bool(s.count() == 0, head).into_pipeline_data()) + Ok(Value::bool(empty, head).into_pipeline_data()) } } PipelineData::Value(value, ..) => { diff --git a/crates/nu-command/src/filters/enumerate.rs b/crates/nu-command/src/filters/enumerate.rs index e46c873c4b..1034780657 100644 --- a/crates/nu-command/src/filters/enumerate.rs +++ b/crates/nu-command/src/filters/enumerate.rs @@ -50,9 +50,9 @@ impl Command for Enumerate { call: &Call, input: PipelineData, ) -> Result { + let head = call.head; let metadata = input.metadata(); let ctrlc = engine_state.ctrlc.clone(); - let span = call.head; Ok(input .into_iter() @@ -60,13 +60,13 @@ impl Command for Enumerate { .map(move |(idx, x)| { Value::record( record! { - "index" => Value::int(idx as i64, span), + "index" => Value::int(idx as i64, head), "item" => x, }, - span, + head, ) }) - .into_pipeline_data_with_metadata(metadata, ctrlc)) + .into_pipeline_data_with_metadata(head, ctrlc, metadata)) } } diff --git a/crates/nu-command/src/filters/every.rs b/crates/nu-command/src/filters/every.rs index a7fc4f1b02..1202b4f7c9 100644 --- a/crates/nu-command/src/filters/every.rs +++ b/crates/nu-command/src/filters/every.rs @@ -78,7 +78,7 @@ impl Command for Every { None } }) - .into_pipeline_data_with_metadata(metadata, engine_state.ctrlc.clone())) + .into_pipeline_data_with_metadata(call.head, engine_state.ctrlc.clone(), metadata)) } } diff --git a/crates/nu-command/src/filters/filter.rs b/crates/nu-command/src/filters/filter.rs index 7fe936b4f4..b158dd3be3 100644 --- a/crates/nu-command/src/filters/filter.rs +++ b/crates/nu-command/src/filters/filter.rs @@ -67,7 +67,7 @@ a variable. On the other hand, the "row condition" syntax is not supported."# Some(Value::error(err, span)) } }) - .into_pipeline_data(engine_state.ctrlc.clone())) + .into_pipeline_data(head, engine_state.ctrlc.clone())) } PipelineData::ExternalStream { stdout: None, .. } => Ok(PipelineData::empty()), PipelineData::ExternalStream { @@ -92,7 +92,7 @@ a variable. On the other hand, the "row condition" syntax is not supported."# } } }) - .into_pipeline_data(engine_state.ctrlc.clone())) + .into_pipeline_data(head, engine_state.ctrlc.clone())) } // This match allows non-iterables to be accepted, // which is currently considered undesirable (Nov 2022). @@ -108,7 +108,7 @@ a variable. On the other hand, the "row condition" syntax is not supported."# Some(Value::error(err, span)) } } - .into_pipeline_data(engine_state.ctrlc.clone())) + .into_pipeline_data(head, engine_state.ctrlc.clone())) } } .map(|data| data.set_metadata(metadata)) diff --git a/crates/nu-command/src/filters/find.rs b/crates/nu-command/src/filters/find.rs index 6efda0d836..b45fe8d810 100644 --- a/crates/nu-command/src/filters/find.rs +++ b/crates/nu-command/src/filters/find.rs @@ -3,7 +3,7 @@ use fancy_regex::Regex; use nu_ansi_term::Style; use nu_color_config::StyleComputer; use nu_engine::command_prelude::*; -use nu_protocol::{Config, ListStream}; +use nu_protocol::Config; use nu_utils::IgnoreCaseExt; #[derive(Clone)] @@ -416,9 +416,9 @@ fn find_with_rest_and_highlight( }, ctrlc, ), - PipelineData::ListStream(stream, metadata) => Ok(ListStream::from_stream( - stream - .map(move |mut x| { + PipelineData::ListStream(stream, metadata) => { + let stream = stream.modify(|iter| { + iter.map(move |mut x| { let span = x.span(); match &mut x { Value::Record { val, .. } => highlight_terms_in_record_with_search_columns( @@ -442,10 +442,11 @@ fn find_with_rest_and_highlight( &cols_to_search_in_filter, invert, ) - }), - ctrlc.clone(), - ) - .into_pipeline_data_with_metadata(metadata, ctrlc)), + }) + }); + + Ok(PipelineData::ListStream(stream, metadata)) + } PipelineData::ExternalStream { stdout: None, .. } => Ok(PipelineData::empty()), PipelineData::ExternalStream { stdout: Some(stream), @@ -496,7 +497,7 @@ fn find_with_rest_and_highlight( Err(e) => return Err(e), }; } - Ok(output.into_pipeline_data(ctrlc)) + Ok(output.into_pipeline_data(span, ctrlc)) } } } diff --git a/crates/nu-command/src/filters/first.rs b/crates/nu-command/src/filters/first.rs index eabd370858..1bc51f2562 100644 --- a/crates/nu-command/src/filters/first.rs +++ b/crates/nu-command/src/filters/first.rs @@ -143,7 +143,7 @@ fn first_helper( } else { Ok(iter .take(rows) - .into_pipeline_data_with_metadata(metadata, ctrlc)) + .into_pipeline_data_with_metadata(span, ctrlc, metadata)) } } // Propagate errors by explicitly matching them before the final case. @@ -156,17 +156,18 @@ fn first_helper( }), } } - PipelineData::ListStream(mut ls, metadata) => { + PipelineData::ListStream(stream, metadata) => { if return_single_element { - if let Some(v) = ls.next() { + if let Some(v) = stream.into_iter().next() { Ok(v.into_pipeline_data()) } else { Err(ShellError::AccessEmptyContent { span: head }) } } else { - Ok(ls - .take(rows) - .into_pipeline_data_with_metadata(metadata, engine_state.ctrlc.clone())) + Ok(PipelineData::ListStream( + stream.modify(|iter| iter.take(rows)), + metadata, + )) } } PipelineData::ExternalStream { span, .. } => Err(ShellError::OnlySupportsThisInputType { diff --git a/crates/nu-command/src/filters/get.rs b/crates/nu-command/src/filters/get.rs index 5772ec2f11..c6232b80fc 100644 --- a/crates/nu-command/src/filters/get.rs +++ b/crates/nu-command/src/filters/get.rs @@ -89,7 +89,7 @@ If multiple cell paths are given, this will produce a list of values."# output.push(val?); } - Ok(output.into_iter().into_pipeline_data(ctrlc)) + Ok(output.into_iter().into_pipeline_data(span, ctrlc)) } .map(|x| x.set_metadata(metadata)) } diff --git a/crates/nu-command/src/filters/group.rs b/crates/nu-command/src/filters/group.rs index 196d2f79c8..821f35f34e 100644 --- a/crates/nu-command/src/filters/group.rs +++ b/crates/nu-command/src/filters/group.rs @@ -1,4 +1,5 @@ use nu_engine::command_prelude::*; +use nu_protocol::ValueIterator; #[derive(Clone)] pub struct Group; @@ -52,6 +53,7 @@ impl Command for Group { call: &Call, input: PipelineData, ) -> Result { + let head = call.head; let group_size: Spanned = call.req(engine_state, stack, 0)?; let ctrlc = engine_state.ctrlc.clone(); let metadata = input.metadata(); @@ -61,16 +63,16 @@ impl Command for Group { let each_group_iterator = EachGroupIterator { group_size: group_size.item, input: Box::new(input.into_iter()), - span: call.head, + span: head, }; - Ok(each_group_iterator.into_pipeline_data_with_metadata(metadata, ctrlc)) + Ok(each_group_iterator.into_pipeline_data_with_metadata(head, ctrlc, metadata)) } } struct EachGroupIterator { group_size: usize, - input: Box + Send>, + input: ValueIterator, span: Span, } diff --git a/crates/nu-command/src/filters/insert.rs b/crates/nu-command/src/filters/insert.rs index 7814bcdb83..c87a2a78b9 100644 --- a/crates/nu-command/src/filters/insert.rs +++ b/crates/nu-command/src/filters/insert.rs @@ -159,7 +159,7 @@ fn insert( } Ok(value.into_pipeline_data_with_metadata(metadata)) } - PipelineData::ListStream(mut stream, metadata) => { + PipelineData::ListStream(stream, metadata) => { if let Some(( &PathMember::Int { val, @@ -169,6 +169,7 @@ fn insert( path, )) = cell_path.members.split_first() { + let mut stream = stream.into_iter(); let mut pre_elems = vec![]; for idx in 0..val { @@ -221,40 +222,39 @@ fn insert( Ok(pre_elems .into_iter() .chain(stream) - .into_pipeline_data_with_metadata(metadata, engine_state.ctrlc.clone())) + .into_pipeline_data_with_metadata(head, engine_state.ctrlc.clone(), metadata)) } else if let Value::Closure { val, .. } = replacement { let mut closure = ClosureEval::new(engine_state, stack, val); - Ok(stream - .map(move |mut value| { - let err = insert_value_by_closure( - &mut value, - &mut closure, - head, - &cell_path.members, - false, - ); + let stream = stream.map(move |mut value| { + let err = insert_value_by_closure( + &mut value, + &mut closure, + head, + &cell_path.members, + false, + ); - if let Err(e) = err { - Value::error(e, head) - } else { - value - } - }) - .into_pipeline_data_with_metadata(metadata, engine_state.ctrlc.clone())) + if let Err(e) = err { + Value::error(e, head) + } else { + value + } + }); + Ok(PipelineData::ListStream(stream, metadata)) } else { - Ok(stream - .map(move |mut value| { - if let Err(e) = value.insert_data_at_cell_path( - &cell_path.members, - replacement.clone(), - head, - ) { - Value::error(e, head) - } else { - value - } - }) - .into_pipeline_data_with_metadata(metadata, engine_state.ctrlc.clone())) + let stream = stream.map(move |mut value| { + if let Err(e) = value.insert_data_at_cell_path( + &cell_path.members, + replacement.clone(), + head, + ) { + Value::error(e, head) + } else { + value + } + }); + + Ok(PipelineData::ListStream(stream, metadata)) } } PipelineData::Empty => Err(ShellError::IncompatiblePathAccess { diff --git a/crates/nu-command/src/filters/interleave.rs b/crates/nu-command/src/filters/interleave.rs index 3365b108db..85a92741a1 100644 --- a/crates/nu-command/src/filters/interleave.rs +++ b/crates/nu-command/src/filters/interleave.rs @@ -147,7 +147,7 @@ interleave // Now that threads are writing to the channel, we just return it as a stream Ok(rx .into_iter() - .into_pipeline_data(engine_state.ctrlc.clone())) + .into_pipeline_data(head, engine_state.ctrlc.clone())) } } diff --git a/crates/nu-command/src/filters/items.rs b/crates/nu-command/src/filters/items.rs index 179043a1fb..490477d965 100644 --- a/crates/nu-command/src/filters/items.rs +++ b/crates/nu-command/src/filters/items.rs @@ -65,7 +65,7 @@ impl Command for Items { } } }) - .into_pipeline_data(engine_state.ctrlc.clone())) + .into_pipeline_data(head, engine_state.ctrlc.clone())) } Value::Error { error, .. } => Err(*error), other => Err(ShellError::OnlySupportsThisInputType { diff --git a/crates/nu-command/src/filters/lines.rs b/crates/nu-command/src/filters/lines.rs index 0a07378afb..e3e0f5d9fd 100644 --- a/crates/nu-command/src/filters/lines.rs +++ b/crates/nu-command/src/filters/lines.rs @@ -52,9 +52,8 @@ impl Command for Lines { } PipelineData::Empty => Ok(PipelineData::Empty), PipelineData::ListStream(stream, metadata) => { - let iter = stream - .into_iter() - .filter_map(move |value| { + let stream = stream.modify(|iter| { + iter.filter_map(move |value| { let span = value.span(); if let Value::String { val, .. } = value { Some( @@ -72,11 +71,10 @@ impl Command for Lines { None } }) - .flatten(); + .flatten() + }); - Ok(iter - .into_pipeline_data(engine_state.ctrlc.clone()) - .set_metadata(metadata)) + Ok(PipelineData::ListStream(stream, metadata)) } PipelineData::Value(val, ..) => { match val { @@ -97,7 +95,7 @@ impl Command for Lines { .. } => Ok(RawStreamLinesAdapter::new(stream, head, skip_empty) .map(move |x| x.unwrap_or_else(|err| Value::error(err, head))) - .into_pipeline_data(ctrlc) + .into_pipeline_data(head, ctrlc) .set_metadata(metadata)), } } diff --git a/crates/nu-command/src/filters/merge.rs b/crates/nu-command/src/filters/merge.rs index 5af331bf0c..8a3e613c56 100644 --- a/crates/nu-command/src/filters/merge.rs +++ b/crates/nu-command/src/filters/merge.rs @@ -85,11 +85,10 @@ repeating this process with row 1, and so on."# call: &Call, input: PipelineData, ) -> Result { + let head = call.head; let merge_value: Value = call.req(engine_state, stack, 0)?; - let metadata = input.metadata(); let ctrlc = engine_state.ctrlc.clone(); - let call = call.clone(); match (&input, merge_value) { // table (list of records) @@ -104,29 +103,25 @@ repeating this process with row 1, and so on."# .into_iter() .map(move |inp| match (inp.as_record(), table_iter.next()) { (Ok(inp), Some(to_merge)) => match to_merge.as_record() { - Ok(to_merge) => Value::record(do_merge(inp, to_merge), call.head), - Err(error) => Value::error(error, call.head), + Ok(to_merge) => Value::record(do_merge(inp, to_merge), head), + Err(error) => Value::error(error, head), }, (_, None) => inp, - (Err(error), _) => Value::error(error, call.head), + (Err(error), _) => Value::error(error, head), }); - if let Some(md) = metadata { - Ok(res.into_pipeline_data_with_metadata(md, ctrlc)) - } else { - Ok(res.into_pipeline_data(ctrlc)) - } + Ok(res.into_pipeline_data_with_metadata(head, ctrlc, metadata)) } // record ( PipelineData::Value(Value::Record { val: inp, .. }, ..), Value::Record { val: to_merge, .. }, - ) => Ok(Value::record(do_merge(inp, &to_merge), call.head).into_pipeline_data()), + ) => Ok(Value::record(do_merge(inp, &to_merge), head).into_pipeline_data()), (PipelineData::Value(val, ..), ..) => { // Only point the "value originates here" arrow at the merge value // if it was generated from a block. Otherwise, point at the pipeline value. -Leon 2022-10-27 let span = if val.span() == Span::test_data() { - Span::new(call.head.start, call.head.start) + Span::new(head.start, head.start) } else { val.span() }; @@ -134,14 +129,14 @@ repeating this process with row 1, and so on."# Err(ShellError::PipelineMismatch { exp_input_type: "input, and argument, to be both record or both table" .to_string(), - dst_span: call.head, + dst_span: head, src_span: span, }) } _ => Err(ShellError::PipelineMismatch { exp_input_type: "input, and argument, to be both record or both table".to_string(), - dst_span: call.head, - src_span: Span::new(call.head.start, call.head.start), + dst_span: head, + src_span: Span::new(head.start, head.start), }), } } diff --git a/crates/nu-command/src/filters/move_.rs b/crates/nu-command/src/filters/move_.rs index ab2f8c55cd..d93368f291 100644 --- a/crates/nu-command/src/filters/move_.rs +++ b/crates/nu-command/src/filters/move_.rs @@ -109,6 +109,7 @@ impl Command for Move { call: &Call, input: PipelineData, ) -> Result { + let head = call.head; let columns: Vec = call.rest(engine_state, stack, 0)?; let after: Option = call.get_flag(engine_state, stack, "after")?; let before: Option = call.get_flag(engine_state, stack, "before")?; @@ -126,7 +127,7 @@ impl Command for Move { return Err(ShellError::GenericError { error: "Cannot move columns".into(), msg: "Use either --after, or --before, not both".into(), - span: Some(call.head), + span: Some(head), help: None, inner: vec![], }) @@ -135,7 +136,7 @@ impl Command for Move { return Err(ShellError::GenericError { error: "Cannot move columns".into(), msg: "Missing --after or --before flag".into(), - span: Some(call.head), + span: Some(head), help: None, inner: vec![], }) @@ -144,36 +145,29 @@ impl Command for Move { let metadata = input.metadata(); let ctrlc = engine_state.ctrlc.clone(); - let call = call.clone(); match input { PipelineData::Value(Value::List { .. }, ..) | PipelineData::ListStream { .. } => { let res = input.into_iter().map(move |x| match x.as_record() { Ok(record) => { - match move_record_columns(record, &columns, &before_or_after, call.head) { + match move_record_columns(record, &columns, &before_or_after, head) { Ok(val) => val, - Err(error) => Value::error(error, call.head), + Err(error) => Value::error(error, head), } } - Err(error) => Value::error(error, call.head), + Err(error) => Value::error(error, head), }); - if let Some(md) = metadata { - Ok(res.into_pipeline_data_with_metadata(md, ctrlc)) - } else { - Ok(res.into_pipeline_data(ctrlc)) - } + Ok(res.into_pipeline_data_with_metadata(head, ctrlc, metadata)) } PipelineData::Value(Value::Record { val, .. }, ..) => { - Ok( - move_record_columns(&val, &columns, &before_or_after, call.head)? - .into_pipeline_data(), - ) + Ok(move_record_columns(&val, &columns, &before_or_after, head)? + .into_pipeline_data()) } _ => Err(ShellError::PipelineMismatch { exp_input_type: "record or table".to_string(), - dst_span: call.head, - src_span: Span::new(call.head.start, call.head.start), + dst_span: head, + src_span: Span::new(head.start, head.start), }), } } diff --git a/crates/nu-command/src/filters/par_each.rs b/crates/nu-command/src/filters/par_each.rs index 4f0a07b300..52c3024270 100644 --- a/crates/nu-command/src/filters/par_each.rs +++ b/crates/nu-command/src/filters/par_each.rs @@ -159,7 +159,7 @@ impl Command for ParEach { }) .collect::>(); - apply_order(vec).into_pipeline_data(engine_state.ctrlc.clone()) + apply_order(vec).into_pipeline_data(span, engine_state.ctrlc.clone()) })), Value::Range { val, .. } => Ok(create_pool(max_threads)?.install(|| { let ctrlc = engine_state.ctrlc.clone(); @@ -186,7 +186,7 @@ impl Command for ParEach { }) .collect::>(); - apply_order(vec).into_pipeline_data(ctrlc) + apply_order(vec).into_pipeline_data(span, ctrlc) })), // This match allows non-iterables to be accepted, // which is currently considered undesirable (Nov 2022). @@ -197,6 +197,7 @@ impl Command for ParEach { } PipelineData::ListStream(stream, ..) => Ok(create_pool(max_threads)?.install(|| { let vec = stream + .into_iter() .enumerate() .par_bridge() .map(move |(index, value)| { @@ -216,7 +217,7 @@ impl Command for ParEach { }) .collect::>(); - apply_order(vec).into_pipeline_data(engine_state.ctrlc.clone()) + apply_order(vec).into_pipeline_data(head, engine_state.ctrlc.clone()) })), PipelineData::ExternalStream { stdout: None, .. } => Ok(PipelineData::empty()), PipelineData::ExternalStream { @@ -241,7 +242,7 @@ impl Command for ParEach { }) .collect::>(); - apply_order(vec).into_pipeline_data(engine_state.ctrlc.clone()) + apply_order(vec).into_pipeline_data(head, engine_state.ctrlc.clone()) })), } .and_then(|x| x.filter(|v| !v.is_nothing(), engine_state.ctrlc.clone())) diff --git a/crates/nu-command/src/filters/prepend.rs b/crates/nu-command/src/filters/prepend.rs index cef8ce8c1a..f017420595 100644 --- a/crates/nu-command/src/filters/prepend.rs +++ b/crates/nu-command/src/filters/prepend.rs @@ -117,7 +117,7 @@ only unwrap the outer list, and leave the variable's contents untouched."# .into_pipeline_data() .into_iter() .chain(input) - .into_pipeline_data_with_metadata(metadata, engine_state.ctrlc.clone())) + .into_pipeline_data_with_metadata(call.head, engine_state.ctrlc.clone(), metadata)) } } diff --git a/crates/nu-command/src/filters/range.rs b/crates/nu-command/src/filters/range.rs index 08d1c0fe42..c89a0b11f2 100644 --- a/crates/nu-command/src/filters/range.rs +++ b/crates/nu-command/src/filters/range.rs @@ -64,6 +64,7 @@ impl Command for Range { call: &Call, input: PipelineData, ) -> Result { + let head = call.head; let metadata = input.metadata(); let rows: Spanned = call.req(engine_state, stack, 0)?; @@ -102,20 +103,20 @@ impl Command for Range { }; if from > to { - Ok(PipelineData::Value(Value::nothing(call.head), None)) + Ok(PipelineData::Value(Value::nothing(head), None)) } else { let iter = v.into_iter().skip(from).take(to - from + 1); - Ok(iter.into_pipeline_data(engine_state.ctrlc.clone())) + Ok(iter.into_pipeline_data(head, engine_state.ctrlc.clone())) } } else { let from = start as usize; let to = end as usize; if from > to { - Ok(PipelineData::Value(Value::nothing(call.head), None)) + Ok(PipelineData::Value(Value::nothing(head), None)) } else { let iter = input.into_iter().skip(from).take(to - from + 1); - Ok(iter.into_pipeline_data(engine_state.ctrlc.clone())) + Ok(iter.into_pipeline_data(head, engine_state.ctrlc.clone())) } } .map(|x| x.set_metadata(metadata)) diff --git a/crates/nu-command/src/filters/reverse.rs b/crates/nu-command/src/filters/reverse.rs index db39ee3bd5..f40e5f3be4 100644 --- a/crates/nu-command/src/filters/reverse.rs +++ b/crates/nu-command/src/filters/reverse.rs @@ -59,11 +59,11 @@ impl Command for Reverse { call: &Call, input: PipelineData, ) -> Result { + let head = call.head; let metadata = input.metadata(); - - let v: Vec<_> = input.into_iter_strict(call.head)?.collect(); - let iter = v.into_iter().rev(); - Ok(iter.into_pipeline_data_with_metadata(metadata, engine_state.ctrlc.clone())) + let values = input.into_iter_strict(head)?.collect::>(); + let iter = values.into_iter().rev(); + Ok(iter.into_pipeline_data_with_metadata(head, engine_state.ctrlc.clone(), metadata)) } } diff --git a/crates/nu-command/src/filters/select.rs b/crates/nu-command/src/filters/select.rs index 5b8e9e0420..3514ac6be7 100644 --- a/crates/nu-command/src/filters/select.rs +++ b/crates/nu-command/src/filters/select.rs @@ -215,7 +215,7 @@ fn select( rows: unique_rows.into_iter().peekable(), current: 0, } - .into_pipeline_data_with_metadata(metadata, engine_state.ctrlc.clone()) + .into_pipeline_data_with_metadata(call_span, engine_state.ctrlc.clone(), metadata) } else { input }; @@ -253,9 +253,11 @@ fn select( } } - Ok(output - .into_iter() - .into_pipeline_data_with_metadata(metadata, engine_state.ctrlc.clone())) + Ok(output.into_iter().into_pipeline_data_with_metadata( + call_span, + engine_state.ctrlc.clone(), + metadata, + )) } _ => { if !columns.is_empty() { @@ -300,7 +302,11 @@ fn select( } } - Ok(values.into_pipeline_data_with_metadata(metadata, engine_state.ctrlc.clone())) + Ok(values.into_pipeline_data_with_metadata( + call_span, + engine_state.ctrlc.clone(), + metadata, + )) } _ => Ok(PipelineData::empty()), } diff --git a/crates/nu-command/src/filters/shuffle.rs b/crates/nu-command/src/filters/shuffle.rs index 598a292e5d..9e023b86c6 100644 --- a/crates/nu-command/src/filters/shuffle.rs +++ b/crates/nu-command/src/filters/shuffle.rs @@ -30,10 +30,10 @@ impl Command for Shuffle { input: PipelineData, ) -> Result { let metadata = input.metadata(); - let mut v: Vec<_> = input.into_iter_strict(call.head)?.collect(); - v.shuffle(&mut thread_rng()); - let iter = v.into_iter(); - Ok(iter.into_pipeline_data_with_metadata(metadata, engine_state.ctrlc.clone())) + let mut values = input.into_iter_strict(call.head)?.collect::>(); + values.shuffle(&mut thread_rng()); + let iter = values.into_iter(); + Ok(iter.into_pipeline_data_with_metadata(call.head, engine_state.ctrlc.clone(), metadata)) } fn examples(&self) -> Vec { diff --git a/crates/nu-command/src/filters/skip/skip_.rs b/crates/nu-command/src/filters/skip/skip_.rs index a76e2b706d..1919263aa3 100644 --- a/crates/nu-command/src/filters/skip/skip_.rs +++ b/crates/nu-command/src/filters/skip/skip_.rs @@ -101,7 +101,7 @@ impl Command for Skip { _ => Ok(input .into_iter_strict(call.head)? .skip(n) - .into_pipeline_data_with_metadata(metadata, ctrlc)), + .into_pipeline_data_with_metadata(input_span, ctrlc, metadata)), } } } diff --git a/crates/nu-command/src/filters/skip/skip_until.rs b/crates/nu-command/src/filters/skip/skip_until.rs index b0a4dd4cd9..74deeda84d 100644 --- a/crates/nu-command/src/filters/skip/skip_until.rs +++ b/crates/nu-command/src/filters/skip/skip_until.rs @@ -88,7 +88,7 @@ impl Command for SkipUntil { .map(|data| data.into_value(head).is_false()) .unwrap_or(false) }) - .into_pipeline_data_with_metadata(metadata, engine_state.ctrlc.clone())) + .into_pipeline_data_with_metadata(head, engine_state.ctrlc.clone(), metadata)) } } diff --git a/crates/nu-command/src/filters/skip/skip_while.rs b/crates/nu-command/src/filters/skip/skip_while.rs index d72bbcd6fc..a832d8f7b1 100644 --- a/crates/nu-command/src/filters/skip/skip_while.rs +++ b/crates/nu-command/src/filters/skip/skip_while.rs @@ -93,7 +93,7 @@ impl Command for SkipWhile { .map(|data| data.into_value(head).is_true()) .unwrap_or(false) }) - .into_pipeline_data_with_metadata(metadata, engine_state.ctrlc.clone())) + .into_pipeline_data_with_metadata(head, engine_state.ctrlc.clone(), metadata)) } } diff --git a/crates/nu-command/src/filters/sort.rs b/crates/nu-command/src/filters/sort.rs index d48901c9df..9feb925cce 100644 --- a/crates/nu-command/src/filters/sort.rs +++ b/crates/nu-command/src/filters/sort.rs @@ -134,10 +134,11 @@ impl Command for Sort { call: &Call, input: PipelineData, ) -> Result { + let head = call.head; let reverse = call.has_flag(engine_state, stack, "reverse")?; let insensitive = call.has_flag(engine_state, stack, "ignore-case")?; let natural = call.has_flag(engine_state, stack, "natural")?; - let metadata = &input.metadata(); + let metadata = input.metadata(); let span = input.span().unwrap_or(call.head); match input { @@ -156,18 +157,18 @@ impl Command for Sort { pipe_data => { let mut vec: Vec<_> = pipe_data.into_iter().collect(); - sort(&mut vec, call.head, insensitive, natural)?; + sort(&mut vec, head, insensitive, natural)?; if reverse { vec.reverse() } let iter = vec.into_iter(); - match metadata { - Some(m) => Ok(iter - .into_pipeline_data_with_metadata(m.clone(), engine_state.ctrlc.clone())), - None => Ok(iter.into_pipeline_data(engine_state.ctrlc.clone())), - } + Ok(iter.into_pipeline_data_with_metadata( + head, + engine_state.ctrlc.clone(), + metadata, + )) } } } diff --git a/crates/nu-command/src/filters/sort_by.rs b/crates/nu-command/src/filters/sort_by.rs index 66c1f2b03f..f3f715bc9d 100644 --- a/crates/nu-command/src/filters/sort_by.rs +++ b/crates/nu-command/src/filters/sort_by.rs @@ -78,33 +78,29 @@ impl Command for SortBy { call: &Call, input: PipelineData, ) -> Result { + let head = call.head; let columns: Vec = call.rest(engine_state, stack, 0)?; let reverse = call.has_flag(engine_state, stack, "reverse")?; let insensitive = call.has_flag(engine_state, stack, "ignore-case")?; let natural = call.has_flag(engine_state, stack, "natural")?; - let metadata = &input.metadata(); - let mut vec: Vec<_> = input.into_iter_strict(call.head)?.collect(); + let metadata = input.metadata(); + let mut vec: Vec<_> = input.into_iter_strict(head)?.collect(); if columns.is_empty() { return Err(ShellError::MissingParameter { param_name: "columns".into(), - span: call.head, + span: head, }); } - crate::sort(&mut vec, columns, call.head, insensitive, natural)?; + crate::sort(&mut vec, columns, head, insensitive, natural)?; if reverse { vec.reverse() } let iter = vec.into_iter(); - match metadata { - Some(m) => { - Ok(iter.into_pipeline_data_with_metadata(m.clone(), engine_state.ctrlc.clone())) - } - None => Ok(iter.into_pipeline_data(engine_state.ctrlc.clone())), - } + Ok(iter.into_pipeline_data_with_metadata(head, engine_state.ctrlc.clone(), metadata)) } } diff --git a/crates/nu-command/src/filters/take/take_.rs b/crates/nu-command/src/filters/take/take_.rs index a5ffe25301..01700420b8 100644 --- a/crates/nu-command/src/filters/take/take_.rs +++ b/crates/nu-command/src/filters/take/take_.rs @@ -42,6 +42,7 @@ impl Command for Take { call: &Call, input: PipelineData, ) -> Result { + let head = call.head; let rows_desired: usize = call.req(engine_state, stack, 0)?; let ctrlc = engine_state.ctrlc.clone(); @@ -54,7 +55,7 @@ impl Command for Take { Value::List { vals, .. } => Ok(vals .into_iter() .take(rows_desired) - .into_pipeline_data_with_metadata(metadata, ctrlc)), + .into_pipeline_data_with_metadata(head, ctrlc, metadata)), Value::Binary { val, .. } => { let slice: Vec = val.into_iter().take(rows_desired).collect(); Ok(PipelineData::Value(Value::binary(slice, span), metadata)) @@ -62,33 +63,34 @@ impl Command for Take { Value::Range { val, .. } => Ok(val .into_range_iter(span, ctrlc.clone()) .take(rows_desired) - .into_pipeline_data_with_metadata(metadata, ctrlc)), + .into_pipeline_data_with_metadata(head, ctrlc, metadata)), // Propagate errors by explicitly matching them before the final case. Value::Error { error, .. } => Err(*error), other => Err(ShellError::OnlySupportsThisInputType { exp_input_type: "list, binary or range".into(), wrong_type: other.get_type().to_string(), - dst_span: call.head, + dst_span: head, src_span: other.span(), }), } } - PipelineData::ListStream(ls, metadata) => Ok(ls - .take(rows_desired) - .into_pipeline_data_with_metadata(metadata, ctrlc)), + PipelineData::ListStream(stream, metadata) => Ok(PipelineData::ListStream( + stream.modify(|iter| iter.take(rows_desired)), + metadata, + )), PipelineData::ExternalStream { span, .. } => { Err(ShellError::OnlySupportsThisInputType { exp_input_type: "list, binary or range".into(), wrong_type: "raw data".into(), - dst_span: call.head, + dst_span: head, src_span: span, }) } PipelineData::Empty => Err(ShellError::OnlySupportsThisInputType { exp_input_type: "list, binary or range".into(), wrong_type: "null".into(), - dst_span: call.head, - src_span: call.head, + dst_span: head, + src_span: head, }), } } diff --git a/crates/nu-command/src/filters/take/take_until.rs b/crates/nu-command/src/filters/take/take_until.rs index 40d2eee019..e3a2a37162 100644 --- a/crates/nu-command/src/filters/take/take_until.rs +++ b/crates/nu-command/src/filters/take/take_until.rs @@ -84,7 +84,7 @@ impl Command for TakeUntil { .map(|data| data.into_value(head).is_false()) .unwrap_or(false) }) - .into_pipeline_data_with_metadata(metadata, engine_state.ctrlc.clone())) + .into_pipeline_data_with_metadata(head, engine_state.ctrlc.clone(), metadata)) } } diff --git a/crates/nu-command/src/filters/take/take_while.rs b/crates/nu-command/src/filters/take/take_while.rs index 1d2a98ee51..632c165847 100644 --- a/crates/nu-command/src/filters/take/take_while.rs +++ b/crates/nu-command/src/filters/take/take_while.rs @@ -84,7 +84,7 @@ impl Command for TakeWhile { .map(|data| data.into_value(head).is_true()) .unwrap_or(false) }) - .into_pipeline_data_with_metadata(metadata, engine_state.ctrlc.clone())) + .into_pipeline_data_with_metadata(head, engine_state.ctrlc.clone(), metadata)) } } diff --git a/crates/nu-command/src/filters/tee.rs b/crates/nu-command/src/filters/tee.rs index 5287f44512..319f70905c 100644 --- a/crates/nu-command/src/filters/tee.rs +++ b/crates/nu-command/src/filters/tee.rs @@ -64,6 +64,7 @@ use it in your pipeline."# call: &Call, input: PipelineData, ) -> Result { + let head = call.head; let use_stderr = call.has_flag(engine_state, stack, "stderr")?; let Spanned { @@ -125,7 +126,7 @@ use it in your pipeline."# if use_stderr { let stderr = stderr .map(|stderr| { - let iter = tee(stderr.stream, with_stream).err_span(call.head)?; + let iter = tee(stderr.stream, with_stream).err_span(head)?; Ok::<_, ShellError>(RawStream::new( Box::new(iter.map(flatten_result)), stderr.ctrlc, @@ -145,7 +146,7 @@ use it in your pipeline."# } else { let stdout = stdout .map(|stdout| { - let iter = tee(stdout.stream, with_stream).err_span(call.head)?; + let iter = tee(stdout.stream, with_stream).err_span(head)?; Ok::<_, ShellError>(RawStream::new( Box::new(iter.map(flatten_result)), stdout.ctrlc, @@ -168,15 +169,16 @@ use it in your pipeline."# _ if use_stderr => Err(ShellError::UnsupportedInput { msg: "--stderr can only be used on external streams".into(), input: "the input to `tee` is not an external stream".into(), - msg_span: call.head, - input_span: input.span().unwrap_or(call.head), + msg_span: head, + input_span: input.span().unwrap_or(head), }), // Handle others with the plain iterator _ => { let teed = tee(input.into_iter(), move |rx| { let input_from_channel = rx.into_pipeline_data_with_metadata( - metadata_clone, + head, closure_engine_state.ctrlc.clone(), + metadata_clone, ); let result = eval_block_with_early_return( &closure_engine_state, @@ -187,9 +189,13 @@ use it in your pipeline."# // Make sure to drain any iterator produced to avoid unexpected behavior result.and_then(|data| data.drain()) }) - .err_span(call.head)? + .err_span(head)? .map(move |result| result.unwrap_or_else(|err| Value::error(err, closure_span))) - .into_pipeline_data_with_metadata(metadata, engine_state.ctrlc.clone()); + .into_pipeline_data_with_metadata( + head, + engine_state.ctrlc.clone(), + metadata, + ); Ok(teed) } diff --git a/crates/nu-command/src/filters/transpose.rs b/crates/nu-command/src/filters/transpose.rs index 9a41457a8f..49caa56d18 100644 --- a/crates/nu-command/src/filters/transpose.rs +++ b/crates/nu-command/src/filters/transpose.rs @@ -284,7 +284,7 @@ pub fn transpose( metadata, )) } else { - Ok(result_data.into_pipeline_data_with_metadata(metadata, ctrlc)) + Ok(result_data.into_pipeline_data_with_metadata(name, ctrlc, metadata)) } } diff --git a/crates/nu-command/src/filters/update.rs b/crates/nu-command/src/filters/update.rs index 76e0674ad8..2cea7deead 100644 --- a/crates/nu-command/src/filters/update.rs +++ b/crates/nu-command/src/filters/update.rs @@ -143,7 +143,7 @@ fn update( } Ok(value.into_pipeline_data_with_metadata(metadata)) } - PipelineData::ListStream(mut stream, metadata) => { + PipelineData::ListStream(stream, metadata) => { if let Some(( &PathMember::Int { val, @@ -153,6 +153,7 @@ fn update( path, )) = cell_path.members.split_first() { + let mut stream = stream.into_iter(); let mut pre_elems = vec![]; for idx in 0..=val { @@ -186,38 +187,38 @@ fn update( Ok(pre_elems .into_iter() .chain(stream) - .into_pipeline_data_with_metadata(metadata, engine_state.ctrlc.clone())) + .into_pipeline_data_with_metadata(head, engine_state.ctrlc.clone(), metadata)) } else if let Value::Closure { val, .. } = replacement { let mut closure = ClosureEval::new(engine_state, stack, val); - Ok(stream - .map(move |mut value| { - let err = update_value_by_closure( - &mut value, - &mut closure, - head, - &cell_path.members, - false, - ); + let stream = stream.map(move |mut value| { + let err = update_value_by_closure( + &mut value, + &mut closure, + head, + &cell_path.members, + false, + ); - if let Err(e) = err { - Value::error(e, head) - } else { - value - } - }) - .into_pipeline_data_with_metadata(metadata, engine_state.ctrlc.clone())) + if let Err(e) = err { + Value::error(e, head) + } else { + value + } + }); + + Ok(PipelineData::ListStream(stream, metadata)) } else { - Ok(stream - .map(move |mut value| { - if let Err(e) = - value.update_data_at_cell_path(&cell_path.members, replacement.clone()) - { - Value::error(e, head) - } else { - value - } - }) - .into_pipeline_data_with_metadata(metadata, engine_state.ctrlc.clone())) + let stream = stream.map(move |mut value| { + if let Err(e) = + value.update_data_at_cell_path(&cell_path.members, replacement.clone()) + { + Value::error(e, head) + } else { + value + } + }); + + Ok(PipelineData::ListStream(stream, metadata)) } } PipelineData::Empty => Err(ShellError::IncompatiblePathAccess { diff --git a/crates/nu-command/src/filters/upsert.rs b/crates/nu-command/src/filters/upsert.rs index e62239f562..b7b4a782f2 100644 --- a/crates/nu-command/src/filters/upsert.rs +++ b/crates/nu-command/src/filters/upsert.rs @@ -189,7 +189,7 @@ fn upsert( } Ok(value.into_pipeline_data_with_metadata(metadata)) } - PipelineData::ListStream(mut stream, metadata) => { + PipelineData::ListStream(stream, metadata) => { if let Some(( &PathMember::Int { val, @@ -199,6 +199,7 @@ fn upsert( path, )) = cell_path.members.split_first() { + let mut stream = stream.into_iter(); let mut pre_elems = vec![]; for idx in 0..val { @@ -246,38 +247,38 @@ fn upsert( Ok(pre_elems .into_iter() .chain(stream) - .into_pipeline_data_with_metadata(metadata, engine_state.ctrlc.clone())) + .into_pipeline_data_with_metadata(head, engine_state.ctrlc.clone(), metadata)) } else if let Value::Closure { val, .. } = replacement { let mut closure = ClosureEval::new(engine_state, stack, val); - Ok(stream - .map(move |mut value| { - let err = upsert_value_by_closure( - &mut value, - &mut closure, - head, - &cell_path.members, - false, - ); + let stream = stream.map(move |mut value| { + let err = upsert_value_by_closure( + &mut value, + &mut closure, + head, + &cell_path.members, + false, + ); - if let Err(e) = err { - Value::error(e, head) - } else { - value - } - }) - .into_pipeline_data_with_metadata(metadata, engine_state.ctrlc.clone())) + if let Err(e) = err { + Value::error(e, head) + } else { + value + } + }); + + Ok(PipelineData::ListStream(stream, metadata)) } else { - Ok(stream - .map(move |mut value| { - if let Err(e) = - value.upsert_data_at_cell_path(&cell_path.members, replacement.clone()) - { - Value::error(e, head) - } else { - value - } - }) - .into_pipeline_data_with_metadata(metadata, engine_state.ctrlc.clone())) + let stream = stream.map(move |mut value| { + if let Err(e) = + value.upsert_data_at_cell_path(&cell_path.members, replacement.clone()) + { + Value::error(e, head) + } else { + value + } + }); + + Ok(PipelineData::ListStream(stream, metadata)) } } PipelineData::Empty => Err(ShellError::IncompatiblePathAccess { diff --git a/crates/nu-command/src/filters/values.rs b/crates/nu-command/src/filters/values.rs index 6a16093ff5..15aad30f69 100644 --- a/crates/nu-command/src/filters/values.rs +++ b/crates/nu-command/src/filters/values.rs @@ -144,7 +144,7 @@ fn values( Value::List { vals, .. } => match get_values(&vals, head, span) { Ok(cols) => Ok(cols .into_iter() - .into_pipeline_data_with_metadata(metadata, ctrlc)), + .into_pipeline_data_with_metadata(head, ctrlc, metadata)), Err(err) => Err(err), }, Value::Custom { val, .. } => { @@ -152,7 +152,7 @@ fn values( match get_values(&[input_as_base_value], head, span) { Ok(cols) => Ok(cols .into_iter() - .into_pipeline_data_with_metadata(metadata, ctrlc)), + .into_pipeline_data_with_metadata(head, ctrlc, metadata)), Err(err) => Err(err), } } @@ -160,7 +160,7 @@ fn values( .values() .cloned() .collect::>() - .into_pipeline_data_with_metadata(metadata, ctrlc)), + .into_pipeline_data_with_metadata(head, ctrlc, metadata)), // Propagate errors Value::Error { error, .. } => Err(*error), other => Err(ShellError::OnlySupportsThisInputType { @@ -176,7 +176,7 @@ fn values( match get_values(&vals, head, head) { Ok(cols) => Ok(cols .into_iter() - .into_pipeline_data_with_metadata(metadata, ctrlc)), + .into_pipeline_data_with_metadata(head, ctrlc, metadata)), Err(err) => Err(err), } } diff --git a/crates/nu-command/src/filters/where_.rs b/crates/nu-command/src/filters/where_.rs index cb35bd8876..7507a7ede1 100644 --- a/crates/nu-command/src/filters/where_.rs +++ b/crates/nu-command/src/filters/where_.rs @@ -61,7 +61,7 @@ not supported."# Ok(data) => data.into_value(head).is_true().then_some(value), Err(err) => Some(Value::error(err, head)), }) - .into_pipeline_data_with_metadata(metadata, engine_state.ctrlc.clone())) + .into_pipeline_data_with_metadata(head, engine_state.ctrlc.clone(), metadata)) } fn examples(&self) -> Vec { diff --git a/crates/nu-command/src/filters/window.rs b/crates/nu-command/src/filters/window.rs index 5c84ad7e98..5b386b9f84 100644 --- a/crates/nu-command/src/filters/window.rs +++ b/crates/nu-command/src/filters/window.rs @@ -1,4 +1,5 @@ use nu_engine::command_prelude::*; +use nu_protocol::ValueIterator; #[derive(Clone)] pub struct Window; @@ -110,6 +111,7 @@ impl Command for Window { call: &Call, input: PipelineData, ) -> Result { + let head = call.head; let group_size: Spanned = call.req(engine_state, stack, 0)?; let ctrlc = engine_state.ctrlc.clone(); let metadata = input.metadata(); @@ -123,19 +125,19 @@ impl Command for Window { let each_group_iterator = EachWindowIterator { group_size: group_size.item, input: Box::new(input.into_iter()), - span: call.head, + span: head, previous: None, stride, remainder, }; - Ok(each_group_iterator.into_pipeline_data_with_metadata(metadata, ctrlc)) + Ok(each_group_iterator.into_pipeline_data_with_metadata(head, ctrlc, metadata)) } } struct EachWindowIterator { group_size: usize, - input: Box + Send>, + input: ValueIterator, span: Span, previous: Option>, stride: usize, diff --git a/crates/nu-command/src/filters/wrap.rs b/crates/nu-command/src/filters/wrap.rs index a5ccf9eed2..24ce8e6821 100644 --- a/crates/nu-command/src/filters/wrap.rs +++ b/crates/nu-command/src/filters/wrap.rs @@ -42,9 +42,9 @@ impl Command for Wrap { | PipelineData::ListStream { .. } => Ok(input .into_iter() .map(move |x| Value::record(record! { name.clone() => x }, span)) - .into_pipeline_data_with_metadata(metadata, engine_state.ctrlc.clone())), + .into_pipeline_data_with_metadata(span, engine_state.ctrlc.clone(), metadata)), PipelineData::ExternalStream { .. } => Ok(Value::record( - record! { name => input.into_value(call.head) }, + record! { name => input.into_value(span) }, span, ) .into_pipeline_data_with_metadata(metadata)), diff --git a/crates/nu-command/src/filters/zip.rs b/crates/nu-command/src/filters/zip.rs index 0a30450091..f4ee739f50 100644 --- a/crates/nu-command/src/filters/zip.rs +++ b/crates/nu-command/src/filters/zip.rs @@ -112,7 +112,7 @@ impl Command for Zip { .into_iter() .zip(other) .map(move |(x, y)| Value::list(vec![x, y], head)) - .into_pipeline_data_with_metadata(metadata, engine_state.ctrlc.clone())) + .into_pipeline_data_with_metadata(head, engine_state.ctrlc.clone(), metadata)) } } diff --git a/crates/nu-command/src/formats/from/json.rs b/crates/nu-command/src/formats/from/json.rs index 5baaea30dd..44f127152f 100644 --- a/crates/nu-command/src/formats/from/json.rs +++ b/crates/nu-command/src/formats/from/json.rs @@ -84,8 +84,11 @@ impl Command for FromJson { .collect() }; - Ok(converted_lines - .into_pipeline_data_with_metadata(metadata, engine_state.ctrlc.clone())) + Ok(converted_lines.into_pipeline_data_with_metadata( + span, + engine_state.ctrlc.clone(), + metadata, + )) } else if strict { Ok(convert_string_to_value_strict(&string_input, span)? .into_pipeline_data_with_metadata(metadata)) diff --git a/crates/nu-command/src/formats/from/msgpack.rs b/crates/nu-command/src/formats/from/msgpack.rs index 0311ecfd1a..75f2be2056 100644 --- a/crates/nu-command/src/formats/from/msgpack.rs +++ b/crates/nu-command/src/formats/from/msgpack.rs @@ -109,10 +109,9 @@ MessagePack: https://msgpack.org/ call: &Call, input: PipelineData, ) -> Result { - let span = input.span().unwrap_or(call.head); let objects = call.has_flag(engine_state, stack, "objects")?; let opts = Opts { - span, + span: call.head, objects, ctrlc: engine_state.ctrlc.clone(), }; @@ -126,10 +125,10 @@ MessagePack: https://msgpack.org/ stdout: Some(raw_stream), .. } => read_msgpack(ReadRawStream::new(raw_stream), opts), - _ => Err(ShellError::PipelineMismatch { + input => Err(ShellError::PipelineMismatch { exp_input_type: "binary".into(), dst_span: call.head, - src_span: span, + src_span: input.span().unwrap_or(call.head), }), } } @@ -257,7 +256,7 @@ pub(crate) fn read_msgpack( None } }) - .into_pipeline_data(ctrlc)) + .into_pipeline_data(span, ctrlc)) } else { // Read a single value and then make sure it's EOF let result = read_value(&mut input, span, 0)?; diff --git a/crates/nu-command/src/formats/from/xml.rs b/crates/nu-command/src/formats/from/xml.rs index 5ac94051f6..c3464e7a25 100644 --- a/crates/nu-command/src/formats/from/xml.rs +++ b/crates/nu-command/src/formats/from/xml.rs @@ -197,15 +197,15 @@ fn from_document_to_value(d: &roxmltree::Document, info: &ParsingInfo) -> Value element_to_value(&d.root_element(), info) } -fn from_xml_string_to_value(s: String, info: &ParsingInfo) -> Result { - let parsed = roxmltree::Document::parse(&s)?; +fn from_xml_string_to_value(s: &str, info: &ParsingInfo) -> Result { + let parsed = roxmltree::Document::parse(s)?; Ok(from_document_to_value(&parsed, info)) } fn from_xml(input: PipelineData, info: &ParsingInfo) -> Result { let (concat_string, span, metadata) = input.collect_string_strict(info.span)?; - match from_xml_string_to_value(concat_string, info) { + match from_xml_string_to_value(&concat_string, info) { Ok(x) => Ok(x.into_pipeline_data_with_metadata(metadata)), Err(err) => Err(process_xml_parse_error(err, span)), } @@ -370,7 +370,7 @@ mod tests { keep_comments: false, keep_processing_instructions: false, }; - from_xml_string_to_value(xml.to_string(), &info) + from_xml_string_to_value(xml, &info) } #[test] diff --git a/crates/nu-command/src/formats/from/yaml.rs b/crates/nu-command/src/formats/from/yaml.rs index 5edb8bdac9..74914ed0c8 100644 --- a/crates/nu-command/src/formats/from/yaml.rs +++ b/crates/nu-command/src/formats/from/yaml.rs @@ -185,14 +185,10 @@ fn convert_yaml_value_to_nu_value( }) } -pub fn from_yaml_string_to_value( - s: String, - span: Span, - val_span: Span, -) -> Result { +pub fn from_yaml_string_to_value(s: &str, span: Span, val_span: Span) -> Result { let mut documents = vec![]; - for document in serde_yaml::Deserializer::from_str(&s) { + for document in serde_yaml::Deserializer::from_str(s) { let v: serde_yaml::Value = serde_yaml::Value::deserialize(document).map_err(|x| ShellError::UnsupportedInput { msg: format!("Could not load YAML: {x}"), @@ -238,7 +234,7 @@ pub fn get_examples() -> Vec> { fn from_yaml(input: PipelineData, head: Span) -> Result { let (concat_string, span, metadata) = input.collect_string_strict(head)?; - match from_yaml_string_to_value(concat_string, head, span) { + match from_yaml_string_to_value(&concat_string, head, span) { Ok(x) => Ok(x.into_pipeline_data_with_metadata(metadata)), Err(other) => Err(other), } @@ -274,11 +270,7 @@ mod test { ]; let config = Config::default(); for tc in tt { - let actual = from_yaml_string_to_value( - tc.input.to_owned(), - Span::test_data(), - Span::test_data(), - ); + let actual = from_yaml_string_to_value(tc.input, Span::test_data(), Span::test_data()); if actual.is_err() { assert!( tc.expected.is_err(), @@ -313,11 +305,7 @@ mod test { // table was non-deterministic. It would take a few executions of the YAML conversion to // see this ordering difference. This loop should be far more than enough to catch a regression. for ii in 1..1000 { - let actual = from_yaml_string_to_value( - String::from(test_yaml), - Span::test_data(), - Span::test_data(), - ); + let actual = from_yaml_string_to_value(test_yaml, Span::test_data(), Span::test_data()); let expected: Result = Ok(Value::test_list(vec![ Value::test_record(record! { diff --git a/crates/nu-command/src/formats/to/text.rs b/crates/nu-command/src/formats/to/text.rs index a70ef4cf85..d6935b0b28 100644 --- a/crates/nu-command/src/formats/to/text.rs +++ b/crates/nu-command/src/formats/to/text.rs @@ -1,6 +1,6 @@ use chrono_humanize::HumanTime; use nu_engine::command_prelude::*; -use nu_protocol::{format_duration, format_filesize_from_conf, Config, ListStream, RawStream}; +use nu_protocol::{format_duration, format_filesize_from_conf, Config, RawStream, ValueIterator}; #[derive(Clone)] pub struct ToText; @@ -41,7 +41,7 @@ impl Command for ToText { Ok(PipelineData::ExternalStream { stdout: Some(RawStream::new( Box::new(ListStreamIterator { - stream, + stream: stream.into_inner(), separator: line_ending.into(), config: config.clone(), }), @@ -86,7 +86,7 @@ impl Command for ToText { } struct ListStreamIterator { - stream: ListStream, + stream: ValueIterator, separator: String, config: Config, } diff --git a/crates/nu-command/src/generators/generate.rs b/crates/nu-command/src/generators/generate.rs index aecf807f43..905c19eb2f 100644 --- a/crates/nu-command/src/generators/generate.rs +++ b/crates/nu-command/src/generators/generate.rs @@ -183,7 +183,7 @@ used as the next argument to the closure, otherwise generation stops. Ok(iter .flatten() - .into_pipeline_data(engine_state.ctrlc.clone())) + .into_pipeline_data(call.head, engine_state.ctrlc.clone())) } } diff --git a/crates/nu-command/src/generators/seq.rs b/crates/nu-command/src/generators/seq.rs index f43454b691..359d479ca0 100644 --- a/crates/nu-command/src/generators/seq.rs +++ b/crates/nu-command/src/generators/seq.rs @@ -1,4 +1,5 @@ use nu_engine::command_prelude::*; +use nu_protocol::ListStream; #[derive(Clone)] pub struct Seq; @@ -119,36 +120,32 @@ pub fn run_seq( let step = if free.len() > 2 { free[1] } else { 1.0 }; let last = { free[free.len() - 1] }; - if !contains_decimals { - // integers only - Ok(PipelineData::ListStream( - nu_protocol::ListStream::from_stream( - IntSeq { - count: first as i64, - step: step as i64, - last: last as i64, - span, - }, - engine_state.ctrlc.clone(), - ), - None, - )) + let stream = if !contains_decimals { + ListStream::new( + IntSeq { + count: first as i64, + step: step as i64, + last: last as i64, + span, + }, + span, + engine_state.ctrlc.clone(), + ) } else { - // floats - Ok(PipelineData::ListStream( - nu_protocol::ListStream::from_stream( - FloatSeq { - first, - step, - last, - index: 0, - span, - }, - engine_state.ctrlc.clone(), - ), - None, - )) - } + ListStream::new( + FloatSeq { + first, + step, + last, + index: 0, + span, + }, + span, + engine_state.ctrlc.clone(), + ) + }; + + Ok(stream.into()) } struct FloatSeq { diff --git a/crates/nu-command/src/help/help_aliases.rs b/crates/nu-command/src/help/help_aliases.rs index f97084bb51..2cc7c7f073 100644 --- a/crates/nu-command/src/help/help_aliases.rs +++ b/crates/nu-command/src/help/help_aliases.rs @@ -92,17 +92,12 @@ pub fn help_aliases( &highlight_style, )?; - return Ok(found_cmds_vec - .into_iter() - .into_pipeline_data(engine_state.ctrlc.clone())); + return Ok(Value::list(found_cmds_vec, head).into_pipeline_data()); } if rest.is_empty() { let found_cmds_vec = build_help_aliases(engine_state, stack, head); - - Ok(found_cmds_vec - .into_iter() - .into_pipeline_data(engine_state.ctrlc.clone())) + Ok(Value::list(found_cmds_vec, head).into_pipeline_data()) } else { let mut name = String::new(); diff --git a/crates/nu-command/src/help/help_commands.rs b/crates/nu-command/src/help/help_commands.rs index 128c838efd..bc508b249b 100644 --- a/crates/nu-command/src/help/help_commands.rs +++ b/crates/nu-command/src/help/help_commands.rs @@ -72,17 +72,12 @@ pub fn help_commands( &highlight_style, )?; - return Ok(found_cmds_vec - .into_iter() - .into_pipeline_data(engine_state.ctrlc.clone())); + return Ok(Value::list(found_cmds_vec, head).into_pipeline_data()); } if rest.is_empty() { let found_cmds_vec = build_help_commands(engine_state, head); - - Ok(found_cmds_vec - .into_iter() - .into_pipeline_data(engine_state.ctrlc.clone())) + Ok(Value::list(found_cmds_vec, head).into_pipeline_data()) } else { let mut name = String::new(); diff --git a/crates/nu-command/src/help/help_escapes.rs b/crates/nu-command/src/help/help_escapes.rs index 73a83f1175..212cbb58bf 100644 --- a/crates/nu-command/src/help/help_escapes.rs +++ b/crates/nu-command/src/help/help_escapes.rs @@ -21,7 +21,7 @@ impl Command for HelpEscapes { fn run( &self, - engine_state: &EngineState, + _engine_state: &EngineState, _stack: &mut Stack, call: &Call, _input: PipelineData, @@ -40,9 +40,7 @@ impl Command for HelpEscapes { )); } - Ok(recs - .into_iter() - .into_pipeline_data(engine_state.ctrlc.clone())) + Ok(Value::list(recs, call.head).into_pipeline_data()) } } diff --git a/crates/nu-command/src/help/help_externs.rs b/crates/nu-command/src/help/help_externs.rs index 3aad5b27fe..624a8d8060 100644 --- a/crates/nu-command/src/help/help_externs.rs +++ b/crates/nu-command/src/help/help_externs.rs @@ -92,17 +92,12 @@ pub fn help_externs( &highlight_style, )?; - return Ok(found_cmds_vec - .into_iter() - .into_pipeline_data(engine_state.ctrlc.clone())); + return Ok(Value::list(found_cmds_vec, head).into_pipeline_data()); } if rest.is_empty() { let found_cmds_vec = build_help_externs(engine_state, stack, head); - - Ok(found_cmds_vec - .into_iter() - .into_pipeline_data(engine_state.ctrlc.clone())) + Ok(Value::list(found_cmds_vec, head).into_pipeline_data()) } else { let mut name = String::new(); diff --git a/crates/nu-command/src/help/help_modules.rs b/crates/nu-command/src/help/help_modules.rs index e51b52154b..f2ddf55f1d 100644 --- a/crates/nu-command/src/help/help_modules.rs +++ b/crates/nu-command/src/help/help_modules.rs @@ -98,17 +98,12 @@ pub fn help_modules( &highlight_style, )?; - return Ok(found_cmds_vec - .into_iter() - .into_pipeline_data(engine_state.ctrlc.clone())); + return Ok(Value::list(found_cmds_vec, head).into_pipeline_data()); } if rest.is_empty() { let found_cmds_vec = build_help_modules(engine_state, stack, head); - - Ok(found_cmds_vec - .into_iter() - .into_pipeline_data(engine_state.ctrlc.clone())) + Ok(Value::list(found_cmds_vec, head).into_pipeline_data()) } else { let mut name = String::new(); diff --git a/crates/nu-command/src/help/help_operators.rs b/crates/nu-command/src/help/help_operators.rs index 72c9e752e9..a7beee3dd5 100644 --- a/crates/nu-command/src/help/help_operators.rs +++ b/crates/nu-command/src/help/help_operators.rs @@ -21,7 +21,7 @@ impl Command for HelpOperators { fn run( &self, - engine_state: &EngineState, + _engine_state: &EngineState, _stack: &mut Stack, call: &Call, _input: PipelineData, @@ -43,9 +43,7 @@ impl Command for HelpOperators { )); } - Ok(recs - .into_iter() - .into_pipeline_data(engine_state.ctrlc.clone())) + Ok(Value::list(recs, head).into_pipeline_data()) } } diff --git a/crates/nu-command/src/math/utils.rs b/crates/nu-command/src/math/utils.rs index 8a19a96fc6..6e8c12dda9 100644 --- a/crates/nu-command/src/math/utils.rs +++ b/crates/nu-command/src/math/utils.rs @@ -69,7 +69,7 @@ pub fn calculate( let span = values.span().unwrap_or(name); match values { PipelineData::ListStream(s, ..) => { - helper_for_tables(&s.collect::>(), span, name, mf) + helper_for_tables(&s.into_iter().collect::>(), span, name, mf) } PipelineData::Value(Value::List { ref vals, .. }, ..) => match &vals[..] { [Value::Record { .. }, _end @ ..] => helper_for_tables( diff --git a/crates/nu-command/src/platform/ansi/ansi_.rs b/crates/nu-command/src/platform/ansi/ansi_.rs index e4f2bca378..427c7c3a73 100644 --- a/crates/nu-command/src/platform/ansi/ansi_.rs +++ b/crates/nu-command/src/platform/ansi/ansi_.rs @@ -660,7 +660,7 @@ Operating system commands: let ctrlc = engine_state.ctrlc.clone(); if list { - return generate_ansi_code_list(ctrlc, call.head, use_ansi_coloring); + return Ok(generate_ansi_code_list(ctrlc, call.head, use_ansi_coloring)); } // The code can now be one of the ansi abbreviations like green_bold @@ -694,7 +694,7 @@ Operating system commands: let ctrlc = working_set.permanent().ctrlc.clone(); if list { - return generate_ansi_code_list(ctrlc, call.head, use_ansi_coloring); + return Ok(generate_ansi_code_list(ctrlc, call.head, use_ansi_coloring)); } // The code can now be one of the ansi abbreviations like green_bold @@ -833,8 +833,8 @@ fn generate_ansi_code_list( ctrlc: Option>, call_span: Span, use_ansi_coloring: bool, -) -> Result { - return Ok(CODE_LIST +) -> PipelineData { + CODE_LIST .iter() .enumerate() .map(move |(i, ansi_code)| { @@ -865,7 +865,7 @@ fn generate_ansi_code_list( Value::record(record, call_span) }) - .into_pipeline_data(ctrlc)); + .into_pipeline_data(call_span, ctrlc) } fn build_ansi_hashmap(v: &[AnsiCode]) -> HashMap<&str, &str> { diff --git a/crates/nu-command/src/random/dice.rs b/crates/nu-command/src/random/dice.rs index b0569c697e..2fb659ad1e 100644 --- a/crates/nu-command/src/random/dice.rs +++ b/crates/nu-command/src/random/dice.rs @@ -78,10 +78,7 @@ fn dice( Value::int(thread_rng.gen_range(1..sides + 1) as i64, span) }); - Ok(PipelineData::ListStream( - ListStream::from_stream(iter, engine_state.ctrlc.clone()), - None, - )) + Ok(ListStream::new(iter, span, engine_state.ctrlc.clone()).into()) } #[cfg(test)] diff --git a/crates/nu-command/src/strings/char_.rs b/crates/nu-command/src/strings/char_.rs index befab1a93d..e227f2667f 100644 --- a/crates/nu-command/src/strings/char_.rs +++ b/crates/nu-command/src/strings/char_.rs @@ -230,7 +230,7 @@ impl Command for Char { // handle -l flag if list { - return generate_character_list(ctrlc, call.head); + return Ok(generate_character_list(ctrlc, call.head)); } // handle -i flag @@ -265,7 +265,7 @@ impl Command for Char { // handle -l flag if list { - return generate_character_list(ctrlc, call_span); + return Ok(generate_character_list(ctrlc, call_span)); } // handle -i flag @@ -286,11 +286,8 @@ impl Command for Char { } } -fn generate_character_list( - ctrlc: Option>, - call_span: Span, -) -> Result { - Ok(CHAR_MAP +fn generate_character_list(ctrlc: Option>, call_span: Span) -> PipelineData { + CHAR_MAP .iter() .map(move |(name, s)| { let unicode = Value::string( @@ -308,7 +305,7 @@ fn generate_character_list( Value::record(record, call_span) }) - .into_pipeline_data(ctrlc)) + .into_pipeline_data(call_span, ctrlc) } fn handle_integer_flag( diff --git a/crates/nu-command/src/strings/detect_columns.rs b/crates/nu-command/src/strings/detect_columns.rs index 9c33ffa494..74bcf07820 100644 --- a/crates/nu-command/src/strings/detect_columns.rs +++ b/crates/nu-command/src/strings/detect_columns.rs @@ -159,7 +159,7 @@ fn guess_width( Err(e) => Value::error(e, input_span), } }) - .into_pipeline_data(engine_state.ctrlc.clone())) + .into_pipeline_data(input_span, engine_state.ctrlc.clone())) } else { let length = result[0].len(); let columns: Vec = (0..length).map(|n| format!("column{n}")).collect(); @@ -184,7 +184,7 @@ fn guess_width( Err(e) => Value::error(e, input_span), } }) - .into_pipeline_data(engine_state.ctrlc.clone())) + .into_pipeline_data(input_span, engine_state.ctrlc.clone())) } } @@ -278,7 +278,7 @@ fn detect_columns( None => Value::record(record, name_span), } }) - .into_pipeline_data(ctrlc)) + .into_pipeline_data(call.head, ctrlc)) } else { Ok(PipelineData::empty()) } diff --git a/crates/nu-command/src/strings/encode_decode/base64.rs b/crates/nu-command/src/strings/encode_decode/base64.rs index 0f91a96466..1c257e1200 100644 --- a/crates/nu-command/src/strings/encode_decode/base64.rs +++ b/crates/nu-command/src/strings/encode_decode/base64.rs @@ -281,7 +281,7 @@ mod tests { #[test] fn base64_decode_binhex() { - let word = Value::test_string("A5\"KC9jRB@IIF'8bF!"); + let word = Value::test_string(r#"B5"LD@jSCAJJG'9cG!"#); let expected = Value::binary(b"a binhex test".as_slice(), Span::test_data()); let actual = action( @@ -304,7 +304,7 @@ mod tests { #[test] fn base64_decode_binhex_with_new_line_input() { - let word = Value::test_string("A5\"KC9jRB\n@IIF'8bF!"); + let word = Value::test_string("B5\"LD@jSC\nAJJG'9cG!"); let expected = Value::binary(b"a binhex test".as_slice(), Span::test_data()); let actual = action( diff --git a/crates/nu-command/src/strings/encode_decode/encode_base64.rs b/crates/nu-command/src/strings/encode_decode/encode_base64.rs index 04e1fcf6d1..090941b76b 100644 --- a/crates/nu-command/src/strings/encode_decode/encode_base64.rs +++ b/crates/nu-command/src/strings/encode_decode/encode_base64.rs @@ -65,7 +65,7 @@ impl Command for EncodeBase64 { Example { description: "Encode a string with the binhex character set", example: "'Some Data' | encode base64 --character-set binhex", - result: Some(Value::test_string(r#"7epXB5"%A@4J"#)), + result: Some(Value::test_string(r#"8fpYC5"%BA4K"#)), }, ] } diff --git a/crates/nu-command/src/strings/parse.rs b/crates/nu-command/src/strings/parse.rs index 658fc20361..8f6d35b0b3 100644 --- a/crates/nu-command/src/strings/parse.rs +++ b/crates/nu-command/src/strings/parse.rs @@ -1,6 +1,6 @@ use fancy_regex::Regex; use nu_engine::command_prelude::*; -use nu_protocol::ListStream; +use nu_protocol::{ListStream, ValueIterator}; use std::sync::{ atomic::{AtomicBool, Ordering}, Arc, @@ -187,44 +187,36 @@ fn operate( } } - Ok(PipelineData::ListStream( - ListStream::from_stream(parsed.into_iter(), ctrlc), - None, - )) + Ok(ListStream::new(parsed.into_iter(), head, ctrlc).into()) } - PipelineData::ListStream(stream, ..) => Ok(PipelineData::ListStream( - ListStream::from_stream( - ParseStreamer { - span: head, - excess: Vec::new(), - regex: regex_pattern, - columns, - stream: stream.stream, - ctrlc: ctrlc.clone(), - }, + PipelineData::ListStream(stream, ..) => Ok(stream + .modify(|stream| ParseStreamer { + span: head, + excess: Vec::new(), + regex: regex_pattern, + columns, + stream, ctrlc, - ), - None, - )), + }) + .into()), PipelineData::ExternalStream { stdout: None, .. } => Ok(PipelineData::Empty), PipelineData::ExternalStream { stdout: Some(stream), .. - } => Ok(PipelineData::ListStream( - ListStream::from_stream( - ParseStreamerExternal { - span: head, - excess: Vec::new(), - regex: regex_pattern, - columns, - stream: stream.stream, - }, - ctrlc, - ), - None, - )), + } => Ok(ListStream::new( + ParseStreamerExternal { + span: head, + excess: Vec::new(), + regex: regex_pattern, + columns, + stream: stream.stream, + }, + head, + ctrlc, + ) + .into()), } } @@ -299,7 +291,7 @@ pub struct ParseStreamer { excess: Vec, regex: Regex, columns: Vec, - stream: Box + Send + 'static>, + stream: ValueIterator, ctrlc: Option>, } diff --git a/crates/nu-command/src/strings/split/list.rs b/crates/nu-command/src/strings/split/list.rs index 08bd8fbc61..470ba12ec4 100644 --- a/crates/nu-command/src/strings/split/list.rs +++ b/crates/nu-command/src/strings/split/list.rs @@ -196,9 +196,12 @@ fn split_list( let mut temp_list = Vec::new(); let mut returned_list = Vec::new(); - let iter = input.into_interruptible_iter(engine_state.ctrlc.clone()); let matcher = Matcher::new(call.has_flag(engine_state, stack, "regex")?, separator)?; - for val in iter { + for val in input { + if nu_utils::ctrl_c::was_pressed(&engine_state.ctrlc) { + break; + } + if matcher.compare(&val)? { if !temp_list.is_empty() { returned_list.push(Value::list(temp_list.clone(), call.head)); diff --git a/crates/nu-command/src/system/complete.rs b/crates/nu-command/src/system/complete.rs index 80dae4d37a..c622c86f3c 100644 --- a/crates/nu-command/src/system/complete.rs +++ b/crates/nu-command/src/system/complete.rs @@ -88,7 +88,7 @@ impl Command for Complete { }; if let Some(exit_code) = exit_code { - let mut v: Vec<_> = exit_code.collect(); + let mut v: Vec<_> = exit_code.into_iter().collect(); if let Some(v) = v.pop() { record.push("exit_code", v); diff --git a/crates/nu-command/src/system/ps.rs b/crates/nu-command/src/system/ps.rs index 11eb66011d..922bf7915b 100644 --- a/crates/nu-command/src/system/ps.rs +++ b/crates/nu-command/src/system/ps.rs @@ -195,5 +195,5 @@ fn run_ps( Ok(output .into_iter() - .into_pipeline_data(engine_state.ctrlc.clone())) + .into_pipeline_data(span, engine_state.ctrlc.clone())) } diff --git a/crates/nu-command/src/system/registry_query.rs b/crates/nu-command/src/system/registry_query.rs index c926ad6aaf..1e2a328356 100644 --- a/crates/nu-command/src/system/registry_query.rs +++ b/crates/nu-command/src/system/registry_query.rs @@ -106,7 +106,7 @@ fn registry_query( *registry_key_span, )) } - Ok(reg_values.into_pipeline_data(engine_state.ctrlc.clone())) + Ok(reg_values.into_pipeline_data(call_span, engine_state.ctrlc.clone())) } else { match registry_value { Some(value) => { diff --git a/crates/nu-command/src/system/run_external.rs b/crates/nu-command/src/system/run_external.rs index 734488fd81..e73bd4ab50 100644 --- a/crates/nu-command/src/system/run_external.rs +++ b/crates/nu-command/src/system/run_external.rs @@ -163,8 +163,6 @@ impl ExternalCommand { ) -> Result { let head = self.name.span; - let ctrlc = engine_state.ctrlc.clone(); - #[allow(unused_mut)] let (cmd, mut reader) = self.create_process(&input, false, head)?; @@ -431,7 +429,7 @@ impl ExternalCommand { ( Some(RawStream::new( Box::new(ByteLines::new(combined)), - ctrlc.clone(), + engine_state.ctrlc.clone(), head, None, )), @@ -439,11 +437,21 @@ impl ExternalCommand { ) } else { let stdout = child.as_mut().stdout.take().map(|out| { - RawStream::new(Box::new(ByteLines::new(out)), ctrlc.clone(), head, None) + RawStream::new( + Box::new(ByteLines::new(out)), + engine_state.ctrlc.clone(), + head, + None, + ) }); let stderr = child.as_mut().stderr.take().map(|err| { - RawStream::new(Box::new(ByteLines::new(err)), ctrlc.clone(), head, None) + RawStream::new( + Box::new(ByteLines::new(err)), + engine_state.ctrlc.clone(), + head, + None, + ) }); if matches!(self.err, OutDest::Pipe) { @@ -505,15 +513,16 @@ impl ExternalCommand { }) .err_span(head)?; - let exit_code_receiver = ValueReceiver::new(exit_code_rx); + let exit_code = Some(ListStream::new( + ValueReceiver::new(exit_code_rx), + head, + None, + )); Ok(PipelineData::ExternalStream { stdout, stderr, - exit_code: Some(ListStream::from_stream( - Box::new(exit_code_receiver), - ctrlc.clone(), - )), + exit_code, span: head, metadata: None, trim_end_newline: true, diff --git a/crates/nu-command/src/system/which_.rs b/crates/nu-command/src/system/which_.rs index f593bcf9fe..1244a57d99 100644 --- a/crates/nu-command/src/system/which_.rs +++ b/crates/nu-command/src/system/which_.rs @@ -214,6 +214,7 @@ fn which( stack: &mut Stack, call: &Call, ) -> Result { + let head = call.head; let which_args = WhichArgs { applications: call.rest(engine_state, stack, 0)?, all: call.has_flag(engine_state, stack, "all")?, @@ -223,7 +224,7 @@ fn which( if which_args.applications.is_empty() { return Err(ShellError::MissingParameter { param_name: "application".into(), - span: call.head, + span: head, }); } @@ -231,7 +232,7 @@ fn which( #[allow(deprecated)] let cwd = env::current_dir_str(engine_state, stack)?; - let paths = env::path_str(engine_state, stack, call.head)?; + let paths = env::path_str(engine_state, stack, head)?; for app in which_args.applications { let values = which_single( @@ -244,7 +245,7 @@ fn which( output.extend(values); } - Ok(output.into_iter().into_pipeline_data(ctrlc)) + Ok(output.into_iter().into_pipeline_data(head, ctrlc)) } #[cfg(test)] diff --git a/crates/nu-command/src/viewers/table.rs b/crates/nu-command/src/viewers/table.rs index 94e17846ad..f86857d81e 100644 --- a/crates/nu-command/src/viewers/table.rs +++ b/crates/nu-command/src/viewers/table.rs @@ -5,7 +5,9 @@ use lscolors::{LsColors, Style}; use nu_color_config::{color_from_hex, StyleComputer, TextStyle}; use nu_engine::{command_prelude::*, env::get_config, env_to_string}; -use nu_protocol::{Config, DataSource, ListStream, PipelineMetadata, RawStream, TableMode}; +use nu_protocol::{ + Config, DataSource, ListStream, PipelineMetadata, RawStream, TableMode, ValueIterator, +}; use nu_table::{ common::create_nu_table_config, CollapsedTable, ExpandedTable, JustTable, NuTable, NuTableCell, StringResult, TableOpts, TableOutput, @@ -381,7 +383,7 @@ fn handle_table_command( // None of these two receive a StyleComputer because handle_row_stream() can produce it by itself using engine_state and stack. PipelineData::Value(Value::List { vals, .. }, metadata) => { let ctrlc = input.engine_state.ctrlc.clone(); - let stream = ListStream::from_stream(vals.into_iter(), ctrlc); + let stream = ListStream::new(vals.into_iter(), span, ctrlc); input.data = PipelineData::Empty; handle_row_stream(input, cfg, stream, metadata) @@ -405,7 +407,7 @@ fn handle_table_command( } PipelineData::Value(Value::Range { val, .. }, metadata) => { let ctrlc = input.engine_state.ctrlc.clone(); - let stream = ListStream::from_stream(val.into_range_iter(span, ctrlc.clone()), ctrlc); + let stream = ListStream::new(val.into_range_iter(span, ctrlc), span, None); input.data = PipelineData::Empty; handle_row_stream(input, cfg, stream, metadata) } @@ -537,7 +539,6 @@ fn handle_row_stream( data_source: DataSource::Ls, }) => { let config = get_config(input.engine_state, input.stack); - let ctrlc = ctrlc.clone(); let ls_colors_env_str = match input.stack.get_env_var(input.engine_state, "LS_COLORS") { Some(v) => Some(env_to_string( "LS_COLORS", @@ -549,67 +550,55 @@ fn handle_row_stream( }; let ls_colors = get_ls_colors(ls_colors_env_str); - ListStream::from_stream( - stream.map(move |mut x| match &mut x { - Value::Record { val: record, .. } => { - // Only the name column gets special colors, for now - if let Some(value) = record.get_mut("name") { - let span = value.span(); - if let Value::String { val, .. } = value { - if let Some(val) = render_path_name(val, &config, &ls_colors, span) - { - *value = val; - } + stream.map(move |mut value| { + if let Value::Record { val: record, .. } = &mut value { + // Only the name column gets special colors, for now + if let Some(value) = record.get_mut("name") { + let span = value.span(); + if let Value::String { val, .. } = value { + if let Some(val) = render_path_name(val, &config, &ls_colors, span) { + *value = val; } } - - x } - _ => x, - }), - ctrlc, - ) + } + value + }) } // Next, `to html -l` sources: Some(PipelineMetadata { data_source: DataSource::HtmlThemes, }) => { - let ctrlc = ctrlc.clone(); - - ListStream::from_stream( - stream.map(move |mut x| match &mut x { - Value::Record { val: record, .. } => { - for (rec_col, rec_val) in record.iter_mut() { - // Every column in the HTML theme table except 'name' is colored - if rec_col != "name" { - continue; - } - // Simple routine to grab the hex code, convert to a style, - // then place it in a new Value::String. - - let span = rec_val.span(); - if let Value::String { val, .. } = rec_val { - let s = match color_from_hex(val) { - Ok(c) => match c { - // .normal() just sets the text foreground color. - Some(c) => c.normal(), - None => nu_ansi_term::Style::default(), - }, - Err(_) => nu_ansi_term::Style::default(), - }; - *rec_val = Value::string( - // Apply the style (ANSI codes) to the string - s.paint(&*val).to_string(), - span, - ); - } + stream.map(|mut value| { + if let Value::Record { val: record, .. } = &mut value { + for (rec_col, rec_val) in record.iter_mut() { + // Every column in the HTML theme table except 'name' is colored + if rec_col != "name" { + continue; + } + // Simple routine to grab the hex code, convert to a style, + // then place it in a new Value::String. + + let span = rec_val.span(); + if let Value::String { val, .. } = rec_val { + let s = match color_from_hex(val) { + Ok(c) => match c { + // .normal() just sets the text foreground color. + Some(c) => c.normal(), + None => nu_ansi_term::Style::default(), + }, + Err(_) => nu_ansi_term::Style::default(), + }; + *rec_val = Value::string( + // Apply the style (ANSI codes) to the string + s.paint(&*val).to_string(), + span, + ); } - x } - _ => x, - }), - ctrlc, - ) + } + value + }) } _ => stream, }; @@ -662,7 +651,7 @@ fn make_clickable_link( struct PagingTableCreator { head: Span, - stream: ListStream, + stream: ValueIterator, engine_state: EngineState, stack: Stack, ctrlc: Option>, @@ -683,7 +672,7 @@ impl PagingTableCreator { ) -> Self { PagingTableCreator { head, - stream, + stream: stream.into_inner(), engine_state, stack, ctrlc, @@ -822,7 +811,7 @@ impl Iterator for PagingTableCreator { } fn stream_collect( - stream: &mut ListStream, + stream: impl Iterator, size: usize, ctrlc: Option>, ) -> (Vec, bool) { @@ -830,7 +819,7 @@ fn stream_collect( let mut end = true; let mut batch = Vec::with_capacity(size); - for (i, item) in stream.by_ref().enumerate() { + for (i, item) in stream.enumerate() { batch.push(item); // If we've been buffering over a second, go ahead and send out what we have so far @@ -853,7 +842,7 @@ fn stream_collect( } fn stream_collect_abbriviated( - stream: &mut ListStream, + stream: impl Iterator, size: usize, ctrlc: Option>, ) -> (Vec, usize, bool) { @@ -866,7 +855,7 @@ fn stream_collect_abbriviated( return (vec![], 0, false); } - for item in stream.by_ref() { + for item in stream { read += 1; if read <= size { diff --git a/crates/nu-command/tests/commands/alias.rs b/crates/nu-command/tests/commands/alias.rs index 65fbbc1d4f..03df53ae42 100644 --- a/crates/nu-command/tests/commands/alias.rs +++ b/crates/nu-command/tests/commands/alias.rs @@ -92,7 +92,7 @@ fn alias_wont_recurse() { #[test] fn alias_wont_recurse2() { Playground::setup("alias_wont_recurse2", |dirs, sandbox| { - sandbox.with_files(vec![FileWithContentToBeTrimmed( + sandbox.with_files(&[FileWithContentToBeTrimmed( "spam.nu", r#" def eggs [] { spam 'eggs' } diff --git a/crates/nu-command/tests/commands/cd.rs b/crates/nu-command/tests/commands/cd.rs index 9cdafc005a..c7c30528e8 100644 --- a/crates/nu-command/tests/commands/cd.rs +++ b/crates/nu-command/tests/commands/cd.rs @@ -26,6 +26,16 @@ fn filesystem_change_from_current_directory_using_relative_path() { }) } +#[test] +fn filesystem_change_from_current_directory_using_relative_path_with_trailing_slash() { + Playground::setup("cd_test_1_slash", |dirs, _| { + // Intentionally not using correct path sep because this should work on Windows + let actual = nu!( cwd: dirs.root(), "cd cd_test_1_slash/; $env.PWD"); + + assert_eq!(PathBuf::from(actual.out), *dirs.test()); + }) +} + #[test] fn filesystem_change_from_current_directory_using_absolute_path() { Playground::setup("cd_test_2", |dirs, _| { @@ -42,6 +52,23 @@ fn filesystem_change_from_current_directory_using_absolute_path() { }) } +#[test] +fn filesystem_change_from_current_directory_using_absolute_path_with_trailing_slash() { + Playground::setup("cd_test_2", |dirs, _| { + let actual = nu!( + cwd: dirs.test(), + r#" + cd '{}{}' + $env.PWD + "#, + dirs.formats().display(), + std::path::MAIN_SEPARATOR_STR, + ); + + assert_eq!(PathBuf::from(actual.out), dirs.formats()); + }) +} + #[test] fn filesystem_switch_back_to_previous_working_directory() { Playground::setup("cd_test_3", |dirs, sandbox| { @@ -151,7 +178,7 @@ fn filesystem_change_to_a_directory_containing_spaces() { #[test] fn filesystem_not_a_directory() { Playground::setup("cd_test_10", |dirs, sandbox| { - sandbox.with_files(vec![EmptyFile("ferris_did_it.txt")]); + sandbox.with_files(&[EmptyFile("ferris_did_it.txt")]); let actual = nu!( cwd: dirs.test(), diff --git a/crates/nu-command/tests/commands/complete.rs b/crates/nu-command/tests/commands/complete.rs index c68845ff24..cc398d4c8c 100644 --- a/crates/nu-command/tests/commands/complete.rs +++ b/crates/nu-command/tests/commands/complete.rs @@ -38,7 +38,7 @@ fn capture_error_with_too_much_stderr_not_hang_nushell() { for _ in 0..bytes { large_file_body.push('a'); } - sandbox.with_files(vec![FileWithContent("a_large_file.txt", &large_file_body)]); + sandbox.with_files(&[FileWithContent("a_large_file.txt", &large_file_body)]); let actual = nu!(cwd: dirs.test(), "sh -c 'cat a_large_file.txt 1>&2' | complete | get stderr"); @@ -58,7 +58,7 @@ fn capture_error_with_too_much_stdout_not_hang_nushell() { for _ in 0..bytes { large_file_body.push('a'); } - sandbox.with_files(vec![FileWithContent("a_large_file.txt", &large_file_body)]); + sandbox.with_files(&[FileWithContent("a_large_file.txt", &large_file_body)]); let actual = nu!(cwd: dirs.test(), "sh -c 'cat a_large_file.txt' | complete | get stdout"); @@ -81,7 +81,7 @@ fn capture_error_with_both_stdout_stderr_messages_not_hang_nushell() { "#; let expect_body = "=".repeat(40960); - sandbox.with_files(vec![FileWithContent("test.sh", script_body)]); + sandbox.with_files(&[FileWithContent("test.sh", script_body)]); // check for stdout let actual = nu!(cwd: dirs.test(), "sh test.sh | complete | get stdout | str trim"); diff --git a/crates/nu-command/tests/commands/database/into_sqlite.rs b/crates/nu-command/tests/commands/database/into_sqlite.rs index 6c25be1f9a..595c88dc38 100644 --- a/crates/nu-command/tests/commands/database/into_sqlite.rs +++ b/crates/nu-command/tests/commands/database/into_sqlite.rs @@ -304,7 +304,7 @@ fn into_sqlite_big_insert() { let nuon_path = dirs.test().join(NUON_FILE_NAME); - playground.with_files(vec![Stub::EmptyFile(&nuon_path.to_string_lossy())]); + playground.with_files(&[Stub::EmptyFile(&nuon_path.to_string_lossy())]); let mut expected_rows = Vec::new(); let mut nuon_file = std::fs::OpenOptions::new() diff --git a/crates/nu-command/tests/commands/du.rs b/crates/nu-command/tests/commands/du.rs index b5ec265153..1e22d54f2f 100644 --- a/crates/nu-command/tests/commands/du.rs +++ b/crates/nu-command/tests/commands/du.rs @@ -51,7 +51,7 @@ fn test_du_flag_max_depth() { #[case("a][c")] fn du_files_with_glob_metachars(#[case] src_name: &str) { Playground::setup("du_test_16", |dirs, sandbox| { - sandbox.with_files(vec![EmptyFile(src_name)]); + sandbox.with_files(&[EmptyFile(src_name)]); let src = dirs.test().join(src_name); diff --git a/crates/nu-command/tests/commands/every.rs b/crates/nu-command/tests/commands/every.rs index 688790c20a..6c52651512 100644 --- a/crates/nu-command/tests/commands/every.rs +++ b/crates/nu-command/tests/commands/every.rs @@ -5,7 +5,7 @@ use nu_test_support::{nu, pipeline}; #[test] fn gets_all_rows_by_every_zero() { Playground::setup("every_test_1", |dirs, sandbox| { - sandbox.with_files(vec![ + sandbox.with_files(&[ EmptyFile("amigos.txt"), EmptyFile("arepas.clu"), EmptyFile("los.txt"), @@ -32,7 +32,7 @@ fn gets_all_rows_by_every_zero() { #[test] fn gets_no_rows_by_every_skip_zero() { Playground::setup("every_test_2", |dirs, sandbox| { - sandbox.with_files(vec![ + sandbox.with_files(&[ EmptyFile("amigos.txt"), EmptyFile("arepas.clu"), EmptyFile("los.txt"), @@ -56,7 +56,7 @@ fn gets_no_rows_by_every_skip_zero() { #[test] fn gets_all_rows_by_every_one() { Playground::setup("every_test_3", |dirs, sandbox| { - sandbox.with_files(vec![ + sandbox.with_files(&[ EmptyFile("amigos.txt"), EmptyFile("arepas.clu"), EmptyFile("los.txt"), @@ -83,7 +83,7 @@ fn gets_all_rows_by_every_one() { #[test] fn gets_no_rows_by_every_skip_one() { Playground::setup("every_test_4", |dirs, sandbox| { - sandbox.with_files(vec![ + sandbox.with_files(&[ EmptyFile("amigos.txt"), EmptyFile("arepas.clu"), EmptyFile("los.txt"), @@ -107,7 +107,7 @@ fn gets_no_rows_by_every_skip_one() { #[test] fn gets_first_row_by_every_too_much() { Playground::setup("every_test_5", |dirs, sandbox| { - sandbox.with_files(vec![ + sandbox.with_files(&[ EmptyFile("amigos.txt"), EmptyFile("arepas.clu"), EmptyFile("los.txt"), @@ -132,7 +132,7 @@ fn gets_first_row_by_every_too_much() { #[test] fn gets_all_rows_except_first_by_every_skip_too_much() { Playground::setup("every_test_6", |dirs, sandbox| { - sandbox.with_files(vec![ + sandbox.with_files(&[ EmptyFile("amigos.txt"), EmptyFile("arepas.clu"), EmptyFile("los.txt"), @@ -156,7 +156,7 @@ fn gets_all_rows_except_first_by_every_skip_too_much() { #[test] fn gets_every_third_row() { Playground::setup("every_test_7", |dirs, sandbox| { - sandbox.with_files(vec![ + sandbox.with_files(&[ EmptyFile("amigos.txt"), EmptyFile("arepas.clu"), EmptyFile("los.txt"), @@ -181,7 +181,7 @@ fn gets_every_third_row() { #[test] fn skips_every_third_row() { Playground::setup("every_test_8", |dirs, sandbox| { - sandbox.with_files(vec![ + sandbox.with_files(&[ EmptyFile("amigos.txt"), EmptyFile("arepas.clu"), EmptyFile("los.txt"), diff --git a/crates/nu-command/tests/commands/first.rs b/crates/nu-command/tests/commands/first.rs index b034274db0..e01478f820 100644 --- a/crates/nu-command/tests/commands/first.rs +++ b/crates/nu-command/tests/commands/first.rs @@ -5,7 +5,7 @@ use nu_test_support::playground::Playground; #[test] fn gets_first_rows_by_amount() { Playground::setup("first_test_1", |dirs, sandbox| { - sandbox.with_files(vec![ + sandbox.with_files(&[ EmptyFile("los.txt"), EmptyFile("tres.txt"), EmptyFile("amigos.txt"), @@ -21,7 +21,7 @@ fn gets_first_rows_by_amount() { #[test] fn gets_all_rows_if_amount_higher_than_all_rows() { Playground::setup("first_test_2", |dirs, sandbox| { - sandbox.with_files(vec![ + sandbox.with_files(&[ EmptyFile("los.txt"), EmptyFile("tres.txt"), EmptyFile("amigos.txt"), @@ -38,7 +38,7 @@ fn gets_all_rows_if_amount_higher_than_all_rows() { #[test] fn gets_first_row_when_no_amount_given() { Playground::setup("first_test_3", |dirs, sandbox| { - sandbox.with_files(vec![EmptyFile("caballeros.txt"), EmptyFile("arepas.clu")]); + sandbox.with_files(&[EmptyFile("caballeros.txt"), EmptyFile("arepas.clu")]); // FIXME: We should probably change first to return a one row table instead of a record here let actual = nu!(cwd: dirs.test(), "ls | first | values | length"); diff --git a/crates/nu-command/tests/commands/format.rs b/crates/nu-command/tests/commands/format.rs index 75567a9a30..6b1649c8b5 100644 --- a/crates/nu-command/tests/commands/format.rs +++ b/crates/nu-command/tests/commands/format.rs @@ -65,7 +65,7 @@ fn error_unmatched_brace() { #[test] fn format_filesize_works() { Playground::setup("format_filesize_test_1", |dirs, sandbox| { - sandbox.with_files(vec![ + sandbox.with_files(&[ EmptyFile("yehuda.txt"), EmptyFile("jttxt"), EmptyFile("andres.txt"), @@ -90,7 +90,7 @@ fn format_filesize_works_with_nonempty_files() { Playground::setup( "format_filesize_works_with_nonempty_files", |dirs, sandbox| { - sandbox.with_files(vec![FileWithContentToBeTrimmed( + sandbox.with_files(&[FileWithContentToBeTrimmed( "sample.toml", r#" [dependency] diff --git a/crates/nu-command/tests/commands/get.rs b/crates/nu-command/tests/commands/get.rs index 4be0c76a6e..049b5b2899 100644 --- a/crates/nu-command/tests/commands/get.rs +++ b/crates/nu-command/tests/commands/get.rs @@ -17,7 +17,7 @@ fn simple_get_list() { #[test] fn fetches_a_row() { Playground::setup("get_test_1", |dirs, sandbox| { - sandbox.with_files(vec![FileWithContent( + sandbox.with_files(&[FileWithContent( "sample.toml", r#" nu_party_venue = "zion" @@ -33,7 +33,7 @@ fn fetches_a_row() { #[test] fn fetches_by_index() { Playground::setup("get_test_2", |dirs, sandbox| { - sandbox.with_files(vec![FileWithContent( + sandbox.with_files(&[FileWithContent( "sample.toml", r#" [package] @@ -53,7 +53,7 @@ fn fetches_by_index() { #[test] fn fetches_by_column_path() { Playground::setup("get_test_3", |dirs, sandbox| { - sandbox.with_files(vec![FileWithContent( + sandbox.with_files(&[FileWithContent( "sample.toml", r#" [package] @@ -70,7 +70,7 @@ fn fetches_by_column_path() { #[test] fn column_paths_are_either_double_quoted_or_regular_unquoted_words_separated_by_dot() { Playground::setup("get_test_4", |dirs, sandbox| { - sandbox.with_files(vec![FileWithContent( + sandbox.with_files(&[FileWithContent( "sample.toml", r#" [package] @@ -88,7 +88,7 @@ fn column_paths_are_either_double_quoted_or_regular_unquoted_words_separated_by_ #[test] fn fetches_more_than_one_column_path() { Playground::setup("get_test_5", |dirs, sandbox| { - sandbox.with_files(vec![FileWithContent( + sandbox.with_files(&[FileWithContent( "sample.toml", r#" [[fortune_tellers]] @@ -121,7 +121,7 @@ fn fetches_more_than_one_column_path() { #[test] fn errors_fetching_by_column_not_present() { Playground::setup("get_test_6", |dirs, sandbox| { - sandbox.with_files(vec![FileWithContent( + sandbox.with_files(&[FileWithContent( "sample.toml", r#" [tacos] @@ -141,7 +141,7 @@ fn errors_fetching_by_column_not_present() { #[test] fn errors_fetching_by_column_using_a_number() { Playground::setup("get_test_7", |dirs, sandbox| { - sandbox.with_files(vec![FileWithContent( + sandbox.with_files(&[FileWithContent( "sample.toml", r#" [spanish_lesson] @@ -158,7 +158,7 @@ fn errors_fetching_by_column_using_a_number() { #[test] fn errors_fetching_by_index_out_of_bounds() { Playground::setup("get_test_8", |dirs, sandbox| { - sandbox.with_files(vec![FileWithContent( + sandbox.with_files(&[FileWithContent( "sample.toml", r#" [spanish_lesson] diff --git a/crates/nu-command/tests/commands/glob.rs b/crates/nu-command/tests/commands/glob.rs index 0ab35158b0..235896f63d 100644 --- a/crates/nu-command/tests/commands/glob.rs +++ b/crates/nu-command/tests/commands/glob.rs @@ -7,7 +7,7 @@ use std::path::{Path, PathBuf}; #[test] fn empty_glob_pattern_triggers_error() { Playground::setup("glob_test_1", |dirs, sandbox| { - sandbox.with_files(vec![ + sandbox.with_files(&[ EmptyFile("yehuda.txt"), EmptyFile("jttxt"), EmptyFile("andres.txt"), @@ -25,7 +25,7 @@ fn empty_glob_pattern_triggers_error() { #[test] fn nonempty_glob_lists_matching_paths() { Playground::setup("glob_sanity_star", |dirs, sandbox| { - sandbox.with_files(vec![ + sandbox.with_files(&[ EmptyFile("yehuda.txt"), EmptyFile("jttxt"), EmptyFile("andres.txt"), @@ -43,13 +43,13 @@ fn nonempty_glob_lists_matching_paths() { #[test] fn glob_subdirs() { Playground::setup("glob_subdirs", |dirs, sandbox| { - sandbox.with_files(vec![ + sandbox.with_files(&[ EmptyFile("yehuda.txt"), EmptyFile("jttxt"), EmptyFile("andres.txt"), ]); sandbox.mkdir("children"); - sandbox.within("children").with_files(vec![ + sandbox.within("children").with_files(&[ EmptyFile("timothy.txt"), EmptyFile("tiffany.txt"), EmptyFile("trish.txt"), @@ -70,13 +70,13 @@ fn glob_subdirs() { #[test] fn glob_subdirs_ignore_dirs() { Playground::setup("glob_subdirs_ignore_directories", |dirs, sandbox| { - sandbox.with_files(vec![ + sandbox.with_files(&[ EmptyFile("yehuda.txt"), EmptyFile("jttxt"), EmptyFile("andres.txt"), ]); sandbox.mkdir("children"); - sandbox.within("children").with_files(vec![ + sandbox.within("children").with_files(&[ EmptyFile("timothy.txt"), EmptyFile("tiffany.txt"), EmptyFile("trish.txt"), @@ -97,13 +97,13 @@ fn glob_subdirs_ignore_dirs() { #[test] fn glob_ignore_files() { Playground::setup("glob_ignore_files", |dirs, sandbox| { - sandbox.with_files(vec![ + sandbox.with_files(&[ EmptyFile("yehuda.txt"), EmptyFile("jttxt"), EmptyFile("andres.txt"), ]); sandbox.mkdir("children"); - sandbox.within("children").with_files(vec![ + sandbox.within("children").with_files(&[ EmptyFile("timothy.txt"), EmptyFile("tiffany.txt"), EmptyFile("trish.txt"), diff --git a/crates/nu-command/tests/commands/hash_/mod.rs b/crates/nu-command/tests/commands/hash_/mod.rs index 21d4dc0dd6..76ae86f6e7 100644 --- a/crates/nu-command/tests/commands/hash_/mod.rs +++ b/crates/nu-command/tests/commands/hash_/mod.rs @@ -15,7 +15,7 @@ fn base64_encode_characterset_binhex() { echo 'username:password' | encode base64 --character-set binhex "#); - assert_eq!(actual.out, "F@0NEPjJD97kE\'&bEhFZEP3"); + assert_eq!(actual.out, "GA0PFQjKE@8kF'&cFhG[FQ3"); } #[test] @@ -31,9 +31,9 @@ fn error_when_invalid_character_set_given() { #[test] fn base64_decode_characterset_binhex() { - let actual = nu!(r#" - echo "F@0NEPjJD97kE'&bEhFZEP3" | decode base64 --character-set binhex --binary | decode utf-8 - "#); + let actual = nu!( + r#""GA0PFQjKE@8kF'&cFhG[FQ3" | decode base64 --character-set binhex --binary | decode utf-8"# + ); assert_eq!(actual.out, "username:password"); } diff --git a/crates/nu-command/tests/commands/help.rs b/crates/nu-command/tests/commands/help.rs index 50367e42fd..26e4a92b26 100644 --- a/crates/nu-command/tests/commands/help.rs +++ b/crates/nu-command/tests/commands/help.rs @@ -38,7 +38,7 @@ fn help_aliases() { #[test] fn help_alias_usage_1() { Playground::setup("help_alias_usage_1", |dirs, sandbox| { - sandbox.with_files(vec![FileWithContent( + sandbox.with_files(&[FileWithContent( "spam.nu", r#" # line1 @@ -70,7 +70,7 @@ fn help_alias_usage_2() { #[test] fn help_alias_usage_3() { Playground::setup("help_alias_usage_3", |dirs, sandbox| { - sandbox.with_files(vec![FileWithContent( + sandbox.with_files(&[FileWithContent( "spam.nu", r#" # line1 @@ -92,7 +92,7 @@ fn help_alias_usage_3() { #[test] fn help_alias_name() { Playground::setup("help_alias_name", |dirs, sandbox| { - sandbox.with_files(vec![FileWithContent( + sandbox.with_files(&[FileWithContent( "spam.nu", r#" # line1 @@ -113,7 +113,7 @@ fn help_alias_name() { #[test] fn help_alias_name_f() { Playground::setup("help_alias_name_f", |dirs, sandbox| { - sandbox.with_files(vec![FileWithContent( + sandbox.with_files(&[FileWithContent( "spam.nu", r#" # line1 @@ -132,7 +132,7 @@ fn help_alias_name_f() { #[test] fn help_export_alias_name_single_word() { Playground::setup("help_export_alias_name_single_word", |dirs, sandbox| { - sandbox.with_files(vec![FileWithContent( + sandbox.with_files(&[FileWithContent( "spam.nu", r#" # line1 @@ -153,7 +153,7 @@ fn help_export_alias_name_single_word() { #[test] fn help_export_alias_name_multi_word() { Playground::setup("help_export_alias_name_multi_word", |dirs, sandbox| { - sandbox.with_files(vec![FileWithContent( + sandbox.with_files(&[FileWithContent( "spam.nu", r#" # line1 @@ -174,7 +174,7 @@ fn help_export_alias_name_multi_word() { #[test] fn help_module_usage_1() { Playground::setup("help_module_usage", |dirs, sandbox| { - sandbox.with_files(vec![FileWithContent( + sandbox.with_files(&[FileWithContent( "spam.nu", r#" # line1 @@ -199,7 +199,7 @@ fn help_module_usage_1() { #[test] fn help_module_name() { Playground::setup("help_module_name", |dirs, sandbox| { - sandbox.with_files(vec![FileWithContent( + sandbox.with_files(&[FileWithContent( "spam.nu", r#" # line1 @@ -222,7 +222,7 @@ fn help_module_name() { #[test] fn help_module_sorted_decls() { Playground::setup("help_module_sorted_decls", |dirs, sandbox| { - sandbox.with_files(vec![FileWithContent( + sandbox.with_files(&[FileWithContent( "spam.nu", r#" module SPAM { @@ -242,7 +242,7 @@ fn help_module_sorted_decls() { #[test] fn help_module_sorted_aliases() { Playground::setup("help_module_sorted_aliases", |dirs, sandbox| { - sandbox.with_files(vec![FileWithContent( + sandbox.with_files(&[FileWithContent( "spam.nu", r#" module SPAM { @@ -262,7 +262,7 @@ fn help_module_sorted_aliases() { #[test] fn help_usage_extra_usage_command() { Playground::setup("help_usage_extra_usage_command", |dirs, sandbox| { - sandbox.with_files(vec![FileWithContent( + sandbox.with_files(&[FileWithContent( "spam.nu", r#" # module_line1 @@ -299,7 +299,7 @@ fn help_usage_extra_usage_command() { #[test] fn help_usage_extra_usage_alias() { Playground::setup("help_usage_extra_usage_alias", |dirs, sandbox| { - sandbox.with_files(vec![FileWithContent( + sandbox.with_files(&[FileWithContent( "spam.nu", r#" # module_line1 diff --git a/crates/nu-command/tests/commands/last.rs b/crates/nu-command/tests/commands/last.rs index f842f26520..b0c67e49be 100644 --- a/crates/nu-command/tests/commands/last.rs +++ b/crates/nu-command/tests/commands/last.rs @@ -15,7 +15,7 @@ fn gets_the_last_row() { #[test] fn gets_last_rows_by_amount() { Playground::setup("last_test_1", |dirs, sandbox| { - sandbox.with_files(vec![ + sandbox.with_files(&[ EmptyFile("los.txt"), EmptyFile("tres.txt"), EmptyFile("amigos.txt"), @@ -31,7 +31,7 @@ fn gets_last_rows_by_amount() { #[test] fn gets_last_row_when_no_amount_given() { Playground::setup("last_test_2", |dirs, sandbox| { - sandbox.with_files(vec![EmptyFile("caballeros.txt"), EmptyFile("arepas.clu")]); + sandbox.with_files(&[EmptyFile("caballeros.txt"), EmptyFile("arepas.clu")]); // FIXME: We should probably change last to return a one row table instead of a record here let actual = nu!(cwd: dirs.test(), "ls | last | values | length"); diff --git a/crates/nu-command/tests/commands/ls.rs b/crates/nu-command/tests/commands/ls.rs index 61afe355e5..8ccdcfaf93 100644 --- a/crates/nu-command/tests/commands/ls.rs +++ b/crates/nu-command/tests/commands/ls.rs @@ -5,7 +5,7 @@ use nu_test_support::{nu, pipeline}; #[test] fn lists_regular_files() { Playground::setup("ls_test_1", |dirs, sandbox| { - sandbox.with_files(vec![ + sandbox.with_files(&[ EmptyFile("yehuda.txt"), EmptyFile("jttxt"), EmptyFile("andres.txt"), @@ -26,7 +26,7 @@ fn lists_regular_files() { #[test] fn lists_regular_files_using_asterisk_wildcard() { Playground::setup("ls_test_2", |dirs, sandbox| { - sandbox.with_files(vec![ + sandbox.with_files(&[ EmptyFile("los.txt"), EmptyFile("tres.txt"), EmptyFile("amigos.txt"), @@ -56,11 +56,11 @@ fn lists_regular_files_in_special_folder() { .mkdir("abcd") .mkdir("abcd/*") .mkdir("abcd/?") - .with_files(vec![EmptyFile("[abcd]/test.txt")]) - .with_files(vec![EmptyFile("abcd]/test.txt")]) - .with_files(vec![EmptyFile("abcd/*/test.txt")]) - .with_files(vec![EmptyFile("abcd/?/test.txt")]) - .with_files(vec![EmptyFile("abcd/?/test2.txt")]); + .with_files(&[EmptyFile("[abcd]/test.txt")]) + .with_files(&[EmptyFile("abcd]/test.txt")]) + .with_files(&[EmptyFile("abcd/*/test.txt")]) + .with_files(&[EmptyFile("abcd/?/test.txt")]) + .with_files(&[EmptyFile("abcd/?/test2.txt")]); let actual = nu!( cwd: dirs.test().join("abcd]"), format!(r#"ls | length"#)); @@ -119,7 +119,7 @@ fn lists_regular_files_in_special_folder() { #[case("'[bbcd].txt'", 1)] fn lists_regular_files_using_question_mark(#[case] command: &str, #[case] expected: usize) { Playground::setup("ls_test_3", |dirs, sandbox| { - sandbox.mkdir("abcd").mkdir("bbcd").with_files(vec![ + sandbox.mkdir("abcd").mkdir("bbcd").with_files(&[ EmptyFile("abcd/xy.txt"), EmptyFile("bbcd/yy.txt"), EmptyFile("[abcd].txt"), @@ -141,7 +141,7 @@ fn lists_regular_files_using_question_mark(#[case] command: &str, #[case] expect #[test] fn lists_regular_files_using_question_mark_wildcard() { Playground::setup("ls_test_3", |dirs, sandbox| { - sandbox.with_files(vec![ + sandbox.with_files(&[ EmptyFile("yehuda.10.txt"), EmptyFile("jt.10.txt"), EmptyFile("andres.10.txt"), @@ -164,11 +164,11 @@ fn lists_regular_files_using_question_mark_wildcard() { fn lists_all_files_in_directories_from_stream() { Playground::setup("ls_test_4", |dirs, sandbox| { sandbox - .with_files(vec![EmptyFile("root1.txt"), EmptyFile("root2.txt")]) + .with_files(&[EmptyFile("root1.txt"), EmptyFile("root2.txt")]) .within("dir_a") - .with_files(vec![EmptyFile("yehuda.10.txt"), EmptyFile("jt10.txt")]) + .with_files(&[EmptyFile("yehuda.10.txt"), EmptyFile("jt10.txt")]) .within("dir_b") - .with_files(vec![ + .with_files(&[ EmptyFile("andres.10.txt"), EmptyFile("chicken_not_to_be_picked_up.100.txt"), ]); @@ -206,7 +206,7 @@ fn does_not_fail_if_glob_matches_empty_directory() { #[test] fn fails_when_glob_doesnt_match() { Playground::setup("ls_test_5", |dirs, sandbox| { - sandbox.with_files(vec![EmptyFile("root1.txt"), EmptyFile("root2.txt")]); + sandbox.with_files(&[EmptyFile("root1.txt"), EmptyFile("root2.txt")]); let actual = nu!( cwd: dirs.test(), @@ -220,7 +220,7 @@ fn fails_when_glob_doesnt_match() { #[test] fn list_files_from_two_parents_up_using_multiple_dots() { Playground::setup("ls_test_6", |dirs, sandbox| { - sandbox.with_files(vec![ + sandbox.with_files(&[ EmptyFile("yahuda.yaml"), EmptyFile("jtjson"), EmptyFile("andres.xml"), @@ -243,7 +243,7 @@ fn list_files_from_two_parents_up_using_multiple_dots() { #[test] fn lists_hidden_file_when_explicitly_specified() { Playground::setup("ls_test_7", |dirs, sandbox| { - sandbox.with_files(vec![ + sandbox.with_files(&[ EmptyFile("los.txt"), EmptyFile("tres.txt"), EmptyFile("amigos.txt"), @@ -267,19 +267,19 @@ fn lists_hidden_file_when_explicitly_specified() { fn lists_all_hidden_files_when_glob_contains_dot() { Playground::setup("ls_test_8", |dirs, sandbox| { sandbox - .with_files(vec![ + .with_files(&[ EmptyFile("root1.txt"), EmptyFile("root2.txt"), EmptyFile(".dotfile1"), ]) .within("dir_a") - .with_files(vec![ + .with_files(&[ EmptyFile("yehuda.10.txt"), EmptyFile("jt10.txt"), EmptyFile(".dotfile2"), ]) .within("dir_b") - .with_files(vec![ + .with_files(&[ EmptyFile("andres.10.txt"), EmptyFile("chicken_not_to_be_picked_up.100.txt"), EmptyFile(".dotfile3"), @@ -304,19 +304,19 @@ fn lists_all_hidden_files_when_glob_contains_dot() { fn lists_all_hidden_files_when_glob_does_not_contain_dot() { Playground::setup("ls_test_8", |dirs, sandbox| { sandbox - .with_files(vec![ + .with_files(&[ EmptyFile("root1.txt"), EmptyFile("root2.txt"), EmptyFile(".dotfile1"), ]) .within("dir_a") - .with_files(vec![ + .with_files(&[ EmptyFile("yehuda.10.txt"), EmptyFile("jt10.txt"), EmptyFile(".dotfile2"), ]) .within(".dir_b") - .with_files(vec![ + .with_files(&[ EmptyFile("andres.10.txt"), EmptyFile("chicken_not_to_be_picked_up.100.txt"), EmptyFile(".dotfile3"), @@ -340,7 +340,7 @@ fn lists_all_hidden_files_when_glob_does_not_contain_dot() { #[cfg(unix)] fn glob_with_hidden_directory() { Playground::setup("ls_test_8", |dirs, sandbox| { - sandbox.within(".dir_b").with_files(vec![ + sandbox.within(".dir_b").with_files(&[ EmptyFile("andres.10.txt"), EmptyFile("chicken_not_to_be_picked_up.100.txt"), EmptyFile(".dotfile3"), @@ -376,7 +376,7 @@ fn fails_with_ls_to_dir_without_permission() { Playground::setup("ls_test_1", |dirs, sandbox| { sandbox .within("dir_a") - .with_files(vec![EmptyFile("yehuda.11.txt"), EmptyFile("jt10.txt")]); + .with_files(&[EmptyFile("yehuda.11.txt"), EmptyFile("jt10.txt")]); let actual = nu!( cwd: dirs.test(), pipeline( @@ -404,7 +404,7 @@ fn fails_with_ls_to_dir_without_permission() { #[test] fn lists_files_including_starting_with_dot() { Playground::setup("ls_test_9", |dirs, sandbox| { - sandbox.with_files(vec![ + sandbox.with_files(&[ EmptyFile("yehuda.txt"), EmptyFile("jttxt"), EmptyFile("andres.txt"), @@ -427,7 +427,7 @@ fn lists_files_including_starting_with_dot() { #[test] fn list_all_columns() { Playground::setup("ls_test_all_columns", |dirs, sandbox| { - sandbox.with_files(vec![ + sandbox.with_files(&[ EmptyFile("Leonardo.yaml"), EmptyFile("Raphael.json"), EmptyFile("Donatello.xml"), @@ -486,7 +486,7 @@ fn lists_with_directory_flag() { Playground::setup("ls_test_flag_directory_1", |dirs, sandbox| { sandbox .within("dir_files") - .with_files(vec![EmptyFile("nushell.json")]) + .with_files(&[EmptyFile("nushell.json")]) .within("dir_empty"); let actual = nu!( cwd: dirs.test(), pipeline( @@ -514,7 +514,7 @@ fn lists_with_directory_flag_without_argument() { Playground::setup("ls_test_flag_directory_2", |dirs, sandbox| { sandbox .within("dir_files") - .with_files(vec![EmptyFile("nushell.json")]) + .with_files(&[EmptyFile("nushell.json")]) .within("dir_empty"); // Test if there are some files in the current directory let actual = nu!( @@ -631,7 +631,7 @@ fn list_directory_contains_invalid_utf8() { #[test] fn list_ignores_ansi() { Playground::setup("ls_test_ansi", |dirs, sandbox| { - sandbox.with_files(vec![ + sandbox.with_files(&[ EmptyFile("los.txt"), EmptyFile("tres.txt"), EmptyFile("amigos.txt"), @@ -662,7 +662,7 @@ fn list_unknown_flag() { fn list_flag_false() { // Check that ls flags respect explicit values Playground::setup("ls_test_false_flag", |dirs, sandbox| { - sandbox.with_files(vec![ + sandbox.with_files(&[ EmptyFile(".hidden"), EmptyFile("normal"), EmptyFile("another_normal"), @@ -705,7 +705,7 @@ fn list_flag_false() { #[test] fn list_empty_string() { Playground::setup("ls_empty_string", |dirs, sandbox| { - sandbox.with_files(vec![EmptyFile("yehuda.txt")]); + sandbox.with_files(&[EmptyFile("yehuda.txt")]); let actual = nu!(cwd: dirs.test(), "ls ''"); assert!(actual.err.contains("does not exist")); @@ -717,7 +717,7 @@ fn list_with_tilde() { Playground::setup("ls_tilde", |dirs, sandbox| { sandbox .within("~tilde") - .with_files(vec![EmptyFile("f1.txt"), EmptyFile("f2.txt")]); + .with_files(&[EmptyFile("f1.txt"), EmptyFile("f2.txt")]); let actual = nu!(cwd: dirs.test(), "ls '~tilde'"); assert!(actual.out.contains("f1.txt")); @@ -737,7 +737,7 @@ fn list_with_tilde() { #[test] fn list_with_multiple_path() { Playground::setup("ls_multiple_path", |dirs, sandbox| { - sandbox.with_files(vec![ + sandbox.with_files(&[ EmptyFile("f1.txt"), EmptyFile("f2.txt"), EmptyFile("f3.txt"), diff --git a/crates/nu-command/tests/commands/move_/umv.rs b/crates/nu-command/tests/commands/move_/umv.rs index 0d47fe3146..0c96c88a36 100644 --- a/crates/nu-command/tests/commands/move_/umv.rs +++ b/crates/nu-command/tests/commands/move_/umv.rs @@ -8,7 +8,7 @@ use std::path::Path; fn moves_a_file() { Playground::setup("umv_test_1", |dirs, sandbox| { sandbox - .with_files(vec![EmptyFile("andres.txt")]) + .with_files(&[EmptyFile("andres.txt")]) .mkdir("expected"); let original = dirs.test().join("andres.txt"); @@ -27,7 +27,7 @@ fn moves_a_file() { #[test] fn overwrites_if_moving_to_existing_file_and_force_provided() { Playground::setup("umv_test_2", |dirs, sandbox| { - sandbox.with_files(vec![EmptyFile("andres.txt"), EmptyFile("jttxt")]); + sandbox.with_files(&[EmptyFile("andres.txt"), EmptyFile("jttxt")]); let original = dirs.test().join("andres.txt"); let expected = dirs.test().join("jttxt"); @@ -63,9 +63,7 @@ fn moves_a_directory() { #[test] fn moves_the_file_inside_directory_if_path_to_move_is_existing_directory() { Playground::setup("umv_test_4", |dirs, sandbox| { - sandbox - .with_files(vec![EmptyFile("jttxt")]) - .mkdir("expected"); + sandbox.with_files(&[EmptyFile("jttxt")]).mkdir("expected"); let original_dir = dirs.test().join("jttxt"); let expected = dirs.test().join("expected/jttxt"); @@ -85,7 +83,7 @@ fn moves_the_directory_inside_directory_if_path_to_move_is_existing_directory() Playground::setup("umv_test_5", |dirs, sandbox| { sandbox .within("contributors") - .with_files(vec![EmptyFile("jttxt")]) + .with_files(&[EmptyFile("jttxt")]) .mkdir("expected"); let original_dir = dirs.test().join("contributors"); @@ -107,7 +105,7 @@ fn moves_using_path_with_wildcard() { Playground::setup("umv_test_7", |dirs, sandbox| { sandbox .within("originals") - .with_files(vec![ + .with_files(&[ EmptyFile("andres.ini"), EmptyFile("caco3_plastics.csv"), EmptyFile("cargo_sample.toml"), @@ -138,7 +136,7 @@ fn moves_using_a_glob() { Playground::setup("umv_test_8", |dirs, sandbox| { sandbox .within("meals") - .with_files(vec![ + .with_files(&[ EmptyFile("arepa.txt"), EmptyFile("empanada.txt"), EmptyFile("taquiza.txt"), @@ -166,11 +164,11 @@ fn moves_a_directory_with_files() { sandbox .mkdir("vehicles/car") .mkdir("vehicles/bicycle") - .with_files(vec![ + .with_files(&[ EmptyFile("vehicles/car/car1.txt"), EmptyFile("vehicles/car/car2.txt"), ]) - .with_files(vec![ + .with_files(&[ EmptyFile("vehicles/bicycle/bicycle1.txt"), EmptyFile("vehicles/bicycle/bicycle2.txt"), ]); @@ -213,7 +211,7 @@ fn errors_if_source_doesnt_exist() { #[ignore = "GNU/uutils overwrites rather than error out"] fn error_if_moving_to_existing_file_without_force() { Playground::setup("umv_test_10_0", |dirs, sandbox| { - sandbox.with_files(vec![EmptyFile("andres.txt"), EmptyFile("jttxt")]); + sandbox.with_files(&[EmptyFile("andres.txt"), EmptyFile("jttxt")]); let actual = nu!( cwd: dirs.test(), @@ -226,7 +224,7 @@ fn error_if_moving_to_existing_file_without_force() { #[test] fn errors_if_destination_doesnt_exist() { Playground::setup("umv_test_10_1", |dirs, sandbox| { - sandbox.with_files(vec![EmptyFile("empty.txt")]); + sandbox.with_files(&[EmptyFile("empty.txt")]); let actual = nu!( cwd: dirs.test(), @@ -241,7 +239,7 @@ fn errors_if_destination_doesnt_exist() { #[ignore = "GNU/uutils doesnt expand, rather cannot stat 'file?.txt'"] fn errors_if_multiple_sources_but_destination_not_a_directory() { Playground::setup("umv_test_10_2", |dirs, sandbox| { - sandbox.with_files(vec![ + sandbox.with_files(&[ EmptyFile("file1.txt"), EmptyFile("file2.txt"), EmptyFile("file3.txt"), @@ -261,9 +259,7 @@ fn errors_if_multiple_sources_but_destination_not_a_directory() { #[test] fn errors_if_renaming_directory_to_an_existing_file() { Playground::setup("umv_test_10_3", |dirs, sandbox| { - sandbox - .mkdir("mydir") - .with_files(vec![EmptyFile("empty.txt")]); + sandbox.mkdir("mydir").with_files(&[EmptyFile("empty.txt")]); let actual = nu!( cwd: dirs.test(), @@ -293,7 +289,7 @@ fn does_not_error_on_relative_parent_path() { Playground::setup("umv_test_11", |dirs, sandbox| { sandbox .mkdir("first") - .with_files(vec![EmptyFile("first/william_hartnell.txt")]); + .with_files(&[EmptyFile("first/william_hartnell.txt")]); let original = dirs.test().join("first/william_hartnell.txt"); let expected = dirs.test().join("william_hartnell.txt"); @@ -311,7 +307,7 @@ fn does_not_error_on_relative_parent_path() { #[test] fn move_files_using_glob_two_parents_up_using_multiple_dots() { Playground::setup("umv_test_12", |dirs, sandbox| { - sandbox.within("foo").within("bar").with_files(vec![ + sandbox.within("foo").within("bar").with_files(&[ EmptyFile("jtjson"), EmptyFile("andres.xml"), EmptyFile("yehuda.yaml"), @@ -345,7 +341,7 @@ fn move_files_using_glob_two_parents_up_using_multiple_dots() { #[test] fn move_file_from_two_parents_up_using_multiple_dots_to_current_dir() { Playground::setup("cp_test_10", |dirs, sandbox| { - sandbox.with_files(vec![EmptyFile("hello_there")]); + sandbox.with_files(&[EmptyFile("hello_there")]); sandbox.within("foo").mkdir("bar"); nu!( @@ -380,7 +376,7 @@ fn does_not_error_when_some_file_is_moving_into_itself() { #[test] fn mv_ignores_ansi() { Playground::setup("umv_test_ansi", |_dirs, sandbox| { - sandbox.with_files(vec![EmptyFile("test.txt")]); + sandbox.with_files(&[EmptyFile("test.txt")]); let actual = nu!( cwd: sandbox.cwd(), r#" @@ -420,7 +416,7 @@ fn mv_change_case_of_directory() { Playground::setup("mv_change_case_of_directory", |dirs, sandbox| { sandbox .mkdir("somedir") - .with_files(vec![EmptyFile("somedir/somefile.txt")]); + .with_files(&[EmptyFile("somedir/somefile.txt")]); let original_dir = String::from("somedir"); let new_dir = String::from("SomeDir"); @@ -459,7 +455,7 @@ fn mv_change_case_of_directory() { // but fail on both macOS and Windows. fn mv_change_case_of_file() { Playground::setup("mv_change_case_of_file", |dirs, sandbox| { - sandbox.with_files(vec![EmptyFile("somefile.txt")]); + sandbox.with_files(&[EmptyFile("somefile.txt")]); let original_file_name = String::from("somefile.txt"); let new_file_name = String::from("SomeFile.txt"); @@ -489,7 +485,7 @@ fn mv_change_case_of_file() { #[ignore = "Update not supported..remove later"] fn mv_with_update_flag() { Playground::setup("umv_with_update_flag", |_dirs, sandbox| { - sandbox.with_files(vec![ + sandbox.with_files(&[ EmptyFile("valid.txt"), FileWithContent("newer_valid.txt", "body"), ]); @@ -502,12 +498,12 @@ fn mv_with_update_flag() { // create a file after assert to make sure that newest_valid.txt is newest std::thread::sleep(std::time::Duration::from_secs(1)); - sandbox.with_files(vec![FileWithContent("newest_valid.txt", "newest_body")]); + sandbox.with_files(&[FileWithContent("newest_valid.txt", "newest_body")]); let actual = nu!(cwd: sandbox.cwd(), "mv -uf newest_valid.txt valid.txt; open valid.txt"); assert_eq!(actual.out, "newest_body"); // when destination doesn't exist - sandbox.with_files(vec![FileWithContent("newest_valid.txt", "newest_body")]); + sandbox.with_files(&[FileWithContent("newest_valid.txt", "newest_body")]); let actual = nu!(cwd: sandbox.cwd(), "mv -uf newest_valid.txt des_missing.txt; open des_missing.txt"); assert_eq!(actual.out, "newest_body"); }); @@ -518,8 +514,8 @@ fn test_mv_no_clobber() { Playground::setup("umv_test_13", |dirs, sandbox| { let file_a = "test_mv_no_clobber_file_a"; let file_b = "test_mv_no_clobber_file_b"; - sandbox.with_files(vec![EmptyFile(file_a)]); - sandbox.with_files(vec![EmptyFile(file_b)]); + sandbox.with_files(&[EmptyFile(file_a)]); + sandbox.with_files(&[EmptyFile(file_b)]); let actual = nu!( cwd: dirs.test(), @@ -566,7 +562,7 @@ fn mv_with_no_target() { #[case("a][c")] fn mv_files_with_glob_metachars(#[case] src_name: &str) { Playground::setup("umv_test_16", |dirs, sandbox| { - sandbox.with_files(vec![FileWithContent( + sandbox.with_files(&[FileWithContent( src_name, "What is the sound of one hand clapping?", )]); @@ -592,7 +588,7 @@ fn mv_files_with_glob_metachars(#[case] src_name: &str) { #[case("a][c")] fn mv_files_with_glob_metachars_when_input_are_variables(#[case] src_name: &str) { Playground::setup("umv_test_18", |dirs, sandbox| { - sandbox.with_files(vec![FileWithContent( + sandbox.with_files(&[FileWithContent( src_name, "What is the sound of one hand clapping?", )]); @@ -626,7 +622,7 @@ fn mv_with_cd() { Playground::setup("umv_test_17", |_dirs, sandbox| { sandbox .mkdir("tmp_dir") - .with_files(vec![FileWithContent("tmp_dir/file.txt", "body")]); + .with_files(&[FileWithContent("tmp_dir/file.txt", "body")]); let actual = nu!( cwd: sandbox.cwd(), @@ -642,7 +638,7 @@ fn test_cp_inside_glob_metachars_dir() { let sub_dir = "test[]"; sandbox .within(sub_dir) - .with_files(vec![FileWithContent("test_file.txt", "hello")]); + .with_files(&[FileWithContent("test_file.txt", "hello")]); let actual = nu!( cwd: dirs.test().join(sub_dir), @@ -661,7 +657,7 @@ fn test_cp_inside_glob_metachars_dir() { #[test] fn mv_with_tilde() { Playground::setup("mv_tilde", |dirs, sandbox| { - sandbox.within("~tilde").with_files(vec![ + sandbox.within("~tilde").with_files(&[ EmptyFile("f1.txt"), EmptyFile("f2.txt"), EmptyFile("f3.txt"), diff --git a/crates/nu-command/tests/commands/nu_check.rs b/crates/nu-command/tests/commands/nu_check.rs index c8c8254411..ee8bf32c24 100644 --- a/crates/nu-command/tests/commands/nu_check.rs +++ b/crates/nu-command/tests/commands/nu_check.rs @@ -5,7 +5,7 @@ use nu_test_support::{nu, pipeline}; #[test] fn parse_script_success() { Playground::setup("nu_check_test_1", |dirs, sandbox| { - sandbox.with_files(vec![FileWithContentToBeTrimmed( + sandbox.with_files(&[FileWithContentToBeTrimmed( "script.nu", r#" greet "world" @@ -30,7 +30,7 @@ fn parse_script_success() { #[test] fn parse_script_with_wrong_type() { Playground::setup("nu_check_test_2", |dirs, sandbox| { - sandbox.with_files(vec![FileWithContentToBeTrimmed( + sandbox.with_files(&[FileWithContentToBeTrimmed( "script.nu", r#" greet "world" @@ -54,7 +54,7 @@ fn parse_script_with_wrong_type() { #[test] fn parse_script_failure() { Playground::setup("nu_check_test_3", |dirs, sandbox| { - sandbox.with_files(vec![FileWithContentToBeTrimmed( + sandbox.with_files(&[FileWithContentToBeTrimmed( "script.nu", r#" greet "world" @@ -79,7 +79,7 @@ fn parse_script_failure() { #[test] fn parse_module_success() { Playground::setup("nu_check_test_4", |dirs, sandbox| { - sandbox.with_files(vec![FileWithContentToBeTrimmed( + sandbox.with_files(&[FileWithContentToBeTrimmed( "foo.nu", r#" # foo.nu @@ -108,7 +108,7 @@ fn parse_module_success() { #[test] fn parse_module_with_wrong_type() { Playground::setup("nu_check_test_5", |dirs, sandbox| { - sandbox.with_files(vec![FileWithContentToBeTrimmed( + sandbox.with_files(&[FileWithContentToBeTrimmed( "foo.nu", r#" # foo.nu @@ -136,7 +136,7 @@ fn parse_module_with_wrong_type() { #[test] fn parse_module_failure() { Playground::setup("nu_check_test_6", |dirs, sandbox| { - sandbox.with_files(vec![FileWithContentToBeTrimmed( + sandbox.with_files(&[FileWithContentToBeTrimmed( "foo.nu", r#" # foo.nu @@ -179,7 +179,7 @@ fn file_not_exist() { #[test] fn parse_module_success_2() { Playground::setup("nu_check_test_10", |dirs, sandbox| { - sandbox.with_files(vec![FileWithContentToBeTrimmed( + sandbox.with_files(&[FileWithContentToBeTrimmed( "foo.nu", r#" # foo.nu @@ -202,7 +202,7 @@ fn parse_module_success_2() { #[test] fn parse_script_success_with_raw_stream() { Playground::setup("nu_check_test_11", |dirs, sandbox| { - sandbox.with_files(vec![FileWithContentToBeTrimmed( + sandbox.with_files(&[FileWithContentToBeTrimmed( "script.nu", r#" greet "world" @@ -227,7 +227,7 @@ fn parse_script_success_with_raw_stream() { #[test] fn parse_module_success_with_raw_stream() { Playground::setup("nu_check_test_12", |dirs, sandbox| { - sandbox.with_files(vec![FileWithContentToBeTrimmed( + sandbox.with_files(&[FileWithContentToBeTrimmed( "foo.nu", r#" # foo.nu @@ -285,7 +285,7 @@ fn parse_string_as_script() { #[test] fn parse_module_success_with_internal_stream() { Playground::setup("nu_check_test_15", |dirs, sandbox| { - sandbox.with_files(vec![FileWithContentToBeTrimmed( + sandbox.with_files(&[FileWithContentToBeTrimmed( "foo.nu", r#" # foo.nu @@ -314,7 +314,7 @@ fn parse_module_success_with_internal_stream() { #[test] fn parse_script_success_with_complex_internal_stream() { Playground::setup("nu_check_test_16", |dirs, sandbox| { - sandbox.with_files(vec![FileWithContentToBeTrimmed( + sandbox.with_files(&[FileWithContentToBeTrimmed( "grep.nu", r#" #grep for nu @@ -363,7 +363,7 @@ fn parse_script_success_with_complex_internal_stream() { #[test] fn parse_script_failure_with_complex_internal_stream() { Playground::setup("nu_check_test_17", |dirs, sandbox| { - sandbox.with_files(vec![FileWithContentToBeTrimmed( + sandbox.with_files(&[FileWithContentToBeTrimmed( "grep.nu", r#" #grep for nu @@ -412,7 +412,7 @@ fn parse_script_failure_with_complex_internal_stream() { #[test] fn parse_script_success_with_complex_external_stream() { Playground::setup("nu_check_test_18", |dirs, sandbox| { - sandbox.with_files(vec![FileWithContentToBeTrimmed( + sandbox.with_files(&[FileWithContentToBeTrimmed( "grep.nu", r#" #grep for nu @@ -461,7 +461,7 @@ fn parse_script_success_with_complex_external_stream() { #[test] fn parse_module_success_with_complex_external_stream() { Playground::setup("nu_check_test_19", |dirs, sandbox| { - sandbox.with_files(vec![FileWithContentToBeTrimmed( + sandbox.with_files(&[FileWithContentToBeTrimmed( "grep.nu", r#" #grep for nu @@ -510,7 +510,7 @@ fn parse_module_success_with_complex_external_stream() { #[test] fn parse_with_flag_success_for_complex_external_stream() { Playground::setup("nu_check_test_20", |dirs, sandbox| { - sandbox.with_files(vec![FileWithContentToBeTrimmed( + sandbox.with_files(&[FileWithContentToBeTrimmed( "grep.nu", r#" #grep for nu @@ -559,7 +559,7 @@ fn parse_with_flag_success_for_complex_external_stream() { #[test] fn parse_with_flag_failure_for_complex_external_stream() { Playground::setup("nu_check_test_21", |dirs, sandbox| { - sandbox.with_files(vec![FileWithContentToBeTrimmed( + sandbox.with_files(&[FileWithContentToBeTrimmed( "grep.nu", r#" #grep for nu @@ -608,7 +608,7 @@ fn parse_with_flag_failure_for_complex_external_stream() { #[test] fn parse_with_flag_failure_for_complex_list_stream() { Playground::setup("nu_check_test_22", |dirs, sandbox| { - sandbox.with_files(vec![FileWithContentToBeTrimmed( + sandbox.with_files(&[FileWithContentToBeTrimmed( "grep.nu", r#" #grep for nu @@ -659,7 +659,7 @@ fn parse_script_with_nested_scripts_success() { Playground::setup("nu_check_test_24", |dirs, sandbox| { sandbox .mkdir("lol") - .with_files(vec![FileWithContentToBeTrimmed( + .with_files(&[FileWithContentToBeTrimmed( "lol/lol.nu", r#" source-env ../foo.nu @@ -667,13 +667,13 @@ fn parse_script_with_nested_scripts_success() { overlay use ../lol/lol_shell.nu "#, )]) - .with_files(vec![FileWithContentToBeTrimmed( + .with_files(&[FileWithContentToBeTrimmed( "lol/lol_shell.nu", r#" export def ls [] { "lol" } "#, )]) - .with_files(vec![FileWithContentToBeTrimmed( + .with_files(&[FileWithContentToBeTrimmed( "foo.nu", r#" $env.FOO = 'foo' @@ -696,13 +696,13 @@ fn nu_check_respects_file_pwd() { Playground::setup("nu_check_test_25", |dirs, sandbox| { sandbox .mkdir("lol") - .with_files(vec![FileWithContentToBeTrimmed( + .with_files(&[FileWithContentToBeTrimmed( "lol/lol.nu", r#" $env.RETURN = (nu-check ../foo.nu) "#, )]) - .with_files(vec![FileWithContentToBeTrimmed( + .with_files(&[FileWithContentToBeTrimmed( "foo.nu", r#" echo 'foo' @@ -725,14 +725,14 @@ fn nu_check_module_dir() { Playground::setup("nu_check_test_26", |dirs, sandbox| { sandbox .mkdir("lol") - .with_files(vec![FileWithContentToBeTrimmed( + .with_files(&[FileWithContentToBeTrimmed( "lol/mod.nu", r#" export module foo.nu export def main [] { 'lol' } "#, )]) - .with_files(vec![FileWithContentToBeTrimmed( + .with_files(&[FileWithContentToBeTrimmed( "lol/foo.nu", r#" export def main [] { 'lol foo' } diff --git a/crates/nu-command/tests/commands/open.rs b/crates/nu-command/tests/commands/open.rs index 434bdbb764..f857718c72 100644 --- a/crates/nu-command/tests/commands/open.rs +++ b/crates/nu-command/tests/commands/open.rs @@ -8,7 +8,7 @@ use rstest::rstest; #[test] fn parses_file_with_uppercase_extension() { Playground::setup("open_test_uppercase_extension", |dirs, sandbox| { - sandbox.with_files(vec![FileWithContent( + sandbox.with_files(&[FileWithContent( "nu.zion.JSON", r#"{ "glossary": { @@ -38,7 +38,7 @@ fn parses_file_with_uppercase_extension() { #[test] fn parses_file_with_multiple_extensions() { Playground::setup("open_test_multiple_extensions", |dirs, sandbox| { - sandbox.with_files(vec![ + sandbox.with_files(&[ FileWithContent("file.tar.gz", "this is a tar.gz file"), FileWithContent("file.tar.xz", "this is a tar.xz file"), ]); @@ -77,7 +77,7 @@ fn parses_file_with_multiple_extensions() { #[test] fn parses_dotfile() { Playground::setup("open_test_dotfile", |dirs, sandbox| { - sandbox.with_files(vec![FileWithContent( + sandbox.with_files(&[FileWithContent( ".gitignore", r#" /target/ @@ -101,7 +101,7 @@ fn parses_dotfile() { #[test] fn parses_csv() { Playground::setup("open_test_1", |dirs, sandbox| { - sandbox.with_files(vec![FileWithContentToBeTrimmed( + sandbox.with_files(&[FileWithContentToBeTrimmed( "nu.zion.csv", r#" author,lang,source @@ -318,7 +318,7 @@ fn test_open_block_command() { #[test] fn open_ignore_ansi() { Playground::setup("open_test_ansi", |dirs, sandbox| { - sandbox.with_files(vec![EmptyFile("nu.zion.txt")]); + sandbox.with_files(&[EmptyFile("nu.zion.txt")]); let actual = nu!( cwd: dirs.test(), pipeline( @@ -345,7 +345,7 @@ fn open_no_parameter() { #[case("a][c")] fn open_files_with_glob_metachars(#[case] src_name: &str) { Playground::setup("open_test_with_glob_metachars", |dirs, sandbox| { - sandbox.with_files(vec![FileWithContent(src_name, "hello")]); + sandbox.with_files(&[FileWithContent(src_name, "hello")]); let src = dirs.test().join(src_name); @@ -384,7 +384,7 @@ fn open_files_inside_glob_metachars_dir() { let sub_dir = "test[]"; sandbox .within(sub_dir) - .with_files(vec![FileWithContent("test_file.txt", "hello")]); + .with_files(&[FileWithContent("test_file.txt", "hello")]); let actual = nu!( cwd: dirs.test().join(sub_dir), diff --git a/crates/nu-command/tests/commands/parse.rs b/crates/nu-command/tests/commands/parse.rs index 93a2b395da..7f98eed83d 100644 --- a/crates/nu-command/tests/commands/parse.rs +++ b/crates/nu-command/tests/commands/parse.rs @@ -8,7 +8,7 @@ mod simple { #[test] fn extracts_fields_from_the_given_the_pattern() { Playground::setup("parse_test_1", |dirs, sandbox| { - sandbox.with_files(vec![Stub::FileWithContentToBeTrimmed( + sandbox.with_files(&[Stub::FileWithContentToBeTrimmed( "key_value_separated_arepa_ingredients.txt", r#" VAR1=Cheese @@ -117,7 +117,7 @@ mod regex { #[test] fn extracts_fields_with_all_named_groups() { Playground::setup("parse_test_regex_1", |dirs, sandbox| { - sandbox.with_files(nushell_git_log_oneline()); + sandbox.with_files(&nushell_git_log_oneline()); let actual = nu!( cwd: dirs.test(), pipeline( @@ -136,7 +136,7 @@ mod regex { #[test] fn extracts_fields_with_all_unnamed_groups() { Playground::setup("parse_test_regex_2", |dirs, sandbox| { - sandbox.with_files(nushell_git_log_oneline()); + sandbox.with_files(&nushell_git_log_oneline()); let actual = nu!( cwd: dirs.test(), pipeline( @@ -155,7 +155,7 @@ mod regex { #[test] fn extracts_fields_with_named_and_unnamed_groups() { Playground::setup("parse_test_regex_3", |dirs, sandbox| { - sandbox.with_files(nushell_git_log_oneline()); + sandbox.with_files(&nushell_git_log_oneline()); let actual = nu!( cwd: dirs.test(), pipeline( @@ -174,7 +174,7 @@ mod regex { #[test] fn errors_with_invalid_regex() { Playground::setup("parse_test_regex_1", |dirs, sandbox| { - sandbox.with_files(nushell_git_log_oneline()); + sandbox.with_files(&nushell_git_log_oneline()); let actual = nu!( cwd: dirs.test(), pipeline( @@ -216,7 +216,7 @@ mod regex { fn parse_handles_external_stream_chunking() { Playground::setup("parse_test_streaming_1", |dirs, sandbox| { let data: String = "abcdefghijklmnopqrstuvwxyz".repeat(1000); - sandbox.with_files(vec![Stub::FileWithContent("data.txt", &data)]); + sandbox.with_files(&[Stub::FileWithContent("data.txt", &data)]); let actual = nu!( cwd: dirs.test(), diff --git a/crates/nu-command/tests/commands/path/exists.rs b/crates/nu-command/tests/commands/path/exists.rs index 5b1b39a002..96fa02c0e8 100644 --- a/crates/nu-command/tests/commands/path/exists.rs +++ b/crates/nu-command/tests/commands/path/exists.rs @@ -5,7 +5,7 @@ use nu_test_support::playground::Playground; #[test] fn checks_if_existing_file_exists() { Playground::setup("path_exists_1", |dirs, sandbox| { - sandbox.with_files(vec![EmptyFile("spam.txt")]); + sandbox.with_files(&[EmptyFile("spam.txt")]); let actual = nu!( cwd: dirs.test(), diff --git a/crates/nu-command/tests/commands/path/expand.rs b/crates/nu-command/tests/commands/path/expand.rs index f3bdeb817b..71f2e03284 100644 --- a/crates/nu-command/tests/commands/path/expand.rs +++ b/crates/nu-command/tests/commands/path/expand.rs @@ -7,9 +7,7 @@ use std::path::PathBuf; #[test] fn expands_path_with_dot() { Playground::setup("path_expand_1", |dirs, sandbox| { - sandbox - .within("menu") - .with_files(vec![EmptyFile("spam.txt")]); + sandbox.within("menu").with_files(&[EmptyFile("spam.txt")]); let actual = nu!( cwd: dirs.test(), pipeline( @@ -28,9 +26,7 @@ fn expands_path_with_dot() { #[test] fn expands_path_without_follow_symlink() { Playground::setup("path_expand_3", |dirs, sandbox| { - sandbox - .within("menu") - .with_files(vec![EmptyFile("spam.txt")]); + sandbox.within("menu").with_files(&[EmptyFile("spam.txt")]); let actual = nu!( cwd: dirs.test(), pipeline( @@ -49,9 +45,7 @@ fn expands_path_without_follow_symlink() { #[test] fn expands_path_with_double_dot() { Playground::setup("path_expand_2", |dirs, sandbox| { - sandbox - .within("menu") - .with_files(vec![EmptyFile("spam.txt")]); + sandbox.within("menu").with_files(&[EmptyFile("spam.txt")]); let actual = nu!( cwd: dirs.test(), pipeline( @@ -69,9 +63,7 @@ fn expands_path_with_double_dot() { #[test] fn const_path_expand() { Playground::setup("const_path_expand", |dirs, sandbox| { - sandbox - .within("menu") - .with_files(vec![EmptyFile("spam.txt")]); + sandbox.within("menu").with_files(&[EmptyFile("spam.txt")]); let actual = nu!( cwd: dirs.test(), pipeline( @@ -121,9 +113,7 @@ mod windows { #[test] fn expands_path_without_follow_symlink() { Playground::setup("path_expand_3", |dirs, sandbox| { - sandbox - .within("menu") - .with_files(vec![EmptyFile("spam.txt")]); + sandbox.within("menu").with_files(&[EmptyFile("spam.txt")]); let cwd = dirs.test(); std::os::windows::fs::symlink_file( diff --git a/crates/nu-command/tests/commands/path/type_.rs b/crates/nu-command/tests/commands/path/type_.rs index f2ba95fd3e..2317cea060 100644 --- a/crates/nu-command/tests/commands/path/type_.rs +++ b/crates/nu-command/tests/commands/path/type_.rs @@ -18,9 +18,7 @@ fn returns_type_of_missing_file() { #[test] fn returns_type_of_existing_file() { Playground::setup("path_expand_1", |dirs, sandbox| { - sandbox - .within("menu") - .with_files(vec![EmptyFile("spam.txt")]); + sandbox.within("menu").with_files(&[EmptyFile("spam.txt")]); let actual = nu!( cwd: dirs.test(), pipeline( @@ -37,9 +35,7 @@ fn returns_type_of_existing_file() { #[test] fn returns_type_of_existing_directory() { Playground::setup("path_expand_1", |dirs, sandbox| { - sandbox - .within("menu") - .with_files(vec![EmptyFile("spam.txt")]); + sandbox.within("menu").with_files(&[EmptyFile("spam.txt")]); let actual = nu!( cwd: dirs.test(), pipeline( @@ -65,9 +61,7 @@ fn returns_type_of_existing_directory() { #[test] fn returns_type_of_existing_file_const() { Playground::setup("path_type_const", |dirs, sandbox| { - sandbox - .within("menu") - .with_files(vec![EmptyFile("spam.txt")]); + sandbox.within("menu").with_files(&[EmptyFile("spam.txt")]); let actual = nu!( cwd: dirs.test(), pipeline( diff --git a/crates/nu-command/tests/commands/prepend.rs b/crates/nu-command/tests/commands/prepend.rs index 6af762225c..8ae5d78fec 100644 --- a/crates/nu-command/tests/commands/prepend.rs +++ b/crates/nu-command/tests/commands/prepend.rs @@ -5,7 +5,7 @@ use nu_test_support::{nu, pipeline}; #[test] fn adds_a_row_to_the_beginning() { Playground::setup("prepend_test_1", |dirs, sandbox| { - sandbox.with_files(vec![FileWithContentToBeTrimmed( + sandbox.with_files(&[FileWithContentToBeTrimmed( "los_tres_caballeros.txt", r#" Andrés N. Robalino diff --git a/crates/nu-command/tests/commands/range.rs b/crates/nu-command/tests/commands/range.rs index 3080e0af0b..5135de6f20 100644 --- a/crates/nu-command/tests/commands/range.rs +++ b/crates/nu-command/tests/commands/range.rs @@ -5,7 +5,7 @@ use nu_test_support::{nu, pipeline}; #[test] fn selects_a_row() { Playground::setup("range_test_1", |dirs, sandbox| { - sandbox.with_files(vec![EmptyFile("notes.txt"), EmptyFile("tests.txt")]); + sandbox.with_files(&[EmptyFile("notes.txt"), EmptyFile("tests.txt")]); let actual = nu!( cwd: dirs.test(), pipeline( @@ -24,7 +24,7 @@ fn selects_a_row() { #[test] fn selects_some_rows() { Playground::setup("range_test_2", |dirs, sandbox| { - sandbox.with_files(vec![ + sandbox.with_files(&[ EmptyFile("notes.txt"), EmptyFile("tests.txt"), EmptyFile("persons.txt"), @@ -47,7 +47,7 @@ fn selects_some_rows() { #[test] fn negative_indices() { Playground::setup("range_test_negative_indices", |dirs, sandbox| { - sandbox.with_files(vec![ + sandbox.with_files(&[ EmptyFile("notes.txt"), EmptyFile("tests.txt"), EmptyFile("persons.txt"), diff --git a/crates/nu-command/tests/commands/redirection.rs b/crates/nu-command/tests/commands/redirection.rs index 7f12f982ee..1eb57077b9 100644 --- a/crates/nu-command/tests/commands/redirection.rs +++ b/crates/nu-command/tests/commands/redirection.rs @@ -127,7 +127,7 @@ fn same_target_redirection_with_too_much_stderr_not_hang_nushell() { for _ in 0..bytes { large_file_body.push('a'); } - sandbox.with_files(vec![FileWithContent("a_large_file.txt", &large_file_body)]); + sandbox.with_files(&[FileWithContent("a_large_file.txt", &large_file_body)]); nu!( cwd: dirs.test(), pipeline( @@ -220,7 +220,7 @@ fn redirection_with_pipeline_works() { let script_body = r"echo message"; let expect_body = "message"; - sandbox.with_files(vec![FileWithContent("test.sh", script_body)]); + sandbox.with_files(&[FileWithContent("test.sh", script_body)]); let actual = nu!( cwd: dirs.test(), diff --git a/crates/nu-command/tests/commands/rm.rs b/crates/nu-command/tests/commands/rm.rs index caeefc6152..b3a273ea86 100644 --- a/crates/nu-command/tests/commands/rm.rs +++ b/crates/nu-command/tests/commands/rm.rs @@ -8,7 +8,7 @@ use std::path::Path; #[test] fn removes_a_file() { Playground::setup("rm_test_1", |dirs, sandbox| { - sandbox.with_files(vec![EmptyFile("i_will_be_deleted.txt")]); + sandbox.with_files(&[EmptyFile("i_will_be_deleted.txt")]); nu!( cwd: dirs.root(), @@ -26,17 +26,17 @@ fn removes_files_with_wildcard() { Playground::setup("rm_test_2", |dirs, sandbox| { sandbox .within("src") - .with_files(vec![ + .with_files(&[ EmptyFile("cli.rs"), EmptyFile("lib.rs"), EmptyFile("prelude.rs"), ]) .within("src/parser") - .with_files(vec![EmptyFile("parse.rs"), EmptyFile("parser.rs")]) + .with_files(&[EmptyFile("parse.rs"), EmptyFile("parser.rs")]) .within("src/parser/parse") - .with_files(vec![EmptyFile("token_tree.rs")]) + .with_files(&[EmptyFile("token_tree.rs")]) .within("src/parser/hir") - .with_files(vec![ + .with_files(&[ EmptyFile("baseline_parse.rs"), EmptyFile("baseline_parse_tokens.rs"), ]); @@ -67,17 +67,17 @@ fn removes_deeply_nested_directories_with_wildcard_and_recursive_flag() { Playground::setup("rm_test_3", |dirs, sandbox| { sandbox .within("src") - .with_files(vec![ + .with_files(&[ EmptyFile("cli.rs"), EmptyFile("lib.rs"), EmptyFile("prelude.rs"), ]) .within("src/parser") - .with_files(vec![EmptyFile("parse.rs"), EmptyFile("parser.rs")]) + .with_files(&[EmptyFile("parse.rs"), EmptyFile("parser.rs")]) .within("src/parser/parse") - .with_files(vec![EmptyFile("token_tree.rs")]) + .with_files(&[EmptyFile("token_tree.rs")]) .within("src/parser/hir") - .with_files(vec![ + .with_files(&[ EmptyFile("baseline_parse.rs"), EmptyFile("baseline_parse_tokens.rs"), ]); @@ -109,7 +109,7 @@ fn removes_directory_contents_without_recursive_flag_if_empty() { #[test] fn removes_directory_contents_with_recursive_flag() { Playground::setup("rm_test_5", |dirs, sandbox| { - sandbox.with_files(vec![ + sandbox.with_files(&[ EmptyFile("yehuda.txt"), EmptyFile("jttxt"), EmptyFile("andres.txt"), @@ -127,7 +127,7 @@ fn removes_directory_contents_with_recursive_flag() { #[test] fn errors_if_attempting_to_delete_a_directory_with_content_without_recursive_flag() { Playground::setup("rm_test_6", |dirs, sandbox| { - sandbox.with_files(vec![EmptyFile("some_empty_file.txt")]); + sandbox.with_files(&[EmptyFile("some_empty_file.txt")]); let actual = nu!( cwd: dirs.root(), "rm rm_test_6" @@ -179,11 +179,11 @@ fn removes_multiple_directories() { Playground::setup("rm_test_9", |dirs, sandbox| { sandbox .within("src") - .with_files(vec![EmptyFile("a.rs"), EmptyFile("b.rs")]) + .with_files(&[EmptyFile("a.rs"), EmptyFile("b.rs")]) .within("src/cli") - .with_files(vec![EmptyFile("c.rs"), EmptyFile("d.rs")]) + .with_files(&[EmptyFile("c.rs"), EmptyFile("d.rs")]) .within("test") - .with_files(vec![EmptyFile("a_test.rs"), EmptyFile("b_test.rs")]); + .with_files(&[EmptyFile("a_test.rs"), EmptyFile("b_test.rs")]); nu!( cwd: dirs.test(), @@ -200,7 +200,7 @@ fn removes_multiple_directories() { #[test] fn removes_multiple_files() { Playground::setup("rm_test_10", |dirs, sandbox| { - sandbox.with_files(vec![ + sandbox.with_files(&[ EmptyFile("yehuda.txt"), EmptyFile("jttxt"), EmptyFile("andres.txt"), @@ -221,7 +221,7 @@ fn removes_multiple_files() { #[test] fn removes_multiple_files_with_asterisks() { Playground::setup("rm_test_11", |dirs, sandbox| { - sandbox.with_files(vec![ + sandbox.with_files(&[ EmptyFile("yehuda.txt"), EmptyFile("jt.txt"), EmptyFile("andres.toml"), @@ -242,7 +242,7 @@ fn removes_multiple_files_with_asterisks() { #[test] fn allows_doubly_specified_file() { Playground::setup("rm_test_12", |dirs, sandbox| { - sandbox.with_files(vec![EmptyFile("yehuda.txt"), EmptyFile("jt.toml")]); + sandbox.with_files(&[EmptyFile("yehuda.txt"), EmptyFile("jt.toml")]); let actual = nu!( cwd: dirs.test(), @@ -260,7 +260,7 @@ fn allows_doubly_specified_file() { #[test] fn remove_files_from_two_parents_up_using_multiple_dots_and_glob() { Playground::setup("rm_test_13", |dirs, sandbox| { - sandbox.with_files(vec![ + sandbox.with_files(&[ EmptyFile("yehuda.txt"), EmptyFile("jt.txt"), EmptyFile("kevin.txt"), @@ -295,7 +295,7 @@ fn no_errors_if_attempting_to_delete_non_existent_file_with_f_flag() { #[test] fn rm_wildcard_keeps_dotfiles() { Playground::setup("rm_test_15", |dirs, sandbox| { - sandbox.with_files(vec![EmptyFile("foo"), EmptyFile(".bar")]); + sandbox.with_files(&[EmptyFile("foo"), EmptyFile(".bar")]); nu!( cwd: dirs.test(), @@ -310,7 +310,7 @@ fn rm_wildcard_keeps_dotfiles() { #[test] fn rm_wildcard_leading_dot_deletes_dotfiles() { Playground::setup("rm_test_16", |dirs, sandbox| { - sandbox.with_files(vec![EmptyFile("foo"), EmptyFile(".bar")]); + sandbox.with_files(&[EmptyFile("foo"), EmptyFile(".bar")]); nu!( cwd: dirs.test(), @@ -325,7 +325,7 @@ fn rm_wildcard_leading_dot_deletes_dotfiles() { #[test] fn removes_files_with_case_sensitive_glob_matches_by_default() { Playground::setup("glob_test", |dirs, sandbox| { - sandbox.with_files(vec![EmptyFile("A0"), EmptyFile("a1")]); + sandbox.with_files(&[EmptyFile("A0"), EmptyFile("a1")]); nu!( cwd: dirs.root(), @@ -343,7 +343,7 @@ fn removes_files_with_case_sensitive_glob_matches_by_default() { #[test] fn remove_ignores_ansi() { Playground::setup("rm_test_ansi", |_dirs, sandbox| { - sandbox.with_files(vec![EmptyFile("test.txt")]); + sandbox.with_files(&[EmptyFile("test.txt")]); let actual = nu!( cwd: sandbox.cwd(), @@ -358,7 +358,7 @@ fn removes_symlink() { let symlink_target = "symlink_target"; let symlink = "symlink"; Playground::setup("rm_test_symlink", |dirs, sandbox| { - sandbox.with_files(vec![EmptyFile(symlink_target)]); + sandbox.with_files(&[EmptyFile(symlink_target)]); #[cfg(not(windows))] std::os::unix::fs::symlink(dirs.test().join(symlink_target), dirs.test().join(symlink)) @@ -392,7 +392,7 @@ fn removes_symlink_pointing_to_directory() { #[test] fn removes_file_after_cd() { Playground::setup("rm_after_cd", |dirs, sandbox| { - sandbox.with_files(vec![EmptyFile("delete.txt")]); + sandbox.with_files(&[EmptyFile("delete.txt")]); nu!( cwd: dirs.root(), @@ -431,11 +431,11 @@ fn rm_prints_filenames_on_error() { Playground::setup("rm_prints_filenames_on_error", |dirs, sandbox| { let file_names = vec!["test1.txt", "test2.txt"]; - let with_files = file_names + let with_files: Vec<_> = file_names .iter() .map(|file_name| EmptyFile(file_name)) .collect(); - sandbox.with_files(with_files); + sandbox.with_files(&with_files); let test_dir = dirs.test(); @@ -467,7 +467,7 @@ fn rm_files_inside_glob_metachars_dir() { let sub_dir = "test[]"; sandbox .within(sub_dir) - .with_files(vec![EmptyFile("test_file.txt")]); + .with_files(&[EmptyFile("test_file.txt")]); let actual = nu!( cwd: dirs.test().join(sub_dir), @@ -489,7 +489,7 @@ fn rm_files_inside_glob_metachars_dir() { #[case("a][c")] fn rm_files_with_glob_metachars(#[case] src_name: &str) { Playground::setup("rm_files_with_glob_metachars", |dirs, sandbox| { - sandbox.with_files(vec![EmptyFile(src_name)]); + sandbox.with_files(&[EmptyFile(src_name)]); let src = dirs.test().join(src_name); @@ -503,7 +503,7 @@ fn rm_files_with_glob_metachars(#[case] src_name: &str) { assert!(!src.exists()); // test with variables - sandbox.with_files(vec![EmptyFile(src_name)]); + sandbox.with_files(&[EmptyFile(src_name)]); let actual = nu!( cwd: dirs.test(), "let f = '{}'; rm $f", @@ -527,7 +527,7 @@ fn rm_files_with_glob_metachars_nw(#[case] src_name: &str) { #[test] fn force_rm_suppress_error() { Playground::setup("force_rm_suppress_error", |dirs, sandbox| { - sandbox.with_files(vec![EmptyFile("test_file.txt")]); + sandbox.with_files(&[EmptyFile("test_file.txt")]); // the second rm should suppress error. let actual = nu!( @@ -542,7 +542,7 @@ fn force_rm_suppress_error() { #[test] fn rm_with_tilde() { Playground::setup("rm_tilde", |dirs, sandbox| { - sandbox.within("~tilde").with_files(vec![ + sandbox.within("~tilde").with_files(&[ EmptyFile("f1.txt"), EmptyFile("f2.txt"), EmptyFile("f3.txt"), diff --git a/crates/nu-command/tests/commands/run_external.rs b/crates/nu-command/tests/commands/run_external.rs index 9c2f0968c7..14428edcbe 100644 --- a/crates/nu-command/tests/commands/run_external.rs +++ b/crates/nu-command/tests/commands/run_external.rs @@ -21,7 +21,7 @@ fn better_empty_redirection() { #[test] fn explicit_glob() { Playground::setup("external with explicit glob", |dirs, sandbox| { - sandbox.with_files(vec![ + sandbox.with_files(&[ EmptyFile("D&D_volume_1.txt"), EmptyFile("D&D_volume_2.txt"), EmptyFile("foo.sh"), @@ -42,7 +42,7 @@ fn explicit_glob() { #[test] fn bare_word_expand_path_glob() { Playground::setup("bare word should do the expansion", |dirs, sandbox| { - sandbox.with_files(vec![ + sandbox.with_files(&[ EmptyFile("D&D_volume_1.txt"), EmptyFile("D&D_volume_2.txt"), EmptyFile("foo.sh"), @@ -64,7 +64,7 @@ fn bare_word_expand_path_glob() { #[test] fn backtick_expand_path_glob() { Playground::setup("backtick should do the expansion", |dirs, sandbox| { - sandbox.with_files(vec![ + sandbox.with_files(&[ EmptyFile("D&D_volume_1.txt"), EmptyFile("D&D_volume_2.txt"), EmptyFile("foo.sh"), @@ -86,7 +86,7 @@ fn backtick_expand_path_glob() { #[test] fn single_quote_does_not_expand_path_glob() { Playground::setup("single quote do not run the expansion", |dirs, sandbox| { - sandbox.with_files(vec![ + sandbox.with_files(&[ EmptyFile("D&D_volume_1.txt"), EmptyFile("D&D_volume_2.txt"), EmptyFile("foo.sh"), @@ -107,7 +107,7 @@ fn single_quote_does_not_expand_path_glob() { #[test] fn double_quote_does_not_expand_path_glob() { Playground::setup("double quote do not run the expansion", |dirs, sandbox| { - sandbox.with_files(vec![ + sandbox.with_files(&[ EmptyFile("D&D_volume_1.txt"), EmptyFile("D&D_volume_2.txt"), EmptyFile("foo.sh"), @@ -251,7 +251,7 @@ fn failed_command_with_semicolon_will_not_execute_following_cmds_windows() { fn can_run_batch_files() { use nu_test_support::fs::Stub::FileWithContent; Playground::setup("run a Windows batch file", |dirs, sandbox| { - sandbox.with_files(vec![FileWithContent( + sandbox.with_files(&[FileWithContent( "foo.cmd", r#" @echo off @@ -271,7 +271,7 @@ fn can_run_batch_files_without_cmd_extension() { Playground::setup( "run a Windows batch file without specifying the extension", |dirs, sandbox| { - sandbox.with_files(vec![FileWithContent( + sandbox.with_files(&[FileWithContent( "foo.cmd", r#" @echo off @@ -292,7 +292,7 @@ fn can_run_batch_files_without_bat_extension() { Playground::setup( "run a Windows batch file without specifying the extension", |dirs, sandbox| { - sandbox.with_files(vec![FileWithContent( + sandbox.with_files(&[FileWithContent( "foo.bat", r#" @echo off diff --git a/crates/nu-command/tests/commands/save.rs b/crates/nu-command/tests/commands/save.rs index 6739cd88fe..b5776a7bb9 100644 --- a/crates/nu-command/tests/commands/save.rs +++ b/crates/nu-command/tests/commands/save.rs @@ -6,7 +6,7 @@ use std::io::Write; #[test] fn writes_out_csv() { Playground::setup("save_test_2", |dirs, sandbox| { - sandbox.with_files(vec![]); + sandbox.with_files(&[]); let expected_file = dirs.test().join("cargo_sample.csv"); @@ -24,7 +24,7 @@ fn writes_out_csv() { #[test] fn writes_out_list() { Playground::setup("save_test_3", |dirs, sandbox| { - sandbox.with_files(vec![]); + sandbox.with_files(&[]); let expected_file = dirs.test().join("list_sample.txt"); @@ -42,7 +42,7 @@ fn writes_out_list() { #[test] fn save_append_will_create_file_if_not_exists() { Playground::setup("save_test_3", |dirs, sandbox| { - sandbox.with_files(vec![]); + sandbox.with_files(&[]); let expected_file = dirs.test().join("new-file.txt"); @@ -60,7 +60,7 @@ fn save_append_will_create_file_if_not_exists() { #[test] fn save_append_will_not_overwrite_content() { Playground::setup("save_test_4", |dirs, sandbox| { - sandbox.with_files(vec![]); + sandbox.with_files(&[]); let expected_file = dirs.test().join("new-file.txt"); @@ -86,7 +86,7 @@ fn save_append_will_not_overwrite_content() { #[test] fn save_stderr_and_stdout_to_afame_file() { Playground::setup("save_test_5", |dirs, sandbox| { - sandbox.with_files(vec![]); + sandbox.with_files(&[]); let actual = nu!( cwd: dirs.root(), @@ -105,7 +105,7 @@ fn save_stderr_and_stdout_to_afame_file() { #[test] fn save_stderr_and_stdout_to_diff_file() { Playground::setup("save_test_6", |dirs, sandbox| { - sandbox.with_files(vec![]); + sandbox.with_files(&[]); let expected_file = dirs.test().join("log.txt"); let expected_stderr_file = dirs.test().join("err.txt"); @@ -132,7 +132,7 @@ fn save_stderr_and_stdout_to_diff_file() { #[test] fn save_string_and_stream_as_raw() { Playground::setup("save_test_7", |dirs, sandbox| { - sandbox.with_files(vec![]); + sandbox.with_files(&[]); let expected_file = dirs.test().join("temp.html"); nu!( cwd: dirs.root(), @@ -151,7 +151,7 @@ fn save_string_and_stream_as_raw() { #[test] fn save_not_override_file_by_default() { Playground::setup("save_test_8", |dirs, sandbox| { - sandbox.with_files(vec![Stub::EmptyFile("log.txt")]); + sandbox.with_files(&[Stub::EmptyFile("log.txt")]); let actual = nu!( cwd: dirs.root(), @@ -164,7 +164,7 @@ fn save_not_override_file_by_default() { #[test] fn save_override_works() { Playground::setup("save_test_9", |dirs, sandbox| { - sandbox.with_files(vec![Stub::EmptyFile("log.txt")]); + sandbox.with_files(&[Stub::EmptyFile("log.txt")]); let expected_file = dirs.test().join("log.txt"); nu!( @@ -179,7 +179,7 @@ fn save_override_works() { #[test] fn save_failure_not_overrides() { Playground::setup("save_test_10", |dirs, sandbox| { - sandbox.with_files(vec![Stub::FileWithContent("result.toml", "Old content")]); + sandbox.with_files(&[Stub::FileWithContent("result.toml", "Old content")]); let expected_file = dirs.test().join("result.toml"); nu!( @@ -195,7 +195,7 @@ fn save_failure_not_overrides() { #[test] fn save_append_works_on_stderr() { Playground::setup("save_test_11", |dirs, sandbox| { - sandbox.with_files(vec![ + sandbox.with_files(&[ Stub::FileWithContent("log.txt", "Old"), Stub::FileWithContent("err.txt", "Old Err"), ]); @@ -222,7 +222,7 @@ fn save_append_works_on_stderr() { #[test] fn save_not_overrides_err_by_default() { Playground::setup("save_test_12", |dirs, sandbox| { - sandbox.with_files(vec![Stub::FileWithContent("err.txt", "Old Err")]); + sandbox.with_files(&[Stub::FileWithContent("err.txt", "Old Err")]); let actual = nu!( cwd: dirs.root(), @@ -239,7 +239,7 @@ fn save_not_overrides_err_by_default() { #[test] fn save_override_works_stderr() { Playground::setup("save_test_13", |dirs, sandbox| { - sandbox.with_files(vec![ + sandbox.with_files(&[ Stub::FileWithContent("log.txt", "Old"), Stub::FileWithContent("err.txt", "Old Err"), ]); @@ -266,7 +266,7 @@ fn save_override_works_stderr() { #[test] fn save_list_stream() { Playground::setup("save_test_13", |dirs, sandbox| { - sandbox.with_files(vec![]); + sandbox.with_files(&[]); let expected_file = dirs.test().join("list_sample.txt"); @@ -283,7 +283,7 @@ fn save_list_stream() { #[test] fn writes_out_range() { Playground::setup("save_test_14", |dirs, sandbox| { - sandbox.with_files(vec![]); + sandbox.with_files(&[]); let expected_file = dirs.test().join("list_sample.json"); @@ -302,7 +302,7 @@ fn writes_out_range() { #[test] fn save_file_correct_relative_path() { Playground::setup("save_test_15", |dirs, sandbox| { - sandbox.with_files(vec![Stub::FileWithContent( + sandbox.with_files(&[Stub::FileWithContent( "test.nu", r#" export def main [] { diff --git a/crates/nu-command/tests/commands/select.rs b/crates/nu-command/tests/commands/select.rs index 028ecc3db7..8039dad9d0 100644 --- a/crates/nu-command/tests/commands/select.rs +++ b/crates/nu-command/tests/commands/select.rs @@ -119,7 +119,7 @@ fn ignores_duplicate_columns_selected() { #[test] fn selects_a_row() { Playground::setup("select_test_1", |dirs, sandbox| { - sandbox.with_files(vec![EmptyFile("notes.txt"), EmptyFile("arepas.txt")]); + sandbox.with_files(&[EmptyFile("notes.txt"), EmptyFile("arepas.txt")]); let actual = nu!( cwd: dirs.test(), pipeline( @@ -138,7 +138,7 @@ fn selects_a_row() { #[test] fn selects_many_rows() { Playground::setup("select_test_2", |dirs, sandbox| { - sandbox.with_files(vec![EmptyFile("notes.txt"), EmptyFile("arepas.txt")]); + sandbox.with_files(&[EmptyFile("notes.txt"), EmptyFile("arepas.txt")]); let actual = nu!( cwd: dirs.test(), pipeline( diff --git a/crates/nu-command/tests/commands/source_env.rs b/crates/nu-command/tests/commands/source_env.rs index 9facc98e42..4e8da55c78 100644 --- a/crates/nu-command/tests/commands/source_env.rs +++ b/crates/nu-command/tests/commands/source_env.rs @@ -12,7 +12,7 @@ fn sources_also_files_under_custom_lib_dirs_path() { let library_path = AbsolutePath::new(dirs.test().join("lib")); nu.with_config(&file); - nu.with_files(vec![FileWithContent( + nu.with_files(&[FileWithContent( "config.toml", &format!( r#" @@ -22,13 +22,13 @@ fn sources_also_files_under_custom_lib_dirs_path() { ), )]); - nu.within("lib").with_files(vec![FileWithContent( + nu.within("lib").with_files(&[FileWithContent( "my_library.nu", r#" source-env my_library/main.nu "#, )]); - nu.within("lib/my_library").with_files(vec![FileWithContent( + nu.within("lib/my_library").with_files(&[FileWithContent( "main.nu", r#" $env.hello = "hello nu" @@ -55,7 +55,7 @@ fn try_source_foo_with_double_quotes_in(testdir: &str, playdir: &str) { foo_file.push_str("/foo.nu"); sandbox.mkdir(&testdir); - sandbox.with_files(vec![FileWithContent(&foo_file, "echo foo")]); + sandbox.with_files(&[FileWithContent(&foo_file, "echo foo")]); let cmd = String::from("source-env ") + r#"""# + foo_file.as_str() + r#"""#; @@ -72,7 +72,7 @@ fn try_source_foo_with_single_quotes_in(testdir: &str, playdir: &str) { foo_file.push_str("/foo.nu"); sandbox.mkdir(&testdir); - sandbox.with_files(vec![FileWithContent(&foo_file, "echo foo")]); + sandbox.with_files(&[FileWithContent(&foo_file, "echo foo")]); let cmd = String::from("source-env ") + r#"'"# + foo_file.as_str() + r#"'"#; @@ -89,7 +89,7 @@ fn try_source_foo_without_quotes_in(testdir: &str, playdir: &str) { foo_file.push_str("/foo.nu"); sandbox.mkdir(&testdir); - sandbox.with_files(vec![FileWithContent(&foo_file, "echo foo")]); + sandbox.with_files(&[FileWithContent(&foo_file, "echo foo")]); let cmd = String::from("source-env ") + foo_file.as_str(); @@ -148,7 +148,7 @@ fn can_source_dynamic_path() { Playground::setup("can_source_dynamic_path", |dirs, sandbox| { let foo_file = "foo.nu"; - sandbox.with_files(vec![FileWithContent(foo_file, "echo foo")]); + sandbox.with_files(&[FileWithContent(foo_file, "echo foo")]); let cmd = format!("let file = `{foo_file}`; source-env $file"); let actual = nu!(cwd: dirs.test(), &cmd); @@ -160,7 +160,7 @@ fn can_source_dynamic_path() { #[test] fn source_env_eval_export_env() { Playground::setup("source_env_eval_export_env", |dirs, sandbox| { - sandbox.with_files(vec![FileWithContentToBeTrimmed( + sandbox.with_files(&[FileWithContentToBeTrimmed( "spam.nu", r#" export-env { $env.FOO = 'foo' } @@ -178,7 +178,7 @@ fn source_env_eval_export_env() { #[test] fn source_env_eval_export_env_hide() { Playground::setup("source_env_eval_export_env", |dirs, sandbox| { - sandbox.with_files(vec![FileWithContentToBeTrimmed( + sandbox.with_files(&[FileWithContentToBeTrimmed( "spam.nu", r#" export-env { hide-env FOO } @@ -202,7 +202,7 @@ fn source_env_do_cd() { Playground::setup("source_env_do_cd", |dirs, sandbox| { sandbox .mkdir("test1/test2") - .with_files(vec![FileWithContentToBeTrimmed( + .with_files(&[FileWithContentToBeTrimmed( "test1/test2/spam.nu", r#" cd test1/test2 @@ -225,7 +225,7 @@ fn source_env_do_cd_file_relative() { Playground::setup("source_env_do_cd_file_relative", |dirs, sandbox| { sandbox .mkdir("test1/test2") - .with_files(vec![FileWithContentToBeTrimmed( + .with_files(&[FileWithContentToBeTrimmed( "test1/test2/spam.nu", r#" cd ($env.FILE_PWD | path join '..') @@ -248,7 +248,7 @@ fn source_env_dont_cd_overlay() { Playground::setup("source_env_dont_cd_overlay", |dirs, sandbox| { sandbox .mkdir("test1/test2") - .with_files(vec![FileWithContentToBeTrimmed( + .with_files(&[FileWithContentToBeTrimmed( "test1/test2/spam.nu", r#" overlay new spam @@ -271,7 +271,7 @@ fn source_env_dont_cd_overlay() { #[test] fn source_env_is_scoped() { Playground::setup("source_env_is_scoped", |dirs, sandbox| { - sandbox.with_files(vec![FileWithContentToBeTrimmed( + sandbox.with_files(&[FileWithContentToBeTrimmed( "spam.nu", r#" def no-name-similar-to-this [] { 'no-name-similar-to-this' } @@ -296,7 +296,7 @@ fn source_env_is_scoped() { #[test] fn source_env_const_file() { Playground::setup("source_env_const_file", |dirs, sandbox| { - sandbox.with_files(vec![FileWithContentToBeTrimmed( + sandbox.with_files(&[FileWithContentToBeTrimmed( "spam.nu", r#" $env.FOO = 'foo' diff --git a/crates/nu-command/tests/commands/split_by.rs b/crates/nu-command/tests/commands/split_by.rs index ab4b7d5459..ab4631d079 100644 --- a/crates/nu-command/tests/commands/split_by.rs +++ b/crates/nu-command/tests/commands/split_by.rs @@ -36,7 +36,7 @@ fn errors_if_no_input() { #[test] fn errors_if_non_record_input() { Playground::setup("split_by_test_2", |dirs, sandbox| { - sandbox.with_files(vec![ + sandbox.with_files(&[ EmptyFile("los.txt"), EmptyFile("tres.txt"), EmptyFile("amigos.txt"), diff --git a/crates/nu-command/tests/commands/split_column.rs b/crates/nu-command/tests/commands/split_column.rs index 9728df1ddd..544c238cfa 100644 --- a/crates/nu-command/tests/commands/split_column.rs +++ b/crates/nu-command/tests/commands/split_column.rs @@ -5,7 +5,7 @@ use nu_test_support::{nu, pipeline}; #[test] fn to_column() { Playground::setup("split_column_test_1", |dirs, sandbox| { - sandbox.with_files(vec![ + sandbox.with_files(&[ FileWithContentToBeTrimmed( "sample.txt", r#" diff --git a/crates/nu-command/tests/commands/split_row.rs b/crates/nu-command/tests/commands/split_row.rs index 3560ea9b5d..3622525a30 100644 --- a/crates/nu-command/tests/commands/split_row.rs +++ b/crates/nu-command/tests/commands/split_row.rs @@ -5,7 +5,7 @@ use nu_test_support::{nu, pipeline}; #[test] fn to_row() { Playground::setup("split_row_test_1", |dirs, sandbox| { - sandbox.with_files(vec![ + sandbox.with_files(&[ FileWithContentToBeTrimmed( "sample.txt", r#" diff --git a/crates/nu-command/tests/commands/str_/into_string.rs b/crates/nu-command/tests/commands/str_/into_string.rs index afc0d227cb..a84d1006e6 100644 --- a/crates/nu-command/tests/commands/str_/into_string.rs +++ b/crates/nu-command/tests/commands/str_/into_string.rs @@ -50,7 +50,7 @@ fn from_string() { #[test] fn from_filename() { Playground::setup("from_filename", |dirs, sandbox| { - sandbox.with_files(vec![FileWithContentToBeTrimmed( + sandbox.with_files(&[FileWithContentToBeTrimmed( "sample.toml", r#" [dependency] @@ -70,7 +70,7 @@ fn from_filename() { #[test] fn from_filesize() { Playground::setup("from_filesize", |dirs, sandbox| { - sandbox.with_files(vec![FileWithContentToBeTrimmed( + sandbox.with_files(&[FileWithContentToBeTrimmed( "sample.toml", r#" [dependency] diff --git a/crates/nu-command/tests/commands/str_/mod.rs b/crates/nu-command/tests/commands/str_/mod.rs index 382f2bf20f..9f1e90e853 100644 --- a/crates/nu-command/tests/commands/str_/mod.rs +++ b/crates/nu-command/tests/commands/str_/mod.rs @@ -8,7 +8,7 @@ use nu_test_support::{nu, pipeline}; #[test] fn trims() { Playground::setup("str_test_1", |dirs, sandbox| { - sandbox.with_files(vec![FileWithContent( + sandbox.with_files(&[FileWithContent( "sample.toml", r#" [dependency] @@ -39,7 +39,7 @@ fn error_trim_multiple_chars() { #[test] fn capitalizes() { Playground::setup("str_test_2", |dirs, sandbox| { - sandbox.with_files(vec![FileWithContent( + sandbox.with_files(&[FileWithContent( "sample.toml", r#" [dependency] @@ -59,7 +59,7 @@ fn capitalizes() { #[test] fn downcases() { Playground::setup("str_test_3", |dirs, sandbox| { - sandbox.with_files(vec![FileWithContent( + sandbox.with_files(&[FileWithContent( "sample.toml", r#" [dependency] @@ -86,7 +86,7 @@ fn non_ascii_downcase() { #[test] fn upcases() { Playground::setup("str_test_4", |dirs, sandbox| { - sandbox.with_files(vec![FileWithContent( + sandbox.with_files(&[FileWithContent( "sample.toml", r#" [package] @@ -114,7 +114,7 @@ fn non_ascii_upcase() { #[ignore = "Playgrounds are not supported in nu-cmd-extra"] fn camelcases() { Playground::setup("str_test_3", |dirs, sandbox| { - sandbox.with_files(vec![FileWithContent( + sandbox.with_files(&[FileWithContent( "sample.toml", r#" [dependency] @@ -165,7 +165,7 @@ fn converts_to_float() { #[test] fn find_and_replaces() { Playground::setup("str_test_6", |dirs, sandbox| { - sandbox.with_files(vec![FileWithContent( + sandbox.with_files(&[FileWithContent( "sample.toml", r#" [fortune.teller] @@ -189,7 +189,7 @@ fn find_and_replaces() { #[test] fn find_and_replaces_without_passing_field() { Playground::setup("str_test_7", |dirs, sandbox| { - sandbox.with_files(vec![FileWithContent( + sandbox.with_files(&[FileWithContent( "sample.toml", r#" [fortune.teller] @@ -233,7 +233,7 @@ fn regex_error_in_pattern() { #[test] fn substrings_the_input() { Playground::setup("str_test_8", |dirs, sandbox| { - sandbox.with_files(vec![FileWithContent( + sandbox.with_files(&[FileWithContent( "sample.toml", r#" [fortune.teller] @@ -257,7 +257,7 @@ fn substrings_the_input() { #[test] fn substring_errors_if_start_index_is_greater_than_end_index() { Playground::setup("str_test_9", |dirs, sandbox| { - sandbox.with_files(vec![FileWithContent( + sandbox.with_files(&[FileWithContent( "sample.toml", r#" [fortune.teller] @@ -282,7 +282,7 @@ fn substring_errors_if_start_index_is_greater_than_end_index() { #[test] fn substrings_the_input_and_returns_the_string_if_end_index_exceeds_length() { Playground::setup("str_test_10", |dirs, sandbox| { - sandbox.with_files(vec![FileWithContent( + sandbox.with_files(&[FileWithContent( "sample.toml", r#" [package] @@ -306,7 +306,7 @@ fn substrings_the_input_and_returns_the_string_if_end_index_exceeds_length() { #[test] fn substrings_the_input_and_returns_blank_if_start_index_exceeds_length() { Playground::setup("str_test_11", |dirs, sandbox| { - sandbox.with_files(vec![FileWithContent( + sandbox.with_files(&[FileWithContent( "sample.toml", r#" [package] @@ -330,7 +330,7 @@ fn substrings_the_input_and_returns_blank_if_start_index_exceeds_length() { #[test] fn substrings_the_input_and_treats_start_index_as_zero_if_blank_start_index_given() { Playground::setup("str_test_12", |dirs, sandbox| { - sandbox.with_files(vec![FileWithContent( + sandbox.with_files(&[FileWithContent( "sample.toml", r#" [package] @@ -354,7 +354,7 @@ fn substrings_the_input_and_treats_start_index_as_zero_if_blank_start_index_give #[test] fn substrings_the_input_and_treats_end_index_as_length_if_blank_end_index_given() { Playground::setup("str_test_13", |dirs, sandbox| { - sandbox.with_files(vec![FileWithContent( + sandbox.with_files(&[FileWithContent( "sample.toml", r#" [package] diff --git a/crates/nu-command/tests/commands/table.rs b/crates/nu-command/tests/commands/table.rs index 130d87c434..a986c7b15b 100644 --- a/crates/nu-command/tests/commands/table.rs +++ b/crates/nu-command/tests/commands/table.rs @@ -505,7 +505,7 @@ fn external_with_too_much_stdout_should_not_hang_nu() { for _ in 0..bytes { large_file_body.push('a'); } - sandbox.with_files(vec![FileWithContent("a_large_file.txt", &large_file_body)]); + sandbox.with_files(&[FileWithContent("a_large_file.txt", &large_file_body)]); let actual = nu!( cwd: dirs.test(), pipeline( @@ -536,7 +536,7 @@ fn table_index_0() { #[test] fn test_expand_big_0() { Playground::setup("test_expand_big_0", |dirs, sandbox| { - sandbox.with_files(vec![FileWithContent( + sandbox.with_files(&[FileWithContent( "sample.toml", r#" [package] @@ -1820,7 +1820,7 @@ fn table_expande_with_no_header_internally_1() { #[test] fn test_collapse_big_0() { Playground::setup("test_expand_big_0", |dirs, sandbox| { - sandbox.with_files(vec![FileWithContent( + sandbox.with_files(&[FileWithContent( "sample.toml", r#" [package] @@ -2562,12 +2562,12 @@ fn create_theme_output(theme: &str) -> Vec { } fn theme_cmd(theme: &str, footer: bool, then: &str) -> String { - let mut with_foorter = String::new(); + let mut with_footer = String::new(); if footer { - with_foorter = "$env.config.footer_mode = \"always\"".to_string(); + with_footer = "$env.config.footer_mode = \"always\"".to_string(); } - format!("$env.config.table.mode = {theme}; $env.config.table.header_on_separator = true; {with_foorter}; {then}") + format!("$env.config.table.mode = {theme}; $env.config.table.header_on_separator = true; {with_footer}; {then}") } #[test] diff --git a/crates/nu-command/tests/commands/touch.rs b/crates/nu-command/tests/commands/touch.rs index d7f5cb875a..26d0325729 100644 --- a/crates/nu-command/tests/commands/touch.rs +++ b/crates/nu-command/tests/commands/touch.rs @@ -39,7 +39,7 @@ fn creates_two_files() { #[test] fn change_modified_time_of_file_to_today() { Playground::setup("change_time_test_9", |dirs, sandbox| { - sandbox.with_files(vec![Stub::EmptyFile("file.txt")]); + sandbox.with_files(&[Stub::EmptyFile("file.txt")]); let path = dirs.test().join("file.txt"); // Set file.txt's times to the past before the test to make sure `touch` actually changes the mtime to today @@ -69,7 +69,7 @@ fn change_modified_time_of_file_to_today() { #[test] fn change_access_time_of_file_to_today() { Playground::setup("change_time_test_18", |dirs, sandbox| { - sandbox.with_files(vec![Stub::EmptyFile("file.txt")]); + sandbox.with_files(&[Stub::EmptyFile("file.txt")]); let path = dirs.test().join("file.txt"); // Set file.txt's times to the past before the test to make sure `touch` actually changes the atime to today @@ -99,7 +99,7 @@ fn change_access_time_of_file_to_today() { #[test] fn change_modified_and_access_time_of_file_to_today() { Playground::setup("change_time_test_27", |dirs, sandbox| { - sandbox.with_files(vec![Stub::EmptyFile("file.txt")]); + sandbox.with_files(&[Stub::EmptyFile("file.txt")]); let path = dirs.test().join("file.txt"); filetime::set_file_times(&path, TIME_ONE, TIME_ONE).unwrap(); @@ -143,7 +143,7 @@ fn change_file_times_if_exists_with_no_create() { Playground::setup( "change_file_times_if_exists_with_no_create", |dirs, sandbox| { - sandbox.with_files(vec![Stub::EmptyFile("file.txt")]); + sandbox.with_files(&[Stub::EmptyFile("file.txt")]); let path = dirs.test().join("file.txt"); filetime::set_file_times(&path, TIME_ONE, TIME_ONE).unwrap(); @@ -208,7 +208,7 @@ fn creates_file_four_dots_quotation_marks() { #[test] fn change_file_times_to_reference_file() { Playground::setup("change_dir_times_to_reference_dir", |dirs, sandbox| { - sandbox.with_files(vec![ + sandbox.with_files(&[ Stub::EmptyFile("reference_file"), Stub::EmptyFile("target_file"), ]); @@ -253,7 +253,7 @@ fn change_file_times_to_reference_file() { #[test] fn change_file_mtime_to_reference() { Playground::setup("change_file_mtime_to_reference", |dirs, sandbox| { - sandbox.with_files(vec![ + sandbox.with_files(&[ Stub::EmptyFile("reference_file"), Stub::EmptyFile("target_file"), ]); diff --git a/crates/nu-command/tests/commands/ucp.rs b/crates/nu-command/tests/commands/ucp.rs index d434d77824..453786ad4e 100644 --- a/crates/nu-command/tests/commands/ucp.rs +++ b/crates/nu-command/tests/commands/ucp.rs @@ -113,7 +113,7 @@ fn copies_the_directory_inside_directory_if_path_to_copy_is_directory_and_with_r Playground::setup("ucp_test_4", |dirs, sandbox| { sandbox .within("originals") - .with_files(vec![ + .with_files(&[ EmptyFile("yehuda.txt"), EmptyFile("jttxt"), EmptyFile("andres.txt"), @@ -151,19 +151,19 @@ fn deep_copies_with_recursive_flag_impl(progress: bool) { Playground::setup("ucp_test_5", |dirs, sandbox| { sandbox .within("originals") - .with_files(vec![EmptyFile("manifest.txt")]) + .with_files(&[EmptyFile("manifest.txt")]) .within("originals/contributors") - .with_files(vec![ + .with_files(&[ EmptyFile("yehuda.txt"), EmptyFile("jttxt"), EmptyFile("andres.txt"), ]) .within("originals/contributors/JT") - .with_files(vec![EmptyFile("errors.txt"), EmptyFile("multishells.txt")]) + .with_files(&[EmptyFile("errors.txt"), EmptyFile("multishells.txt")]) .within("originals/contributors/andres") - .with_files(vec![EmptyFile("coverage.txt"), EmptyFile("commands.txt")]) + .with_files(&[EmptyFile("coverage.txt"), EmptyFile("commands.txt")]) .within("originals/contributors/yehuda") - .with_files(vec![EmptyFile("defer-evaluation.txt")]) + .with_files(&[EmptyFile("defer-evaluation.txt")]) .mkdir("expected"); let expected_dir = dirs.test().join("expected").join("originals"); @@ -324,7 +324,7 @@ fn copy_files_using_glob_two_parents_up_using_multiple_dots() { fn copy_files_using_glob_two_parents_up_using_multiple_dots_imp(progress: bool) { Playground::setup("ucp_test_9", |dirs, sandbox| { - sandbox.within("foo").within("bar").with_files(vec![ + sandbox.within("foo").within("bar").with_files(&[ EmptyFile("jtjson"), EmptyFile("andres.xml"), EmptyFile("yehuda.yaml"), @@ -363,7 +363,7 @@ fn copy_file_and_dir_from_two_parents_up_using_multiple_dots_to_current_dir_recu progress: bool, ) { Playground::setup("ucp_test_10", |dirs, sandbox| { - sandbox.with_files(vec![EmptyFile("hello_there")]); + sandbox.with_files(&[EmptyFile("hello_there")]); sandbox.mkdir("hello_again"); sandbox.within("foo").mkdir("bar"); @@ -390,7 +390,7 @@ fn copy_to_non_existing_dir() { fn copy_to_non_existing_dir_impl(progress: bool) { Playground::setup("ucp_test_11", |_dirs, sandbox| { - sandbox.with_files(vec![EmptyFile("empty_file")]); + sandbox.with_files(&[EmptyFile("empty_file")]); let progress_flag = if progress { "-p" } else { "" }; let actual = nu!( @@ -413,7 +413,7 @@ fn copy_dir_contains_symlink_ignored_impl(progress: bool) { Playground::setup("ucp_test_12", |_dirs, sandbox| { sandbox .within("tmp_dir") - .with_files(vec![EmptyFile("hello_there"), EmptyFile("good_bye")]) + .with_files(&[EmptyFile("hello_there"), EmptyFile("good_bye")]) .within("tmp_dir") .symlink("good_bye", "dangle_symlink"); @@ -446,7 +446,7 @@ fn copy_dir_contains_symlink_impl(progress: bool) { Playground::setup("ucp_test_13", |_dirs, sandbox| { sandbox .within("tmp_dir") - .with_files(vec![EmptyFile("hello_there"), EmptyFile("good_bye")]) + .with_files(&[EmptyFile("hello_there"), EmptyFile("good_bye")]) .within("tmp_dir") .symlink("good_bye", "dangle_symlink"); @@ -477,7 +477,7 @@ fn copy_dir_symlink_file_body_not_changed_impl(progress: bool) { Playground::setup("ucp_test_14", |_dirs, sandbox| { sandbox .within("tmp_dir") - .with_files(vec![EmptyFile("hello_there"), EmptyFile("good_bye")]) + .with_files(&[EmptyFile("hello_there"), EmptyFile("good_bye")]) .within("tmp_dir") .symlink("good_bye", "dangle_symlink"); @@ -507,7 +507,7 @@ fn copy_identical_file() { fn copy_identical_file_impl(progress: bool) { Playground::setup("ucp_test_15", |dirs, sandbox| { - sandbox.with_files(vec![EmptyFile("same.txt")]); + sandbox.with_files(&[EmptyFile("same.txt")]); let progress_flag = if progress { "-p" } else { "" }; @@ -538,7 +538,7 @@ fn copy_ignores_ansi() { fn copy_ignores_ansi_impl(progress: bool) { Playground::setup("ucp_test_16", |_dirs, sandbox| { - sandbox.with_files(vec![EmptyFile("test.txt")]); + sandbox.with_files(&[EmptyFile("test.txt")]); let progress_flag = if progress { "-p" } else { "" }; @@ -563,7 +563,7 @@ fn copy_file_not_exists_dst() { #[cfg(unix)] fn copy_file_not_exists_dst_impl(progress: bool) { Playground::setup("ucp_test_17", |_dirs, sandbox| { - sandbox.with_files(vec![EmptyFile("valid.txt")]); + sandbox.with_files(&[EmptyFile("valid.txt")]); let progress_flag = if progress { "-p" } else { "" }; @@ -589,7 +589,7 @@ fn copy_file_with_read_permission() { fn copy_file_with_read_permission_impl(progress: bool) { Playground::setup("ucp_test_18", |_dirs, sandbox| { - sandbox.with_files(vec![ + sandbox.with_files(&[ EmptyFile("valid.txt"), FileWithPermission("invalid_prem.txt", false), ]); @@ -775,7 +775,7 @@ fn test_cp_arg_force() { Playground::setup("ucp_test_24", |dirs, sandbox| { let src = dirs.fixtures.join("cp").join(TEST_HELLO_WORLD_SOURCE); let src_hash = get_file_hash(src.display()); - sandbox.with_files(vec![FileWithPermission("invalid_prem.txt", false)]); + sandbox.with_files(&[FileWithPermission("invalid_prem.txt", false)]); nu!( cwd: dirs.root(), @@ -827,7 +827,7 @@ fn test_cp_nested_directory_to_itself_disallowed() { #[test] fn test_cp_same_file_force() { Playground::setup("ucp_test_27", |dirs, sandbox| { - sandbox.with_files(vec![EmptyFile("f")]); + sandbox.with_files(&[EmptyFile("f")]); let actual = nu!( cwd: dirs.test(), "cp --force {} {}", @@ -862,7 +862,7 @@ fn test_cp_arg_no_clobber() { #[test] fn test_cp_arg_no_clobber_twice() { Playground::setup("ucp_test_29", |dirs, sandbox| { - sandbox.with_files(vec![ + sandbox.with_files(&[ EmptyFile("source.txt"), FileWithContent("source_with_body.txt", "some-body"), ]); @@ -961,7 +961,7 @@ fn test_cp_only_source_no_dest() { #[test] fn test_cp_with_vars() { Playground::setup("ucp_test_33", |dirs, sandbox| { - sandbox.with_files(vec![EmptyFile("input")]); + sandbox.with_files(&[EmptyFile("input")]); nu!( cwd: dirs.test(), "let src = 'input'; let dst = 'target'; cp $src $dst", @@ -974,7 +974,7 @@ fn test_cp_with_vars() { fn test_cp_destination_after_cd() { Playground::setup("ucp_test_34", |dirs, sandbox| { sandbox.mkdir("test"); - sandbox.with_files(vec![EmptyFile("test/file.txt")]); + sandbox.with_files(&[EmptyFile("test/file.txt")]); nu!( cwd: dirs.test(), // Defining variable avoid path expansion of cp argument. @@ -992,7 +992,7 @@ fn test_cp_destination_after_cd() { #[case("a][c")] fn copies_files_with_glob_metachars(#[case] src_name: &str) { Playground::setup("ucp_test_34", |dirs, sandbox| { - sandbox.with_files(vec![FileWithContent( + sandbox.with_files(&[FileWithContent( src_name, "What is the sound of one hand clapping?", )]); @@ -1026,7 +1026,7 @@ fn copies_files_with_glob_metachars(#[case] src_name: &str) { #[case("a][c")] fn copies_files_with_glob_metachars_when_input_are_variables(#[case] src_name: &str) { Playground::setup("ucp_test_35", |dirs, sandbox| { - sandbox.with_files(vec![FileWithContent( + sandbox.with_files(&[FileWithContent( src_name, "What is the sound of one hand clapping?", )]); @@ -1069,7 +1069,7 @@ fn test_cp_preserve_timestamps() { // Preserve timestamp and mode Playground::setup("ucp_test_35", |dirs, sandbox| { - sandbox.with_files(vec![EmptyFile("file.txt")]); + sandbox.with_files(&[EmptyFile("file.txt")]); let actual = nu!( cwd: dirs.test(), " @@ -1093,7 +1093,7 @@ fn test_cp_preserve_only_timestamps() { // Preserve timestamps and discard all other attributes including mode Playground::setup("ucp_test_35", |dirs, sandbox| { - sandbox.with_files(vec![EmptyFile("file.txt")]); + sandbox.with_files(&[EmptyFile("file.txt")]); let actual = nu!( cwd: dirs.test(), " @@ -1118,7 +1118,7 @@ fn test_cp_preserve_nothing() { // Preserve no attributes Playground::setup("ucp_test_35", |dirs, sandbox| { - sandbox.with_files(vec![EmptyFile("file.txt")]); + sandbox.with_files(&[EmptyFile("file.txt")]); let actual = nu!( cwd: dirs.test(), " @@ -1142,7 +1142,7 @@ fn test_cp_inside_glob_metachars_dir() { let sub_dir = "test[]"; sandbox .within(sub_dir) - .with_files(vec![FileWithContent("test_file.txt", "hello")]); + .with_files(&[FileWithContent("test_file.txt", "hello")]); let actual = nu!( cwd: dirs.test().join(sub_dir), @@ -1163,7 +1163,7 @@ fn test_cp_inside_glob_metachars_dir() { fn test_cp_to_customized_home_directory() { Playground::setup("cp_to_home", |dirs, sandbox| { std::env::set_var("HOME", dirs.test()); - sandbox.with_files(vec![EmptyFile("test_file.txt")]); + sandbox.with_files(&[EmptyFile("test_file.txt")]); let actual = nu!(cwd: dirs.test(), "mkdir test; cp test_file.txt ~/test/"); assert!(actual.err.is_empty()); @@ -1177,7 +1177,7 @@ fn test_cp_to_customized_home_directory() { #[test] fn cp_with_tilde() { Playground::setup("cp_tilde", |dirs, sandbox| { - sandbox.within("~tilde").with_files(vec![ + sandbox.within("~tilde").with_files(&[ EmptyFile("f1.txt"), EmptyFile("f2.txt"), EmptyFile("f3.txt"), @@ -1218,7 +1218,7 @@ fn copy_file_with_update_flag() { fn copy_file_with_update_flag_impl(progress: bool) { Playground::setup("cp_test_36", |_dirs, sandbox| { - sandbox.with_files(vec![ + sandbox.with_files(&[ EmptyFile("valid.txt"), FileWithContent("newer_valid.txt", "body"), ]); @@ -1234,7 +1234,7 @@ fn copy_file_with_update_flag_impl(progress: bool) { // create a file after assert to make sure that newest_valid.txt is newest std::thread::sleep(std::time::Duration::from_secs(1)); - sandbox.with_files(vec![FileWithContent("newest_valid.txt", "newest_body")]); + sandbox.with_files(&[FileWithContent("newest_valid.txt", "newest_body")]); let actual = nu!(cwd: sandbox.cwd(), "cp {} -u newest_valid.txt valid.txt; open valid.txt", progress_flag); assert_eq!(actual.out, "newest_body"); @@ -1249,7 +1249,7 @@ fn cp_with_cd() { Playground::setup("cp_test_37", |_dirs, sandbox| { sandbox .mkdir("tmp_dir") - .with_files(vec![FileWithContent("tmp_dir/file.txt", "body")]); + .with_files(&[FileWithContent("tmp_dir/file.txt", "body")]); let actual = nu!( cwd: sandbox.cwd(), diff --git a/crates/nu-command/tests/commands/use_.rs b/crates/nu-command/tests/commands/use_.rs index 9d98e34fab..8cb783f96b 100644 --- a/crates/nu-command/tests/commands/use_.rs +++ b/crates/nu-command/tests/commands/use_.rs @@ -9,7 +9,7 @@ fn use_module_file_within_block() { Playground::setup("use_test_1", |dirs, nu| { let file = AbsolutePath::new(dirs.test().join("spam.nu")); - nu.with_files(vec![FileWithContent( + nu.with_files(&[FileWithContent( &file.to_string(), r#" export def foo [] { @@ -39,7 +39,7 @@ fn use_keeps_doc_comments() { Playground::setup("use_doc_comments", |dirs, nu| { let file = AbsolutePath::new(dirs.test().join("spam.nu")); - nu.with_files(vec![FileWithContent( + nu.with_files(&[FileWithContent( &file.to_string(), r#" # this is my foo command @@ -68,7 +68,7 @@ fn use_keeps_doc_comments() { #[test] fn use_eval_export_env() { Playground::setup("use_eval_export_env", |dirs, sandbox| { - sandbox.with_files(vec![FileWithContentToBeTrimmed( + sandbox.with_files(&[FileWithContentToBeTrimmed( "spam.nu", r#" export-env { $env.FOO = 'foo' } @@ -86,7 +86,7 @@ fn use_eval_export_env() { #[test] fn use_eval_export_env_hide() { Playground::setup("use_eval_export_env", |dirs, sandbox| { - sandbox.with_files(vec![FileWithContentToBeTrimmed( + sandbox.with_files(&[FileWithContentToBeTrimmed( "spam.nu", r#" export-env { hide-env FOO } @@ -106,7 +106,7 @@ fn use_do_cd() { Playground::setup("use_do_cd", |dirs, sandbox| { sandbox .mkdir("test1/test2") - .with_files(vec![FileWithContentToBeTrimmed( + .with_files(&[FileWithContentToBeTrimmed( "test1/test2/spam.nu", r#" export-env { cd test1/test2 } @@ -126,7 +126,7 @@ fn use_do_cd_file_relative() { Playground::setup("use_do_cd_file_relative", |dirs, sandbox| { sandbox .mkdir("test1/test2") - .with_files(vec![FileWithContentToBeTrimmed( + .with_files(&[FileWithContentToBeTrimmed( "test1/test2/spam.nu", r#" export-env { cd ($env.FILE_PWD | path join '..') } @@ -146,7 +146,7 @@ fn use_dont_cd_overlay() { Playground::setup("use_dont_cd_overlay", |dirs, sandbox| { sandbox .mkdir("test1/test2") - .with_files(vec![FileWithContentToBeTrimmed( + .with_files(&[FileWithContentToBeTrimmed( "test1/test2/spam.nu", r#" export-env { @@ -168,7 +168,7 @@ fn use_dont_cd_overlay() { #[test] fn use_export_env_combined() { Playground::setup("use_is_scoped", |dirs, sandbox| { - sandbox.with_files(vec![FileWithContentToBeTrimmed( + sandbox.with_files(&[FileWithContentToBeTrimmed( "spam.nu", r#" def foo [] { 'foo' } diff --git a/crates/nu-command/tests/commands/zip.rs b/crates/nu-command/tests/commands/zip.rs index b8915cb896..e116a1ac92 100644 --- a/crates/nu-command/tests/commands/zip.rs +++ b/crates/nu-command/tests/commands/zip.rs @@ -17,7 +17,7 @@ export def expect [ #[test] fn zips_two_tables() { Playground::setup("zip_test_1", |dirs, nu| { - nu.with_files(vec![FileWithContent( + nu.with_files(&[FileWithContent( "zip_test.nu", &format!("{ZIP_POWERED_TEST_ASSERTION_SCRIPT}\n"), )]); diff --git a/crates/nu-command/tests/format_conversions/csv.rs b/crates/nu-command/tests/format_conversions/csv.rs index 8b332d6269..5915b3c4d4 100644 --- a/crates/nu-command/tests/format_conversions/csv.rs +++ b/crates/nu-command/tests/format_conversions/csv.rs @@ -15,7 +15,7 @@ fn table_to_csv_text_and_from_csv_text_back_into_table() { #[test] fn table_to_csv_text() { Playground::setup("filter_to_csv_test_1", |dirs, sandbox| { - sandbox.with_files(vec![FileWithContentToBeTrimmed( + sandbox.with_files(&[FileWithContentToBeTrimmed( "csv_text_sample.txt", r#" importer,shipper,tariff_item,name,origin @@ -47,7 +47,7 @@ fn table_to_csv_text() { #[test] fn table_to_csv_text_skipping_headers_after_conversion() { Playground::setup("filter_to_csv_test_2", |dirs, sandbox| { - sandbox.with_files(vec![FileWithContentToBeTrimmed( + sandbox.with_files(&[FileWithContentToBeTrimmed( "csv_text_sample.txt", r#" importer,shipper,tariff_item,name,origin @@ -77,7 +77,7 @@ fn table_to_csv_text_skipping_headers_after_conversion() { #[test] fn infers_types() { Playground::setup("filter_from_csv_test_1", |dirs, sandbox| { - sandbox.with_files(vec![FileWithContentToBeTrimmed( + sandbox.with_files(&[FileWithContentToBeTrimmed( "los_cuatro_mosqueteros.csv", r#" first_name,last_name,rusty_luck,d @@ -104,7 +104,7 @@ fn infers_types() { #[test] fn from_csv_text_to_table() { Playground::setup("filter_from_csv_test_2", |dirs, sandbox| { - sandbox.with_files(vec![FileWithContentToBeTrimmed( + sandbox.with_files(&[FileWithContentToBeTrimmed( "los_tres_caballeros.txt", r#" first_name,last_name,rusty_luck @@ -131,7 +131,7 @@ fn from_csv_text_to_table() { #[test] fn from_csv_text_with_separator_to_table() { Playground::setup("filter_from_csv_test_3", |dirs, sandbox| { - sandbox.with_files(vec![FileWithContentToBeTrimmed( + sandbox.with_files(&[FileWithContentToBeTrimmed( "los_tres_caballeros.txt", r#" first_name;last_name;rusty_luck @@ -158,7 +158,7 @@ fn from_csv_text_with_separator_to_table() { #[test] fn from_csv_text_with_tab_separator_to_table() { Playground::setup("filter_from_csv_test_4", |dirs, sandbox| { - sandbox.with_files(vec![FileWithContentToBeTrimmed( + sandbox.with_files(&[FileWithContentToBeTrimmed( "los_tres_caballeros.txt", r#" first_name last_name rusty_luck @@ -185,7 +185,7 @@ fn from_csv_text_with_tab_separator_to_table() { #[test] fn from_csv_text_with_comments_to_table() { Playground::setup("filter_from_csv_test_5", |dirs, sandbox| { - sandbox.with_files(vec![FileWithContentToBeTrimmed( + sandbox.with_files(&[FileWithContentToBeTrimmed( "los_tres_caballeros.txt", r#" # This is a comment @@ -215,7 +215,7 @@ fn from_csv_text_with_comments_to_table() { #[test] fn from_csv_text_with_custom_quotes_to_table() { Playground::setup("filter_from_csv_test_6", |dirs, sandbox| { - sandbox.with_files(vec![FileWithContentToBeTrimmed( + sandbox.with_files(&[FileWithContentToBeTrimmed( "los_tres_caballeros.txt", r#" first_name,last_name,rusty_luck @@ -242,7 +242,7 @@ fn from_csv_text_with_custom_quotes_to_table() { #[test] fn from_csv_text_with_custom_escapes_to_table() { Playground::setup("filter_from_csv_test_7", |dirs, sandbox| { - sandbox.with_files(vec![FileWithContentToBeTrimmed( + sandbox.with_files(&[FileWithContentToBeTrimmed( "los_tres_caballeros.txt", r#" first_name,last_name,rusty_luck @@ -269,7 +269,7 @@ fn from_csv_text_with_custom_escapes_to_table() { #[test] fn from_csv_text_skipping_headers_to_table() { Playground::setup("filter_from_csv_test_8", |dirs, sandbox| { - sandbox.with_files(vec![FileWithContentToBeTrimmed( + sandbox.with_files(&[FileWithContentToBeTrimmed( "los_tres_amigos.txt", r#" Andrés,Robalino,1 @@ -295,7 +295,7 @@ fn from_csv_text_skipping_headers_to_table() { #[test] fn from_csv_text_with_missing_columns_to_table() { Playground::setup("filter_from_csv_test_9", |dirs, sandbox| { - sandbox.with_files(vec![FileWithContentToBeTrimmed( + sandbox.with_files(&[FileWithContentToBeTrimmed( "los_tres_caballeros.txt", r#" first_name,last_name,rusty_luck @@ -323,7 +323,7 @@ fn from_csv_text_with_missing_columns_to_table() { #[test] fn from_csv_text_with_multiple_char_separator() { Playground::setup("filter_from_csv_test_10", |dirs, sandbox| { - sandbox.with_files(vec![FileWithContentToBeTrimmed( + sandbox.with_files(&[FileWithContentToBeTrimmed( "los_tres_caballeros.txt", r#" first_name,last_name,rusty_luck @@ -350,7 +350,7 @@ fn from_csv_text_with_multiple_char_separator() { #[test] fn from_csv_text_with_wrong_type_separator() { Playground::setup("filter_from_csv_test_11", |dirs, sandbox| { - sandbox.with_files(vec![FileWithContentToBeTrimmed( + sandbox.with_files(&[FileWithContentToBeTrimmed( "los_tres_caballeros.txt", r#" first_name,last_name,rusty_luck @@ -410,7 +410,7 @@ fn string_to_csv_error() { #[test] fn parses_csv_with_unicode_sep() { Playground::setup("filter_from_csv_unicode_sep_test_3", |dirs, sandbox| { - sandbox.with_files(vec![FileWithContentToBeTrimmed( + sandbox.with_files(&[FileWithContentToBeTrimmed( "los_tres_caballeros.txt", r#" first_name;last_name;rusty_luck @@ -437,7 +437,7 @@ fn parses_csv_with_unicode_sep() { #[test] fn parses_csv_with_unicode_x1f_sep() { Playground::setup("filter_from_csv_unicode_sep_x1f_test_3", |dirs, sandbox| { - sandbox.with_files(vec![FileWithContentToBeTrimmed( + sandbox.with_files(&[FileWithContentToBeTrimmed( "los_tres_caballeros.txt", r#" first_namelast_namerusty_luck diff --git a/crates/nu-command/tests/format_conversions/json.rs b/crates/nu-command/tests/format_conversions/json.rs index be3476e222..1989000df6 100644 --- a/crates/nu-command/tests/format_conversions/json.rs +++ b/crates/nu-command/tests/format_conversions/json.rs @@ -20,7 +20,7 @@ fn table_to_json_text_and_from_json_text_back_into_table() { #[test] fn from_json_text_to_table() { Playground::setup("filter_from_json_test_1", |dirs, sandbox| { - sandbox.with_files(vec![FileWithContentToBeTrimmed( + sandbox.with_files(&[FileWithContentToBeTrimmed( "katz.txt", r#" { @@ -46,7 +46,7 @@ fn from_json_text_to_table() { #[test] fn from_json_text_to_table_strict() { Playground::setup("filter_from_json_test_1_strict", |dirs, sandbox| { - sandbox.with_files(vec![FileWithContentToBeTrimmed( + sandbox.with_files(&[FileWithContentToBeTrimmed( "katz.txt", r#" { @@ -72,7 +72,7 @@ fn from_json_text_to_table_strict() { #[test] fn from_json_text_recognizing_objects_independently_to_table() { Playground::setup("filter_from_json_test_2", |dirs, sandbox| { - sandbox.with_files(vec![FileWithContentToBeTrimmed( + sandbox.with_files(&[FileWithContentToBeTrimmed( "katz.txt", r#" {"name": "Yehuda", "rusty_luck": 1} @@ -99,7 +99,7 @@ fn from_json_text_recognizing_objects_independently_to_table() { #[test] fn from_json_text_recognizing_objects_independently_to_table_strict() { Playground::setup("filter_from_json_test_2_strict", |dirs, sandbox| { - sandbox.with_files(vec![FileWithContentToBeTrimmed( + sandbox.with_files(&[FileWithContentToBeTrimmed( "katz.txt", r#" {"name": "Yehuda", "rusty_luck": 1} @@ -126,7 +126,7 @@ fn from_json_text_recognizing_objects_independently_to_table_strict() { #[test] fn table_to_json_text() { Playground::setup("filter_to_json_test", |dirs, sandbox| { - sandbox.with_files(vec![FileWithContentToBeTrimmed( + sandbox.with_files(&[FileWithContentToBeTrimmed( "sample.txt", r#" JonAndrehudaTZ,3 @@ -155,7 +155,7 @@ fn table_to_json_text() { #[test] fn table_to_json_text_strict() { Playground::setup("filter_to_json_test_strict", |dirs, sandbox| { - sandbox.with_files(vec![FileWithContentToBeTrimmed( + sandbox.with_files(&[FileWithContentToBeTrimmed( "sample.txt", r#" JonAndrehudaTZ,3 diff --git a/crates/nu-command/tests/format_conversions/ssv.rs b/crates/nu-command/tests/format_conversions/ssv.rs index 859ba01fc9..a673b122fb 100644 --- a/crates/nu-command/tests/format_conversions/ssv.rs +++ b/crates/nu-command/tests/format_conversions/ssv.rs @@ -5,7 +5,7 @@ use nu_test_support::{nu, pipeline}; #[test] fn from_ssv_text_to_table() { Playground::setup("filter_from_ssv_test_1", |dirs, sandbox| { - sandbox.with_files(vec![FileWithContentToBeTrimmed( + sandbox.with_files(&[FileWithContentToBeTrimmed( "oc_get_svc.txt", r#" NAME LABELS SELECTOR IP PORT(S) @@ -32,7 +32,7 @@ fn from_ssv_text_to_table() { #[test] fn from_ssv_text_to_table_with_separator_specified() { Playground::setup("filter_from_ssv_test_1", |dirs, sandbox| { - sandbox.with_files(vec![FileWithContentToBeTrimmed( + sandbox.with_files(&[FileWithContentToBeTrimmed( "oc_get_svc.txt", r#" NAME LABELS SELECTOR IP PORT(S) @@ -59,7 +59,7 @@ fn from_ssv_text_to_table_with_separator_specified() { #[test] fn from_ssv_text_treating_first_line_as_data_with_flag() { Playground::setup("filter_from_ssv_test_2", |dirs, sandbox| { - sandbox.with_files(vec![FileWithContentToBeTrimmed( + sandbox.with_files(&[FileWithContentToBeTrimmed( "oc_get_svc.txt", r#" docker-registry docker-registry=default docker-registry=default 172.30.78.158 5000/TCP diff --git a/crates/nu-command/tests/format_conversions/tsv.rs b/crates/nu-command/tests/format_conversions/tsv.rs index ca71c25e7a..9627d0d0be 100644 --- a/crates/nu-command/tests/format_conversions/tsv.rs +++ b/crates/nu-command/tests/format_conversions/tsv.rs @@ -25,7 +25,7 @@ fn table_to_tsv_text_and_from_tsv_text_back_into_table_using_csv_separator() { #[test] fn table_to_tsv_text() { Playground::setup("filter_to_tsv_test_1", |dirs, sandbox| { - sandbox.with_files(vec![FileWithContentToBeTrimmed( + sandbox.with_files(&[FileWithContentToBeTrimmed( "tsv_text_sample.txt", r#" importer shipper tariff_item name origin @@ -54,7 +54,7 @@ fn table_to_tsv_text() { #[test] fn table_to_tsv_text_skipping_headers_after_conversion() { Playground::setup("filter_to_tsv_test_2", |dirs, sandbox| { - sandbox.with_files(vec![FileWithContentToBeTrimmed( + sandbox.with_files(&[FileWithContentToBeTrimmed( "tsv_text_sample.txt", r#" importer shipper tariff_item name origin @@ -81,7 +81,7 @@ fn table_to_tsv_text_skipping_headers_after_conversion() { #[test] fn from_tsv_text_to_table() { Playground::setup("filter_from_tsv_test_1", |dirs, sandbox| { - sandbox.with_files(vec![FileWithContentToBeTrimmed( + sandbox.with_files(&[FileWithContentToBeTrimmed( "los_tres_amigos.txt", r#" first Name Last Name rusty_luck @@ -108,7 +108,7 @@ fn from_tsv_text_to_table() { #[test] fn from_tsv_text_with_comments_to_table() { Playground::setup("filter_from_tsv_test_2", |dirs, sandbox| { - sandbox.with_files(vec![FileWithContentToBeTrimmed( + sandbox.with_files(&[FileWithContentToBeTrimmed( "los_tres_caballeros.txt", r#" # This is a comment @@ -138,7 +138,7 @@ fn from_tsv_text_with_comments_to_table() { #[test] fn from_tsv_text_with_custom_quotes_to_table() { Playground::setup("filter_from_tsv_test_3", |dirs, sandbox| { - sandbox.with_files(vec![FileWithContentToBeTrimmed( + sandbox.with_files(&[FileWithContentToBeTrimmed( "los_tres_caballeros.txt", r#" first_name last_name rusty_luck @@ -165,7 +165,7 @@ fn from_tsv_text_with_custom_quotes_to_table() { #[test] fn from_tsv_text_with_custom_escapes_to_table() { Playground::setup("filter_from_tsv_test_4", |dirs, sandbox| { - sandbox.with_files(vec![FileWithContentToBeTrimmed( + sandbox.with_files(&[FileWithContentToBeTrimmed( "los_tres_caballeros.txt", r#" first_name last_name rusty_luck @@ -192,7 +192,7 @@ fn from_tsv_text_with_custom_escapes_to_table() { #[test] fn from_tsv_text_skipping_headers_to_table() { Playground::setup("filter_from_tsv_test_5", |dirs, sandbox| { - sandbox.with_files(vec![FileWithContentToBeTrimmed( + sandbox.with_files(&[FileWithContentToBeTrimmed( "los_tres_amigos.txt", r#" Andrés Robalino 1 @@ -218,7 +218,7 @@ fn from_tsv_text_skipping_headers_to_table() { #[test] fn from_tsv_text_with_missing_columns_to_table() { Playground::setup("filter_from_tsv_test_6", |dirs, sandbox| { - sandbox.with_files(vec![FileWithContentToBeTrimmed( + sandbox.with_files(&[FileWithContentToBeTrimmed( "los_tres_caballeros.txt", r#" first_name last_name rusty_luck @@ -246,7 +246,7 @@ fn from_tsv_text_with_missing_columns_to_table() { #[test] fn from_tsv_text_with_multiple_char_comment() { Playground::setup("filter_from_tsv_test_7", |dirs, sandbox| { - sandbox.with_files(vec![FileWithContentToBeTrimmed( + sandbox.with_files(&[FileWithContentToBeTrimmed( "los_tres_caballeros.txt", r#" first_name last_name rusty_luck @@ -271,7 +271,7 @@ fn from_tsv_text_with_multiple_char_comment() { #[test] fn from_tsv_text_with_wrong_type_comment() { Playground::setup("filter_from_csv_test_8", |dirs, sandbox| { - sandbox.with_files(vec![FileWithContentToBeTrimmed( + sandbox.with_files(&[FileWithContentToBeTrimmed( "los_tres_caballeros.txt", r#" first_name last_name rusty_luck diff --git a/crates/nu-explore/src/nu_common/value.rs b/crates/nu-explore/src/nu_common/value.rs index 3720582735..fde4394dac 100644 --- a/crates/nu-explore/src/nu_common/value.rs +++ b/crates/nu-explore/src/nu_common/value.rs @@ -22,9 +22,9 @@ pub fn collect_pipeline(input: PipelineData) -> Result<(Vec, Vec (Vec, Vec>) { +fn collect_list_stream(stream: ListStream) -> (Vec, Vec>) { let mut records = vec![]; - for item in stream.by_ref() { + for item in stream { records.push(item); } @@ -70,7 +70,7 @@ fn collect_external_stream( data.push(value); } if let Some(exit_code) = exit_code { - let list = exit_code.collect::>(); + let list = exit_code.into_iter().collect::>(); let val = Value::list(list, span); columns.push(String::from("exit_code")); diff --git a/crates/nu-json/src/de.rs b/crates/nu-json/src/de.rs index 6fcfbbf7d7..fff4da0d6f 100644 --- a/crates/nu-json/src/de.rs +++ b/crates/nu-json/src/de.rs @@ -260,8 +260,8 @@ where } _ => { if chf == b'-' || chf.is_ascii_digit() { - let mut pn = ParseNumber::new(self.str_buf.iter().copied()); - match pn.parse(false) { + let mut parser = ParseNumber::new(self.str_buf.iter().copied()); + match parser.parse(false) { Ok(Number::F64(v)) => { self.rdr.uneat_char(ch); return visitor.visit_f64(v); diff --git a/crates/nu-parser/src/flatten.rs b/crates/nu-parser/src/flatten.rs index cb1d1de110..3484c53d0f 100644 --- a/crates/nu-parser/src/flatten.rs +++ b/crates/nu-parser/src/flatten.rs @@ -49,87 +49,147 @@ pub enum FlatShape { VarDecl(VarId), } -impl Display for FlatShape { - fn fmt(&self, f: &mut Formatter) -> Result { +impl FlatShape { + pub fn as_str(&self) -> &str { match self { - FlatShape::And => write!(f, "shape_and"), - FlatShape::Binary => write!(f, "shape_binary"), - FlatShape::Block => write!(f, "shape_block"), - FlatShape::Bool => write!(f, "shape_bool"), - FlatShape::Closure => write!(f, "shape_closure"), - FlatShape::Custom(_) => write!(f, "shape_custom"), - FlatShape::DateTime => write!(f, "shape_datetime"), - FlatShape::Directory => write!(f, "shape_directory"), - FlatShape::External => write!(f, "shape_external"), - FlatShape::ExternalArg => write!(f, "shape_externalarg"), - FlatShape::ExternalResolved => write!(f, "shape_external_resolved"), - FlatShape::Filepath => write!(f, "shape_filepath"), - FlatShape::Flag => write!(f, "shape_flag"), - FlatShape::Float => write!(f, "shape_float"), - FlatShape::Garbage => write!(f, "shape_garbage"), - FlatShape::GlobPattern => write!(f, "shape_globpattern"), - FlatShape::Int => write!(f, "shape_int"), - FlatShape::InternalCall(_) => write!(f, "shape_internalcall"), - FlatShape::Keyword => write!(f, "shape_keyword"), - FlatShape::List => write!(f, "shape_list"), - FlatShape::Literal => write!(f, "shape_literal"), - FlatShape::MatchPattern => write!(f, "shape_match_pattern"), - FlatShape::Nothing => write!(f, "shape_nothing"), - FlatShape::Operator => write!(f, "shape_operator"), - FlatShape::Or => write!(f, "shape_or"), - FlatShape::Pipe => write!(f, "shape_pipe"), - FlatShape::Range => write!(f, "shape_range"), - FlatShape::RawString => write!(f, "shape_raw_string"), - FlatShape::Record => write!(f, "shape_record"), - FlatShape::Redirection => write!(f, "shape_redirection"), - FlatShape::Signature => write!(f, "shape_signature"), - FlatShape::String => write!(f, "shape_string"), - FlatShape::StringInterpolation => write!(f, "shape_string_interpolation"), - FlatShape::Table => write!(f, "shape_table"), - FlatShape::Variable(_) => write!(f, "shape_variable"), - FlatShape::VarDecl(_) => write!(f, "shape_vardecl"), + FlatShape::And => "shape_and", + FlatShape::Binary => "shape_binary", + FlatShape::Block => "shape_block", + FlatShape::Bool => "shape_bool", + FlatShape::Closure => "shape_closure", + FlatShape::Custom(_) => "shape_custom", + FlatShape::DateTime => "shape_datetime", + FlatShape::Directory => "shape_directory", + FlatShape::External => "shape_external", + FlatShape::ExternalArg => "shape_externalarg", + FlatShape::ExternalResolved => "shape_external_resolved", + FlatShape::Filepath => "shape_filepath", + FlatShape::Flag => "shape_flag", + FlatShape::Float => "shape_float", + FlatShape::Garbage => "shape_garbage", + FlatShape::GlobPattern => "shape_globpattern", + FlatShape::Int => "shape_int", + FlatShape::InternalCall(_) => "shape_internalcall", + FlatShape::Keyword => "shape_keyword", + FlatShape::List => "shape_list", + FlatShape::Literal => "shape_literal", + FlatShape::MatchPattern => "shape_match_pattern", + FlatShape::Nothing => "shape_nothing", + FlatShape::Operator => "shape_operator", + FlatShape::Or => "shape_or", + FlatShape::Pipe => "shape_pipe", + FlatShape::Range => "shape_range", + FlatShape::RawString => "shape_raw_string", + FlatShape::Record => "shape_record", + FlatShape::Redirection => "shape_redirection", + FlatShape::Signature => "shape_signature", + FlatShape::String => "shape_string", + FlatShape::StringInterpolation => "shape_string_interpolation", + FlatShape::Table => "shape_table", + FlatShape::Variable(_) => "shape_variable", + FlatShape::VarDecl(_) => "shape_vardecl", } } } -pub fn flatten_block(working_set: &StateWorkingSet, block: &Block) -> Vec<(Span, FlatShape)> { - let mut output = vec![]; - - for pipeline in &block.pipelines { - output.extend(flatten_pipeline(working_set, pipeline)); +impl Display for FlatShape { + fn fmt(&self, f: &mut Formatter) -> Result { + f.write_str(self.as_str()) } - output } -pub fn flatten_expression( +/* +The `_into` functions below (e.g., `flatten_block_into`) take an existing `output` `Vec` +and append more data to it. This is to reduce the number of intermediate `Vec`s. +The non-`into` functions (e.g., `flatten_block`) are part of the crate's public API +and return a new `Vec` instead of modifying an existing one. +*/ + +fn flatten_block_into( + working_set: &StateWorkingSet, + block: &Block, + output: &mut Vec<(Span, FlatShape)>, +) { + for pipeline in &block.pipelines { + flatten_pipeline_into(working_set, pipeline, output); + } +} + +fn flatten_pipeline_into( + working_set: &StateWorkingSet, + pipeline: &Pipeline, + output: &mut Vec<(Span, FlatShape)>, +) { + for expr in &pipeline.elements { + flatten_pipeline_element_into(working_set, expr, output) + } +} + +fn flatten_pipeline_element_into( + working_set: &StateWorkingSet, + pipeline_element: &PipelineElement, + output: &mut Vec<(Span, FlatShape)>, +) { + if let Some(span) = pipeline_element.pipe { + output.push((span, FlatShape::Pipe)); + } + + flatten_expression_into(working_set, &pipeline_element.expr, output); + + if let Some(redirection) = pipeline_element.redirection.as_ref() { + match redirection { + PipelineRedirection::Single { target, .. } => { + output.push((target.span(), FlatShape::Redirection)); + if let Some(expr) = target.expr() { + flatten_expression_into(working_set, expr, output); + } + } + PipelineRedirection::Separate { out, err } => { + let (out, err) = if out.span() <= err.span() { + (out, err) + } else { + (err, out) + }; + + output.push((out.span(), FlatShape::Redirection)); + if let Some(expr) = out.expr() { + flatten_expression_into(working_set, expr, output); + } + output.push((err.span(), FlatShape::Redirection)); + if let Some(expr) = err.expr() { + flatten_expression_into(working_set, expr, output); + } + } + } + } +} + +fn flatten_expression_into( working_set: &StateWorkingSet, expr: &Expression, -) -> Vec<(Span, FlatShape)> { + output: &mut Vec<(Span, FlatShape)>, +) { if let Some(custom_completion) = &expr.custom_completion { - return vec![(expr.span, FlatShape::Custom(*custom_completion))]; + output.push((expr.span, FlatShape::Custom(*custom_completion))); + return; } match &expr.expr { Expr::BinaryOp(lhs, op, rhs) => { - let mut output = vec![]; - output.extend(flatten_expression(working_set, lhs)); - output.extend(flatten_expression(working_set, op)); - output.extend(flatten_expression(working_set, rhs)); - output + flatten_expression_into(working_set, lhs, output); + flatten_expression_into(working_set, op, output); + flatten_expression_into(working_set, rhs, output); } - Expr::UnaryNot(inner_expr) => { - let mut output = vec![( + Expr::UnaryNot(expr) => { + output.push(( Span::new(expr.span.start, expr.span.start + 3), FlatShape::Operator, - )]; - output.extend(flatten_expression(working_set, inner_expr)); - output + )); + flatten_expression_into(working_set, expr, output); } Expr::Closure(block_id) => { let outer_span = expr.span; - let mut output = vec![]; - let block = working_set.get_block(*block_id); let flattened = flatten_block(working_set, block); @@ -154,16 +214,12 @@ pub fn flatten_expression( output.extend(flattened); if let Some(last) = last { - output.push(last) + output.push(last); } - - output } Expr::Block(block_id) | Expr::RowCondition(block_id) | Expr::Subexpression(block_id) => { let outer_span = expr.span; - let mut output = vec![]; - let flattened = flatten_block(working_set, working_set.get_block(*block_id)); if let Some(first) = flattened.first() { @@ -184,150 +240,99 @@ pub fn flatten_expression( output.extend(flattened); if let Some(last) = last { - output.push(last) + output.push(last); } - - output } Expr::Call(call) => { - let mut output = vec![]; - if call.head.end != 0 { // Make sure we don't push synthetic calls output.push((call.head, FlatShape::InternalCall(call.decl_id))); } - let mut args = vec![]; + let arg_start = output.len(); for arg in &call.arguments { match arg { Argument::Positional(positional) | Argument::Unknown(positional) => { - let flattened = flatten_expression(working_set, positional); - args.extend(flattened); + flatten_expression_into(working_set, positional, output) } Argument::Named(named) => { if named.0.span.end != 0 { // Ignore synthetic flags - args.push((named.0.span, FlatShape::Flag)); + output.push((named.0.span, FlatShape::Flag)); } if let Some(expr) = &named.2 { - args.extend(flatten_expression(working_set, expr)); + flatten_expression_into(working_set, expr, output); } } Argument::Spread(expr) => { - args.push(( + output.push(( Span::new(expr.span.start - 3, expr.span.start), FlatShape::Operator, )); - args.extend(flatten_expression(working_set, expr)); + flatten_expression_into(working_set, expr, output); } } } // sort these since flags and positional args can be intermixed - args.sort(); - - output.extend(args); - output + output[arg_start..].sort(); } Expr::ExternalCall(head, args) => { - let mut output = vec![]; - - match **head { - Expression { - expr: Expr::String(..), - span, - .. - } => { - output.push((span, FlatShape::External)); - } - _ => { - output.extend(flatten_expression(working_set, head)); - } + if let Expr::String(..) = &head.expr { + output.push((head.span, FlatShape::External)); + } else { + flatten_expression_into(working_set, head, output); } for arg in args.as_ref() { - //output.push((*arg, FlatShape::ExternalArg)); match arg { - ExternalArgument::Regular(expr) => match expr { - Expression { - expr: Expr::String(..), - span, - .. - } => { - output.push((*span, FlatShape::ExternalArg)); + ExternalArgument::Regular(expr) => { + if let Expr::String(..) = &expr.expr { + output.push((expr.span, FlatShape::ExternalArg)); + } else { + flatten_expression_into(working_set, expr, output); } - _ => { - output.extend(flatten_expression(working_set, expr)); - } - }, + } ExternalArgument::Spread(expr) => { output.push(( Span::new(expr.span.start - 3, expr.span.start), FlatShape::Operator, )); - output.extend(flatten_expression(working_set, expr)); + flatten_expression_into(working_set, expr, output); } } } - - output - } - Expr::Garbage => { - vec![(expr.span, FlatShape::Garbage)] - } - Expr::Nothing => { - vec![(expr.span, FlatShape::Nothing)] - } - Expr::DateTime(_) => { - vec![(expr.span, FlatShape::DateTime)] - } - Expr::Binary(_) => { - vec![(expr.span, FlatShape::Binary)] - } - Expr::Int(_) => { - vec![(expr.span, FlatShape::Int)] - } - Expr::Float(_) => { - vec![(expr.span, FlatShape::Float)] } + Expr::Garbage => output.push((expr.span, FlatShape::Garbage)), + Expr::Nothing => output.push((expr.span, FlatShape::Nothing)), + Expr::DateTime(_) => output.push((expr.span, FlatShape::DateTime)), + Expr::Binary(_) => output.push((expr.span, FlatShape::Binary)), + Expr::Int(_) => output.push((expr.span, FlatShape::Int)), + Expr::Float(_) => output.push((expr.span, FlatShape::Float)), Expr::MatchBlock(matches) => { - let mut output = vec![]; - - for match_ in matches { - output.extend(flatten_pattern(&match_.0)); - output.extend(flatten_expression(working_set, &match_.1)); + for (pattern, expr) in matches { + flatten_pattern_into(pattern, output); + flatten_expression_into(working_set, expr, output); } - - output } Expr::ValueWithUnit(value) => { - let mut output = flatten_expression(working_set, &value.expr); + flatten_expression_into(working_set, &value.expr, output); output.push((value.unit.span, FlatShape::String)); - - output } Expr::CellPath(cell_path) => { - let mut output = vec![]; - for path_element in &cell_path.members { - match path_element { - PathMember::String { span, .. } => output.push((*span, FlatShape::String)), - PathMember::Int { span, .. } => output.push((*span, FlatShape::Int)), - } - } - output + output.extend(cell_path.members.iter().map(|member| match *member { + PathMember::String { span, .. } => (span, FlatShape::String), + PathMember::Int { span, .. } => (span, FlatShape::Int), + })); } Expr::FullCellPath(cell_path) => { - let mut output = vec![]; - output.extend(flatten_expression(working_set, &cell_path.head)); - for path_element in &cell_path.tail { - match path_element { - PathMember::String { span, .. } => output.push((*span, FlatShape::String)), - PathMember::Int { span, .. } => output.push((*span, FlatShape::Int)), - } - } - output + flatten_expression_into(working_set, &cell_path.head, output); + output.extend(cell_path.tail.iter().map(|member| match *member { + PathMember::String { span, .. } => (span, FlatShape::String), + PathMember::Int { span, .. } => (span, FlatShape::Int), + })); } Expr::ImportPattern(import_pattern) => { - let mut output = vec![(import_pattern.head.span, FlatShape::String)]; + output.push((import_pattern.head.span, FlatShape::String)); for member in &import_pattern.members { match member { @@ -336,50 +341,33 @@ pub fn flatten_expression( output.push((*span, FlatShape::String)) } ImportPatternMember::List { names } => { - for (_, span) in names { - output.push((*span, FlatShape::String)); - } + output.extend(names.iter().map(|&(_, span)| (span, FlatShape::String))) } } } - - output - } - Expr::Overlay(_) => { - vec![(expr.span, FlatShape::String)] } + Expr::Overlay(_) => output.push((expr.span, FlatShape::String)), Expr::Range(range) => { - let mut output = vec![]; if let Some(f) = &range.from { - output.extend(flatten_expression(working_set, f)); + flatten_expression_into(working_set, f, output); } if let Some(s) = &range.next { - output.extend(vec![(range.operator.next_op_span, FlatShape::Operator)]); - output.extend(flatten_expression(working_set, s)); + output.push((range.operator.next_op_span, FlatShape::Operator)); + flatten_expression_into(working_set, s, output); } - output.extend(vec![(range.operator.span, FlatShape::Operator)]); + output.push((range.operator.span, FlatShape::Operator)); if let Some(t) = &range.to { - output.extend(flatten_expression(working_set, t)); + flatten_expression_into(working_set, t, output); } - output - } - Expr::Bool(_) => { - vec![(expr.span, FlatShape::Bool)] - } - Expr::Filepath(_, _) => { - vec![(expr.span, FlatShape::Filepath)] - } - Expr::Directory(_, _) => { - vec![(expr.span, FlatShape::Directory)] - } - Expr::GlobPattern(_, _) => { - vec![(expr.span, FlatShape::GlobPattern)] } + Expr::Bool(_) => output.push((expr.span, FlatShape::Bool)), + Expr::Filepath(_, _) => output.push((expr.span, FlatShape::Filepath)), + Expr::Directory(_, _) => output.push((expr.span, FlatShape::Directory)), + Expr::GlobPattern(_, _) => output.push((expr.span, FlatShape::GlobPattern)), Expr::List(list) => { let outer_span = expr.span; let mut last_end = outer_span.start; - let mut output = vec![]; for item in list { match item { ListItem::Item(expr) => { @@ -398,11 +386,11 @@ pub fn flatten_expression( output.extend(flattened); } ListItem::Spread(_, expr) => { - let mut output = vec![( + output.push(( Span::new(expr.span.start, expr.span.start + 3), FlatShape::Operator, - )]; - output.extend(flatten_expression(working_set, expr)); + )); + flatten_expression_into(working_set, expr, output); } } } @@ -410,37 +398,32 @@ pub fn flatten_expression( if last_end < outer_span.end { output.push((Span::new(last_end, outer_span.end), FlatShape::List)); } - output } Expr::StringInterpolation(exprs) => { - let mut output = vec![]; + let mut flattened = vec![]; for expr in exprs { - output.extend(flatten_expression(working_set, expr)); + flatten_expression_into(working_set, expr, &mut flattened); } - if let Some(first) = output.first() { + if let Some(first) = flattened.first() { if first.0.start != expr.span.start { // If we aren't a bare word interpolation, also highlight the outer quotes - output.insert( - 0, - ( - Span::new(expr.span.start, expr.span.start + 2), - FlatShape::StringInterpolation, - ), - ); output.push(( + Span::new(expr.span.start, expr.span.start + 2), + FlatShape::StringInterpolation, + )); + flattened.push(( Span::new(expr.span.end - 1, expr.span.end), FlatShape::StringInterpolation, )); } } - output + output.extend(flattened); } Expr::Record(list) => { let outer_span = expr.span; let mut last_end = outer_span.start; - let mut output = vec![]; for l in list { match l { RecordItem::Pair(key, val) => { @@ -477,50 +460,38 @@ pub fn flatten_expression( output.push((*op_span, FlatShape::Operator)); last_end = op_span.end; - let flattened_inner = flatten_expression(working_set, record); - if let Some(first) = flattened_inner.first() { + let flattened = flatten_expression(working_set, record); + if let Some(first) = flattened.first() { if first.0.start > last_end { output .push((Span::new(last_end, first.0.start), FlatShape::Record)); } } - if let Some(last) = flattened_inner.last() { + if let Some(last) = flattened.last() { last_end = last.0.end; } - output.extend(flattened_inner); + output.extend(flattened); } } } if last_end < outer_span.end { output.push((Span::new(last_end, outer_span.end), FlatShape::Record)); } - - output } Expr::Keyword(kw) => { - let mut output = vec![(kw.span, FlatShape::Keyword)]; - output.extend(flatten_expression(working_set, &kw.expr)); - output - } - Expr::Operator(_) => { - vec![(expr.span, FlatShape::Operator)] - } - Expr::Signature(_) => { - vec![(expr.span, FlatShape::Signature)] - } - Expr::String(_) => { - vec![(expr.span, FlatShape::String)] - } - Expr::RawString(_) => { - vec![(expr.span, FlatShape::RawString)] + output.push((kw.span, FlatShape::Keyword)); + flatten_expression_into(working_set, &kw.expr, output); } + Expr::Operator(_) => output.push((expr.span, FlatShape::Operator)), + Expr::Signature(_) => output.push((expr.span, FlatShape::Signature)), + Expr::String(_) => output.push((expr.span, FlatShape::String)), + Expr::RawString(_) => output.push((expr.span, FlatShape::RawString)), Expr::Table(table) => { let outer_span = expr.span; let mut last_end = outer_span.start; - let mut output = vec![]; - for e in table.columns.as_ref() { - let flattened = flatten_expression(working_set, e); + for col in table.columns.as_ref() { + let flattened = flatten_expression(working_set, col); if let Some(first) = flattened.first() { if first.0.start > last_end { output.push((Span::new(last_end, first.0.start), FlatShape::Table)); @@ -553,83 +524,17 @@ pub fn flatten_expression( if last_end < outer_span.end { output.push((Span::new(last_end, outer_span.end), FlatShape::Table)); } - - output - } - Expr::Var(var_id) => { - vec![(expr.span, FlatShape::Variable(*var_id))] - } - Expr::VarDecl(var_id) => { - vec![(expr.span, FlatShape::VarDecl(*var_id))] } + Expr::Var(var_id) => output.push((expr.span, FlatShape::Variable(*var_id))), + Expr::VarDecl(var_id) => output.push((expr.span, FlatShape::VarDecl(*var_id))), } } -pub fn flatten_pipeline_element( - working_set: &StateWorkingSet, - pipeline_element: &PipelineElement, -) -> Vec<(Span, FlatShape)> { - let mut output = if let Some(span) = pipeline_element.pipe { - let mut output = vec![(span, FlatShape::Pipe)]; - output.extend(flatten_expression(working_set, &pipeline_element.expr)); - output - } else { - flatten_expression(working_set, &pipeline_element.expr) - }; - - if let Some(redirection) = pipeline_element.redirection.as_ref() { - match redirection { - PipelineRedirection::Single { target, .. } => { - output.push((target.span(), FlatShape::Redirection)); - if let Some(expr) = target.expr() { - output.extend(flatten_expression(working_set, expr)); - } - } - PipelineRedirection::Separate { out, err } => { - let (out, err) = if out.span() <= err.span() { - (out, err) - } else { - (err, out) - }; - - output.push((out.span(), FlatShape::Redirection)); - if let Some(expr) = out.expr() { - output.extend(flatten_expression(working_set, expr)); - } - output.push((err.span(), FlatShape::Redirection)); - if let Some(expr) = err.expr() { - output.extend(flatten_expression(working_set, expr)); - } - } - } - } - - output -} - -pub fn flatten_pipeline( - working_set: &StateWorkingSet, - pipeline: &Pipeline, -) -> Vec<(Span, FlatShape)> { - let mut output = vec![]; - for expr in &pipeline.elements { - output.extend(flatten_pipeline_element(working_set, expr)) - } - output -} - -pub fn flatten_pattern(match_pattern: &MatchPattern) -> Vec<(Span, FlatShape)> { - let mut output = vec![]; +fn flatten_pattern_into(match_pattern: &MatchPattern, output: &mut Vec<(Span, FlatShape)>) { match &match_pattern.pattern { - Pattern::Garbage => { - output.push((match_pattern.span, FlatShape::Garbage)); - } - Pattern::IgnoreValue => { - output.push((match_pattern.span, FlatShape::Nothing)); - } - Pattern::IgnoreRest => { - output.push((match_pattern.span, FlatShape::Nothing)); - } + Pattern::Garbage => output.push((match_pattern.span, FlatShape::Garbage)), + Pattern::IgnoreValue => output.push((match_pattern.span, FlatShape::Nothing)), + Pattern::IgnoreRest => output.push((match_pattern.span, FlatShape::Nothing)), Pattern::List(items) => { if let Some(first) = items.first() { if let Some(last) = items.last() { @@ -638,7 +543,7 @@ pub fn flatten_pattern(match_pattern: &MatchPattern) -> Vec<(Span, FlatShape)> { FlatShape::MatchPattern, )); for item in items { - output.extend(flatten_pattern(item)); + flatten_pattern_into(item, output); } output.push(( Span::new(last.span.end, match_pattern.span.end), @@ -656,8 +561,8 @@ pub fn flatten_pattern(match_pattern: &MatchPattern) -> Vec<(Span, FlatShape)> { Span::new(match_pattern.span.start, first.1.span.start), FlatShape::MatchPattern, )); - for item in items { - output.extend(flatten_pattern(&item.1)); + for (_, pattern) in items { + flatten_pattern_into(pattern, output); } output.push(( Span::new(last.1.span.end, match_pattern.span.end), @@ -668,20 +573,46 @@ pub fn flatten_pattern(match_pattern: &MatchPattern) -> Vec<(Span, FlatShape)> { output.push((match_pattern.span, FlatShape::MatchPattern)); } } - Pattern::Value(_) => { - output.push((match_pattern.span, FlatShape::MatchPattern)); - } - Pattern::Variable(var_id) => { - output.push((match_pattern.span, FlatShape::VarDecl(*var_id))); - } - Pattern::Rest(var_id) => { - output.push((match_pattern.span, FlatShape::VarDecl(*var_id))); - } + Pattern::Value(_) => output.push((match_pattern.span, FlatShape::MatchPattern)), + Pattern::Variable(var_id) => output.push((match_pattern.span, FlatShape::VarDecl(*var_id))), + Pattern::Rest(var_id) => output.push((match_pattern.span, FlatShape::VarDecl(*var_id))), Pattern::Or(patterns) => { for pattern in patterns { - output.extend(flatten_pattern(pattern)); + flatten_pattern_into(pattern, output); } } } +} + +pub fn flatten_block(working_set: &StateWorkingSet, block: &Block) -> Vec<(Span, FlatShape)> { + let mut output = Vec::new(); + flatten_block_into(working_set, block, &mut output); + output +} + +pub fn flatten_pipeline( + working_set: &StateWorkingSet, + pipeline: &Pipeline, +) -> Vec<(Span, FlatShape)> { + let mut output = Vec::new(); + flatten_pipeline_into(working_set, pipeline, &mut output); + output +} + +pub fn flatten_pipeline_element( + working_set: &StateWorkingSet, + pipeline_element: &PipelineElement, +) -> Vec<(Span, FlatShape)> { + let mut output = Vec::new(); + flatten_pipeline_element_into(working_set, pipeline_element, &mut output); + output +} + +pub fn flatten_expression( + working_set: &StateWorkingSet, + expr: &Expression, +) -> Vec<(Span, FlatShape)> { + let mut output = Vec::new(); + flatten_expression_into(working_set, expr, &mut output); output } diff --git a/crates/nu-path/src/components.rs b/crates/nu-path/src/components.rs index b7f60598c2..9cb74dc373 100644 --- a/crates/nu-path/src/components.rs +++ b/crates/nu-path/src/components.rs @@ -24,15 +24,13 @@ //! `Path::join()`. It works because `PathBuf::push("")` will add a trailing //! slash when the original path doesn't have one. -#[cfg(unix)] -use std::os::unix::ffi::OsStrExt; -#[cfg(windows)] -use std::os::windows::ffi::OsStrExt; use std::{ ffi::OsStr, path::{Component, Path}, }; +use crate::trailing_slash::has_trailing_slash; + /// Like `Path::components()`, but produces an extra empty component at the end /// when `path` contains a trailing slash. /// @@ -63,17 +61,6 @@ pub fn components(path: &Path) -> impl Iterator { })) } -#[cfg(windows)] -fn has_trailing_slash(path: &Path) -> bool { - let last = path.as_os_str().encode_wide().last(); - last == Some(b'\\' as u16) || last == Some(b'/' as u16) -} -#[cfg(unix)] -fn has_trailing_slash(path: &Path) -> bool { - let last = path.as_os_str().as_bytes().last(); - last == Some(&b'/') -} - #[cfg(test)] mod test { //! We'll go through every variant of Component, with or without trailing diff --git a/crates/nu-path/src/lib.rs b/crates/nu-path/src/lib.rs index e4baf36e76..6c064d4b57 100644 --- a/crates/nu-path/src/lib.rs +++ b/crates/nu-path/src/lib.rs @@ -4,8 +4,10 @@ pub mod dots; pub mod expansions; mod helpers; mod tilde; +mod trailing_slash; pub use components::components; pub use expansions::{canonicalize_with, expand_path_with, expand_to_real_path, locate_in_dirs}; pub use helpers::{config_dir, config_dir_old, home_dir}; pub use tilde::expand_tilde; +pub use trailing_slash::{has_trailing_slash, strip_trailing_slash}; diff --git a/crates/nu-path/src/trailing_slash.rs b/crates/nu-path/src/trailing_slash.rs new file mode 100644 index 0000000000..4daf5d45ef --- /dev/null +++ b/crates/nu-path/src/trailing_slash.rs @@ -0,0 +1,108 @@ +use std::{ + borrow::Cow, + path::{Path, PathBuf}, +}; + +/// Strip any trailing slashes from a non-root path. This is required in some contexts, for example +/// for the `PWD` environment variable. +pub fn strip_trailing_slash(path: &Path) -> Cow { + if has_trailing_slash(path) { + // If there are, the safest thing to do is have Rust parse the path for us and build it + // again. This will correctly handle a root directory, but it won't add the trailing slash. + let mut out = PathBuf::with_capacity(path.as_os_str().len()); + out.extend(path.components()); + Cow::Owned(out) + } else { + // The path is safe and doesn't contain any trailing slashes. + Cow::Borrowed(path) + } +} + +/// `true` if the path has a trailing slash, including if it's the root directory. +#[cfg(windows)] +pub fn has_trailing_slash(path: &Path) -> bool { + use std::os::windows::ffi::OsStrExt; + + let last = path.as_os_str().encode_wide().last(); + last == Some(b'\\' as u16) || last == Some(b'/' as u16) +} + +/// `true` if the path has a trailing slash, including if it's the root directory. +#[cfg(unix)] +pub fn has_trailing_slash(path: &Path) -> bool { + use std::os::unix::ffi::OsStrExt; + + let last = path.as_os_str().as_bytes().last(); + last == Some(&b'/') +} + +#[cfg(test)] +mod tests { + use super::*; + + #[cfg_attr(not(unix), ignore = "only for Unix")] + #[test] + fn strip_root_unix() { + assert_eq!(Path::new("/"), strip_trailing_slash(Path::new("/"))); + } + + #[cfg_attr(not(unix), ignore = "only for Unix")] + #[test] + fn strip_non_trailing_unix() { + assert_eq!( + Path::new("/foo/bar"), + strip_trailing_slash(Path::new("/foo/bar")) + ); + } + + #[cfg_attr(not(unix), ignore = "only for Unix")] + #[test] + fn strip_trailing_unix() { + assert_eq!( + Path::new("/foo/bar"), + strip_trailing_slash(Path::new("/foo/bar/")) + ); + } + + #[cfg_attr(not(windows), ignore = "only for Windows")] + #[test] + fn strip_root_windows() { + assert_eq!(Path::new(r"C:\"), strip_trailing_slash(Path::new(r"C:\"))); + } + + #[cfg_attr(not(windows), ignore = "only for Windows")] + #[test] + fn strip_non_trailing_windows() { + assert_eq!( + Path::new(r"C:\foo\bar"), + strip_trailing_slash(Path::new(r"C:\foo\bar")) + ); + } + + #[cfg_attr(not(windows), ignore = "only for Windows")] + #[test] + fn strip_non_trailing_windows_unc() { + assert_eq!( + Path::new(r"\\foo\bar"), + strip_trailing_slash(Path::new(r"\\foo\bar")) + ); + } + + #[cfg_attr(not(windows), ignore = "only for Windows")] + #[test] + fn strip_trailing_windows() { + assert_eq!( + Path::new(r"C:\foo\bar"), + strip_trailing_slash(Path::new(r"C:\foo\bar\")) + ); + } + + #[cfg_attr(not(windows), ignore = "only for Windows")] + #[test] + fn strip_trailing_windows_unc() { + assert_eq!( + Path::new(r"\\foo\bar"), + strip_trailing_slash(Path::new(r"\\foo\bar\")) + ); + } +} diff --git a/crates/nu-plugin-core/src/interface/mod.rs b/crates/nu-plugin-core/src/interface/mod.rs index 4124e83bfb..3fb86aee36 100644 --- a/crates/nu-plugin-core/src/interface/mod.rs +++ b/crates/nu-plugin-core/src/interface/mod.rs @@ -183,7 +183,7 @@ pub trait InterfaceManager { PipelineDataHeader::ListStream(info) => { let handle = self.stream_manager().get_handle(); let reader = handle.read_stream(info.id, self.get_interface())?; - PipelineData::ListStream(ListStream::from_stream(reader, ctrlc.cloned()), None) + ListStream::new(reader, info.span, ctrlc.cloned()).into() } PipelineDataHeader::ExternalStream(info) => { let handle = self.stream_manager().get_handle(); @@ -203,7 +203,7 @@ pub trait InterfaceManager { .map(|list_info| { handle .read_stream(list_info.id, self.get_interface()) - .map(|reader| ListStream::from_stream(reader, ctrlc.cloned())) + .map(|reader| ListStream::new(reader, info.span, ctrlc.cloned())) }) .transpose()?, span: info.span, @@ -278,7 +278,10 @@ pub trait Interface: Clone + Send { PipelineData::ListStream(stream, _) => { let (id, writer) = new_stream(LIST_STREAM_HIGH_PRESSURE)?; Ok(( - PipelineDataHeader::ListStream(ListStreamInfo { id }), + PipelineDataHeader::ListStream(ListStreamInfo { + id, + span: stream.span(), + }), PipelineDataWriter::ListStream(writer, stream), )) } @@ -316,7 +319,7 @@ pub trait Interface: Clone + Send { .map(|(stream, (id, _))| RawStreamInfo::new(*id, stream)), exit_code: exit_code_stream .as_ref() - .map(|&(id, _)| ListStreamInfo { id }), + .map(|&(id, _)| ListStreamInfo { id, span }), trim_end_newline, }); // Collect the writers diff --git a/crates/nu-plugin-core/src/interface/tests.rs b/crates/nu-plugin-core/src/interface/tests.rs index 33b6ef27ae..ce7be52f30 100644 --- a/crates/nu-plugin-core/src/interface/tests.rs +++ b/crates/nu-plugin-core/src/interface/tests.rs @@ -161,7 +161,10 @@ fn read_pipeline_data_list_stream() -> Result<(), ShellError> { } test.add(StreamMessage::End(7)); - let header = PipelineDataHeader::ListStream(ListStreamInfo { id: 7 }); + let header = PipelineDataHeader::ListStream(ListStreamInfo { + id: 7, + span: Span::test_data(), + }); let pipe = manager.read_pipeline_data(header, None)?; assert!( @@ -221,7 +224,10 @@ fn read_pipeline_data_external_stream() -> Result<(), ShellError> { is_binary: true, known_size: None, }), - exit_code: Some(ListStreamInfo { id: 14 }), + exit_code: Some(ListStreamInfo { + id: 14, + span: Span::test_data(), + }), trim_end_newline: true, }); @@ -273,7 +279,10 @@ fn read_pipeline_data_external_stream() -> Result<(), ShellError> { } assert_eq!(iterations, count, "stderr length"); - assert_eq!(vec![Value::test_int(1)], exit_code.collect::>()); + assert_eq!( + vec![Value::test_int(1)], + exit_code.into_iter().collect::>() + ); } _ => panic!("unexpected PipelineData: {pipe:?}"), } @@ -284,30 +293,13 @@ fn read_pipeline_data_external_stream() -> Result<(), ShellError> { Ok(()) } -#[test] -fn read_pipeline_data_ctrlc() -> Result<(), ShellError> { - let manager = TestInterfaceManager::new(&TestCase::new()); - let header = PipelineDataHeader::ListStream(ListStreamInfo { id: 0 }); - let ctrlc = Default::default(); - match manager.read_pipeline_data(header, Some(&ctrlc))? { - PipelineData::ListStream( - ListStream { - ctrlc: stream_ctrlc, - .. - }, - _, - ) => { - assert!(Arc::ptr_eq(&ctrlc, &stream_ctrlc.expect("ctrlc not set"))); - Ok(()) - } - _ => panic!("Unexpected PipelineData, should have been ListStream"), - } -} - #[test] fn read_pipeline_data_prepared_properly() -> Result<(), ShellError> { let manager = TestInterfaceManager::new(&TestCase::new()); - let header = PipelineDataHeader::ListStream(ListStreamInfo { id: 0 }); + let header = PipelineDataHeader::ListStream(ListStreamInfo { + id: 0, + span: Span::test_data(), + }); match manager.read_pipeline_data(header, None)? { PipelineData::ListStream(_, meta) => match meta { Some(PipelineMetadata { data_source }) => match data_source { @@ -404,7 +396,7 @@ fn write_pipeline_data_list_stream() -> Result<(), ShellError> { // Set up pipeline data for a list stream let pipe = PipelineData::ListStream( - ListStream::from_stream(values.clone().into_iter(), None), + ListStream::new(values.clone().into_iter(), Span::test_data(), None), None, ); @@ -474,8 +466,9 @@ fn write_pipeline_data_external_stream() -> Result<(), ShellError> { span, None, )), - exit_code: Some(ListStream::from_stream( + exit_code: Some(ListStream::new( std::iter::once(exit_code.clone()), + Span::test_data(), None, )), span, diff --git a/crates/nu-plugin-engine/src/interface/mod.rs b/crates/nu-plugin-engine/src/interface/mod.rs index be14dbdc2d..3447d6a907 100644 --- a/crates/nu-plugin-engine/src/interface/mod.rs +++ b/crates/nu-plugin-engine/src/interface/mod.rs @@ -11,8 +11,8 @@ use nu_plugin_protocol::{ PluginOutput, ProtocolInfo, StreamId, StreamMessage, }; use nu_protocol::{ - ast::Operator, CustomValue, IntoInterruptiblePipelineData, IntoSpanned, ListStream, - PipelineData, PluginSignature, ShellError, Span, Spanned, Value, + ast::Operator, CustomValue, IntoSpanned, PipelineData, PluginSignature, ShellError, Span, + Spanned, Value, }; use std::{ collections::{btree_map, BTreeMap}, @@ -592,14 +592,15 @@ impl InterfaceManager for PluginInterfaceManager { })?; Ok(data) } - PipelineData::ListStream(ListStream { stream, ctrlc, .. }, meta) => { + PipelineData::ListStream(stream, meta) => { let source = self.state.source.clone(); - Ok(stream - .map(move |mut value| { + Ok(PipelineData::ListStream( + stream.map(move |mut value| { let _ = PluginCustomValueWithSource::add_source_in(&mut value, &source); value - }) - .into_pipeline_data_with_metadata(meta, ctrlc)) + }), + meta, + )) } PipelineData::Empty | PipelineData::ExternalStream { .. } => Ok(data), } @@ -1076,18 +1077,19 @@ impl Interface for PluginInterface { state.prepare_value(&mut value, &self.state.source)?; Ok(PipelineData::Value(value, meta)) } - PipelineData::ListStream(ListStream { stream, ctrlc, .. }, meta) => { + PipelineData::ListStream(stream, meta) => { let source = self.state.source.clone(); let state = state.clone(); - Ok(stream - .map(move |mut value| { + Ok(PipelineData::ListStream( + stream.map(move |mut value| { match state.prepare_value(&mut value, &source) { Ok(()) => value, // Put the error in the stream instead Err(err) => Value::error(err, value.span()), } - }) - .into_pipeline_data_with_metadata(meta, ctrlc)) + }), + meta, + )) } PipelineData::Empty | PipelineData::ExternalStream { .. } => Ok(data), } diff --git a/crates/nu-plugin-engine/src/interface/tests.rs b/crates/nu-plugin-engine/src/interface/tests.rs index 007568d726..7548703191 100644 --- a/crates/nu-plugin-engine/src/interface/tests.rs +++ b/crates/nu-plugin-engine/src/interface/tests.rs @@ -52,7 +52,10 @@ fn manager_consume_all_exits_after_streams_and_interfaces_are_dropped() -> Resul // Create a stream... let stream = manager.read_pipeline_data( - PipelineDataHeader::ListStream(ListStreamInfo { id: 0 }), + PipelineDataHeader::ListStream(ListStreamInfo { + id: 0, + span: Span::test_data(), + }), None, )?; @@ -105,7 +108,10 @@ fn manager_consume_all_propagates_io_error_to_readers() -> Result<(), ShellError test.set_read_error(test_io_error()); let stream = manager.read_pipeline_data( - PipelineDataHeader::ListStream(ListStreamInfo { id: 0 }), + PipelineDataHeader::ListStream(ListStreamInfo { + id: 0, + span: Span::test_data(), + }), None, )?; @@ -331,7 +337,10 @@ fn manager_consume_call_response_forwards_to_subscriber_with_pipeline_data( manager.consume(PluginOutput::CallResponse( 0, - PluginCallResponse::PipelineData(PipelineDataHeader::ListStream(ListStreamInfo { id: 0 })), + PluginCallResponse::PipelineData(PipelineDataHeader::ListStream(ListStreamInfo { + id: 0, + span: Span::test_data(), + })), ))?; for i in 0..2 { @@ -372,7 +381,10 @@ fn manager_consume_call_response_registers_streams() -> Result<(), ShellError> { // Check list streams, external streams manager.consume(PluginOutput::CallResponse( 0, - PluginCallResponse::PipelineData(PipelineDataHeader::ListStream(ListStreamInfo { id: 0 })), + PluginCallResponse::PipelineData(PipelineDataHeader::ListStream(ListStreamInfo { + id: 0, + span: Span::test_data(), + })), ))?; manager.consume(PluginOutput::CallResponse( 1, @@ -388,7 +400,10 @@ fn manager_consume_call_response_registers_streams() -> Result<(), ShellError> { is_binary: false, known_size: None, }), - exit_code: Some(ListStreamInfo { id: 3 }), + exit_code: Some(ListStreamInfo { + id: 3, + span: Span::test_data(), + }), trim_end_newline: false, })), ))?; @@ -448,7 +463,10 @@ fn manager_consume_engine_call_forwards_to_subscriber_with_pipeline_data() -> Re span: Span::test_data(), }, positional: vec![], - input: PipelineDataHeader::ListStream(ListStreamInfo { id: 2 }), + input: PipelineDataHeader::ListStream(ListStreamInfo { + id: 2, + span: Span::test_data(), + }), redirect_stdout: false, redirect_stderr: false, }, @@ -681,7 +699,7 @@ fn manager_prepare_pipeline_data_adds_source_to_list_streams() -> Result<(), She [Value::test_custom_value(Box::new( test_plugin_custom_value(), ))] - .into_pipeline_data(None), + .into_pipeline_data(Span::test_data(), None), )?; let value = data @@ -855,7 +873,7 @@ fn interface_write_plugin_call_writes_run_with_stream_input() -> Result<(), Shel positional: vec![], named: vec![], }, - input: values.clone().into_pipeline_data(None), + input: values.clone().into_pipeline_data(Span::test_data(), None), }), None, )?; @@ -1131,7 +1149,10 @@ fn interface_prepare_pipeline_data_accepts_normal_streams() -> Result<(), ShellE let interface = TestCase::new().plugin("test").get_interface(); let values = normal_values(&interface); let state = CurrentCallState::default(); - let data = interface.prepare_pipeline_data(values.clone().into_pipeline_data(None), &state)?; + let data = interface.prepare_pipeline_data( + values.clone().into_pipeline_data(Span::test_data(), None), + &state, + )?; let mut count = 0; for (expected_value, actual_value) in values.iter().zip(data) { @@ -1191,7 +1212,10 @@ fn interface_prepare_pipeline_data_rejects_bad_custom_value_in_a_stream() -> Res let interface = TestCase::new().plugin("test").get_interface(); let values = bad_custom_values(); let state = CurrentCallState::default(); - let data = interface.prepare_pipeline_data(values.clone().into_pipeline_data(None), &state)?; + let data = interface.prepare_pipeline_data( + values.clone().into_pipeline_data(Span::test_data(), None), + &state, + )?; let mut count = 0; for value in data { diff --git a/crates/nu-plugin-protocol/src/lib.rs b/crates/nu-plugin-protocol/src/lib.rs index 57bec28327..e40136ca56 100644 --- a/crates/nu-plugin-protocol/src/lib.rs +++ b/crates/nu-plugin-protocol/src/lib.rs @@ -116,6 +116,7 @@ impl PipelineDataHeader { #[derive(Serialize, Deserialize, Debug, PartialEq, Eq, Clone)] pub struct ListStreamInfo { pub id: StreamId, + pub span: Span, } /// Additional information about external streams diff --git a/crates/nu-plugin-test-support/src/lib.rs b/crates/nu-plugin-test-support/src/lib.rs index dd301d4d2b..8aa675fd1f 100644 --- a/crates/nu-plugin-test-support/src/lib.rs +++ b/crates/nu-plugin-test-support/src/lib.rs @@ -79,7 +79,7 @@ //! //! // #[test] //! fn test_lowercase() -> Result<(), ShellError> { -//! let input = vec![Value::test_string("FooBar")].into_pipeline_data(None); +//! let input = vec![Value::test_string("FooBar")].into_pipeline_data(Span::test_data(), None); //! let output = PluginTest::new("lowercase", LowercasePlugin.into())? //! .eval_with("lowercase", input)? //! .into_value(Span::test_data()); diff --git a/crates/nu-plugin-test-support/src/plugin_test.rs b/crates/nu-plugin-test-support/src/plugin_test.rs index a059c19ab0..5f34fbee46 100644 --- a/crates/nu-plugin-test-support/src/plugin_test.rs +++ b/crates/nu-plugin-test-support/src/plugin_test.rs @@ -91,7 +91,7 @@ impl PluginTest { /// let result = PluginTest::new("my_plugin", MyPlugin.into())? /// .eval_with( /// "my-command", - /// vec![Value::test_int(42)].into_pipeline_data(None) + /// vec![Value::test_int(42)].into_pipeline_data(Span::test_data(), None) /// )? /// .into_value(Span::test_data()); /// assert_eq!(Value::test_string("42"), result); diff --git a/crates/nu-plugin-test-support/tests/lowercase/mod.rs b/crates/nu-plugin-test-support/tests/lowercase/mod.rs index 25a6063dc0..33446cea86 100644 --- a/crates/nu-plugin-test-support/tests/lowercase/mod.rs +++ b/crates/nu-plugin-test-support/tests/lowercase/mod.rs @@ -68,7 +68,7 @@ impl Plugin for LowercasePlugin { fn test_lowercase_using_eval_with() -> Result<(), ShellError> { let result = PluginTest::new("lowercase", LowercasePlugin.into())?.eval_with( "lowercase", - vec![Value::test_string("HeLlO wOrLd")].into_pipeline_data(None), + vec![Value::test_string("HeLlO wOrLd")].into_pipeline_data(Span::test_data(), None), )?; assert_eq!( diff --git a/crates/nu-plugin/src/plugin/interface/mod.rs b/crates/nu-plugin/src/plugin/interface/mod.rs index 630c6b2979..70e143ece5 100644 --- a/crates/nu-plugin/src/plugin/interface/mod.rs +++ b/crates/nu-plugin/src/plugin/interface/mod.rs @@ -11,8 +11,8 @@ use nu_plugin_protocol::{ ProtocolInfo, }; use nu_protocol::{ - engine::Closure, Config, IntoInterruptiblePipelineData, LabeledError, ListStream, PipelineData, - PluginSignature, ShellError, Span, Spanned, Value, + engine::Closure, Config, LabeledError, PipelineData, PluginSignature, ShellError, Span, + Spanned, Value, }; use std::{ collections::{btree_map, BTreeMap, HashMap}, @@ -336,14 +336,15 @@ impl InterfaceManager for EngineInterfaceManager { PluginCustomValue::deserialize_custom_values_in(value)?; Ok(data) } - PipelineData::ListStream(ListStream { stream, ctrlc, .. }, meta) => Ok(stream - .map(|mut value| { + PipelineData::ListStream(stream, meta) => { + let stream = stream.map(|mut value| { let span = value.span(); PluginCustomValue::deserialize_custom_values_in(&mut value) .map(|()| value) .unwrap_or_else(|err| Value::error(err, span)) - }) - .into_pipeline_data_with_metadata(meta, ctrlc)), + }); + Ok(PipelineData::ListStream(stream, meta)) + } PipelineData::Empty | PipelineData::ExternalStream { .. } => Ok(data), } } @@ -910,14 +911,15 @@ impl Interface for EngineInterface { PluginCustomValue::serialize_custom_values_in(value)?; Ok(data) } - PipelineData::ListStream(ListStream { stream, ctrlc, .. }, meta) => Ok(stream - .map(|mut value| { + PipelineData::ListStream(stream, meta) => { + let stream = stream.map(|mut value| { let span = value.span(); PluginCustomValue::serialize_custom_values_in(&mut value) .map(|_| value) .unwrap_or_else(|err| Value::error(err, span)) - }) - .into_pipeline_data_with_metadata(meta, ctrlc)), + }); + Ok(PipelineData::ListStream(stream, meta)) + } PipelineData::Empty | PipelineData::ExternalStream { .. } => Ok(data), } } diff --git a/crates/nu-plugin/src/plugin/interface/tests.rs b/crates/nu-plugin/src/plugin/interface/tests.rs index 7fc7bf06e4..17018cbc00 100644 --- a/crates/nu-plugin/src/plugin/interface/tests.rs +++ b/crates/nu-plugin/src/plugin/interface/tests.rs @@ -56,7 +56,10 @@ fn manager_consume_all_exits_after_streams_and_interfaces_are_dropped() -> Resul // Create a stream... let stream = manager.read_pipeline_data( - PipelineDataHeader::ListStream(ListStreamInfo { id: 0 }), + PipelineDataHeader::ListStream(ListStreamInfo { + id: 0, + span: Span::test_data(), + }), None, )?; @@ -109,7 +112,10 @@ fn manager_consume_all_propagates_io_error_to_readers() -> Result<(), ShellError test.set_read_error(test_io_error()); let stream = manager.read_pipeline_data( - PipelineDataHeader::ListStream(ListStreamInfo { id: 0 }), + PipelineDataHeader::ListStream(ListStreamInfo { + id: 0, + span: Span::test_data(), + }), None, )?; @@ -395,7 +401,10 @@ fn manager_consume_call_run_forwards_to_receiver_with_pipeline_data() -> Result< positional: vec![], named: vec![], }, - input: PipelineDataHeader::ListStream(ListStreamInfo { id: 6 }), + input: PipelineDataHeader::ListStream(ListStreamInfo { + id: 6, + span: Span::test_data(), + }), }), ))?; @@ -534,7 +543,10 @@ fn manager_consume_engine_call_response_forwards_to_subscriber_with_pipeline_dat manager.consume(PluginInput::EngineCallResponse( 0, - EngineCallResponse::PipelineData(PipelineDataHeader::ListStream(ListStreamInfo { id: 0 })), + EngineCallResponse::PipelineData(PipelineDataHeader::ListStream(ListStreamInfo { + id: 0, + span: Span::test_data(), + })), ))?; for i in 0..2 { @@ -590,7 +602,7 @@ fn manager_prepare_pipeline_data_deserializes_custom_values_in_streams() -> Resu [Value::test_custom_value(Box::new( test_plugin_custom_value(), ))] - .into_pipeline_data(None), + .into_pipeline_data(Span::test_data(), None), )?; let value = data @@ -621,7 +633,8 @@ fn manager_prepare_pipeline_data_embeds_deserialization_errors_in_streams() -> R let span = Span::new(20, 30); let data = manager.prepare_pipeline_data( - [Value::custom(Box::new(invalid_custom_value), span)].into_pipeline_data(None), + [Value::custom(Box::new(invalid_custom_value), span)] + .into_pipeline_data(Span::test_data(), None), )?; let value = data @@ -703,7 +716,8 @@ fn interface_write_response_with_stream() -> Result<(), ShellError> { interface .write_response(Ok::<_, ShellError>( - [Value::test_int(3), Value::test_int(4), Value::test_int(5)].into_pipeline_data(None), + [Value::test_int(3), Value::test_int(4), Value::test_int(5)] + .into_pipeline_data(Span::test_data(), None), ))? .write()?; @@ -1105,7 +1119,7 @@ fn interface_prepare_pipeline_data_serializes_custom_values_in_streams() -> Resu [Value::test_custom_value(Box::new( expected_test_custom_value(), ))] - .into_pipeline_data(None), + .into_pipeline_data(Span::test_data(), None), &(), )?; @@ -1163,7 +1177,8 @@ fn interface_prepare_pipeline_data_embeds_serialization_errors_in_streams() -> R let span = Span::new(40, 60); let data = interface.prepare_pipeline_data( - [Value::custom(Box::new(CantSerialize::BadVariant), span)].into_pipeline_data(None), + [Value::custom(Box::new(CantSerialize::BadVariant), span)] + .into_pipeline_data(Span::test_data(), None), &(), )?; diff --git a/crates/nu-protocol/src/engine/engine_state.rs b/crates/nu-protocol/src/engine/engine_state.rs index cab3dcc48a..5012754b3b 100644 --- a/crates/nu-protocol/src/engine/engine_state.rs +++ b/crates/nu-protocol/src/engine/engine_state.rs @@ -923,8 +923,8 @@ impl EngineState { } /// Returns the current working directory, which is guaranteed to be an - /// absolute path without trailing slashes, but might contain symlink - /// components. + /// absolute path without trailing slashes (unless it's the root path), but + /// might contain symlink components. /// /// If `stack` is supplied, also considers modifications to the working /// directory on the stack that have yet to be merged into the engine state. @@ -941,6 +941,11 @@ impl EngineState { }) } + // Helper function to check if a path is a root path. + fn is_root(path: &Path) -> bool { + path.parent().is_none() + } + // Helper function to check if a path has trailing slashes. fn has_trailing_slash(path: &Path) -> bool { nu_path::components(path).last() @@ -958,7 +963,9 @@ impl EngineState { if let Value::String { val, .. } = pwd { let path = PathBuf::from(val); - if has_trailing_slash(&path) { + // Technically, a root path counts as "having trailing slashes", but + // for the purpose of PWD, a root path is acceptable. + if !is_root(&path) && has_trailing_slash(&path) { error("$env.PWD contains trailing slashes") } else if !path.is_absolute() { error("$env.PWD is not an absolute path") @@ -1235,6 +1242,18 @@ mod test_cwd { engine_state.cwd(None).unwrap_err(); } + #[test] + fn pwd_points_to_root() { + #[cfg(windows)] + let root = Path::new(r"C:\"); + #[cfg(not(windows))] + let root = Path::new("/"); + + let engine_state = engine_state_with_pwd(root); + let cwd = engine_state.cwd(None).unwrap(); + assert_path_eq!(cwd, root); + } + #[test] fn pwd_points_to_normal_file() { let file = NamedTempFile::new().unwrap(); diff --git a/crates/nu-protocol/src/eval_base.rs b/crates/nu-protocol/src/eval_base.rs index 59ec57db7e..b294c491d1 100644 --- a/crates/nu-protocol/src/eval_base.rs +++ b/crates/nu-protocol/src/eval_base.rs @@ -4,8 +4,7 @@ use crate::{ ExternalArgument, ListItem, Math, Operator, RecordItem, }, debugger::DebugContext, - Config, IntoInterruptiblePipelineData, Range, Record, ShellError, Span, Value, VarId, - ENV_VARIABLE_ID, + Config, Range, Record, ShellError, Span, Value, VarId, ENV_VARIABLE_ID, }; use std::{borrow::Cow, collections::HashMap}; @@ -278,18 +277,13 @@ pub trait Eval { Self::eval_row_condition_or_closure(state, mut_state, *block_id, expr.span) } Expr::StringInterpolation(exprs) => { - let mut parts = vec![]; - for expr in exprs { - parts.push(Self::eval::(state, mut_state, expr)?); - } - let config = Self::get_config(state, mut_state); + let str = exprs + .iter() + .map(|expr| Self::eval::(state, mut_state, expr).map(|v| v.to_expanded_string(", ", &config))) + .collect::>()?; - parts - .into_iter() - .into_pipeline_data(None) - .collect_string("", &config) - .map(|x| Value::string(x, expr.span)) + Ok(Value::string(str, expr.span)) } Expr::Overlay(_) => Self::eval_overlay(state, expr.span), Expr::GlobPattern(pattern, quoted) => { diff --git a/crates/nu-protocol/src/pipeline_data/list_stream.rs b/crates/nu-protocol/src/pipeline_data/list_stream.rs new file mode 100644 index 0000000000..117c264219 --- /dev/null +++ b/crates/nu-protocol/src/pipeline_data/list_stream.rs @@ -0,0 +1,156 @@ +use crate::{Config, PipelineData, ShellError, Span, Value}; +use std::{ + fmt::Debug, + sync::{atomic::AtomicBool, Arc}, +}; + +pub type ValueIterator = Box + Send + 'static>; + +/// A potentially infinite, interruptible stream of [`Value`]s. +/// +/// In practice, a "stream" here means anything which can be iterated and produces Values. +/// Like other iterators in Rust, observing values from this stream will drain the items +/// as you view them and the stream cannot be replayed. +pub struct ListStream { + stream: ValueIterator, + span: Span, +} + +impl ListStream { + /// Create a new [`ListStream`] from a [`Value`] `Iterator`. + pub fn new( + iter: impl Iterator + Send + 'static, + span: Span, + interrupt: Option>, + ) -> Self { + Self { + stream: Box::new(Interrupt::new(iter, interrupt)), + span, + } + } + + /// Returns the [`Span`] associated with this [`ListStream`]. + pub fn span(&self) -> Span { + self.span + } + + /// Convert a [`ListStream`] into its inner [`Value`] `Iterator`. + pub fn into_inner(self) -> ValueIterator { + self.stream + } + + /// Converts each value in a [`ListStream`] into a string and then joins the strings together + /// using the given separator. + pub fn into_string(self, separator: &str, config: &Config) -> String { + self.into_iter() + .map(|val| val.to_expanded_string(", ", config)) + .collect::>() + .join(separator) + } + + /// Collect the values of a [`ListStream`] into a list [`Value`]. + pub fn into_value(self) -> Value { + Value::list(self.stream.collect(), self.span) + } + + /// Consume all values in the stream, returning an error if any of the values is a `Value::Error`. + pub fn drain(self) -> Result<(), ShellError> { + for next in self { + if let Value::Error { error, .. } = next { + return Err(*error); + } + } + Ok(()) + } + + /// Modify the inner iterator of a [`ListStream`] using a function. + /// + /// This can be used to call any number of standard iterator functions on the [`ListStream`]. + /// E.g., `take`, `filter`, `step_by`, and more. + /// + /// ``` + /// use nu_protocol::{ListStream, Span, Value}; + /// + /// let span = Span::unknown(); + /// let stream = ListStream::new(std::iter::repeat(Value::int(0, span)), span, None); + /// let new_stream = stream.modify(|iter| iter.take(100)); + /// ``` + pub fn modify(self, f: impl FnOnce(ValueIterator) -> I) -> Self + where + I: Iterator + Send + 'static, + { + Self { + stream: Box::new(f(self.stream)), + span: self.span, + } + } + + /// Create a new [`ListStream`] whose values are the results of applying the given function + /// to each of the values in the original [`ListStream`]. + pub fn map(self, mapping: impl FnMut(Value) -> Value + Send + 'static) -> Self { + self.modify(|iter| iter.map(mapping)) + } +} + +impl Debug for ListStream { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + f.debug_struct("ListStream").finish() + } +} + +impl IntoIterator for ListStream { + type Item = Value; + + type IntoIter = IntoIter; + + fn into_iter(self) -> Self::IntoIter { + IntoIter { + stream: self.into_inner(), + } + } +} + +impl From for PipelineData { + fn from(stream: ListStream) -> Self { + Self::ListStream(stream, None) + } +} + +pub struct IntoIter { + stream: ValueIterator, +} + +impl Iterator for IntoIter { + type Item = Value; + + fn next(&mut self) -> Option { + self.stream.next() + } +} + +struct Interrupt { + iter: I, + interrupt: Option>, +} + +impl Interrupt { + fn new(iter: I, interrupt: Option>) -> Self { + Self { iter, interrupt } + } +} + +impl Iterator for Interrupt { + type Item = ::Item; + + fn next(&mut self) -> Option { + if nu_utils::ctrl_c::was_pressed(&self.interrupt) { + None + } else { + self.iter.next() + } + } + + fn size_hint(&self) -> (usize, Option) { + self.iter.size_hint() + } +} diff --git a/crates/nu-protocol/src/pipeline_data/mod.rs b/crates/nu-protocol/src/pipeline_data/mod.rs index 94096c31a4..71c667fa70 100644 --- a/crates/nu-protocol/src/pipeline_data/mod.rs +++ b/crates/nu-protocol/src/pipeline_data/mod.rs @@ -1,10 +1,12 @@ +pub mod list_stream; mod metadata; mod out_dest; -mod stream; +mod raw_stream; +pub use list_stream::{ListStream, ValueIterator}; pub use metadata::*; pub use out_dest::*; -pub use stream::*; +pub use raw_stream::*; use crate::{ ast::{Call, PathMember}, @@ -76,8 +78,9 @@ impl PipelineData { PipelineData::ExternalStream { stdout: None, stderr: None, - exit_code: Some(ListStream::from_stream( + exit_code: Some(ListStream::new( [Value::int(exit_code, Span::unknown())].into_iter(), + Span::unknown(), None, )), span: Span::unknown(), @@ -118,7 +121,7 @@ impl PipelineData { /// PipelineData doesn't always have a Span, but we can try! pub fn span(&self) -> Option { match self { - PipelineData::ListStream(..) => None, + PipelineData::ListStream(stream, ..) => Some(stream.span()), PipelineData::ExternalStream { span, .. } => Some(*span), PipelineData::Value(v, _) => Some(v.span()), PipelineData::Empty => None, @@ -131,7 +134,7 @@ impl PipelineData { PipelineData::Value(Value::Nothing { .. }, ..) => Value::nothing(span), PipelineData::Value(v, ..) => v.with_span(span), PipelineData::ListStream(s, ..) => Value::list( - s.collect(), + s.into_iter().collect(), span, // FIXME? ), PipelineData::ExternalStream { @@ -403,51 +406,54 @@ impl PipelineData { /// /// It returns Err if the `self` cannot be converted to an iterator. pub fn into_iter_strict(self, span: Span) -> Result { - match self { - PipelineData::Value(value, metadata) => match value { - Value::List { vals, .. } => Ok(PipelineIterator(PipelineData::ListStream( - ListStream::from_stream(vals.into_iter(), None), - metadata, - ))), - Value::Binary { val, .. } => Ok(PipelineIterator(PipelineData::ListStream( - ListStream::from_stream( - val.into_iter().map(move |x| Value::int(x as i64, span)), - None, + Ok(PipelineIterator(match self { + PipelineData::Value(value, ..) => { + let val_span = value.span(); + match value { + Value::List { vals, .. } => PipelineIteratorInner::ListStream( + ListStream::new(vals.into_iter(), val_span, None).into_iter(), ), - metadata, - ))), - Value::Range { val, .. } => Ok(PipelineIterator(PipelineData::ListStream( - ListStream::from_stream(val.into_range_iter(value.span(), None), None), - metadata, - ))) - , - // Propagate errors by explicitly matching them before the final case. - Value::Error { error, .. } => Err(*error), - other => Err(ShellError::OnlySupportsThisInputType { + Value::Binary { val, .. } => PipelineIteratorInner::ListStream( + ListStream::new( + val.into_iter().map(move |x| Value::int(x as i64, val_span)), + val_span, + None, + ) + .into_iter(), + ), + Value::Range { val, .. } => PipelineIteratorInner::ListStream( + ListStream::new(val.into_range_iter(value.span(), None), val_span, None) + .into_iter(), + ), + // Propagate errors by explicitly matching them before the final case. + Value::Error { error, .. } => return Err(*error), + other => { + return Err(ShellError::OnlySupportsThisInputType { + exp_input_type: "list, binary, raw data or range".into(), + wrong_type: other.get_type().to_string(), + dst_span: span, + src_span: val_span, + }) + } + } + } + PipelineData::ListStream(stream, ..) => { + PipelineIteratorInner::ListStream(stream.into_iter()) + } + PipelineData::Empty => { + return Err(ShellError::OnlySupportsThisInputType { exp_input_type: "list, binary, raw data or range".into(), - wrong_type: other.get_type().to_string(), + wrong_type: "null".into(), dst_span: span, - src_span: other.span(), - }), - }, - PipelineData::Empty => Err(ShellError::OnlySupportsThisInputType { - exp_input_type: "list, binary, raw data or range".into(), - wrong_type: "null".into(), - dst_span: span, - src_span: span, - }), - other => Ok(PipelineIterator(other)), - } - } - - pub fn into_interruptible_iter(self, ctrlc: Option>) -> PipelineIterator { - let mut iter = self.into_iter(); - - if let PipelineIterator(PipelineData::ListStream(s, ..)) = &mut iter { - s.ctrlc = ctrlc; - } - - iter + src_span: span, + }) + } + PipelineData::ExternalStream { + stdout: Some(stdout), + .. + } => PipelineIteratorInner::ExternalStream(stdout), + PipelineData::ExternalStream { stdout: None, .. } => PipelineIteratorInner::Empty, + })) } pub fn collect_string(self, separator: &str, config: &Config) -> Result { @@ -516,9 +522,8 @@ impl PipelineData { ) -> Result { match self { // FIXME: there are probably better ways of doing this - PipelineData::ListStream(stream, ..) => { - Value::list(stream.collect(), head).follow_cell_path(cell_path, insensitive) - } + PipelineData::ListStream(stream, ..) => Value::list(stream.into_iter().collect(), head) + .follow_cell_path(cell_path, insensitive), PipelineData::Value(v, ..) => v.follow_cell_path(cell_path, insensitive), PipelineData::Empty => Err(ShellError::IncompatiblePathAccess { type_name: "empty pipeline".to_string(), @@ -531,22 +536,6 @@ impl PipelineData { } } - pub fn upsert_cell_path( - &mut self, - cell_path: &[PathMember], - callback: Box Value>, - head: Span, - ) -> Result<(), ShellError> { - match self { - // FIXME: there are probably better ways of doing this - PipelineData::ListStream(stream, ..) => { - Value::list(stream.collect(), head).upsert_cell_path(cell_path, callback) - } - PipelineData::Value(v, ..) => v.upsert_cell_path(cell_path, callback), - _ => Ok(()), - } - } - /// Simplified mapper to help with simple values also. For full iterator support use `.into_iter()` instead pub fn map( self, @@ -562,12 +551,12 @@ impl PipelineData { let span = value.span(); match value { Value::List { vals, .. } => { - Ok(vals.into_iter().map(f).into_pipeline_data(ctrlc)) + Ok(vals.into_iter().map(f).into_pipeline_data(span, ctrlc)) } Value::Range { val, .. } => Ok(val .into_range_iter(span, ctrlc.clone()) .map(f) - .into_pipeline_data(ctrlc)), + .into_pipeline_data(span, ctrlc)), value => match f(value) { Value::Error { error, .. } => Err(*error), v => Ok(v.into_pipeline_data()), @@ -575,7 +564,9 @@ impl PipelineData { } } PipelineData::Empty => Ok(PipelineData::Empty), - PipelineData::ListStream(stream, ..) => Ok(stream.map(f).into_pipeline_data(ctrlc)), + PipelineData::ListStream(stream, ..) => { + Ok(PipelineData::ListStream(stream.map(f), None)) + } PipelineData::ExternalStream { stdout: None, .. } => Ok(PipelineData::empty()), PipelineData::ExternalStream { stdout: Some(stream), @@ -614,21 +605,22 @@ impl PipelineData { let span = value.span(); match value { Value::List { vals, .. } => { - Ok(vals.into_iter().flat_map(f).into_pipeline_data(ctrlc)) + Ok(vals.into_iter().flat_map(f).into_pipeline_data(span, ctrlc)) } Value::Range { val, .. } => Ok(val .into_range_iter(span, ctrlc.clone()) .flat_map(f) - .into_pipeline_data(ctrlc)), - value => Ok(f(value).into_iter().into_pipeline_data(ctrlc)), + .into_pipeline_data(span, ctrlc)), + value => Ok(f(value).into_iter().into_pipeline_data(span, ctrlc)), } } PipelineData::ListStream(stream, ..) => { - Ok(stream.flat_map(f).into_pipeline_data(ctrlc)) + Ok(stream.modify(|iter| iter.flat_map(f)).into()) } PipelineData::ExternalStream { stdout: None, .. } => Ok(PipelineData::Empty), PipelineData::ExternalStream { stdout: Some(stream), + span, trim_end_newline, .. } => { @@ -640,11 +632,11 @@ impl PipelineData { } Ok(f(Value::string(st, collected.span)) .into_iter() - .into_pipeline_data(ctrlc)) + .into_pipeline_data(span, ctrlc)) } else { Ok(f(Value::binary(collected.item, collected.span)) .into_iter() - .into_pipeline_data(ctrlc)) + .into_pipeline_data(span, ctrlc)) } } } @@ -665,12 +657,12 @@ impl PipelineData { let span = value.span(); match value { Value::List { vals, .. } => { - Ok(vals.into_iter().filter(f).into_pipeline_data(ctrlc)) + Ok(vals.into_iter().filter(f).into_pipeline_data(span, ctrlc)) } Value::Range { val, .. } => Ok(val .into_range_iter(span, ctrlc.clone()) .filter(f) - .into_pipeline_data(ctrlc)), + .into_pipeline_data(span, ctrlc)), value => { if f(&value) { Ok(value.into_pipeline_data()) @@ -680,7 +672,7 @@ impl PipelineData { } } } - PipelineData::ListStream(stream, ..) => Ok(stream.filter(f).into_pipeline_data(ctrlc)), + PipelineData::ListStream(stream, ..) => Ok(stream.modify(|iter| iter.filter(f)).into()), PipelineData::ExternalStream { stdout: None, .. } => Ok(PipelineData::Empty), PipelineData::ExternalStream { stdout: Some(stream), @@ -764,7 +756,6 @@ impl PipelineData { match exit_code { Some(exit_code_stream) => { - let ctrlc = exit_code_stream.ctrlc.clone(); let exit_code: Vec = exit_code_stream.into_iter().collect(); if let Some(Value::Int { val: code, .. }) = exit_code.last() { // if exit_code is not 0, it indicates error occurred, return back Err. @@ -776,7 +767,7 @@ impl PipelineData { PipelineData::ExternalStream { stdout: None, stderr, - exit_code: Some(ListStream::from_stream(exit_code.into_iter(), ctrlc)), + exit_code: Some(ListStream::new(exit_code.into_iter(), span, None)), span, metadata, trim_end_newline, @@ -947,7 +938,14 @@ impl PipelineData { } } -pub struct PipelineIterator(PipelineData); +enum PipelineIteratorInner { + Empty, + Value(Value), + ListStream(list_stream::IntoIter), + ExternalStream(RawStream), +} + +pub struct PipelineIterator(PipelineIteratorInner); impl IntoIterator for PipelineData { type Item = Value; @@ -955,23 +953,29 @@ impl IntoIterator for PipelineData { type IntoIter = PipelineIterator; fn into_iter(self) -> Self::IntoIter { - match self { - PipelineData::Value(value, metadata) => { + PipelineIterator(match self { + PipelineData::Value(value, ..) => { let span = value.span(); match value { - Value::List { vals, .. } => PipelineIterator(PipelineData::ListStream( - ListStream::from_stream(vals.into_iter(), None), - metadata, - )), - Value::Range { val, .. } => PipelineIterator(PipelineData::ListStream( - ListStream::from_stream(val.into_range_iter(span, None), None), - metadata, - )), - x => PipelineIterator(PipelineData::Value(x, metadata)), + Value::List { vals, .. } => PipelineIteratorInner::ListStream( + ListStream::new(vals.into_iter(), span, None).into_iter(), + ), + Value::Range { val, .. } => PipelineIteratorInner::ListStream( + ListStream::new(val.into_range_iter(span, None), span, None).into_iter(), + ), + x => PipelineIteratorInner::Value(x), } } - x => PipelineIterator(x), - } + PipelineData::ListStream(stream, ..) => { + PipelineIteratorInner::ListStream(stream.into_iter()) + } + PipelineData::ExternalStream { + stdout: Some(stdout), + .. + } => PipelineIteratorInner::ExternalStream(stdout), + PipelineData::ExternalStream { stdout: None, .. } => PipelineIteratorInner::Empty, + PipelineData::Empty => PipelineIteratorInner::Empty, + }) } } @@ -1075,15 +1079,11 @@ impl Iterator for PipelineIterator { fn next(&mut self) -> Option { match &mut self.0 { - PipelineData::Empty => None, - PipelineData::Value(Value::Nothing { .. }, ..) => None, - PipelineData::Value(v, ..) => Some(std::mem::take(v)), - PipelineData::ListStream(stream, ..) => stream.next(), - PipelineData::ExternalStream { stdout: None, .. } => None, - PipelineData::ExternalStream { - stdout: Some(stream), - .. - } => stream.next().map(|x| match x { + PipelineIteratorInner::Empty => None, + PipelineIteratorInner::Value(Value::Nothing { .. }, ..) => None, + PipelineIteratorInner::Value(v, ..) => Some(std::mem::take(v)), + PipelineIteratorInner::ListStream(stream, ..) => stream.next(), + PipelineIteratorInner::ExternalStream(stream) => stream.next().map(|x| match x { Ok(x) => x, Err(err) => Value::error( err, @@ -1120,11 +1120,12 @@ where } pub trait IntoInterruptiblePipelineData { - fn into_pipeline_data(self, ctrlc: Option>) -> PipelineData; + fn into_pipeline_data(self, span: Span, ctrlc: Option>) -> PipelineData; fn into_pipeline_data_with_metadata( self, - metadata: impl Into>, + span: Span, ctrlc: Option>, + metadata: impl Into>, ) -> PipelineData; } @@ -1134,20 +1135,18 @@ where I::IntoIter: Send + 'static, ::Item: Into, { - fn into_pipeline_data(self, ctrlc: Option>) -> PipelineData { - PipelineData::ListStream( - ListStream::from_stream(self.into_iter().map(Into::into), ctrlc), - None, - ) + fn into_pipeline_data(self, span: Span, ctrlc: Option>) -> PipelineData { + ListStream::new(self.into_iter().map(Into::into), span, ctrlc).into() } fn into_pipeline_data_with_metadata( self, - metadata: impl Into>, + span: Span, ctrlc: Option>, + metadata: impl Into>, ) -> PipelineData { PipelineData::ListStream( - ListStream::from_stream(self.into_iter().map(Into::into), ctrlc), + ListStream::new(self.into_iter().map(Into::into), span, ctrlc), metadata.into(), ) } diff --git a/crates/nu-protocol/src/pipeline_data/stream.rs b/crates/nu-protocol/src/pipeline_data/raw_stream.rs similarity index 74% rename from crates/nu-protocol/src/pipeline_data/stream.rs rename to crates/nu-protocol/src/pipeline_data/raw_stream.rs index 58e759229b..846cdd772b 100644 --- a/crates/nu-protocol/src/pipeline_data/stream.rs +++ b/crates/nu-protocol/src/pipeline_data/raw_stream.rs @@ -174,72 +174,3 @@ impl Iterator for RawStream { } } } - -/// A potentially infinite stream of values, optionally with a mean to send a Ctrl-C signal to stop -/// the stream from continuing. -/// -/// In practice, a "stream" here means anything which can be iterated and produce Values as it iterates. -/// Like other iterators in Rust, observing values from this stream will drain the items as you view them -/// and the stream cannot be replayed. -pub struct ListStream { - pub stream: Box + Send + 'static>, - pub ctrlc: Option>, - first_guard: bool, -} - -impl ListStream { - pub fn into_string(self, separator: &str, config: &Config) -> String { - self.map(|x: Value| x.to_expanded_string(", ", config)) - .collect::>() - .join(separator) - } - - pub fn drain(self) -> Result<(), ShellError> { - for next in self { - if let Value::Error { error, .. } = next { - return Err(*error); - } - } - Ok(()) - } - - pub fn from_stream( - input: impl Iterator + Send + 'static, - ctrlc: Option>, - ) -> ListStream { - ListStream { - stream: Box::new(input), - ctrlc, - first_guard: true, - } - } -} - -impl Debug for ListStream { - fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { - f.debug_struct("ListStream").finish() - } -} - -impl Iterator for ListStream { - type Item = Value; - - fn next(&mut self) -> Option { - // We need to check `first_guard` to guarantee that it always have something to return in - // underlying stream. - // - // A realworld example is running an external commands, which have an `exit_code` - // ListStream. - // When we press ctrl-c, the external command receives the signal too, if we don't have - // `first_guard`, the `exit_code` ListStream will return Nothing, which is not expected - if self.first_guard { - self.first_guard = false; - return self.stream.next(); - } - if nu_utils::ctrl_c::was_pressed(&self.ctrlc) { - None - } else { - self.stream.next() - } - } -} diff --git a/crates/nu-std/CONTRIBUTING.md b/crates/nu-std/CONTRIBUTING.md index 9108956a76..1677a31de1 100644 --- a/crates/nu-std/CONTRIBUTING.md +++ b/crates/nu-std/CONTRIBUTING.md @@ -13,7 +13,7 @@ You'll generally find the team members on [Discord `#standard-library` channel][discord#standard-library] and can have preliminary discussions there to clarify the issues involved. -You can open a [Github issue][new-issue] to have a more focused discussion of +You can open a [GitHub issue][new-issue] to have a more focused discussion of your idea. Generally, we think the standard library should contain items that are relevant diff --git a/crates/nu-table/src/types/general.rs b/crates/nu-table/src/types/general.rs index ee09248fb1..4a6cd302e8 100644 --- a/crates/nu-table/src/types/general.rs +++ b/crates/nu-table/src/types/general.rs @@ -99,7 +99,7 @@ fn table(input: &[Value], opts: &TableOpts<'_>) -> TableResult { .filter(|header| header != INDEX_COLUMN_NAME) .collect(); - let table = to_table_with_header(input, headers, with_index, row_offset, opts)?; + let table = to_table_with_header(input, &headers, with_index, row_offset, opts)?; let table = table.map(|table| TableOutput::new(table, true, with_index)); Ok(table) @@ -107,7 +107,7 @@ fn table(input: &[Value], opts: &TableOpts<'_>) -> TableResult { fn to_table_with_header( input: &[Value], - headers: Vec, + headers: &[String], with_index: bool, row_offset: usize, opts: &TableOpts<'_>, diff --git a/crates/nu-test-support/src/macros.rs b/crates/nu-test-support/src/macros.rs index d79c358885..c18dd5ac81 100644 --- a/crates/nu-test-support/src/macros.rs +++ b/crates/nu-test-support/src/macros.rs @@ -284,7 +284,7 @@ pub fn nu_run_test(opts: NuOpts, commands: impl AsRef, with_std: bool) -> O command.arg("--no-std-lib"); } command - .arg(format!("-c {}", escape_quote_string(commands))) + .arg(format!("-c {}", escape_quote_string(&commands))) .stdout(Stdio::piped()) .stderr(Stdio::piped()); @@ -353,7 +353,7 @@ where let plugin_path = nu_path::canonicalize_with(&plugin, &test_bins) .unwrap_or_else(|_| panic!("failed to canonicalize plugin {} path", &plugin)); let plugin_path = plugin_path.to_string_lossy(); - escape_quote_string(plugin_path.into_owned()) + escape_quote_string(&plugin_path) }) .collect(); let plugins_arg = format!("[{}]", plugin_paths_quoted.join(",")); @@ -397,7 +397,7 @@ where Outcome::new(out, err.into_owned(), output.status) } -fn escape_quote_string(input: String) -> String { +fn escape_quote_string(input: &str) -> String { let mut output = String::with_capacity(input.len() + 2); output.push('"'); diff --git a/crates/nu-test-support/src/playground/play.rs b/crates/nu-test-support/src/playground/play.rs index 6e229e0c8f..902997200e 100644 --- a/crates/nu-test-support/src/playground/play.rs +++ b/crates/nu-test-support/src/playground/play.rs @@ -199,7 +199,7 @@ impl<'a> Playground<'a> { self } - pub fn with_files(&mut self, files: Vec) -> &mut Self { + pub fn with_files(&mut self, files: &[Stub]) -> &mut Self { let endl = fs::line_ending(); files diff --git a/crates/nu_plugin_example/src/commands/generate.rs b/crates/nu_plugin_example/src/commands/generate.rs index 67d30dcb9c..9938518f4c 100644 --- a/crates/nu_plugin_example/src/commands/generate.rs +++ b/crates/nu_plugin_example/src/commands/generate.rs @@ -60,8 +60,8 @@ impl PluginCommand for Generate { call: &EvaluatedCall, _input: PipelineData, ) -> Result { + let head = call.head; let engine = engine.clone(); - let call = call.clone(); let initial: Value = call.req(0)?; let closure = call.req(1)?; @@ -83,9 +83,9 @@ impl PluginCommand for Generate { }) .transpose() }) - .map(|result| result.unwrap_or_else(|err| Value::error(err, call.head))) + .map(|result| result.unwrap_or_else(|err| Value::error(err, head))) }) - .into_pipeline_data(None)) + .into_pipeline_data(head, None)) } } diff --git a/crates/nu_plugin_example/src/commands/seq.rs b/crates/nu_plugin_example/src/commands/seq.rs index 52a21a646a..5652b3ef9a 100644 --- a/crates/nu_plugin_example/src/commands/seq.rs +++ b/crates/nu_plugin_example/src/commands/seq.rs @@ -50,12 +50,11 @@ impl PluginCommand for Seq { call: &EvaluatedCall, _input: PipelineData, ) -> Result { + let head = call.head; let first: i64 = call.req(0)?; let last: i64 = call.req(1)?; - let span = call.head; - let iter = (first..=last).map(move |number| Value::int(number, span)); - let list_stream = ListStream::from_stream(iter, None); - Ok(PipelineData::ListStream(list_stream, None)) + let iter = (first..=last).map(move |number| Value::int(number, head)); + Ok(ListStream::new(iter, head, None).into()) } } diff --git a/crates/nu_plugin_polars/src/dataframe/eager/sample.rs b/crates/nu_plugin_polars/src/dataframe/eager/sample.rs index 48ca05959a..59f9ad6eee 100644 --- a/crates/nu_plugin_polars/src/dataframe/eager/sample.rs +++ b/crates/nu_plugin_polars/src/dataframe/eager/sample.rs @@ -1,14 +1,14 @@ use nu_plugin::{EngineInterface, EvaluatedCall, PluginCommand}; use nu_protocol::{ - Category, Example, LabeledError, PipelineData, ShellError, Signature, Spanned, SyntaxShape, - Type, + Category, Example, LabeledError, PipelineData, ShellError, Signature, Span, Spanned, + SyntaxShape, Type, Value, }; use polars::prelude::NamedFrom; use polars::series::Series; use crate::{values::CustomValueSupport, PolarsPlugin}; -use super::super::values::NuDataFrame; +use super::super::values::{Column, NuDataFrame}; #[derive(Clone)] pub struct SampleDF; @@ -66,6 +66,23 @@ impl PluginCommand for SampleDF { "[[a b]; [1 2] [3 4] [5 6]] | polars into-df | polars sample --fraction 0.5 --replace", result: None, // No expected value because sampling is random }, + Example { + description: "Shows sample row using using predefined seed 1", + example: + "[[a b]; [1 2] [3 4] [5 6]] | polars into-df | polars sample --seed 1 --n-rows 1", + result: Some( + NuDataFrame::try_from_columns( + vec![ + Column::new("a".to_string(), vec![Value::test_int(5)]), + Column::new("b".to_string(), vec![Value::test_int(6)]), + ], + None, + ) + .expect("should not fail") + .into_value(Span::test_data()), + ) + }, + ] } @@ -133,3 +150,14 @@ fn command( let df = NuDataFrame::new(false, df?); df.to_pipeline_data(plugin, engine, call.head) } + +#[cfg(test)] +mod test { + use super::*; + use crate::test::test_polars_plugin_command; + + #[test] + fn test_examples() -> Result<(), ShellError> { + test_polars_plugin_command(&SampleDF) + } +} diff --git a/crates/nu_plugin_polars/src/dataframe/lazy/to_lazy.rs b/crates/nu_plugin_polars/src/dataframe/lazy/to_lazy.rs index 2437699b54..c4e013ac6a 100644 --- a/crates/nu_plugin_polars/src/dataframe/lazy/to_lazy.rs +++ b/crates/nu_plugin_polars/src/dataframe/lazy/to_lazy.rs @@ -33,10 +33,16 @@ impl PluginCommand for ToLazyFrame { fn examples(&self) -> Vec { vec![Example { - description: "Takes a dictionary and creates a lazy dataframe", + description: "Takes a table and creates a lazyframe", example: "[[a b];[1 2] [3 4]] | polars into-lazy", result: None, - }] + }, + Example { + description: "Takes a table, creates a lazyframe, assigns column 'b' type str, displays the schema", + example: "[[a b];[1 2] [3 4]] | polars into-lazy --schema {b: str} | polars schema", + result: None + }, + ] } fn run( diff --git a/crates/nu_plugin_polars/src/dataframe/series/cumulative.rs b/crates/nu_plugin_polars/src/dataframe/series/cumulative.rs index ad4740663e..7455297b59 100644 --- a/crates/nu_plugin_polars/src/dataframe/series/cumulative.rs +++ b/crates/nu_plugin_polars/src/dataframe/series/cumulative.rs @@ -67,27 +67,50 @@ impl PluginCommand for Cumulative { } fn examples(&self) -> Vec { - vec![Example { - description: "Cumulative sum for a series", - example: "[1 2 3 4 5] | polars into-df | polars cumulative sum", - result: Some( - NuDataFrame::try_from_columns( - vec![Column::new( - "0_cumulative_sum".to_string(), - vec![ - Value::test_int(1), - Value::test_int(3), - Value::test_int(6), - Value::test_int(10), - Value::test_int(15), - ], - )], - None, - ) - .expect("simple df for test should not fail") - .into_value(Span::test_data()), - ), - }] + vec![ + Example { + description: "Cumulative sum for a series", + example: "[1 2 3 4 5] | polars into-df | polars cumulative sum", + result: Some( + NuDataFrame::try_from_columns( + vec![Column::new( + "0_cumulative_sum".to_string(), + vec![ + Value::test_int(1), + Value::test_int(3), + Value::test_int(6), + Value::test_int(10), + Value::test_int(15), + ], + )], + None, + ) + .expect("simple df for test should not fail") + .into_value(Span::test_data()), + ), + }, + Example { + description: "Cumulative sum for a series in reverse order", + example: "[1 2 3 4 5] | polars into-df | polars cumulative sum --reverse", + result: Some( + NuDataFrame::try_from_columns( + vec![Column::new( + "0_cumulative_sum".to_string(), + vec![ + Value::test_int(15), + Value::test_int(14), + Value::test_int(12), + Value::test_int(9), + Value::test_int(5), + ], + )], + None, + ) + .expect("simple df for test should not fail") + .into_value(Span::test_data()), + ), + }, + ] } fn run( diff --git a/crates/nu_plugin_polars/src/dataframe/series/date/as_date.rs b/crates/nu_plugin_polars/src/dataframe/series/date/as_date.rs index 5228a25e51..414853d291 100644 --- a/crates/nu_plugin_polars/src/dataframe/series/date/as_date.rs +++ b/crates/nu_plugin_polars/src/dataframe/series/date/as_date.rs @@ -41,11 +41,18 @@ impl PluginCommand for AsDate { } fn examples(&self) -> Vec { - vec![Example { - description: "Converts string to date", - example: r#"["2021-12-30" "2021-12-31"] | polars into-df | polars as-date "%Y-%m-%d""#, - result: None, - }] + vec![ + Example { + description: "Converts string to date", + example: r#"["2021-12-30" "2021-12-31"] | polars into-df | polars as-date "%Y-%m-%d""#, + result: None, // help is needed on how to provide results + }, + Example { + description: "Converts string to date", + example: r#"["2021-12-30" "2021-12-31 21:00:00"] | polars into-df | polars as-date "%Y-%m-%d" --not-exact"#, + result: None, + }, + ] } fn run( @@ -99,3 +106,14 @@ fn command( let df = NuDataFrame::try_from_series_vec(vec![res], call.head)?; df.to_pipeline_data(plugin, engine, call.head) } + +#[cfg(test)] +mod test { + use super::*; + use crate::test::test_polars_plugin_command; + + #[test] + fn test_examples() -> Result<(), ShellError> { + test_polars_plugin_command(&AsDate) + } +} diff --git a/crates/nu_plugin_polars/src/dataframe/series/date/as_datetime.rs b/crates/nu_plugin_polars/src/dataframe/series/date/as_datetime.rs index 2cbea57507..8e01fda6ac 100644 --- a/crates/nu_plugin_polars/src/dataframe/series/date/as_datetime.rs +++ b/crates/nu_plugin_polars/src/dataframe/series/date/as_datetime.rs @@ -116,6 +116,30 @@ impl PluginCommand for AsDateTime { .into_value(Span::test_data()), ), }, + Example { + description: "Converts string to datetime using the `--not-exact` flag even with excessive symbols", + example: r#"["2021-12-30 00:00:00 GMT+4"] | polars into-df | polars as-datetime "%Y-%m-%d %H:%M:%S" --not-exact"#, + result: Some( + NuDataFrame::try_from_columns( + vec![Column::new( + "datetime".to_string(), + vec![ + Value::date( + DateTime::parse_from_str( + "2021-12-30 00:00:00 +0000", + "%Y-%m-%d %H:%M:%S %z", + ) + .expect("date calculation should not fail in test"), + Span::test_data(), + ), + ], + )], + None, + ) + .expect("simple df for test should not fail") + .into_value(Span::test_data()), + ), + }, ] } diff --git a/crates/nu_plugin_polars/src/dataframe/series/shift.rs b/crates/nu_plugin_polars/src/dataframe/series/shift.rs index 9b5f8b2f63..64e8fe5b62 100644 --- a/crates/nu_plugin_polars/src/dataframe/series/shift.rs +++ b/crates/nu_plugin_polars/src/dataframe/series/shift.rs @@ -45,21 +45,45 @@ impl PluginCommand for Shift { } fn examples(&self) -> Vec { - vec![Example { - description: "Shifts the values by a given period", - example: "[1 2 2 3 3] | polars into-df | polars shift 2 | polars drop-nulls", - result: Some( - NuDataFrame::try_from_columns( - vec![Column::new( - "0".to_string(), - vec![Value::test_int(1), Value::test_int(2), Value::test_int(2)], - )], - None, - ) - .expect("simple df for test should not fail") - .into_value(Span::test_data()), - ), - }] + vec![ + Example { + description: "Shifts the values by a given period", + example: "[1 2 2 3 3] | polars into-df | polars shift 2 | polars drop-nulls", + result: Some( + NuDataFrame::try_from_columns( + vec![Column::new( + "0".to_string(), + vec![Value::test_int(1), Value::test_int(2), Value::test_int(2)], + )], + None, + ) + .expect("simple df for test should not fail") + .into_value(Span::test_data()), + ), + }, + Example { + description: "Shifts the values by a given period, fill absent values with 0", + example: + "[1 2 2 3 3] | polars into-lazy | polars shift 2 --fill 0 | polars collect", + result: Some( + NuDataFrame::try_from_columns( + vec![Column::new( + "0".to_string(), + vec![ + Value::test_int(0), + Value::test_int(0), + Value::test_int(1), + Value::test_int(2), + Value::test_int(2), + ], + )], + None, + ) + .expect("simple df for test should not fail") + .into_value(Span::test_data()), + ), + }, + ] } fn run( diff --git a/crates/nuon/README.md b/crates/nuon/README.md new file mode 100644 index 0000000000..d11aa8104c --- /dev/null +++ b/crates/nuon/README.md @@ -0,0 +1,35 @@ +Support for the NUON format. + +The NUON format is a superset of JSON designed to fit the feel of Nushell. +Some of its extra features are +- trailing commas are allowed +- commas are optional in lists +- quotes are not required around keys or any _bare_ string that do not contain spaces +- comments are allowed, though not preserved when using [`from_nuon`] + +## Example +below is some data in the JSON format +```json +{ + "name": "Some One", + "birth": "1970-01-01", + "stats": [ + 2544729499973429198, + 687051042647753531, + 6702443901704799912 + ] +} +``` + +and an equivalent piece of data written in NUON +```nuon +{ + name: "Some One", # the name of the person + birth: "1970-01-01", # their date of birth + stats: [ # some dummy "stats" about them + 2544729499973429198, + 687051042647753531, + 6702443901704799912, # note the trailing comma here... + ], # and here +} # wait, are these comments in a JSON-like document?!?! +``` diff --git a/crates/nuon/src/from.rs b/crates/nuon/src/from.rs index 457b12d5f9..862b756db7 100644 --- a/crates/nuon/src/from.rs +++ b/crates/nuon/src/from.rs @@ -7,7 +7,9 @@ use std::sync::Arc; /// convert a raw string representation of NUON data to an actual Nushell [`Value`] /// -/// > **Note** +// WARNING: please leave the following two trailing spaces, they matter for the documentation +// formatting +/// > **Note** /// > [`Span`] can be passed to [`from_nuon`] if there is context available to the caller, e.g. when /// > using this function in a command implementation such as /// [`from nuon`](https://www.nushell.sh/commands/docs/from_nuon.html). diff --git a/crates/nuon/src/lib.rs b/crates/nuon/src/lib.rs index cb86480580..891ccae62a 100644 --- a/crates/nuon/src/lib.rs +++ b/crates/nuon/src/lib.rs @@ -1,9 +1,4 @@ -//! Support for the NUON format. -//! -//! The NUON format is a superset of JSON designed to fit the feel of Nushell. -//! Some of its extra features are -//! - trailing commas are allowed -//! - quotes are not required around keys +#![doc = include_str!("../README.md")] mod from; mod to; diff --git a/crates/nuon/src/to.rs b/crates/nuon/src/to.rs index 0dec32869c..1a5306a135 100644 --- a/crates/nuon/src/to.rs +++ b/crates/nuon/src/to.rs @@ -39,7 +39,9 @@ pub enum ToStyle { /// convert an actual Nushell [`Value`] to a raw string representation of the NUON data /// -/// > **Note** +// WARNING: please leave the following two trailing spaces, they matter for the documentation +// formatting +/// > **Note** /// > a [`Span`] can be passed to [`to_nuon`] if there is context available to the caller, e.g. when /// > using this function in a command implementation such as [`to nuon`](https://www.nushell.sh/commands/docs/to_nuon.html). /// diff --git a/scripts/build.rs b/scripts/build.rs index f5823043e0..beabba80dc 100644 --- a/scripts/build.rs +++ b/scripts/build.rs @@ -10,4 +10,9 @@ fn main() { } #[cfg(not(windows))] -fn main() {} +fn main() { + // Tango uses dynamic linking, to allow us to dynamically change between two bench suit at runtime. + // This is currently not supported on non nightly rust, on windows. + println!("cargo:rustc-link-arg-benches=-rdynamic"); + println!("cargo:rerun-if-changed=build.rs"); +} diff --git a/tests/modules/mod.rs b/tests/modules/mod.rs index 2e868c3e5d..c556d6fa7a 100644 --- a/tests/modules/mod.rs +++ b/tests/modules/mod.rs @@ -7,7 +7,7 @@ use pretty_assertions::assert_eq; fn module_private_import_decl() { Playground::setup("module_private_import_decl", |dirs, sandbox| { sandbox - .with_files(vec![FileWithContentToBeTrimmed( + .with_files(&[FileWithContentToBeTrimmed( "main.nu", " use spam.nu foo-helper @@ -15,7 +15,7 @@ fn module_private_import_decl() { export def foo [] { foo-helper } ", )]) - .with_files(vec![FileWithContentToBeTrimmed( + .with_files(&[FileWithContentToBeTrimmed( "spam.nu", r#" def get-foo [] { "foo" } @@ -35,7 +35,7 @@ fn module_private_import_decl() { fn module_private_import_alias() { Playground::setup("module_private_import_alias", |dirs, sandbox| { sandbox - .with_files(vec![FileWithContentToBeTrimmed( + .with_files(&[FileWithContentToBeTrimmed( "main.nu", " use spam.nu foo-helper @@ -43,7 +43,7 @@ fn module_private_import_alias() { export def foo [] { foo-helper } ", )]) - .with_files(vec![FileWithContentToBeTrimmed( + .with_files(&[FileWithContentToBeTrimmed( "spam.nu", r#" export alias foo-helper = echo "foo" @@ -62,13 +62,13 @@ fn module_private_import_alias() { fn module_private_import_decl_not_public() { Playground::setup("module_private_import_decl_not_public", |dirs, sandbox| { sandbox - .with_files(vec![FileWithContentToBeTrimmed( + .with_files(&[FileWithContentToBeTrimmed( "main.nu", " use spam.nu foo-helper ", )]) - .with_files(vec![FileWithContentToBeTrimmed( + .with_files(&[FileWithContentToBeTrimmed( "spam.nu", r#" def get-foo [] { "foo" } @@ -88,13 +88,13 @@ fn module_private_import_decl_not_public() { fn module_public_import_decl() { Playground::setup("module_public_import_decl", |dirs, sandbox| { sandbox - .with_files(vec![FileWithContentToBeTrimmed( + .with_files(&[FileWithContentToBeTrimmed( "main.nu", " export use spam.nu foo ", )]) - .with_files(vec![FileWithContentToBeTrimmed( + .with_files(&[FileWithContentToBeTrimmed( "spam.nu", r#" def foo-helper [] { "foo" } @@ -114,13 +114,13 @@ fn module_public_import_decl() { fn module_public_import_alias() { Playground::setup("module_public_import_alias", |dirs, sandbox| { sandbox - .with_files(vec![FileWithContentToBeTrimmed( + .with_files(&[FileWithContentToBeTrimmed( "main.nu", " export use spam.nu foo ", )]) - .with_files(vec![FileWithContentToBeTrimmed( + .with_files(&[FileWithContentToBeTrimmed( "spam.nu", r#" export alias foo = echo "foo" @@ -139,25 +139,25 @@ fn module_public_import_alias() { fn module_nested_imports() { Playground::setup("module_nested_imports", |dirs, sandbox| { sandbox - .with_files(vec![FileWithContentToBeTrimmed( + .with_files(&[FileWithContentToBeTrimmed( "main.nu", " export use spam.nu [ foo bar ] ", )]) - .with_files(vec![FileWithContentToBeTrimmed( + .with_files(&[FileWithContentToBeTrimmed( "spam.nu", " export use spam2.nu [ foo bar ] ", )]) - .with_files(vec![FileWithContentToBeTrimmed( + .with_files(&[FileWithContentToBeTrimmed( "spam2.nu", " export use spam3.nu [ foo bar ] ", )]) - .with_files(vec![FileWithContentToBeTrimmed( + .with_files(&[FileWithContentToBeTrimmed( "spam3.nu", r#" export def foo [] { "foo" } @@ -183,25 +183,25 @@ fn module_nested_imports_in_dirs() { .mkdir("spam") .mkdir("spam/spam2") .mkdir("spam/spam3") - .with_files(vec![FileWithContentToBeTrimmed( + .with_files(&[FileWithContentToBeTrimmed( "main.nu", " export use spam/spam.nu [ foo bar ] ", )]) - .with_files(vec![FileWithContentToBeTrimmed( + .with_files(&[FileWithContentToBeTrimmed( "spam/spam.nu", " export use spam2/spam2.nu [ foo bar ] ", )]) - .with_files(vec![FileWithContentToBeTrimmed( + .with_files(&[FileWithContentToBeTrimmed( "spam/spam2/spam2.nu", " export use ../spam3/spam3.nu [ foo bar ] ", )]) - .with_files(vec![FileWithContentToBeTrimmed( + .with_files(&[FileWithContentToBeTrimmed( "spam/spam3/spam3.nu", r#" export def foo [] { "foo" } @@ -224,13 +224,13 @@ fn module_nested_imports_in_dirs() { fn module_public_import_decl_prefixed() { Playground::setup("module_public_import_decl", |dirs, sandbox| { sandbox - .with_files(vec![FileWithContentToBeTrimmed( + .with_files(&[FileWithContentToBeTrimmed( "main.nu", " export use spam.nu ", )]) - .with_files(vec![FileWithContentToBeTrimmed( + .with_files(&[FileWithContentToBeTrimmed( "spam.nu", r#" def foo-helper [] { "foo" } @@ -253,26 +253,26 @@ fn module_nested_imports_in_dirs_prefixed() { .mkdir("spam") .mkdir("spam/spam2") .mkdir("spam/spam3") - .with_files(vec![FileWithContentToBeTrimmed( + .with_files(&[FileWithContentToBeTrimmed( "main.nu", r#" export use spam/spam.nu [ "spam2 foo" "spam2 spam3 bar" ] "#, )]) - .with_files(vec![FileWithContentToBeTrimmed( + .with_files(&[FileWithContentToBeTrimmed( "spam/spam.nu", " export use spam2/spam2.nu ", )]) - .with_files(vec![FileWithContentToBeTrimmed( + .with_files(&[FileWithContentToBeTrimmed( "spam/spam2/spam2.nu", " export use ../spam3/spam3.nu export use ../spam3/spam3.nu foo ", )]) - .with_files(vec![FileWithContentToBeTrimmed( + .with_files(&[FileWithContentToBeTrimmed( "spam/spam3/spam3.nu", r#" export def foo [] { "foo" } @@ -295,7 +295,7 @@ fn module_nested_imports_in_dirs_prefixed() { fn module_import_env_1() { Playground::setup("module_import_env_1", |dirs, sandbox| { sandbox - .with_files(vec![FileWithContentToBeTrimmed( + .with_files(&[FileWithContentToBeTrimmed( "main.nu", " export-env { source-env spam.nu } @@ -303,7 +303,7 @@ fn module_import_env_1() { export def foo [] { $env.FOO_HELPER } ", )]) - .with_files(vec![FileWithContentToBeTrimmed( + .with_files(&[FileWithContentToBeTrimmed( "spam.nu", r#" export-env { $env.FOO_HELPER = "foo" } @@ -322,13 +322,13 @@ fn module_import_env_1() { fn module_import_env_2() { Playground::setup("module_import_env_2", |dirs, sandbox| { sandbox - .with_files(vec![FileWithContentToBeTrimmed( + .with_files(&[FileWithContentToBeTrimmed( "main.nu", " export-env { source-env spam.nu } ", )]) - .with_files(vec![FileWithContentToBeTrimmed( + .with_files(&[FileWithContentToBeTrimmed( "spam.nu", r#" export-env { $env.FOO = "foo" } @@ -346,7 +346,7 @@ fn module_import_env_2() { #[test] fn module_cyclical_imports_0() { Playground::setup("module_cyclical_imports_0", |dirs, sandbox| { - sandbox.with_files(vec![FileWithContentToBeTrimmed( + sandbox.with_files(&[FileWithContentToBeTrimmed( "spam.nu", " use eggs.nu @@ -364,7 +364,7 @@ fn module_cyclical_imports_0() { #[test] fn module_cyclical_imports_1() { Playground::setup("module_cyclical_imports_1", |dirs, sandbox| { - sandbox.with_files(vec![FileWithContentToBeTrimmed( + sandbox.with_files(&[FileWithContentToBeTrimmed( "spam.nu", " use spam.nu @@ -383,13 +383,13 @@ fn module_cyclical_imports_1() { fn module_cyclical_imports_2() { Playground::setup("module_cyclical_imports_2", |dirs, sandbox| { sandbox - .with_files(vec![FileWithContentToBeTrimmed( + .with_files(&[FileWithContentToBeTrimmed( "spam.nu", " use eggs.nu ", )]) - .with_files(vec![FileWithContentToBeTrimmed( + .with_files(&[FileWithContentToBeTrimmed( "eggs.nu", " use spam.nu @@ -408,19 +408,19 @@ fn module_cyclical_imports_2() { fn module_cyclical_imports_3() { Playground::setup("module_cyclical_imports_3", |dirs, sandbox| { sandbox - .with_files(vec![FileWithContentToBeTrimmed( + .with_files(&[FileWithContentToBeTrimmed( "spam.nu", " use eggs.nu ", )]) - .with_files(vec![FileWithContentToBeTrimmed( + .with_files(&[FileWithContentToBeTrimmed( "eggs.nu", " use bacon.nu ", )]) - .with_files(vec![FileWithContentToBeTrimmed( + .with_files(&[FileWithContentToBeTrimmed( "bacon.nu", " use spam.nu @@ -438,7 +438,7 @@ fn module_cyclical_imports_3() { #[test] fn module_import_const_file() { Playground::setup("module_import_const_file", |dirs, sandbox| { - sandbox.with_files(vec![FileWithContentToBeTrimmed( + sandbox.with_files(&[FileWithContentToBeTrimmed( "spam.nu", r#" export def foo [] { "foo" } @@ -456,7 +456,7 @@ fn module_import_const_file() { #[test] fn module_import_const_module_name() { Playground::setup("module_import_const_file", |dirs, sandbox| { - sandbox.with_files(vec![FileWithContentToBeTrimmed( + sandbox.with_files(&[FileWithContentToBeTrimmed( "spam.nu", r#" export def foo [] { "foo" } diff --git a/tests/overlays/mod.rs b/tests/overlays/mod.rs index c5ddf81e33..15697f467d 100644 --- a/tests/overlays/mod.rs +++ b/tests/overlays/mod.rs @@ -873,7 +873,7 @@ fn overlay_use_do_cd() { Playground::setup("overlay_use_do_cd", |dirs, sandbox| { sandbox .mkdir("test1/test2") - .with_files(vec![FileWithContentToBeTrimmed( + .with_files(&[FileWithContentToBeTrimmed( "test1/test2/spam.nu", " export-env { cd test1/test2 } @@ -896,7 +896,7 @@ fn overlay_use_do_cd_file_relative() { Playground::setup("overlay_use_do_cd_file_relative", |dirs, sandbox| { sandbox .mkdir("test1/test2") - .with_files(vec![FileWithContentToBeTrimmed( + .with_files(&[FileWithContentToBeTrimmed( "test1/test2/spam.nu", " export-env { cd ($env.FILE_PWD | path join '..') } @@ -919,7 +919,7 @@ fn overlay_use_dont_cd_overlay() { Playground::setup("overlay_use_dont_cd_overlay", |dirs, sandbox| { sandbox .mkdir("test1/test2") - .with_files(vec![FileWithContentToBeTrimmed( + .with_files(&[FileWithContentToBeTrimmed( "test1/test2/spam.nu", " export-env { diff --git a/tests/parsing/mod.rs b/tests/parsing/mod.rs index 3bbed9b7c4..5a6b55fc44 100644 --- a/tests/parsing/mod.rs +++ b/tests/parsing/mod.rs @@ -93,7 +93,7 @@ fn parse_file_relative_to_parsed_file_simple() { sandbox .mkdir("lol") .mkdir("lol/lol") - .with_files(vec![FileWithContentToBeTrimmed( + .with_files(&[FileWithContentToBeTrimmed( "lol/lol/lol.nu", " use ../lol_shell.nu @@ -101,7 +101,7 @@ fn parse_file_relative_to_parsed_file_simple() { $env.LOL = (lol_shell ls) ", )]) - .with_files(vec![FileWithContentToBeTrimmed( + .with_files(&[FileWithContentToBeTrimmed( "lol/lol_shell.nu", r#" export def ls [] { "lol" } @@ -123,7 +123,7 @@ fn parse_file_relative_to_parsed_file_simple() { #[test] fn predecl_signature_single_inp_out_type() { Playground::setup("predecl_signature_single_inp_out_type", |dirs, sandbox| { - sandbox.with_files(vec![FileWithContentToBeTrimmed( + sandbox.with_files(&[FileWithContentToBeTrimmed( "spam1.nu", " def main [] { foo } @@ -143,7 +143,7 @@ fn predecl_signature_multiple_inp_out_types() { Playground::setup( "predecl_signature_multiple_inp_out_types", |dirs, sandbox| { - sandbox.with_files(vec![FileWithContentToBeTrimmed( + sandbox.with_files(&[FileWithContentToBeTrimmed( "spam2.nu", " def main [] { foo } @@ -166,7 +166,7 @@ fn parse_file_relative_to_parsed_file() { sandbox .mkdir("lol") .mkdir("lol/lol") - .with_files(vec![FileWithContentToBeTrimmed( + .with_files(&[FileWithContentToBeTrimmed( "lol/lol/lol.nu", " source-env ../../foo.nu @@ -176,13 +176,13 @@ fn parse_file_relative_to_parsed_file() { $env.LOL = $'($env.FOO) (lol_shell ls) (ls)' ", )]) - .with_files(vec![FileWithContentToBeTrimmed( + .with_files(&[FileWithContentToBeTrimmed( "lol/lol_shell.nu", r#" export def ls [] { "lol" } "#, )]) - .with_files(vec![FileWithContentToBeTrimmed( + .with_files(&[FileWithContentToBeTrimmed( "foo.nu", " $env.FOO = 'foo' @@ -206,19 +206,19 @@ fn parse_file_relative_to_parsed_file_dont_use_cwd_1() { Playground::setup("relative_files", |dirs, sandbox| { sandbox .mkdir("lol") - .with_files(vec![FileWithContentToBeTrimmed( + .with_files(&[FileWithContentToBeTrimmed( "lol/lol.nu", " source-env foo.nu ", )]) - .with_files(vec![FileWithContentToBeTrimmed( + .with_files(&[FileWithContentToBeTrimmed( "lol/foo.nu", " $env.FOO = 'good' ", )]) - .with_files(vec![FileWithContentToBeTrimmed( + .with_files(&[FileWithContentToBeTrimmed( "foo.nu", " $env.FOO = 'bad' @@ -242,13 +242,13 @@ fn parse_file_relative_to_parsed_file_dont_use_cwd_2() { Playground::setup("relative_files", |dirs, sandbox| { sandbox .mkdir("lol") - .with_files(vec![FileWithContentToBeTrimmed( + .with_files(&[FileWithContentToBeTrimmed( "lol/lol.nu", " source-env foo.nu ", )]) - .with_files(vec![FileWithContentToBeTrimmed( + .with_files(&[FileWithContentToBeTrimmed( "foo.nu", " $env.FOO = 'bad' diff --git a/tests/path/canonicalize.rs b/tests/path/canonicalize.rs index cf40a0024c..f714480779 100644 --- a/tests/path/canonicalize.rs +++ b/tests/path/canonicalize.rs @@ -8,7 +8,7 @@ use std::path::Path; #[test] fn canonicalize_path() { Playground::setup("nu_path_test_1", |dirs, sandbox| { - sandbox.with_files(vec![EmptyFile("spam.txt")]); + sandbox.with_files(&[EmptyFile("spam.txt")]); let mut spam = dirs.test().to_owned(); spam.push("spam.txt"); @@ -23,7 +23,7 @@ fn canonicalize_path() { #[test] fn canonicalize_unicode_path() { Playground::setup("nu_path_test_1", |dirs, sandbox| { - sandbox.with_files(vec![EmptyFile("🚒.txt")]); + sandbox.with_files(&[EmptyFile("🚒.txt")]); let mut spam = dirs.test().to_owned(); spam.push("🚒.txt"); @@ -45,7 +45,7 @@ fn canonicalize_non_utf8_path() { #[test] fn canonicalize_path_relative_to() { Playground::setup("nu_path_test_1", |dirs, sandbox| { - sandbox.with_files(vec![EmptyFile("spam.txt")]); + sandbox.with_files(&[EmptyFile("spam.txt")]); let actual = canonicalize_with("spam.txt", dirs.test()).expect("Failed to canonicalize"); let mut expected = dirs.test().to_owned(); @@ -59,7 +59,7 @@ fn canonicalize_path_relative_to() { fn canonicalize_unicode_path_relative_to_unicode_path_with_spaces() { Playground::setup("nu_path_test_1", |dirs, sandbox| { sandbox.mkdir("e-$ èрт🚒♞中片-j"); - sandbox.with_files(vec![EmptyFile("e-$ èрт🚒♞中片-j/🚒.txt")]); + sandbox.with_files(&[EmptyFile("e-$ èрт🚒♞中片-j/🚒.txt")]); let mut relative_to = dirs.test().to_owned(); relative_to.push("e-$ èрт🚒♞中片-j"); @@ -81,7 +81,7 @@ fn canonicalize_non_utf8_path_relative_to_non_utf8_path_with_spaces() { #[test] fn canonicalize_absolute_path_relative_to() { Playground::setup("nu_path_test_1", |dirs, sandbox| { - sandbox.with_files(vec![EmptyFile("spam.txt")]); + sandbox.with_files(&[EmptyFile("spam.txt")]); let mut absolute_path = dirs.test().to_owned(); absolute_path.push("spam.txt"); @@ -116,7 +116,7 @@ fn canonicalize_many_dots() { #[test] fn canonicalize_path_with_dot_relative_to() { Playground::setup("nu_path_test_1", |dirs, sandbox| { - sandbox.with_files(vec![EmptyFile("spam.txt")]); + sandbox.with_files(&[EmptyFile("spam.txt")]); let actual = canonicalize_with("./spam.txt", dirs.test()).expect("Failed to canonicalize"); let mut expected = dirs.test().to_owned(); @@ -129,7 +129,7 @@ fn canonicalize_path_with_dot_relative_to() { #[test] fn canonicalize_path_with_many_dots_relative_to() { Playground::setup("nu_path_test_1", |dirs, sandbox| { - sandbox.with_files(vec![EmptyFile("spam.txt")]); + sandbox.with_files(&[EmptyFile("spam.txt")]); let actual = canonicalize_with("././/.//////./././//.////spam.txt", dirs.test()) .expect("Failed to canonicalize"); @@ -155,7 +155,7 @@ fn canonicalize_double_dot() { fn canonicalize_path_with_double_dot_relative_to() { Playground::setup("nu_path_test_1", |dirs, sandbox| { sandbox.mkdir("foo"); - sandbox.with_files(vec![EmptyFile("spam.txt")]); + sandbox.with_files(&[EmptyFile("spam.txt")]); let actual = canonicalize_with("foo/../spam.txt", dirs.test()).expect("Failed to canonicalize"); @@ -170,7 +170,7 @@ fn canonicalize_path_with_double_dot_relative_to() { fn canonicalize_path_with_many_double_dots_relative_to() { Playground::setup("nu_path_test_1", |dirs, sandbox| { sandbox.mkdir("foo/bar/baz"); - sandbox.with_files(vec![EmptyFile("spam.txt")]); + sandbox.with_files(&[EmptyFile("spam.txt")]); let actual = canonicalize_with("foo/bar/baz/../../../spam.txt", dirs.test()) .expect("Failed to canonicalize"); @@ -205,7 +205,7 @@ fn canonicalize_ndots2() { fn canonicalize_path_with_3_ndots_relative_to() { Playground::setup("nu_path_test_1", |dirs, sandbox| { sandbox.mkdir("foo/bar"); - sandbox.with_files(vec![EmptyFile("spam.txt")]); + sandbox.with_files(&[EmptyFile("spam.txt")]); let actual = canonicalize_with("foo/bar/.../spam.txt", dirs.test()).expect("Failed to canonicalize"); @@ -220,7 +220,7 @@ fn canonicalize_path_with_3_ndots_relative_to() { fn canonicalize_path_with_many_3_ndots_relative_to() { Playground::setup("nu_path_test_1", |dirs, sandbox| { sandbox.mkdir("foo/bar/baz/eggs/sausage/bacon"); - sandbox.with_files(vec![EmptyFile("spam.txt")]); + sandbox.with_files(&[EmptyFile("spam.txt")]); let actual = canonicalize_with( "foo/bar/baz/eggs/sausage/bacon/.../.../.../spam.txt", @@ -238,7 +238,7 @@ fn canonicalize_path_with_many_3_ndots_relative_to() { fn canonicalize_path_with_4_ndots_relative_to() { Playground::setup("nu_path_test_1", |dirs, sandbox| { sandbox.mkdir("foo/bar/baz"); - sandbox.with_files(vec![EmptyFile("spam.txt")]); + sandbox.with_files(&[EmptyFile("spam.txt")]); let actual = canonicalize_with("foo/bar/baz/..../spam.txt", dirs.test()) .expect("Failed to canonicalize"); @@ -253,7 +253,7 @@ fn canonicalize_path_with_4_ndots_relative_to() { fn canonicalize_path_with_many_4_ndots_relative_to() { Playground::setup("nu_path_test_1", |dirs, sandbox| { sandbox.mkdir("foo/bar/baz/eggs/sausage/bacon"); - sandbox.with_files(vec![EmptyFile("spam.txt")]); + sandbox.with_files(&[EmptyFile("spam.txt")]); let actual = canonicalize_with( "foo/bar/baz/eggs/sausage/bacon/..../..../spam.txt", @@ -271,7 +271,7 @@ fn canonicalize_path_with_many_4_ndots_relative_to() { fn canonicalize_path_with_way_too_many_dots_relative_to() { Playground::setup("nu_path_test_1", |dirs, sandbox| { sandbox.mkdir("foo/bar/baz/eggs/sausage/bacon/vikings"); - sandbox.with_files(vec![EmptyFile("spam.txt")]); + sandbox.with_files(&[EmptyFile("spam.txt")]); let mut relative_to = dirs.test().to_owned(); relative_to.push("foo/bar/baz/eggs/sausage/bacon/vikings"); @@ -289,7 +289,7 @@ fn canonicalize_path_with_way_too_many_dots_relative_to() { fn canonicalize_unicode_path_with_way_too_many_dots_relative_to_unicode_path_with_spaces() { Playground::setup("nu_path_test_1", |dirs, sandbox| { sandbox.mkdir("foo/áčěéí +šř=é/baz/eggs/e-$ èрт🚒♞中片-j/bacon/öäöä öäöä"); - sandbox.with_files(vec![EmptyFile("🚒.txt")]); + sandbox.with_files(&[EmptyFile("🚒.txt")]); let mut relative_to = dirs.test().to_owned(); relative_to.push("foo/áčěéí +šř=é/baz/eggs/e-$ èрт🚒♞中片-j/bacon/öäöä öäöä"); @@ -329,7 +329,7 @@ fn canonicalize_tilde_relative_to() { #[test] fn canonicalize_symlink() { Playground::setup("nu_path_test_1", |dirs, sandbox| { - sandbox.with_files(vec![EmptyFile("spam.txt")]); + sandbox.with_files(&[EmptyFile("spam.txt")]); sandbox.symlink("spam.txt", "link_to_spam.txt"); let mut symlink_path = dirs.test().to_owned(); @@ -348,7 +348,7 @@ fn canonicalize_symlink() { #[test] fn canonicalize_symlink_relative_to() { Playground::setup("nu_path_test_1", |dirs, sandbox| { - sandbox.with_files(vec![EmptyFile("spam.txt")]); + sandbox.with_files(&[EmptyFile("spam.txt")]); sandbox.symlink("spam.txt", "link_to_spam.txt"); let actual = @@ -379,7 +379,7 @@ fn canonicalize_symlink_loop_relative_to_should_fail() { #[test] fn canonicalize_nested_symlink_relative_to() { Playground::setup("nu_path_test_1", |dirs, sandbox| { - sandbox.with_files(vec![EmptyFile("spam.txt")]); + sandbox.with_files(&[EmptyFile("spam.txt")]); sandbox.symlink("spam.txt", "link_to_spam.txt"); sandbox.symlink("link_to_spam.txt", "link_to_link_to_spam.txt"); @@ -397,7 +397,7 @@ fn canonicalize_nested_symlink_relative_to() { fn canonicalize_nested_symlink_within_symlink_dir_relative_to() { Playground::setup("nu_path_test_1", |dirs, sandbox| { sandbox.mkdir("foo/bar/baz"); - sandbox.with_files(vec![EmptyFile("foo/bar/baz/spam.txt")]); + sandbox.with_files(&[EmptyFile("foo/bar/baz/spam.txt")]); sandbox.symlink("foo/bar/baz/spam.txt", "foo/bar/link_to_spam.txt"); sandbox.symlink("foo/bar/link_to_spam.txt", "foo/link_to_link_to_spam.txt"); sandbox.symlink("foo", "link_to_foo"); diff --git a/tests/plugins/core_inc.rs b/tests/plugins/core_inc.rs index 28017c4b23..64890dd32d 100644 --- a/tests/plugins/core_inc.rs +++ b/tests/plugins/core_inc.rs @@ -26,7 +26,7 @@ fn chooses_highest_increment_if_given_more_than_one() { #[test] fn by_one_with_field_passed() { Playground::setup("plugin_inc_test_1", |dirs, sandbox| { - sandbox.with_files(vec![FileWithContent( + sandbox.with_files(&[FileWithContent( "sample.toml", r#" [package] @@ -47,7 +47,7 @@ fn by_one_with_field_passed() { #[test] fn by_one_with_no_field_passed() { Playground::setup("plugin_inc_test_2", |dirs, sandbox| { - sandbox.with_files(vec![FileWithContent( + sandbox.with_files(&[FileWithContent( "sample.toml", r#" [package] @@ -68,7 +68,7 @@ fn by_one_with_no_field_passed() { #[test] fn semversion_major_inc() { Playground::setup("plugin_inc_test_3", |dirs, sandbox| { - sandbox.with_files(vec![FileWithContent( + sandbox.with_files(&[FileWithContent( "sample.toml", r#" [package] @@ -89,7 +89,7 @@ fn semversion_major_inc() { #[test] fn semversion_minor_inc() { Playground::setup("plugin_inc_test_4", |dirs, sandbox| { - sandbox.with_files(vec![FileWithContent( + sandbox.with_files(&[FileWithContent( "sample.toml", r#" [package] @@ -110,7 +110,7 @@ fn semversion_minor_inc() { #[test] fn semversion_patch_inc() { Playground::setup("plugin_inc_test_5", |dirs, sandbox| { - sandbox.with_files(vec![FileWithContent( + sandbox.with_files(&[FileWithContent( "sample.toml", r#" [package] @@ -131,7 +131,7 @@ fn semversion_patch_inc() { #[test] fn semversion_without_passing_field() { Playground::setup("plugin_inc_test_6", |dirs, sandbox| { - sandbox.with_files(vec![FileWithContent( + sandbox.with_files(&[FileWithContent( "sample.toml", r#" [package] diff --git a/tests/plugins/formats/ics.rs b/tests/plugins/formats/ics.rs index c503f6569d..2ab827d0be 100644 --- a/tests/plugins/formats/ics.rs +++ b/tests/plugins/formats/ics.rs @@ -6,7 +6,7 @@ use pretty_assertions::assert_eq; #[test] fn infers_types() { Playground::setup("filter_from_ics_test_1", |dirs, sandbox| { - sandbox.with_files(vec![FileWithContentToBeTrimmed( + sandbox.with_files(&[FileWithContentToBeTrimmed( "calendar.ics", r#" BEGIN:VCALENDAR @@ -58,7 +58,7 @@ fn infers_types() { #[test] fn from_ics_text_to_table() { Playground::setup("filter_from_ics_test_2", |dirs, sandbox| { - sandbox.with_files(vec![FileWithContentToBeTrimmed( + sandbox.with_files(&[FileWithContentToBeTrimmed( "calendar.txt", r#" BEGIN:VCALENDAR @@ -102,7 +102,7 @@ fn from_ics_text_to_table() { #[test] fn from_ics_text_with_linebreak_to_table() { Playground::setup("filter_from_ics_test_3", |dirs, sandbox| { - sandbox.with_files(vec![FileWithContent( + sandbox.with_files(&[FileWithContent( "calendar.txt", r#"BEGIN:VCALENDAR BEGIN:VEVENT diff --git a/tests/plugins/formats/ini.rs b/tests/plugins/formats/ini.rs index cd467d5559..eee592dac6 100644 --- a/tests/plugins/formats/ini.rs +++ b/tests/plugins/formats/ini.rs @@ -33,7 +33,7 @@ fn parses_utf16_ini() { #[test] fn read_ini_with_missing_session() { Playground::setup("from ini with missiong session", |dirs, sandbox| { - sandbox.with_files(vec![FileWithContentToBeTrimmed( + sandbox.with_files(&[FileWithContentToBeTrimmed( "some_missing.ini", r#" min-width=450 diff --git a/tests/plugins/formats/vcf.rs b/tests/plugins/formats/vcf.rs index d57269bbdd..b2012ab184 100644 --- a/tests/plugins/formats/vcf.rs +++ b/tests/plugins/formats/vcf.rs @@ -6,7 +6,7 @@ use pretty_assertions::assert_eq; #[test] fn infers_types() { Playground::setup("filter_from_vcf_test_1", |dirs, sandbox| { - sandbox.with_files(vec![FileWithContentToBeTrimmed( + sandbox.with_files(&[FileWithContentToBeTrimmed( "contacts.vcf", r" BEGIN:VCARD @@ -46,7 +46,7 @@ fn infers_types() { #[test] fn from_vcf_text_to_table() { Playground::setup("filter_from_vcf_test_2", |dirs, sandbox| { - sandbox.with_files(vec![FileWithContentToBeTrimmed( + sandbox.with_files(&[FileWithContentToBeTrimmed( "contacts.txt", r" BEGIN:VCARD @@ -86,7 +86,7 @@ fn from_vcf_text_to_table() { #[test] fn from_vcf_text_with_linebreak_to_table() { Playground::setup("filter_from_vcf_test_3", |dirs, sandbox| { - sandbox.with_files(vec![FileWithContent( + sandbox.with_files(&[FileWithContent( "contacts.txt", r"BEGIN:VCARD VERSION:3.0 diff --git a/tests/plugins/registry_file.rs b/tests/plugins/registry_file.rs index 674be48f15..3f7da6dd03 100644 --- a/tests/plugins/registry_file.rs +++ b/tests/plugins/registry_file.rs @@ -136,7 +136,7 @@ fn plugin_add_to_custom_path() { fn plugin_rm_then_restart_nu() { let example_plugin_path = example_plugin_path(); Playground::setup("plugin rm from custom path", |dirs, playground| { - playground.with_files(vec![ + playground.with_files(&[ Stub::FileWithContent("config.nu", ""), Stub::FileWithContent("env.nu", ""), ]); @@ -318,7 +318,7 @@ fn plugin_rm_using_filename() { fn warning_on_invalid_plugin_item() { let example_plugin_path = example_plugin_path(); Playground::setup("warning on invalid plugin item", |dirs, playground| { - playground.with_files(vec![ + playground.with_files(&[ Stub::FileWithContent("config.nu", ""), Stub::FileWithContent("env.nu", ""), ]); @@ -380,7 +380,7 @@ fn warning_on_invalid_plugin_item() { #[test] fn plugin_use_error_not_found() { Playground::setup("plugin use error not found", |dirs, playground| { - playground.with_files(vec![ + playground.with_files(&[ Stub::FileWithContent("config.nu", ""), Stub::FileWithContent("env.nu", ""), ]); diff --git a/tests/scope/mod.rs b/tests/scope/mod.rs index c6ff308802..bfcbb14958 100644 --- a/tests/scope/mod.rs +++ b/tests/scope/mod.rs @@ -109,7 +109,7 @@ fn correct_scope_modules_fields() { "#; Playground::setup("correct_scope_modules_fields", |dirs, sandbox| { - sandbox.with_files(vec![FileWithContent("spam.nu", module_setup)]); + sandbox.with_files(&[FileWithContent("spam.nu", module_setup)]); let inp = &[ "use spam.nu", @@ -191,7 +191,7 @@ fn correct_scope_aliases_fields() { "#; Playground::setup("correct_scope_aliases_fields", |dirs, sandbox| { - sandbox.with_files(vec![FileWithContent("spam.nu", module_setup)]); + sandbox.with_files(&[FileWithContent("spam.nu", module_setup)]); let inp = &[ "use spam.nu", @@ -248,7 +248,7 @@ fn correct_scope_externs_fields() { "#; Playground::setup("correct_scope_aliases_fields", |dirs, sandbox| { - sandbox.with_files(vec![FileWithContent("spam.nu", module_setup)]); + sandbox.with_files(&[FileWithContent("spam.nu", module_setup)]); let inp = &[ "use spam.nu", diff --git a/tests/shell/environment/env.rs b/tests/shell/environment/env.rs index f44d634b4d..7061761c70 100644 --- a/tests/shell/environment/env.rs +++ b/tests/shell/environment/env.rs @@ -129,7 +129,7 @@ fn passes_with_env_env_var_to_external_process() { #[test] fn has_file_pwd() { Playground::setup("has_file_pwd", |dirs, sandbox| { - sandbox.with_files(vec![FileWithContent("spam.nu", "$env.FILE_PWD")]); + sandbox.with_files(&[FileWithContent("spam.nu", "$env.FILE_PWD")]); let actual = nu!(cwd: dirs.test(), "nu spam.nu"); @@ -140,7 +140,7 @@ fn has_file_pwd() { #[test] fn has_file_loc() { Playground::setup("has_file_pwd", |dirs, sandbox| { - sandbox.with_files(vec![FileWithContent("spam.nu", "$env.CURRENT_FILE")]); + sandbox.with_files(&[FileWithContent("spam.nu", "$env.CURRENT_FILE")]); let actual = nu!(cwd: dirs.test(), "nu spam.nu"); @@ -154,7 +154,7 @@ fn has_file_loc() { #[serial] fn passes_env_from_local_cfg_to_external_process() { Playground::setup("autoenv_dir", |dirs, sandbox| { - sandbox.with_files(vec![FileWithContent( + sandbox.with_files(&[FileWithContent( ".nu-env", r#"[env] FOO = "foo" diff --git a/tests/shell/mod.rs b/tests/shell/mod.rs index 7f15d3027c..ba7465f5e7 100644 --- a/tests/shell/mod.rs +++ b/tests/shell/mod.rs @@ -65,7 +65,7 @@ fn nu_lib_dirs_repl() { Playground::setup("nu_lib_dirs_repl", |dirs, sandbox| { sandbox .mkdir("scripts") - .with_files(vec![FileWithContentToBeTrimmed( + .with_files(&[FileWithContentToBeTrimmed( "scripts/foo.nu", r#" $env.FOO = "foo" @@ -90,13 +90,13 @@ fn nu_lib_dirs_script() { Playground::setup("nu_lib_dirs_script", |dirs, sandbox| { sandbox .mkdir("scripts") - .with_files(vec![FileWithContentToBeTrimmed( + .with_files(&[FileWithContentToBeTrimmed( "scripts/foo.nu", r#" $env.FOO = "foo" "#, )]) - .with_files(vec![FileWithContentToBeTrimmed( + .with_files(&[FileWithContentToBeTrimmed( "main.nu", " source-env foo.nu @@ -121,7 +121,7 @@ fn nu_lib_dirs_relative_repl() { Playground::setup("nu_lib_dirs_relative_repl", |dirs, sandbox| { sandbox .mkdir("scripts") - .with_files(vec![FileWithContentToBeTrimmed( + .with_files(&[FileWithContentToBeTrimmed( "scripts/foo.nu", r#" $env.FOO = "foo" @@ -147,13 +147,13 @@ fn const_nu_lib_dirs_relative() { Playground::setup("const_nu_lib_dirs_relative", |dirs, sandbox| { sandbox .mkdir("scripts") - .with_files(vec![FileWithContentToBeTrimmed( + .with_files(&[FileWithContentToBeTrimmed( "scripts/foo.nu", r#" $env.FOO = "foo" "#, )]) - .with_files(vec![FileWithContentToBeTrimmed( + .with_files(&[FileWithContentToBeTrimmed( "main.nu", " const NU_LIB_DIRS = [ 'scripts' ] @@ -174,13 +174,13 @@ fn nu_lib_dirs_relative_script() { Playground::setup("nu_lib_dirs_relative_script", |dirs, sandbox| { sandbox .mkdir("scripts") - .with_files(vec![FileWithContentToBeTrimmed( + .with_files(&[FileWithContentToBeTrimmed( "scripts/main.nu", " source-env ../foo.nu ", )]) - .with_files(vec![FileWithContentToBeTrimmed( + .with_files(&[FileWithContentToBeTrimmed( "foo.nu", r#" $env.FOO = "foo" @@ -288,7 +288,7 @@ fn run_with_no_newline() { fn main_script_can_have_subcommands1() { Playground::setup("main_subcommands", |dirs, sandbox| { sandbox.mkdir("main_subcommands"); - sandbox.with_files(vec![FileWithContent( + sandbox.with_files(&[FileWithContent( "script.nu", r#"def "main foo" [x: int] { print ($x + 100) @@ -309,7 +309,7 @@ fn main_script_can_have_subcommands1() { fn main_script_can_have_subcommands2() { Playground::setup("main_subcommands", |dirs, sandbox| { sandbox.mkdir("main_subcommands"); - sandbox.with_files(vec![FileWithContent( + sandbox.with_files(&[FileWithContent( "script.nu", r#"def "main foo" [x: int] { print ($x + 100) @@ -330,7 +330,7 @@ fn main_script_can_have_subcommands2() { fn source_empty_file() { Playground::setup("source_empty_file", |dirs, sandbox| { sandbox.mkdir("source_empty_file"); - sandbox.with_files(vec![FileWithContent("empty.nu", "")]); + sandbox.with_files(&[FileWithContent("empty.nu", "")]); let actual = nu!(cwd: dirs.test(), pipeline("nu empty.nu")); assert!(actual.out.is_empty()); diff --git a/tests/shell/pipeline/commands/external.rs b/tests/shell/pipeline/commands/external.rs index 4b9427c32c..88d443e4fd 100644 --- a/tests/shell/pipeline/commands/external.rs +++ b/tests/shell/pipeline/commands/external.rs @@ -168,7 +168,7 @@ fn err_pipe_with_failed_external_works() { #[test] fn dont_run_glob_if_pass_variable_to_external() { Playground::setup("dont_run_glob", |dirs, sandbox| { - sandbox.with_files(vec![ + sandbox.with_files(&[ EmptyFile("jt_likes_cake.txt"), EmptyFile("andres_likes_arepas.txt"), ]); @@ -182,7 +182,7 @@ fn dont_run_glob_if_pass_variable_to_external() { #[test] fn run_glob_if_pass_variable_to_external() { Playground::setup("run_glob_on_external", |dirs, sandbox| { - sandbox.with_files(vec![ + sandbox.with_files(&[ EmptyFile("jt_likes_cake.txt"), EmptyFile("andres_likes_arepas.txt"), ]); @@ -202,7 +202,7 @@ mod it_evaluation { #[test] fn takes_rows_of_nu_value_strings() { Playground::setup("it_argument_test_1", |dirs, sandbox| { - sandbox.with_files(vec![ + sandbox.with_files(&[ EmptyFile("jt_likes_cake.txt"), EmptyFile("andres_likes_arepas.txt"), ]); @@ -225,7 +225,7 @@ mod it_evaluation { #[test] fn takes_rows_of_nu_value_lines() { Playground::setup("it_argument_test_2", |dirs, sandbox| { - sandbox.with_files(vec![FileWithContentToBeTrimmed( + sandbox.with_files(&[FileWithContentToBeTrimmed( "nu_candies.txt", " AndrásWithKitKatzz @@ -258,7 +258,7 @@ mod it_evaluation { #[test] fn supports_fetching_given_a_column_path_to_it() { Playground::setup("it_argument_test_3", |dirs, sandbox| { - sandbox.with_files(vec![FileWithContent( + sandbox.with_files(&[FileWithContent( "sample.toml", r#" nu_party_venue = "zion" @@ -286,7 +286,7 @@ mod stdin_evaluation { fn does_not_panic_with_no_newline_in_stream() { let actual = nu!(pipeline( r#" - nu --testbin nonu "wheres the nuline?" | length + nu --testbin nonu "where's the nuline?" | length "# )); @@ -349,7 +349,7 @@ mod external_words { #[case("$ sign.toml", r#""$ sign.toml""#)] fn external_arg_with_special_characters(#[case] path: &str, #[case] nu_path_argument: &str) { Playground::setup("external_arg_with_quotes", |dirs, sandbox| { - sandbox.with_files(vec![FileWithContent( + sandbox.with_files(&[FileWithContent( path, r#" nu_party_venue = "zion" @@ -479,7 +479,7 @@ mod external_command_arguments { Playground::setup( "expands_table_of_primitives_to_positional_arguments", |dirs, sandbox| { - sandbox.with_files(vec![ + sandbox.with_files(&[ EmptyFile("jt_likes_cake.txt"), EmptyFile("andres_likes_arepas.txt"), EmptyFile("ferris_not_here.txt"), @@ -505,7 +505,7 @@ mod external_command_arguments { Playground::setup( "expands_table_of_primitives_to_positional_arguments", |dirs, sandbox| { - sandbox.with_files(vec![ + sandbox.with_files(&[ EmptyFile("jt_likes_cake.txt"), EmptyFile("andres_likes_arepas.txt"), EmptyFile("ferris_not_here.txt"), @@ -531,7 +531,7 @@ mod external_command_arguments { |dirs, sandbox| { sandbox.mkdir("cd"); - sandbox.with_files(vec![EmptyFile("cd/jt_likes_cake.txt")]); + sandbox.with_files(&[EmptyFile("cd/jt_likes_cake.txt")]); let actual = nu!( cwd: dirs.test(), pipeline( diff --git a/tests/shell/pipeline/commands/internal.rs b/tests/shell/pipeline/commands/internal.rs index 06163639d7..7bc75b07ad 100644 --- a/tests/shell/pipeline/commands/internal.rs +++ b/tests/shell/pipeline/commands/internal.rs @@ -29,7 +29,7 @@ fn takes_rows_of_nu_value_strings_and_pipes_it_to_stdin_of_external() { #[test] fn treats_dot_dot_as_path_not_range() { Playground::setup("dot_dot_dir", |dirs, sandbox| { - sandbox.with_files(vec![FileWithContentToBeTrimmed( + sandbox.with_files(&[FileWithContentToBeTrimmed( "nu_times.csv", " name,rusty_luck,origin @@ -83,7 +83,7 @@ fn for_loop() { #[test] fn subexpression_handles_dot() { Playground::setup("subexpression_handles_dot", |dirs, sandbox| { - sandbox.with_files(vec![FileWithContentToBeTrimmed( + sandbox.with_files(&[FileWithContentToBeTrimmed( "nu_times.csv", " name,rusty_luck,origin diff --git a/toolkit.nu b/toolkit.nu index 98fcd4400b..407998c514 100644 --- a/toolkit.nu +++ b/toolkit.nu @@ -491,6 +491,31 @@ export def cov [] { print $"Coverage generation took ($end - $start)." } + +# Benchmark the current branch against the main branch +# Ensure you have `cargo-export` installed to generate separate artifacts for each branch. +export def "benchmark-current-branch-with-main" [] { + let main = "main" + let current_branch = (git branch --show-current) + + cargo export $"target/($current_branch)" -- bench + git checkout $main + cargo export $"target/($main)" -- bench + git checkout $current_branch + ^$"./target/($current_branch)/benchmarks" compare $"./target/($main)/benchmarks" -o -s 50 +} + +# Benchmark the current branch and logs the result in `./target/samples` +# Ensure you have `cargo-export` installed to generate separate artifacts for each branch. +export def "benchmark-and-log-result" [] { + let current_branch = (git branch --show-current) + let current_dir = "./" | path expand + let res_path = $"($current_dir)/target/samples" + + cargo export $"target/($current_branch)" -- bench + ^$"./target/($current_branch)/benchmarks" compare -o -s 50 --dump $res_path +} + # Build all Windows archives and MSIs for release manually # # This builds std and full distributions for both aarch64 and x86_64. diff --git a/typos.toml b/typos.toml index a8c81542e9..92fecd5cb6 100644 --- a/typos.toml +++ b/typos.toml @@ -1,17 +1,27 @@ [files] -extend-exclude = ["crates/nu-command/tests/commands/table.rs", "*.tsv", "*.json", "*.txt", "tests/fixtures/formats/*"] +extend-exclude = [ + ".git/", + "crates/nu-cmd-extra/assets/228_themes.json", + "tests/fixtures/formats/", +] +ignore-hidden = false -[default.extend-words] -# Ignore false-positives +[default] +extend-ignore-re = [ + "Plasticos Rival", + "│ in_custom_valu │", + "│ ine │", + ":es\\|ful\\(", + "\\\\u\\{e7ba\\}", + "([0-9a-f][0-9a-f] ){4}", + "--find ba\\b", + "0x\\[ba be\\]", + "\\)BaR'", +] + +[type.rust.extend-words] nd = "nd" -pn = "pn" -fo = "fo" -ful = "ful" -ons = "ons" -ba = "ba" -Plasticos = "Plasticos" -IIF = "IIF" numer = "numer" + +[default.extend-identifiers] ratatui = "ratatui" -doas = "doas" -wheres = "wheres"