├── .envrc ├── assets └── capture.png ├── .gitignore ├── .cargo └── config.toml ├── src ├── main.rs ├── searchresult.rs ├── print.rs ├── search.rs └── structs.rs ├── LICENSE ├── flake.nix ├── Cargo.toml ├── CHANGELOG.md ├── flake.lock ├── benchmarks └── run ├── README.md ├── wix └── main.wxs ├── .github └── workflows │ └── release.yml └── Cargo.lock /.envrc: -------------------------------------------------------------------------------- 1 | use flake -------------------------------------------------------------------------------- /assets/capture.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/LyonSyonII/hunt-rs/HEAD/assets/capture.png -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | **/target 2 | flamegraph.svg 3 | perf.data 4 | perf.data.old 5 | callgrind.out.* 6 | gecko_profile.json 7 | main_*.rs.bak 8 | benchmarks/* 9 | .direnv/ 10 | 11 | !benchmarks/run -------------------------------------------------------------------------------- /.cargo/config.toml: -------------------------------------------------------------------------------- 1 | [unstable] 2 | profile-rustflags = true 3 | codegen-backend = true 4 | 5 | [profile.dev] 6 | incremental = true 7 | opt-level = 0 8 | codegen-backend = "cranelift" 9 | rustflags = [ 10 | "-Zthreads=0", #num cores 11 | ] 12 | 13 | [profile.dev.build-override] 14 | opt-level = 3 15 | 16 | [profile.dev.package."*"] 17 | incremental = false 18 | codegen-backend = "llvm" 19 | opt-level = 3 -------------------------------------------------------------------------------- /src/main.rs: -------------------------------------------------------------------------------- 1 | mod print; 2 | mod search; 3 | mod searchresult; 4 | mod structs; 5 | 6 | #[cfg(not(any(test, miri)))] 7 | #[global_allocator] 8 | static GLOBAL: mimalloc::MiMalloc = mimalloc::MiMalloc; 9 | 10 | fn main() -> std::io::Result<()> { 11 | profi::print_on_exit!(stderr); 12 | let search = structs::Cli::run(); 13 | 14 | let buffers = search.search(); 15 | search.print_results(buffers)?; 16 | 17 | Ok(()) 18 | } 19 | -------------------------------------------------------------------------------- /src/searchresult.rs: -------------------------------------------------------------------------------- 1 | pub type Path = thin_str::ThinStr; 2 | 3 | pub enum SearchResult { 4 | Contains(Path), 5 | Exact(Path), 6 | } 7 | 8 | impl SearchResult { 9 | pub fn contains(path: String) -> Self { 10 | Self::Contains(path.into()) 11 | } 12 | pub fn exact(path: String) -> Self { 13 | Self::Exact(path.into()) 14 | } 15 | } 16 | 17 | impl std::fmt::Display for SearchResult { 18 | fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { 19 | match self { 20 | Self::Contains(path) => f.write_str(path), 21 | Self::Exact(path) => f.write_str(path), 22 | } 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2022 LyonSyonII 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /flake.nix: -------------------------------------------------------------------------------- 1 | { 2 | inputs = { 3 | nixpkgs.url = "github:NixOS/nixpkgs/nixpkgs-unstable"; 4 | fenix.url = "github:nix-community/fenix/monthly"; 5 | flake-utils.url = "github:numtide/flake-utils"; 6 | }; 7 | outputs = { self, nixpkgs, flake-utils, ... }@inputs: flake-utils.lib.eachDefaultSystem (system: 8 | let 9 | pkgs = import nixpkgs { 10 | inherit system; 11 | overlays = [ inputs.fenix.overlays.default ]; 12 | }; 13 | components = [ 14 | "rustc" 15 | "cargo" 16 | "clippy" 17 | "rustfmt" 18 | "rust-analyzer" 19 | "rust-src" 20 | "llvm-tools-preview" 21 | # Nightly 22 | "rustc-codegen-cranelift-preview" 23 | "miri" 24 | ]; 25 | nightly = pkgs.fenix.complete.withComponents components; 26 | # stable = pkgs.fenix.stable.withComponents ( nixpkgs.lib.sublist 0 (builtins.length components - 3) components ); 27 | in { 28 | devShells.default = pkgs.mkShell rec { 29 | nativeBuildInputs = with pkgs; [ 30 | nightly 31 | # stable 32 | fenix.targets.x86_64-unknown-linux-gnu.latest.rust-std 33 | mold 34 | ]; 35 | 36 | buildInputs = []; 37 | 38 | RUST_SRC_PATH = "${pkgs.fenix.complete.rust-src}/lib/rustlib/src/rust/library"; 39 | RUSTC_WRAPPER = "${pkgs.sccache}/bin/sccache"; 40 | RUSTFLAGS = "-Ctarget-cpu=native -Clink-arg=-fuse-ld=mold"; 41 | 42 | LD_LIBRARY_PATH = with pkgs; lib.makeLibraryPath nativeBuildInputs; 43 | }; 44 | }); 45 | } 46 | -------------------------------------------------------------------------------- /Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "hunt" 3 | description = "Simple command to quickly search a file/folder by name." 4 | documentation = "https://github.com/LyonSyonII/hunt-rs" 5 | repository = "https://github.com/LyonSyonII/hunt-rs" 6 | keywords = ["algorithms", "filesystem"] 7 | readme = "README.md" 8 | license = "MIT" 9 | version = "3.0.0" 10 | authors = ["Liam G "] 11 | edition = "2024" 12 | 13 | [package.metadata.wix] 14 | upgrade-guid = "93301563-2D91-4224-B838-C60D235011A0" 15 | path-guid = "35E701F2-8BE5-44F5-A8AB-3864E32599B9" 16 | license = false 17 | eula = false 18 | 19 | [dependencies] 20 | clap = { version = "4.5.40", features = ["derive", "color"] } # Command line argument parser 21 | colored = "3.0.0" # Colored output 22 | rayon = "1.10.0" # Parallelism library 23 | crossbeam-channel = "0.5.15" # Faster channels (mpmc) 24 | mimalloc = { version = "0.1.47", default-features = false } # Faster allocator 25 | thin_str = "0.1.0" # Thinner string (only 8 bytes) 26 | memchr = { version = "2.7.5", features = ["std", "alloc"] } # Small substring search optimization 27 | inquire = { version = "0.7.5" } # Multiselect CLI interface 28 | 29 | # Multithreaded fine-grained profiler 30 | [dependencies.profi] 31 | version = "0.1.2" 32 | features = ["rayon", "attributes"] 33 | default-features = false 34 | 35 | [target.'cfg(target_os = "linux")'.dependencies] 36 | rustix = { version = "1.0.7", default-features = false, features = ["fs", "alloc"] } 37 | 38 | [target.'cfg(windows)'.dependencies] 39 | winapi-util = "0.1.9" 40 | 41 | [profile.release] 42 | lto = true 43 | codegen-units = 1 44 | strip = true 45 | debug = "line-tables-only" 46 | panic = "abort" 47 | 48 | [profile.profiling] 49 | inherits = "release" 50 | debug = true 51 | strip = false 52 | 53 | # The profile that 'cargo dist' will build with 54 | [profile.dist] 55 | inherits = "release" 56 | lto = "thin" 57 | 58 | [features] 59 | perf = ["profi/enable"] # Enable performance measurements 60 | 61 | # Config for 'cargo dist' 62 | [workspace.metadata.dist] 63 | # The preferred cargo-dist version to use in CI (Cargo.toml SemVer syntax) 64 | cargo-dist-version = "0.10.0" 65 | # CI backends to support 66 | ci = ["github"] 67 | # The installers to generate for each app 68 | installers = ["shell", "powershell", "msi"] 69 | # Target platforms to build apps for (Rust target-triple syntax) 70 | targets = ["aarch64-apple-darwin", "x86_64-apple-darwin", "x86_64-unknown-linux-gnu", "x86_64-pc-windows-msvc"] 71 | # Publish jobs to run in CI 72 | pr-run-mode = "plan" 73 | -------------------------------------------------------------------------------- /CHANGELOG.md: -------------------------------------------------------------------------------- 1 | # Changelog 2 | 3 | All notable changes to this project will be documented in this file. 4 | 5 | ## \[3.0.0] 6 | 7 | ### 🚀 Features - Breaking Changes 8 | - `--ignore` can now skip files/directories with a specific name, instead of just paths. 9 | - Breaking change, semantics are not the same as previous version, though it shouldn't affect much. 10 | - Addresses [#12](https://github.com/LyonSyonII/hunt-rs/issues/12). 11 | - 12 | ### 🐛 Bug Fixes 13 | - `--ignore` now has the exact same behaviour regardless of the `--canonicalize` flag. 14 | 15 | ## \[2.4.0] 16 | 17 | ### 🚀 Features 18 | 19 | - Add `--select` and `--multiselect` options for an interactive file select screen. 20 | - Useful for chaining `hunt` with other commands. 21 | - Remove implicit ignore list, as it affected performance globally for a very small gain in specific queries. 22 | - More optimized substring search with [memchr](https://crates.io/crates/memchr). 23 | 24 | ## \[2.3.0] 25 | 26 | ### 🚀 Features 27 | 28 | - Multiple small optimizations for up to 25% performance improvement 29 | - Parallelism is now at directory level instead of file level 30 | 31 | ## \[2.2.0] 32 | 33 | ### 🚀 Features 34 | 35 | - Use `crossbeam_channel` for up to 90% performance improvement 36 | - [feat: use ignore hidden detection implementation for correctness](https://github.com/LyonSyonII/hunt-rs/commit/dff0be53c6a2c0d1e4002c51900225d5be8892e7) 37 | 38 | ### 🐛 Bug Fixes 39 | 40 | - [fix: fixed freeze when reading from current directory](https://github.com/LyonSyonII/hunt-rs/commit/f54de3d8963020d2c9266b380d09e736b7bb49f0) 41 | - [fix: Output is no longer highlighted when -s or -ss is provided](https://github.com/LyonSyonII/hunt-rs/commit/bf9aecbd7d6c49578232d19640ad9e99136a22ae) 42 | 43 | ## \[2.1.0] 44 | 45 | ### 🚀 Features 46 | 47 | - Changed `sort_unstable` to `sort` for up to 20% performance improvement 48 | - Re-added color to --help output 49 | 50 | ### 🐛 Bug Fixes 51 | 52 | - Avoid allocation in case of case_sensitivity 53 | - Fixed canonicalization 54 | 55 | ## \[2.0.0] 56 | ### Breaking changes 57 | - Updated to clap 4.3.0. 58 | - Changed `case_sensitive` flag from `-c` to `-C`. 59 | - Changed `hidden` flag from `-h` to `-H`. 60 | - `help` can now be triggered by `-h` and `--help`. 61 | - Added `--canonicalize` and `-c` flags 62 | - `hunt`'s output will now depend on the paths in `SEARCH_IN_DIRS`. 63 | Only queries starting with `/` will be canonicallized. 64 | - Addresses [#2](https://github.com/LyonSyonII/hunt-rs/issues/2). 65 | - The `-ss` flag now prints the results incrementally, as no sorting is needed. 66 | - The "File not found" message will only be shown when no `-s` flag is provided. 67 | - Addresses [#4](https://github.com/LyonSyonII/hunt-rs/issues/4). 68 | 69 | ### Other changes 70 | - Fixed README examples to account for the flag changes. 71 | - Updated multiple dependencies 72 | 73 | 74 | 75 | 17 | 18 | 46 | 47 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 69 | 70 | 80 | 81 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 106 | 111 | 112 | 113 | 114 | 122 | 123 | 124 | 130 | 131 | 132 | 133 | 134 | 135 | 136 | 145 | 146 | 150 | 151 | 152 | 153 | 154 | 160 | 161 | 162 | 163 | 164 | 165 | 166 | 167 | 173 | 174 | 175 | 176 | 177 | 178 | 179 | 180 | 181 | 191 | 1 192 | 1 193 | 194 | 195 | 196 | 197 | 202 | 203 | 204 | 205 | 213 | 214 | 215 | 216 | 224 | 225 | 226 | 227 | 228 | 229 | -------------------------------------------------------------------------------- /src/structs.rs: -------------------------------------------------------------------------------- 1 | use clap::Parser; 2 | 3 | use std::path::PathBuf; 4 | 5 | pub type ResultPath = thin_str::ThinStr; 6 | pub type ContainsBuf = Vec; 7 | pub type ExactBuf = Vec; 8 | pub type Buffers = (ExactBuf, ContainsBuf); 9 | 10 | pub struct Search { 11 | /// If the search must stop when a match is found. 12 | pub first: bool, 13 | /// If only exact matches must be accounted for. 14 | pub exact: bool, 15 | /// If all paths should be canonicalized. 16 | pub canonicalize: bool, 17 | /// If the search is case sensitive. 18 | pub case_sensitive: bool, 19 | /// If the search is limited to specific directories. 20 | pub limit: bool, 21 | /// If the output must be verbose or not. 22 | pub verbose: bool, 23 | /// If hidden directories must be traversed and hidden files counted as matches. 24 | pub hidden: bool, 25 | /// If the select interface will be shown. 26 | pub select: bool, 27 | /// If the multiselect interface will be shown. 28 | pub multiselect: bool, 29 | /// Type of the output. 30 | /// 31 | /// Simple makes it not to be highlighted and removes the "Exact:" and "Contains:" distinctions. 32 | /// 33 | /// In addition, SuperSimple does not sort the results. 34 | pub output: Output, 35 | /// Name of the file/folder we're searching. 36 | pub name: String, 37 | /// Pattern the query must start with. 38 | pub starts: String, 39 | /// Pattern the query must end with. 40 | pub ends: String, 41 | /// Type of the query. It can be a File, a Directory or All. 42 | pub ftype: FileType, 43 | /// Directories the user has stated to ignore. 44 | pub explicit_ignore: Vec, 45 | // /// Directories hard-coded to be ignored. 46 | // pub hardcoded_ignore: phf::Set<&'static str>, 47 | /// Directories specified by the user to be searched in. 48 | pub dirs: Vec, 49 | 50 | /// Memchr Finder 51 | pub finder: memchr::memmem::Finder<'static>, 52 | 53 | pub max_depth: usize, 54 | } 55 | 56 | impl Search { 57 | #[allow(clippy::too_many_arguments)] 58 | pub fn new( 59 | first: bool, 60 | exact: bool, 61 | canonicalize: bool, 62 | case_sensitive: bool, 63 | limit: bool, 64 | verbose: bool, 65 | hidden: bool, 66 | select: bool, 67 | multiselect: bool, 68 | output: u8, 69 | name: String, 70 | starts: String, 71 | ends: String, 72 | ftype: FileType, 73 | explicit_ignore: Vec, 74 | search_in_dirs: Vec, 75 | ) -> Search { 76 | let output = match output { 77 | 0 => Output::Normal, 78 | 1 => Output::Simple, 79 | _ => Output::SuperSimple, 80 | }; 81 | let finder = memchr::memmem::Finder::new(name.as_bytes()).into_owned(); 82 | let max_depth = std::env::var("HUNT_MAX_DEPTH") 83 | .map(|v| v.parse().ok()) 84 | .ok() 85 | .flatten() 86 | .unwrap_or(usize::MAX); 87 | 88 | Search { 89 | first, 90 | exact, 91 | canonicalize, 92 | case_sensitive, 93 | limit, 94 | verbose, 95 | hidden, 96 | select, 97 | multiselect, 98 | output, 99 | name, 100 | starts, 101 | ends, 102 | ftype, 103 | explicit_ignore, 104 | dirs: search_in_dirs, 105 | 106 | finder, 107 | max_depth, 108 | } 109 | } 110 | } 111 | 112 | #[derive(PartialEq, Clone, Copy)] 113 | pub enum Output { 114 | Normal, 115 | Simple, 116 | SuperSimple, 117 | } 118 | 119 | #[derive(PartialEq, Clone, Copy)] 120 | pub enum FileType { 121 | Dir, 122 | File, 123 | All, 124 | } 125 | 126 | impl From> for FileType { 127 | fn from(s: Option) -> Self { 128 | if let Some(s) = s { 129 | match s.as_str() { 130 | "d" => FileType::Dir, 131 | "f" => FileType::File, 132 | _ => { 133 | eprintln!( 134 | "File type {} not recognized\nPlease use 'f' for files and 'd' for directories\nSee --help for more information\n", 135 | s 136 | ); 137 | std::process::exit(1) 138 | } 139 | } 140 | } else { 141 | FileType::All 142 | } 143 | } 144 | } 145 | 146 | fn styles() -> clap::builder::Styles { 147 | clap::builder::Styles::styled() 148 | .header( 149 | clap::builder::styling::AnsiColor::Green.on_default() 150 | | clap::builder::styling::Effects::BOLD, 151 | ) 152 | .usage( 153 | clap::builder::styling::AnsiColor::Green.on_default() 154 | | clap::builder::styling::Effects::BOLD, 155 | ) 156 | .literal( 157 | clap::builder::styling::AnsiColor::Cyan.on_default() 158 | | clap::builder::styling::Effects::BOLD, 159 | ) 160 | .placeholder(clap::builder::styling::AnsiColor::Cyan.on_default()) 161 | } 162 | 163 | #[derive(clap::Parser, Debug)] 164 | #[command( 165 | name = "Hunt", 166 | about = "Simple command to search a file/folder by name on the current directory.\nBy default it searches all occurrences.", 167 | version, 168 | styles = styles() 169 | )] 170 | pub struct Cli { 171 | /// Stop when first occurrence is found 172 | #[arg(short, long)] 173 | first: bool, 174 | 175 | /// Only search for exactly matching occurrences, any file only containing the query will be skipped 176 | /// 177 | /// e.g. if query is "SomeFile", "I'mSomeFile" will be skipped, as its name contains more letters than the search 178 | #[arg(short, long)] 179 | exact: bool, 180 | 181 | /// If enabled, all paths will be canonicalized. 182 | #[arg(short, long)] 183 | canonicalize: bool, 184 | 185 | /// If enabled, the search will be case-sensitive 186 | /// 187 | /// Note that case-sensitivity will be activated automatically when the search query contains an uppercase letter 188 | #[arg(short = 'C', long)] 189 | case_sensitive: bool, 190 | 191 | /// Print verbose output 192 | /// 193 | /// It'll show all errors found: 194 | /// e.g. "Could not read /proc/81261/map_files" 195 | #[arg(short, long)] 196 | verbose: bool, 197 | 198 | /// Prints without formatting (without "Contains:" and "Exact:") 199 | /// 200 | /// -ss Output is not sorted 201 | #[arg(short, long, action = clap::ArgAction::Count)] 202 | simple: u8, 203 | 204 | /// If enabled, it searches inside hidden directories 205 | /// 206 | /// If not enabled, hidden directories will be skipped 207 | #[arg(short = 'H', long)] 208 | hidden: bool, 209 | 210 | /// When the search is finished, choose one file between the results 211 | /// 212 | /// The selected file will be printed as if -ss was used 213 | #[arg(long, conflicts_with_all(["simple", "multiselect", "first"]))] 214 | select: bool, 215 | 216 | /// When the search is finished, choose between the results 217 | /// 218 | /// The selected files will be printed one after the other, separated by spaces 219 | #[arg(long, conflicts_with_all(["simple", "select", "first"]))] 220 | multiselect: bool, 221 | 222 | /// Only files that start with this will be found 223 | #[arg(short = 'S', long = "starts")] 224 | starts_with: Option, 225 | 226 | /// Only files that end with this will be found 227 | #[arg(short = 'E', long = "ends")] 228 | ends_with: Option, 229 | 230 | /// Specifies the type of the file 231 | /// 232 | /// 'f' -> file | 'd' -> directory 233 | #[arg(short = 't', long = "type")] 234 | file_type: Option, 235 | 236 | /// Ignores the provided files/directories. 237 | /// The format is: '-i dir1,dir2,dir3,...' 238 | /// 239 | /// Which files will be ignored depends on how they are written: 240 | /// - If the path is absolute or relative, only that file will be ignored 241 | /// Examples: '/home/user/Downloads' or './Downloads' 242 | /// - If only a name is provided, ALL matching files/directories will be ignored 243 | /// Examples: 'file.txt' or 'node_modules' 244 | #[arg( 245 | short = 'i', 246 | long = "ignore", 247 | value_delimiter = ',', 248 | verbatim_doc_comment 249 | )] 250 | ignore: Option>, 251 | 252 | /// Name of the file/folder to search. If starts/ends are specified, this field can be skipped 253 | name: Option, 254 | 255 | /// Directories where you want to search 256 | /// 257 | /// If provided, hunt will only search there 258 | /// 259 | /// If not provided, hunt will search in the current directory 260 | /// 261 | /// These directories are treated independently, so if one is nested into another the search will be done two times: 262 | /// 263 | /// e.g. "hunt somefile /home/user /home/user/downloads" will search in the home directory, and because /home/user/downloads is inside it, /downloads will be traversed two times 264 | #[arg(required = false)] 265 | search_in_dirs: Vec, 266 | } 267 | 268 | impl Cli { 269 | #[profi::profile] 270 | pub fn run() -> Search { 271 | let cli = Self::parse(); 272 | 273 | let mut search_in_dirs = cli.search_in_dirs; 274 | let mut starts = cli.starts_with.unwrap_or_default(); 275 | let mut ends = cli.ends_with.unwrap_or_default(); 276 | let ftype = cli.file_type.into(); 277 | 278 | let name = match cli.name { 279 | // If directory is given but no file name is specified, print files in that directory 280 | // ex. hunt /home/user 281 | Some(n) if n == "." || n.contains(std::path::MAIN_SEPARATOR) => { 282 | search_in_dirs.insert(0, PathBuf::from(n)); 283 | String::new() 284 | } 285 | Some(n) => n, 286 | None => String::new(), 287 | }; 288 | 289 | let case_sensitive = 290 | cli.case_sensitive || name.contains(|c: char| c.is_alphabetic() && c.is_uppercase()); 291 | if !case_sensitive { 292 | starts.make_ascii_lowercase(); 293 | ends.make_ascii_lowercase(); 294 | } 295 | 296 | let mut ignore_dirs = cli.ignore.unwrap_or_default(); 297 | // canonicalize non global paths 298 | // ./Cargo.toml => canonicalized 299 | // /home/user//Cargo.toml 300 | for p in ignore_dirs.iter_mut() { 301 | if p.is_absolute() || p.starts_with("./") { 302 | let Ok(c) = p.canonicalize() else { continue }; 303 | *p = c; 304 | } 305 | } 306 | 307 | Search::new( 308 | cli.first, 309 | cli.exact, 310 | cli.canonicalize, 311 | case_sensitive, 312 | !search_in_dirs.is_empty(), 313 | cli.verbose, 314 | cli.hidden, 315 | cli.select, 316 | cli.multiselect, 317 | cli.simple, 318 | name, 319 | starts, 320 | ends, 321 | ftype, 322 | ignore_dirs, 323 | search_in_dirs, 324 | ) 325 | } 326 | } 327 | -------------------------------------------------------------------------------- /.github/workflows/release.yml: -------------------------------------------------------------------------------- 1 | # Copyright 2022-2023, axodotdev 2 | # SPDX-License-Identifier: MIT or Apache-2.0 3 | # 4 | # CI that: 5 | # 6 | # * checks for a Git Tag that looks like a release 7 | # * builds artifacts with cargo-dist (archives, installers, hashes) 8 | # * uploads those artifacts to temporary workflow zip 9 | # * on success, uploads the artifacts to a Github Release 10 | # 11 | # Note that the Github Release will be created with a generated 12 | # title/body based on your changelogs. 13 | 14 | name: Release 15 | 16 | permissions: 17 | contents: write 18 | 19 | # This task will run whenever you push a git tag that looks like a version 20 | # like "1.0.0", "v0.1.0-prerelease.1", "my-app/0.1.0", "releases/v1.0.0", etc. 21 | # Various formats will be parsed into a VERSION and an optional PACKAGE_NAME, where 22 | # PACKAGE_NAME must be the name of a Cargo package in your workspace, and VERSION 23 | # must be a Cargo-style SemVer Version (must have at least major.minor.patch). 24 | # 25 | # If PACKAGE_NAME is specified, then the announcement will be for that 26 | # package (erroring out if it doesn't have the given version or isn't cargo-dist-able). 27 | # 28 | # If PACKAGE_NAME isn't specified, then the announcement will be for all 29 | # (cargo-dist-able) packages in the workspace with that version (this mode is 30 | # intended for workspaces with only one dist-able package, or with all dist-able 31 | # packages versioned/released in lockstep). 32 | # 33 | # If you push multiple tags at once, separate instances of this workflow will 34 | # spin up, creating an independent announcement for each one. However Github 35 | # will hard limit this to 3 tags per commit, as it will assume more tags is a 36 | # mistake. 37 | # 38 | # If there's a prerelease-style suffix to the version, then the release(s) 39 | # will be marked as a prerelease. 40 | on: 41 | push: 42 | tags: 43 | - '**[0-9]+.[0-9]+.[0-9]+*' 44 | pull_request: 45 | 46 | jobs: 47 | # Run 'cargo dist plan' (or host) to determine what tasks we need to do 48 | plan: 49 | runs-on: ubuntu-latest 50 | outputs: 51 | val: ${{ steps.plan.outputs.manifest }} 52 | tag: ${{ !github.event.pull_request && github.ref_name || '' }} 53 | tag-flag: ${{ !github.event.pull_request && format('--tag={0}', github.ref_name) || '' }} 54 | publishing: ${{ !github.event.pull_request }} 55 | env: 56 | GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} 57 | steps: 58 | - uses: actions/checkout@v4 59 | with: 60 | submodules: recursive 61 | - name: Install cargo-dist 62 | # we specify bash to get pipefail; it guards against the `curl` command 63 | # failing. otherwise `sh` won't catch that `curl` returned non-0 64 | shell: bash 65 | run: "curl --proto '=https' --tlsv1.2 -LsSf https://github.com/axodotdev/cargo-dist/releases/download/v0.10.0/cargo-dist-installer.sh | sh" 66 | # sure would be cool if github gave us proper conditionals... 67 | # so here's a doubly-nested ternary-via-truthiness to try to provide the best possible 68 | # functionality based on whether this is a pull_request, and whether it's from a fork. 69 | # (PRs run on the *source* but secrets are usually on the *target* -- that's *good* 70 | # but also really annoying to build CI around when it needs secrets to work right.) 71 | - id: plan 72 | run: | 73 | cargo dist ${{ (!github.event.pull_request && format('host --steps=create --tag={0}', github.ref_name)) || 'plan' }} --output-format=json > plan-dist-manifest.json 74 | echo "cargo dist ran successfully" 75 | cat plan-dist-manifest.json 76 | echo "manifest=$(jq -c "." plan-dist-manifest.json)" >> "$GITHUB_OUTPUT" 77 | - name: "Upload dist-manifest.json" 78 | uses: actions/upload-artifact@v4 79 | with: 80 | name: artifacts-plan-dist-manifest 81 | path: plan-dist-manifest.json 82 | 83 | # Build and packages all the platform-specific things 84 | build-local-artifacts: 85 | name: build-local-artifacts (${{ join(matrix.targets, ', ') }}) 86 | # Let the initial task tell us to not run (currently very blunt) 87 | needs: 88 | - plan 89 | if: ${{ fromJson(needs.plan.outputs.val).ci.github.artifacts_matrix.include != null && (needs.plan.outputs.publishing == 'true' || fromJson(needs.plan.outputs.val).ci.github.pr_run_mode == 'upload') }} 90 | strategy: 91 | fail-fast: false 92 | # Target platforms/runners are computed by cargo-dist in create-release. 93 | # Each member of the matrix has the following arguments: 94 | # 95 | # - runner: the github runner 96 | # - dist-args: cli flags to pass to cargo dist 97 | # - install-dist: expression to run to install cargo-dist on the runner 98 | # 99 | # Typically there will be: 100 | # - 1 "global" task that builds universal installers 101 | # - N "local" tasks that build each platform's binaries and platform-specific installers 102 | matrix: ${{ fromJson(needs.plan.outputs.val).ci.github.artifacts_matrix }} 103 | runs-on: ${{ matrix.runner }} 104 | env: 105 | GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} 106 | BUILD_MANIFEST_NAME: target/distrib/${{ join(matrix.targets, '-') }}-dist-manifest.json 107 | steps: 108 | - uses: actions/checkout@v4 109 | with: 110 | submodules: recursive 111 | - uses: swatinem/rust-cache@v2 112 | - name: Install cargo-dist 113 | run: ${{ matrix.install_dist }} 114 | # Get the dist-manifest 115 | - name: Fetch local artifacts 116 | uses: actions/download-artifact@v4 117 | with: 118 | pattern: artifacts-* 119 | path: target/distrib/ 120 | merge-multiple: true 121 | - name: Install dependencies 122 | run: | 123 | ${{ matrix.packages_install }} 124 | - name: Build artifacts 125 | run: | 126 | # Actually do builds and make zips and whatnot 127 | cargo dist build ${{ needs.plan.outputs.tag-flag }} --print=linkage --output-format=json ${{ matrix.dist_args }} > dist-manifest.json 128 | echo "cargo dist ran successfully" 129 | - id: cargo-dist 130 | name: Post-build 131 | # We force bash here just because github makes it really hard to get values up 132 | # to "real" actions without writing to env-vars, and writing to env-vars has 133 | # inconsistent syntax between shell and powershell. 134 | shell: bash 135 | run: | 136 | # Parse out what we just built and upload it to scratch storage 137 | echo "paths<> "$GITHUB_OUTPUT" 138 | jq --raw-output ".artifacts[]?.path | select( . != null )" dist-manifest.json >> "$GITHUB_OUTPUT" 139 | echo "EOF" >> "$GITHUB_OUTPUT" 140 | 141 | cp dist-manifest.json "$BUILD_MANIFEST_NAME" 142 | - name: "Upload artifacts" 143 | uses: actions/upload-artifact@v4 144 | with: 145 | name: artifacts-build-local-${{ join(matrix.targets, '_') }} 146 | path: | 147 | ${{ steps.cargo-dist.outputs.paths }} 148 | ${{ env.BUILD_MANIFEST_NAME }} 149 | 150 | # Build and package all the platform-agnostic(ish) things 151 | build-global-artifacts: 152 | needs: 153 | - plan 154 | - build-local-artifacts 155 | runs-on: "ubuntu-20.04" 156 | env: 157 | GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} 158 | BUILD_MANIFEST_NAME: target/distrib/global-dist-manifest.json 159 | steps: 160 | - uses: actions/checkout@v4 161 | with: 162 | submodules: recursive 163 | - name: Install cargo-dist 164 | run: "curl --proto '=https' --tlsv1.2 -LsSf https://github.com/axodotdev/cargo-dist/releases/download/v0.10.0/cargo-dist-installer.sh | sh" 165 | # Get all the local artifacts for the global tasks to use (for e.g. checksums) 166 | - name: Fetch local artifacts 167 | uses: actions/download-artifact@v4 168 | with: 169 | pattern: artifacts-* 170 | path: target/distrib/ 171 | merge-multiple: true 172 | - id: cargo-dist 173 | shell: bash 174 | run: | 175 | cargo dist build ${{ needs.plan.outputs.tag-flag }} --output-format=json "--artifacts=global" > dist-manifest.json 176 | echo "cargo dist ran successfully" 177 | 178 | # Parse out what we just built and upload it to scratch storage 179 | echo "paths<> "$GITHUB_OUTPUT" 180 | jq --raw-output ".artifacts[]?.path | select( . != null )" dist-manifest.json >> "$GITHUB_OUTPUT" 181 | echo "EOF" >> "$GITHUB_OUTPUT" 182 | 183 | cp dist-manifest.json "$BUILD_MANIFEST_NAME" 184 | - name: "Upload artifacts" 185 | uses: actions/upload-artifact@v4 186 | with: 187 | name: artifacts-build-global 188 | path: | 189 | ${{ steps.cargo-dist.outputs.paths }} 190 | ${{ env.BUILD_MANIFEST_NAME }} 191 | # Determines if we should publish/announce 192 | host: 193 | needs: 194 | - plan 195 | - build-local-artifacts 196 | - build-global-artifacts 197 | # Only run if we're "publishing", and only if local and global didn't fail (skipped is fine) 198 | if: ${{ always() && needs.plan.outputs.publishing == 'true' && (needs.build-global-artifacts.result == 'skipped' || needs.build-global-artifacts.result == 'success') && (needs.build-local-artifacts.result == 'skipped' || needs.build-local-artifacts.result == 'success') }} 199 | env: 200 | GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} 201 | runs-on: "ubuntu-20.04" 202 | outputs: 203 | val: ${{ steps.host.outputs.manifest }} 204 | steps: 205 | - uses: actions/checkout@v4 206 | with: 207 | submodules: recursive 208 | - name: Install cargo-dist 209 | run: "curl --proto '=https' --tlsv1.2 -LsSf https://github.com/axodotdev/cargo-dist/releases/download/v0.10.0/cargo-dist-installer.sh | sh" 210 | # Fetch artifacts from scratch-storage 211 | - name: Fetch artifacts 212 | uses: actions/download-artifact@v4 213 | with: 214 | pattern: artifacts-* 215 | path: target/distrib/ 216 | merge-multiple: true 217 | # This is a harmless no-op for Github Releases, hosting for that happens in "announce" 218 | - id: host 219 | shell: bash 220 | run: | 221 | cargo dist host ${{ needs.plan.outputs.tag-flag }} --steps=upload --steps=release --output-format=json > dist-manifest.json 222 | echo "artifacts uploaded and released successfully" 223 | cat dist-manifest.json 224 | echo "manifest=$(jq -c "." dist-manifest.json)" >> "$GITHUB_OUTPUT" 225 | - name: "Upload dist-manifest.json" 226 | uses: actions/upload-artifact@v4 227 | with: 228 | # Overwrite the previous copy 229 | name: artifacts-dist-manifest 230 | path: dist-manifest.json 231 | 232 | # Create a Github Release while uploading all files to it 233 | announce: 234 | needs: 235 | - plan 236 | - host 237 | # use "always() && ..." to allow us to wait for all publish jobs while 238 | # still allowing individual publish jobs to skip themselves (for prereleases). 239 | # "host" however must run to completion, no skipping allowed! 240 | if: ${{ always() && needs.host.result == 'success' }} 241 | runs-on: "ubuntu-20.04" 242 | env: 243 | GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} 244 | steps: 245 | - uses: actions/checkout@v4 246 | with: 247 | submodules: recursive 248 | - name: "Download Github Artifacts" 249 | uses: actions/download-artifact@v4 250 | with: 251 | pattern: artifacts-* 252 | path: artifacts 253 | merge-multiple: true 254 | - name: Cleanup 255 | run: | 256 | # Remove the granular manifests 257 | rm -f artifacts/*-dist-manifest.json 258 | - name: Create Github Release 259 | uses: ncipollo/release-action@v1 260 | with: 261 | tag: ${{ needs.plan.outputs.tag }} 262 | name: ${{ fromJson(needs.host.outputs.val).announcement_title }} 263 | body: ${{ fromJson(needs.host.outputs.val).announcement_github_body }} 264 | prerelease: ${{ fromJson(needs.host.outputs.val).announcement_is_prerelease }} 265 | artifacts: "artifacts/*" 266 | -------------------------------------------------------------------------------- /Cargo.lock: -------------------------------------------------------------------------------- 1 | # This file is automatically @generated by Cargo. 2 | # It is not intended for manual editing. 3 | version = 3 4 | 5 | [[package]] 6 | name = "anstream" 7 | version = "0.6.14" 8 | source = "registry+https://github.com/rust-lang/crates.io-index" 9 | checksum = "418c75fa768af9c03be99d17643f93f79bbba589895012a80e3452a19ddda15b" 10 | dependencies = [ 11 | "anstyle", 12 | "anstyle-parse", 13 | "anstyle-query", 14 | "anstyle-wincon", 15 | "colorchoice", 16 | "is_terminal_polyfill", 17 | "utf8parse", 18 | ] 19 | 20 | [[package]] 21 | name = "anstyle" 22 | version = "1.0.10" 23 | source = "registry+https://github.com/rust-lang/crates.io-index" 24 | checksum = "55cc3b69f167a1ef2e161439aa98aed94e6028e5f9a59be9a6ffb47aef1651f9" 25 | 26 | [[package]] 27 | name = "anstyle-parse" 28 | version = "0.2.4" 29 | source = "registry+https://github.com/rust-lang/crates.io-index" 30 | checksum = "c03a11a9034d92058ceb6ee011ce58af4a9bf61491aa7e1e59ecd24bd40d22d4" 31 | dependencies = [ 32 | "utf8parse", 33 | ] 34 | 35 | [[package]] 36 | name = "anstyle-query" 37 | version = "1.0.3" 38 | source = "registry+https://github.com/rust-lang/crates.io-index" 39 | checksum = "a64c907d4e79225ac72e2a354c9ce84d50ebb4586dee56c82b3ee73004f537f5" 40 | dependencies = [ 41 | "windows-sys 0.52.0", 42 | ] 43 | 44 | [[package]] 45 | name = "anstyle-wincon" 46 | version = "3.0.3" 47 | source = "registry+https://github.com/rust-lang/crates.io-index" 48 | checksum = "61a38449feb7068f52bb06c12759005cf459ee52bb4adc1d5a7c4322d716fb19" 49 | dependencies = [ 50 | "anstyle", 51 | "windows-sys 0.52.0", 52 | ] 53 | 54 | [[package]] 55 | name = "autocfg" 56 | version = "1.3.0" 57 | source = "registry+https://github.com/rust-lang/crates.io-index" 58 | checksum = "0c4b4d0bd25bd0b74681c0ad21497610ce1b7c91b1022cd21c80c6fbdd9476b0" 59 | 60 | [[package]] 61 | name = "beef" 62 | version = "0.5.2" 63 | source = "registry+https://github.com/rust-lang/crates.io-index" 64 | checksum = "3a8241f3ebb85c056b509d4327ad0358fbbba6ffb340bf388f26350aeda225b1" 65 | 66 | [[package]] 67 | name = "bitflags" 68 | version = "1.3.2" 69 | source = "registry+https://github.com/rust-lang/crates.io-index" 70 | checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" 71 | 72 | [[package]] 73 | name = "bitflags" 74 | version = "2.5.0" 75 | source = "registry+https://github.com/rust-lang/crates.io-index" 76 | checksum = "cf4b9d6a944f767f8e5e0db018570623c85f3d925ac718db4e06d0187adb21c1" 77 | 78 | [[package]] 79 | name = "bumpalo" 80 | version = "3.16.0" 81 | source = "registry+https://github.com/rust-lang/crates.io-index" 82 | checksum = "79296716171880943b8470b5f8d03aa55eb2e645a4874bdbb28adb49162e012c" 83 | 84 | [[package]] 85 | name = "byteorder" 86 | version = "1.5.0" 87 | source = "registry+https://github.com/rust-lang/crates.io-index" 88 | checksum = "1fd0f2584146f6f2ef48085050886acf353beff7305ebd1ae69500e27c67f64b" 89 | 90 | [[package]] 91 | name = "cc" 92 | version = "1.0.98" 93 | source = "registry+https://github.com/rust-lang/crates.io-index" 94 | checksum = "41c270e7540d725e65ac7f1b212ac8ce349719624d7bcff99f8e2e488e8cf03f" 95 | 96 | [[package]] 97 | name = "cfg-if" 98 | version = "1.0.0" 99 | source = "registry+https://github.com/rust-lang/crates.io-index" 100 | checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" 101 | 102 | [[package]] 103 | name = "clap" 104 | version = "4.5.40" 105 | source = "registry+https://github.com/rust-lang/crates.io-index" 106 | checksum = "40b6887a1d8685cebccf115538db5c0efe625ccac9696ad45c409d96566e910f" 107 | dependencies = [ 108 | "clap_builder", 109 | "clap_derive", 110 | ] 111 | 112 | [[package]] 113 | name = "clap_builder" 114 | version = "4.5.40" 115 | source = "registry+https://github.com/rust-lang/crates.io-index" 116 | checksum = "e0c66c08ce9f0c698cbce5c0279d0bb6ac936d8674174fe48f736533b964f59e" 117 | dependencies = [ 118 | "anstream", 119 | "anstyle", 120 | "clap_lex", 121 | "strsim", 122 | ] 123 | 124 | [[package]] 125 | name = "clap_derive" 126 | version = "4.5.40" 127 | source = "registry+https://github.com/rust-lang/crates.io-index" 128 | checksum = "d2c7947ae4cc3d851207c1adb5b5e260ff0cca11446b1d6d1423788e442257ce" 129 | dependencies = [ 130 | "heck 0.5.0", 131 | "proc-macro2", 132 | "quote", 133 | "syn 2.0.65", 134 | ] 135 | 136 | [[package]] 137 | name = "clap_lex" 138 | version = "0.7.5" 139 | source = "registry+https://github.com/rust-lang/crates.io-index" 140 | checksum = "b94f61472cee1439c0b966b47e3aca9ae07e45d070759512cd390ea2bebc6675" 141 | 142 | [[package]] 143 | name = "colorchoice" 144 | version = "1.0.1" 145 | source = "registry+https://github.com/rust-lang/crates.io-index" 146 | checksum = "0b6a852b24ab71dffc585bcb46eaf7959d175cb865a7152e35b348d1b2960422" 147 | 148 | [[package]] 149 | name = "colored" 150 | version = "3.0.0" 151 | source = "registry+https://github.com/rust-lang/crates.io-index" 152 | checksum = "fde0e0ec90c9dfb3b4b1a0891a7dcd0e2bffde2f7efed5fe7c9bb00e5bfb915e" 153 | dependencies = [ 154 | "windows-sys 0.52.0", 155 | ] 156 | 157 | [[package]] 158 | name = "comfy-table" 159 | version = "7.1.1" 160 | source = "registry+https://github.com/rust-lang/crates.io-index" 161 | checksum = "b34115915337defe99b2aff5c2ce6771e5fbc4079f4b506301f5cf394c8452f7" 162 | dependencies = [ 163 | "strum", 164 | "strum_macros", 165 | "unicode-width", 166 | ] 167 | 168 | [[package]] 169 | name = "crossbeam-channel" 170 | version = "0.5.15" 171 | source = "registry+https://github.com/rust-lang/crates.io-index" 172 | checksum = "82b8f8f868b36967f9606790d1903570de9ceaf870a7bf9fbbd3016d636a2cb2" 173 | dependencies = [ 174 | "crossbeam-utils", 175 | ] 176 | 177 | [[package]] 178 | name = "crossbeam-deque" 179 | version = "0.8.5" 180 | source = "registry+https://github.com/rust-lang/crates.io-index" 181 | checksum = "613f8cc01fe9cf1a3eb3d7f488fd2fa8388403e97039e2f73692932e291a770d" 182 | dependencies = [ 183 | "crossbeam-epoch", 184 | "crossbeam-utils", 185 | ] 186 | 187 | [[package]] 188 | name = "crossbeam-epoch" 189 | version = "0.9.18" 190 | source = "registry+https://github.com/rust-lang/crates.io-index" 191 | checksum = "5b82ac4a3c2ca9c3460964f020e1402edd5753411d7737aa39c3714ad1b5420e" 192 | dependencies = [ 193 | "crossbeam-utils", 194 | ] 195 | 196 | [[package]] 197 | name = "crossbeam-utils" 198 | version = "0.8.20" 199 | source = "registry+https://github.com/rust-lang/crates.io-index" 200 | checksum = "22ec99545bb0ed0ea7bb9b8e1e9122ea386ff8a48c0922e43f36d45ab09e0e80" 201 | 202 | [[package]] 203 | name = "crossterm" 204 | version = "0.25.0" 205 | source = "registry+https://github.com/rust-lang/crates.io-index" 206 | checksum = "e64e6c0fbe2c17357405f7c758c1ef960fce08bdfb2c03d88d2a18d7e09c4b67" 207 | dependencies = [ 208 | "bitflags 1.3.2", 209 | "crossterm_winapi", 210 | "libc", 211 | "mio", 212 | "parking_lot", 213 | "signal-hook", 214 | "signal-hook-mio", 215 | "winapi", 216 | ] 217 | 218 | [[package]] 219 | name = "crossterm_winapi" 220 | version = "0.9.1" 221 | source = "registry+https://github.com/rust-lang/crates.io-index" 222 | checksum = "acdd7c62a3665c7f6830a51635d9ac9b23ed385797f70a83bb8bafe9c572ab2b" 223 | dependencies = [ 224 | "winapi", 225 | ] 226 | 227 | [[package]] 228 | name = "ctor" 229 | version = "0.1.26" 230 | source = "registry+https://github.com/rust-lang/crates.io-index" 231 | checksum = "6d2301688392eb071b0bf1a37be05c469d3cc4dbbd95df672fe28ab021e6a096" 232 | dependencies = [ 233 | "quote", 234 | "syn 1.0.109", 235 | ] 236 | 237 | [[package]] 238 | name = "dyn-clone" 239 | version = "1.0.17" 240 | source = "registry+https://github.com/rust-lang/crates.io-index" 241 | checksum = "0d6ef0072f8a535281e4876be788938b528e9a1d43900b82c2569af7da799125" 242 | 243 | [[package]] 244 | name = "either" 245 | version = "1.12.0" 246 | source = "registry+https://github.com/rust-lang/crates.io-index" 247 | checksum = "3dca9240753cf90908d7e4aac30f630662b02aebaa1b58a3cadabdb23385b58b" 248 | 249 | [[package]] 250 | name = "equivalent" 251 | version = "1.0.1" 252 | source = "registry+https://github.com/rust-lang/crates.io-index" 253 | checksum = "5443807d6dff69373d433ab9ef5378ad8df50ca6298caf15de6e52e24aaf54d5" 254 | 255 | [[package]] 256 | name = "errno" 257 | version = "0.3.13" 258 | source = "registry+https://github.com/rust-lang/crates.io-index" 259 | checksum = "778e2ac28f6c47af28e4907f13ffd1e1ddbd400980a9abd7c8df189bf578a5ad" 260 | dependencies = [ 261 | "libc", 262 | "windows-sys 0.52.0", 263 | ] 264 | 265 | [[package]] 266 | name = "fuzzy-matcher" 267 | version = "0.3.7" 268 | source = "registry+https://github.com/rust-lang/crates.io-index" 269 | checksum = "54614a3312934d066701a80f20f15fa3b56d67ac7722b39eea5b4c9dd1d66c94" 270 | dependencies = [ 271 | "thread_local", 272 | ] 273 | 274 | [[package]] 275 | name = "fxhash" 276 | version = "0.2.1" 277 | source = "registry+https://github.com/rust-lang/crates.io-index" 278 | checksum = "c31b6d751ae2c7f11320402d34e41349dd1016f8d5d45e48c4312bc8625af50c" 279 | dependencies = [ 280 | "byteorder", 281 | ] 282 | 283 | [[package]] 284 | name = "hashbrown" 285 | version = "0.14.5" 286 | source = "registry+https://github.com/rust-lang/crates.io-index" 287 | checksum = "e5274423e17b7c9fc20b6e7e208532f9b19825d82dfd615708b70edd83df41f1" 288 | 289 | [[package]] 290 | name = "heck" 291 | version = "0.4.1" 292 | source = "registry+https://github.com/rust-lang/crates.io-index" 293 | checksum = "95505c38b4572b2d910cecb0281560f54b440a19336cbbcb27bf6ce6adc6f5a8" 294 | 295 | [[package]] 296 | name = "heck" 297 | version = "0.5.0" 298 | source = "registry+https://github.com/rust-lang/crates.io-index" 299 | checksum = "2304e00983f87ffb38b55b444b5e3b60a884b5d30c0fca7d82fe33449bbe55ea" 300 | 301 | [[package]] 302 | name = "hunt" 303 | version = "3.0.0" 304 | dependencies = [ 305 | "clap", 306 | "colored", 307 | "crossbeam-channel", 308 | "inquire", 309 | "memchr", 310 | "mimalloc", 311 | "profi", 312 | "rayon", 313 | "rustix", 314 | "thin_str", 315 | "winapi-util", 316 | ] 317 | 318 | [[package]] 319 | name = "indexmap" 320 | version = "2.2.6" 321 | source = "registry+https://github.com/rust-lang/crates.io-index" 322 | checksum = "168fb715dda47215e360912c096649d23d58bf392ac62f73919e831745e40f26" 323 | dependencies = [ 324 | "equivalent", 325 | "hashbrown", 326 | ] 327 | 328 | [[package]] 329 | name = "inquire" 330 | version = "0.7.5" 331 | source = "registry+https://github.com/rust-lang/crates.io-index" 332 | checksum = "0fddf93031af70e75410a2511ec04d49e758ed2f26dad3404a934e0fb45cc12a" 333 | dependencies = [ 334 | "bitflags 2.5.0", 335 | "crossterm", 336 | "dyn-clone", 337 | "fuzzy-matcher", 338 | "fxhash", 339 | "newline-converter", 340 | "once_cell", 341 | "unicode-segmentation", 342 | "unicode-width", 343 | ] 344 | 345 | [[package]] 346 | name = "is_terminal_polyfill" 347 | version = "1.70.0" 348 | source = "registry+https://github.com/rust-lang/crates.io-index" 349 | checksum = "f8478577c03552c21db0e2724ffb8986a5ce7af88107e6be5d2ee6e158c12800" 350 | 351 | [[package]] 352 | name = "js-sys" 353 | version = "0.3.69" 354 | source = "registry+https://github.com/rust-lang/crates.io-index" 355 | checksum = "29c15563dc2726973df627357ce0c9ddddbea194836909d655df6a75d2cf296d" 356 | dependencies = [ 357 | "wasm-bindgen", 358 | ] 359 | 360 | [[package]] 361 | name = "libc" 362 | version = "0.2.174" 363 | source = "registry+https://github.com/rust-lang/crates.io-index" 364 | checksum = "1171693293099992e19cddea4e8b849964e9846f4acee11b3948bcc337be8776" 365 | 366 | [[package]] 367 | name = "libmimalloc-sys" 368 | version = "0.1.43" 369 | source = "registry+https://github.com/rust-lang/crates.io-index" 370 | checksum = "bf88cd67e9de251c1781dbe2f641a1a3ad66eaae831b8a2c38fbdc5ddae16d4d" 371 | dependencies = [ 372 | "cc", 373 | "libc", 374 | ] 375 | 376 | [[package]] 377 | name = "linux-raw-sys" 378 | version = "0.9.4" 379 | source = "registry+https://github.com/rust-lang/crates.io-index" 380 | checksum = "cd945864f07fe9f5371a27ad7b52a172b4b499999f1d97574c9fa68373937e12" 381 | 382 | [[package]] 383 | name = "lock_api" 384 | version = "0.4.12" 385 | source = "registry+https://github.com/rust-lang/crates.io-index" 386 | checksum = "07af8b9cdd281b7915f413fa73f29ebd5d55d0d3f0155584dade1ff18cea1b17" 387 | dependencies = [ 388 | "autocfg", 389 | "scopeguard", 390 | ] 391 | 392 | [[package]] 393 | name = "log" 394 | version = "0.4.21" 395 | source = "registry+https://github.com/rust-lang/crates.io-index" 396 | checksum = "90ed8c1e510134f979dbc4f070f87d4313098b704861a105fe34231c70a3901c" 397 | 398 | [[package]] 399 | name = "memchr" 400 | version = "2.7.5" 401 | source = "registry+https://github.com/rust-lang/crates.io-index" 402 | checksum = "32a282da65faaf38286cf3be983213fcf1d2e2a58700e808f83f4ea9a4804bc0" 403 | 404 | [[package]] 405 | name = "mimalloc" 406 | version = "0.1.47" 407 | source = "registry+https://github.com/rust-lang/crates.io-index" 408 | checksum = "b1791cbe101e95af5764f06f20f6760521f7158f69dbf9d6baf941ee1bf6bc40" 409 | dependencies = [ 410 | "libmimalloc-sys", 411 | ] 412 | 413 | [[package]] 414 | name = "minstant" 415 | version = "0.1.7" 416 | source = "registry+https://github.com/rust-lang/crates.io-index" 417 | checksum = "1fb9b5c752f145ac5046bccc3c4f62892e3c950c1d1eab80c5949cd68a2078db" 418 | dependencies = [ 419 | "ctor", 420 | "web-time", 421 | ] 422 | 423 | [[package]] 424 | name = "mio" 425 | version = "0.8.11" 426 | source = "registry+https://github.com/rust-lang/crates.io-index" 427 | checksum = "a4a650543ca06a924e8b371db273b2756685faae30f8487da1b56505a8f78b0c" 428 | dependencies = [ 429 | "libc", 430 | "log", 431 | "wasi", 432 | "windows-sys 0.48.0", 433 | ] 434 | 435 | [[package]] 436 | name = "newline-converter" 437 | version = "0.3.0" 438 | source = "registry+https://github.com/rust-lang/crates.io-index" 439 | checksum = "47b6b097ecb1cbfed438542d16e84fd7ad9b0c76c8a65b7f9039212a3d14dc7f" 440 | dependencies = [ 441 | "unicode-segmentation", 442 | ] 443 | 444 | [[package]] 445 | name = "once_cell" 446 | version = "1.19.0" 447 | source = "registry+https://github.com/rust-lang/crates.io-index" 448 | checksum = "3fdb12b2476b595f9358c5161aa467c2438859caa136dec86c26fdd2efe17b92" 449 | 450 | [[package]] 451 | name = "parking_lot" 452 | version = "0.12.2" 453 | source = "registry+https://github.com/rust-lang/crates.io-index" 454 | checksum = "7e4af0ca4f6caed20e900d564c242b8e5d4903fdacf31d3daf527b66fe6f42fb" 455 | dependencies = [ 456 | "lock_api", 457 | "parking_lot_core", 458 | ] 459 | 460 | [[package]] 461 | name = "parking_lot_core" 462 | version = "0.9.10" 463 | source = "registry+https://github.com/rust-lang/crates.io-index" 464 | checksum = "1e401f977ab385c9e4e3ab30627d6f26d00e2c73eef317493c4ec6d468726cf8" 465 | dependencies = [ 466 | "cfg-if", 467 | "libc", 468 | "redox_syscall", 469 | "smallvec", 470 | "windows-targets 0.52.5", 471 | ] 472 | 473 | [[package]] 474 | name = "proc-macro-crate" 475 | version = "3.1.0" 476 | source = "registry+https://github.com/rust-lang/crates.io-index" 477 | checksum = "6d37c51ca738a55da99dc0c4a34860fd675453b8b36209178c2249bb13651284" 478 | dependencies = [ 479 | "toml_edit", 480 | ] 481 | 482 | [[package]] 483 | name = "proc-macro2" 484 | version = "1.0.83" 485 | source = "registry+https://github.com/rust-lang/crates.io-index" 486 | checksum = "0b33eb56c327dec362a9e55b3ad14f9d2f0904fb5a5b03b513ab5465399e9f43" 487 | dependencies = [ 488 | "unicode-ident", 489 | ] 490 | 491 | [[package]] 492 | name = "profi" 493 | version = "0.1.2" 494 | source = "registry+https://github.com/rust-lang/crates.io-index" 495 | checksum = "41a7771fea2a42f1d0df39c3c9a742284b56166670393884fca87eb56d43efc0" 496 | dependencies = [ 497 | "beef", 498 | "comfy-table", 499 | "indexmap", 500 | "minstant", 501 | "profi-attributes", 502 | "rayon", 503 | ] 504 | 505 | [[package]] 506 | name = "profi-attributes" 507 | version = "0.1.2" 508 | source = "registry+https://github.com/rust-lang/crates.io-index" 509 | checksum = "725c1a2cf15516eb45afb27f7d86889132299f5756e245043c046c7a34126cab" 510 | dependencies = [ 511 | "proc-macro-crate", 512 | ] 513 | 514 | [[package]] 515 | name = "quote" 516 | version = "1.0.36" 517 | source = "registry+https://github.com/rust-lang/crates.io-index" 518 | checksum = "0fa76aaf39101c457836aec0ce2316dbdc3ab723cdda1c6bd4e6ad4208acaca7" 519 | dependencies = [ 520 | "proc-macro2", 521 | ] 522 | 523 | [[package]] 524 | name = "rayon" 525 | version = "1.10.0" 526 | source = "registry+https://github.com/rust-lang/crates.io-index" 527 | checksum = "b418a60154510ca1a002a752ca9714984e21e4241e804d32555251faf8b78ffa" 528 | dependencies = [ 529 | "either", 530 | "rayon-core", 531 | ] 532 | 533 | [[package]] 534 | name = "rayon-core" 535 | version = "1.12.1" 536 | source = "registry+https://github.com/rust-lang/crates.io-index" 537 | checksum = "1465873a3dfdaa8ae7cb14b4383657caab0b3e8a0aa9ae8e04b044854c8dfce2" 538 | dependencies = [ 539 | "crossbeam-deque", 540 | "crossbeam-utils", 541 | ] 542 | 543 | [[package]] 544 | name = "redox_syscall" 545 | version = "0.5.1" 546 | source = "registry+https://github.com/rust-lang/crates.io-index" 547 | checksum = "469052894dcb553421e483e4209ee581a45100d31b4018de03e5a7ad86374a7e" 548 | dependencies = [ 549 | "bitflags 2.5.0", 550 | ] 551 | 552 | [[package]] 553 | name = "rustix" 554 | version = "1.0.7" 555 | source = "registry+https://github.com/rust-lang/crates.io-index" 556 | checksum = "c71e83d6afe7ff64890ec6b71d6a69bb8a610ab78ce364b3352876bb4c801266" 557 | dependencies = [ 558 | "bitflags 2.5.0", 559 | "errno", 560 | "libc", 561 | "linux-raw-sys", 562 | "windows-sys 0.52.0", 563 | ] 564 | 565 | [[package]] 566 | name = "rustversion" 567 | version = "1.0.17" 568 | source = "registry+https://github.com/rust-lang/crates.io-index" 569 | checksum = "955d28af4278de8121b7ebeb796b6a45735dc01436d898801014aced2773a3d6" 570 | 571 | [[package]] 572 | name = "scopeguard" 573 | version = "1.2.0" 574 | source = "registry+https://github.com/rust-lang/crates.io-index" 575 | checksum = "94143f37725109f92c262ed2cf5e59bce7498c01bcc1502d7b9afe439a4e9f49" 576 | 577 | [[package]] 578 | name = "signal-hook" 579 | version = "0.3.17" 580 | source = "registry+https://github.com/rust-lang/crates.io-index" 581 | checksum = "8621587d4798caf8eb44879d42e56b9a93ea5dcd315a6487c357130095b62801" 582 | dependencies = [ 583 | "libc", 584 | "signal-hook-registry", 585 | ] 586 | 587 | [[package]] 588 | name = "signal-hook-mio" 589 | version = "0.2.3" 590 | source = "registry+https://github.com/rust-lang/crates.io-index" 591 | checksum = "29ad2e15f37ec9a6cc544097b78a1ec90001e9f71b81338ca39f430adaca99af" 592 | dependencies = [ 593 | "libc", 594 | "mio", 595 | "signal-hook", 596 | ] 597 | 598 | [[package]] 599 | name = "signal-hook-registry" 600 | version = "1.4.2" 601 | source = "registry+https://github.com/rust-lang/crates.io-index" 602 | checksum = "a9e9e0b4211b72e7b8b6e85c807d36c212bdb33ea8587f7569562a84df5465b1" 603 | dependencies = [ 604 | "libc", 605 | ] 606 | 607 | [[package]] 608 | name = "smallvec" 609 | version = "1.13.2" 610 | source = "registry+https://github.com/rust-lang/crates.io-index" 611 | checksum = "3c5e1a9a646d36c3599cd173a41282daf47c44583ad367b8e6837255952e5c67" 612 | 613 | [[package]] 614 | name = "strsim" 615 | version = "0.11.1" 616 | source = "registry+https://github.com/rust-lang/crates.io-index" 617 | checksum = "7da8b5736845d9f2fcb837ea5d9e2628564b3b043a70948a3f0b778838c5fb4f" 618 | 619 | [[package]] 620 | name = "strum" 621 | version = "0.26.2" 622 | source = "registry+https://github.com/rust-lang/crates.io-index" 623 | checksum = "5d8cec3501a5194c432b2b7976db6b7d10ec95c253208b45f83f7136aa985e29" 624 | 625 | [[package]] 626 | name = "strum_macros" 627 | version = "0.26.2" 628 | source = "registry+https://github.com/rust-lang/crates.io-index" 629 | checksum = "c6cf59daf282c0a494ba14fd21610a0325f9f90ec9d1231dea26bcb1d696c946" 630 | dependencies = [ 631 | "heck 0.4.1", 632 | "proc-macro2", 633 | "quote", 634 | "rustversion", 635 | "syn 2.0.65", 636 | ] 637 | 638 | [[package]] 639 | name = "syn" 640 | version = "1.0.109" 641 | source = "registry+https://github.com/rust-lang/crates.io-index" 642 | checksum = "72b64191b275b66ffe2469e8af2c1cfe3bafa67b529ead792a6d0160888b4237" 643 | dependencies = [ 644 | "proc-macro2", 645 | "quote", 646 | "unicode-ident", 647 | ] 648 | 649 | [[package]] 650 | name = "syn" 651 | version = "2.0.65" 652 | source = "registry+https://github.com/rust-lang/crates.io-index" 653 | checksum = "d2863d96a84c6439701d7a38f9de935ec562c8832cc55d1dde0f513b52fad106" 654 | dependencies = [ 655 | "proc-macro2", 656 | "quote", 657 | "unicode-ident", 658 | ] 659 | 660 | [[package]] 661 | name = "thin_str" 662 | version = "0.1.0" 663 | source = "registry+https://github.com/rust-lang/crates.io-index" 664 | checksum = "be9d479371ac7a8e00f077b47e26db313447fa59ca276ad73c4716975f3895d4" 665 | 666 | [[package]] 667 | name = "thread_local" 668 | version = "1.1.8" 669 | source = "registry+https://github.com/rust-lang/crates.io-index" 670 | checksum = "8b9ef9bad013ada3808854ceac7b46812a6465ba368859a37e2100283d2d719c" 671 | dependencies = [ 672 | "cfg-if", 673 | "once_cell", 674 | ] 675 | 676 | [[package]] 677 | name = "toml_datetime" 678 | version = "0.6.6" 679 | source = "registry+https://github.com/rust-lang/crates.io-index" 680 | checksum = "4badfd56924ae69bcc9039335b2e017639ce3f9b001c393c1b2d1ef846ce2cbf" 681 | 682 | [[package]] 683 | name = "toml_edit" 684 | version = "0.21.1" 685 | source = "registry+https://github.com/rust-lang/crates.io-index" 686 | checksum = "6a8534fd7f78b5405e860340ad6575217ce99f38d4d5c8f2442cb5ecb50090e1" 687 | dependencies = [ 688 | "indexmap", 689 | "toml_datetime", 690 | "winnow", 691 | ] 692 | 693 | [[package]] 694 | name = "unicode-ident" 695 | version = "1.0.12" 696 | source = "registry+https://github.com/rust-lang/crates.io-index" 697 | checksum = "3354b9ac3fae1ff6755cb6db53683adb661634f67557942dea4facebec0fee4b" 698 | 699 | [[package]] 700 | name = "unicode-segmentation" 701 | version = "1.11.0" 702 | source = "registry+https://github.com/rust-lang/crates.io-index" 703 | checksum = "d4c87d22b6e3f4a18d4d40ef354e97c90fcb14dd91d7dc0aa9d8a1172ebf7202" 704 | 705 | [[package]] 706 | name = "unicode-width" 707 | version = "0.1.12" 708 | source = "registry+https://github.com/rust-lang/crates.io-index" 709 | checksum = "68f5e5f3158ecfd4b8ff6fe086db7c8467a2dfdac97fe420f2b7c4aa97af66d6" 710 | 711 | [[package]] 712 | name = "utf8parse" 713 | version = "0.2.1" 714 | source = "registry+https://github.com/rust-lang/crates.io-index" 715 | checksum = "711b9620af191e0cdc7468a8d14e709c3dcdb115b36f838e601583af800a370a" 716 | 717 | [[package]] 718 | name = "wasi" 719 | version = "0.11.0+wasi-snapshot-preview1" 720 | source = "registry+https://github.com/rust-lang/crates.io-index" 721 | checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423" 722 | 723 | [[package]] 724 | name = "wasm-bindgen" 725 | version = "0.2.92" 726 | source = "registry+https://github.com/rust-lang/crates.io-index" 727 | checksum = "4be2531df63900aeb2bca0daaaddec08491ee64ceecbee5076636a3b026795a8" 728 | dependencies = [ 729 | "cfg-if", 730 | "wasm-bindgen-macro", 731 | ] 732 | 733 | [[package]] 734 | name = "wasm-bindgen-backend" 735 | version = "0.2.92" 736 | source = "registry+https://github.com/rust-lang/crates.io-index" 737 | checksum = "614d787b966d3989fa7bb98a654e369c762374fd3213d212cfc0251257e747da" 738 | dependencies = [ 739 | "bumpalo", 740 | "log", 741 | "once_cell", 742 | "proc-macro2", 743 | "quote", 744 | "syn 2.0.65", 745 | "wasm-bindgen-shared", 746 | ] 747 | 748 | [[package]] 749 | name = "wasm-bindgen-macro" 750 | version = "0.2.92" 751 | source = "registry+https://github.com/rust-lang/crates.io-index" 752 | checksum = "a1f8823de937b71b9460c0c34e25f3da88250760bec0ebac694b49997550d726" 753 | dependencies = [ 754 | "quote", 755 | "wasm-bindgen-macro-support", 756 | ] 757 | 758 | [[package]] 759 | name = "wasm-bindgen-macro-support" 760 | version = "0.2.92" 761 | source = "registry+https://github.com/rust-lang/crates.io-index" 762 | checksum = "e94f17b526d0a461a191c78ea52bbce64071ed5c04c9ffe424dcb38f74171bb7" 763 | dependencies = [ 764 | "proc-macro2", 765 | "quote", 766 | "syn 2.0.65", 767 | "wasm-bindgen-backend", 768 | "wasm-bindgen-shared", 769 | ] 770 | 771 | [[package]] 772 | name = "wasm-bindgen-shared" 773 | version = "0.2.92" 774 | source = "registry+https://github.com/rust-lang/crates.io-index" 775 | checksum = "af190c94f2773fdb3729c55b007a722abb5384da03bc0986df4c289bf5567e96" 776 | 777 | [[package]] 778 | name = "web-time" 779 | version = "1.1.0" 780 | source = "registry+https://github.com/rust-lang/crates.io-index" 781 | checksum = "5a6580f308b1fad9207618087a65c04e7a10bc77e02c8e84e9b00dd4b12fa0bb" 782 | dependencies = [ 783 | "js-sys", 784 | "wasm-bindgen", 785 | ] 786 | 787 | [[package]] 788 | name = "winapi" 789 | version = "0.3.9" 790 | source = "registry+https://github.com/rust-lang/crates.io-index" 791 | checksum = "5c839a674fcd7a98952e593242ea400abe93992746761e38641405d28b00f419" 792 | dependencies = [ 793 | "winapi-i686-pc-windows-gnu", 794 | "winapi-x86_64-pc-windows-gnu", 795 | ] 796 | 797 | [[package]] 798 | name = "winapi-i686-pc-windows-gnu" 799 | version = "0.4.0" 800 | source = "registry+https://github.com/rust-lang/crates.io-index" 801 | checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6" 802 | 803 | [[package]] 804 | name = "winapi-util" 805 | version = "0.1.9" 806 | source = "registry+https://github.com/rust-lang/crates.io-index" 807 | checksum = "cf221c93e13a30d793f7645a0e7762c55d169dbb0a49671918a2319d289b10bb" 808 | dependencies = [ 809 | "windows-sys 0.52.0", 810 | ] 811 | 812 | [[package]] 813 | name = "winapi-x86_64-pc-windows-gnu" 814 | version = "0.4.0" 815 | source = "registry+https://github.com/rust-lang/crates.io-index" 816 | checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" 817 | 818 | [[package]] 819 | name = "windows-sys" 820 | version = "0.48.0" 821 | source = "registry+https://github.com/rust-lang/crates.io-index" 822 | checksum = "677d2418bec65e3338edb076e806bc1ec15693c5d0104683f2efe857f61056a9" 823 | dependencies = [ 824 | "windows-targets 0.48.5", 825 | ] 826 | 827 | [[package]] 828 | name = "windows-sys" 829 | version = "0.52.0" 830 | source = "registry+https://github.com/rust-lang/crates.io-index" 831 | checksum = "282be5f36a8ce781fad8c8ae18fa3f9beff57ec1b52cb3de0789201425d9a33d" 832 | dependencies = [ 833 | "windows-targets 0.52.5", 834 | ] 835 | 836 | [[package]] 837 | name = "windows-targets" 838 | version = "0.48.5" 839 | source = "registry+https://github.com/rust-lang/crates.io-index" 840 | checksum = "9a2fa6e2155d7247be68c096456083145c183cbbbc2764150dda45a87197940c" 841 | dependencies = [ 842 | "windows_aarch64_gnullvm 0.48.5", 843 | "windows_aarch64_msvc 0.48.5", 844 | "windows_i686_gnu 0.48.5", 845 | "windows_i686_msvc 0.48.5", 846 | "windows_x86_64_gnu 0.48.5", 847 | "windows_x86_64_gnullvm 0.48.5", 848 | "windows_x86_64_msvc 0.48.5", 849 | ] 850 | 851 | [[package]] 852 | name = "windows-targets" 853 | version = "0.52.5" 854 | source = "registry+https://github.com/rust-lang/crates.io-index" 855 | checksum = "6f0713a46559409d202e70e28227288446bf7841d3211583a4b53e3f6d96e7eb" 856 | dependencies = [ 857 | "windows_aarch64_gnullvm 0.52.5", 858 | "windows_aarch64_msvc 0.52.5", 859 | "windows_i686_gnu 0.52.5", 860 | "windows_i686_gnullvm", 861 | "windows_i686_msvc 0.52.5", 862 | "windows_x86_64_gnu 0.52.5", 863 | "windows_x86_64_gnullvm 0.52.5", 864 | "windows_x86_64_msvc 0.52.5", 865 | ] 866 | 867 | [[package]] 868 | name = "windows_aarch64_gnullvm" 869 | version = "0.48.5" 870 | source = "registry+https://github.com/rust-lang/crates.io-index" 871 | checksum = "2b38e32f0abccf9987a4e3079dfb67dcd799fb61361e53e2882c3cbaf0d905d8" 872 | 873 | [[package]] 874 | name = "windows_aarch64_gnullvm" 875 | version = "0.52.5" 876 | source = "registry+https://github.com/rust-lang/crates.io-index" 877 | checksum = "7088eed71e8b8dda258ecc8bac5fb1153c5cffaf2578fc8ff5d61e23578d3263" 878 | 879 | [[package]] 880 | name = "windows_aarch64_msvc" 881 | version = "0.48.5" 882 | source = "registry+https://github.com/rust-lang/crates.io-index" 883 | checksum = "dc35310971f3b2dbbf3f0690a219f40e2d9afcf64f9ab7cc1be722937c26b4bc" 884 | 885 | [[package]] 886 | name = "windows_aarch64_msvc" 887 | version = "0.52.5" 888 | source = "registry+https://github.com/rust-lang/crates.io-index" 889 | checksum = "9985fd1504e250c615ca5f281c3f7a6da76213ebd5ccc9561496568a2752afb6" 890 | 891 | [[package]] 892 | name = "windows_i686_gnu" 893 | version = "0.48.5" 894 | source = "registry+https://github.com/rust-lang/crates.io-index" 895 | checksum = "a75915e7def60c94dcef72200b9a8e58e5091744960da64ec734a6c6e9b3743e" 896 | 897 | [[package]] 898 | name = "windows_i686_gnu" 899 | version = "0.52.5" 900 | source = "registry+https://github.com/rust-lang/crates.io-index" 901 | checksum = "88ba073cf16d5372720ec942a8ccbf61626074c6d4dd2e745299726ce8b89670" 902 | 903 | [[package]] 904 | name = "windows_i686_gnullvm" 905 | version = "0.52.5" 906 | source = "registry+https://github.com/rust-lang/crates.io-index" 907 | checksum = "87f4261229030a858f36b459e748ae97545d6f1ec60e5e0d6a3d32e0dc232ee9" 908 | 909 | [[package]] 910 | name = "windows_i686_msvc" 911 | version = "0.48.5" 912 | source = "registry+https://github.com/rust-lang/crates.io-index" 913 | checksum = "8f55c233f70c4b27f66c523580f78f1004e8b5a8b659e05a4eb49d4166cca406" 914 | 915 | [[package]] 916 | name = "windows_i686_msvc" 917 | version = "0.52.5" 918 | source = "registry+https://github.com/rust-lang/crates.io-index" 919 | checksum = "db3c2bf3d13d5b658be73463284eaf12830ac9a26a90c717b7f771dfe97487bf" 920 | 921 | [[package]] 922 | name = "windows_x86_64_gnu" 923 | version = "0.48.5" 924 | source = "registry+https://github.com/rust-lang/crates.io-index" 925 | checksum = "53d40abd2583d23e4718fddf1ebec84dbff8381c07cae67ff7768bbf19c6718e" 926 | 927 | [[package]] 928 | name = "windows_x86_64_gnu" 929 | version = "0.52.5" 930 | source = "registry+https://github.com/rust-lang/crates.io-index" 931 | checksum = "4e4246f76bdeff09eb48875a0fd3e2af6aada79d409d33011886d3e1581517d9" 932 | 933 | [[package]] 934 | name = "windows_x86_64_gnullvm" 935 | version = "0.48.5" 936 | source = "registry+https://github.com/rust-lang/crates.io-index" 937 | checksum = "0b7b52767868a23d5bab768e390dc5f5c55825b6d30b86c844ff2dc7414044cc" 938 | 939 | [[package]] 940 | name = "windows_x86_64_gnullvm" 941 | version = "0.52.5" 942 | source = "registry+https://github.com/rust-lang/crates.io-index" 943 | checksum = "852298e482cd67c356ddd9570386e2862b5673c85bd5f88df9ab6802b334c596" 944 | 945 | [[package]] 946 | name = "windows_x86_64_msvc" 947 | version = "0.48.5" 948 | source = "registry+https://github.com/rust-lang/crates.io-index" 949 | checksum = "ed94fce61571a4006852b7389a063ab983c02eb1bb37b47f8272ce92d06d9538" 950 | 951 | [[package]] 952 | name = "windows_x86_64_msvc" 953 | version = "0.52.5" 954 | source = "registry+https://github.com/rust-lang/crates.io-index" 955 | checksum = "bec47e5bfd1bff0eeaf6d8b485cc1074891a197ab4225d504cb7a1ab88b02bf0" 956 | 957 | [[package]] 958 | name = "winnow" 959 | version = "0.5.40" 960 | source = "registry+https://github.com/rust-lang/crates.io-index" 961 | checksum = "f593a95398737aeed53e489c785df13f3618e41dbcd6718c6addbf1395aa6876" 962 | dependencies = [ 963 | "memchr", 964 | ] 965 | --------------------------------------------------------------------------------