├── .gitignore ├── .github ├── FUNDING.yml ├── dependabot.yml └── workflows │ ├── stale.yml │ └── ci.yml ├── assets ├── if-let.png ├── if-let-white.png ├── if-let-flowgraph.svg └── logo.svg ├── examples ├── range.rs ├── if_let.rs ├── range_inclusive.rs ├── error-cases │ ├── closures.rs │ └── threads.rs ├── file.rs ├── traits.rs └── debug.rs ├── CONTRIBUTING.md ├── src ├── tmpfile.rs ├── format.rs ├── bin │ └── inspect │ │ └── main.rs ├── errors.rs ├── diff.rs ├── config.rs ├── hir.rs ├── comment.rs └── lib.rs ├── Makefile ├── Cargo.toml ├── LICENSE-MIT ├── CHANGELOG.md ├── README.md ├── LICENSE-APACHE └── Cargo.lock /.gitignore: -------------------------------------------------------------------------------- 1 | /target 2 | **/*.rs.bk 3 | -------------------------------------------------------------------------------- /.github/FUNDING.yml: -------------------------------------------------------------------------------- 1 | github: mre 2 | patreon: hellorust 3 | -------------------------------------------------------------------------------- /assets/if-let.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mre/cargo-inspect/HEAD/assets/if-let.png -------------------------------------------------------------------------------- /assets/if-let-white.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mre/cargo-inspect/HEAD/assets/if-let-white.png -------------------------------------------------------------------------------- /examples/range.rs: -------------------------------------------------------------------------------- 1 | fn main() { 2 | for _n in 1..3 { 3 | // Do something with n 4 | } 5 | } 6 | -------------------------------------------------------------------------------- /examples/if_let.rs: -------------------------------------------------------------------------------- 1 | fn main() { 2 | if let Some(_x) = Some(1) { 3 | // Do something with x 4 | } 5 | } 6 | -------------------------------------------------------------------------------- /examples/range_inclusive.rs: -------------------------------------------------------------------------------- 1 | fn main() { 2 | for _n in 1..=3 { 3 | // Do something with n 4 | } 5 | } 6 | -------------------------------------------------------------------------------- /examples/error-cases/closures.rs: -------------------------------------------------------------------------------- 1 | // Closures won't be desugared by default 2 | fn main() { 3 | let closure = |i: i32| i * i; 4 | } 5 | -------------------------------------------------------------------------------- /examples/file.rs: -------------------------------------------------------------------------------- 1 | use std::fs::File; 2 | use std::io::Error; 3 | 4 | fn main() -> Result<(), Error> { 5 | let _file = File::open("file.txt")?; 6 | Ok(()) 7 | } 8 | -------------------------------------------------------------------------------- /.github/dependabot.yml: -------------------------------------------------------------------------------- 1 | version: 2 2 | updates: 3 | - package-ecosystem: cargo 4 | directory: "/" 5 | schedule: 6 | interval: daily 7 | time: "04:00" 8 | open-pull-requests-limit: 10 9 | -------------------------------------------------------------------------------- /examples/traits.rs: -------------------------------------------------------------------------------- 1 | #[derive(PartialEq, Debug)] 2 | struct Shoe { 3 | size: u32, 4 | style: String, 5 | } 6 | 7 | fn main() { 8 | let shoe1 = Shoe { size: 44, style: String::from("sneaker") }; 9 | let shoe2 = Shoe { size: 44, style: String::from("sandal") }; 10 | assert_eq!(shoe1, shoe2); 11 | } -------------------------------------------------------------------------------- /CONTRIBUTING.md: -------------------------------------------------------------------------------- 1 | # Contributing 2 | 3 | Thanks for considering to contribute! :rainbow: 4 | 5 | As of now, everything is in flux, so I suggest you just look at the [issue tracker](https://github.com/mre/cargo-inspect/issues) 6 | and pick a task that you'd like to work on. 7 | 8 | I will try to provide mentorship as much as I can. 9 | -------------------------------------------------------------------------------- /examples/debug.rs: -------------------------------------------------------------------------------- 1 | #[derive(Debug)] 2 | struct Point { 3 | x: i32, 4 | y: i32, 5 | } 6 | 7 | fn main() { 8 | let a = Point {x: 10, y:10}; 9 | let b = Point {x: 5, y:16}; 10 | 11 | println!("a.x: {} a.y: {}", a.x, a.y); 12 | println!("b.x: {} b.y: {}", b.x, b.y); 13 | 14 | // TODO Do something more itneresting with these two refs 15 | } 16 | -------------------------------------------------------------------------------- /src/tmpfile.rs: -------------------------------------------------------------------------------- 1 | pub use crate::errors::InspectError; 2 | use std::fs::File; 3 | use std::path::PathBuf; 4 | use tempfile::tempdir; 5 | 6 | /// Create a temporary file 7 | pub fn tmpfile() -> Result { 8 | let tmp_path = tempdir()?.into_path(); 9 | let file_path = tmp_path.join("temp.rs"); 10 | File::create(&file_path)?; 11 | Ok(file_path) 12 | } 13 | -------------------------------------------------------------------------------- /examples/error-cases/threads.rs: -------------------------------------------------------------------------------- 1 | /// Comments in threads won't appear at the expected position 2 | /// See for yourself by running `cargo inspect` on this file. 3 | 4 | use std::thread; 5 | use std::time::Duration; 6 | 7 | fn main() { 8 | thread::spawn(|| { 9 | // Above for loop 10 | for i in 1..10 { 11 | // Above println 12 | println!("hi number {} from the spawned thread!", i); 13 | 14 | // Above thread::sleep 15 | thread::sleep(Duration::from_millis(1)); 16 | } 17 | }); 18 | } 19 | -------------------------------------------------------------------------------- /Makefile: -------------------------------------------------------------------------------- 1 | # Needed SHELL since I'm using zsh 2 | SHELL := /bin/bash 3 | 4 | .PHONY: help 5 | help: ## This help message 6 | @echo -e "$$(grep -hE '^\S+:.*##' $(MAKEFILE_LIST) | sed -e 's/:.*##\s*/:/' -e 's/^\(.\+\):\(.*\)/\\x1b[36m\1\\x1b[m:\2/' | column -c2 -t -s :)" 7 | 8 | .PHONY: check 9 | check: ## Check project 10 | cargo check 11 | 12 | .PHONY: build 13 | build: ## Build project 14 | cargo build 15 | 16 | .PHONY: install 17 | install: ## Install cargo-inspect on the local machine 18 | cargo install --force --path . 19 | 20 | .PHONY: test 21 | test: ## Run tests 22 | cargo test 23 | 24 | .PHONY: publish 25 | publish: ## Publish new version of cargo-inspect 26 | cargo publish -------------------------------------------------------------------------------- /.github/workflows/stale.yml: -------------------------------------------------------------------------------- 1 | name: "Close stale issues" 2 | on: 3 | schedule: 4 | - cron: "0 4 * * *" 5 | 6 | jobs: 7 | stale: 8 | runs-on: ubuntu-latest 9 | steps: 10 | - uses: actions/stale@v1.1.0 11 | with: 12 | repo-token: ${{ secrets.GITHUB_TOKEN }} 13 | stale-issue-message: > 14 | This issue has been automatically marked as stale because it has not had 15 | recent activity in the last 60 days. It will be closed in 7 days if no further activity occurs. 16 | Thank you for your contributions. 17 | days-before-stale: 60 18 | days-before-close: 7 19 | stale-issue-label: stale 20 | -------------------------------------------------------------------------------- /.github/workflows/ci.yml: -------------------------------------------------------------------------------- 1 | name: Rust 2 | 3 | on: 4 | release: 5 | types: [created] 6 | push: 7 | branches: [ master ] 8 | pull_request: 9 | branches: [ master ] 10 | 11 | env: 12 | CARGO_TERM_COLOR: always 13 | 14 | jobs: 15 | build: 16 | runs-on: ubuntu-latest 17 | 18 | steps: 19 | - uses: actions/checkout@v2 20 | - name: Build 21 | run: cargo build --verbose 22 | - name: Run tests 23 | run: cargo test --verbose 24 | 25 | rust-publish: 26 | if: startsWith(github.ref, 'refs/tags/') 27 | needs: build 28 | runs-on: ubuntu-latest 29 | steps: 30 | - uses: actions/checkout@v1 31 | 32 | - name: Publish on crates.io 33 | run: | 34 | cargo login ${{ secrets.CARGO }} 35 | cargo publish 36 | 37 | -------------------------------------------------------------------------------- /Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | authors = [ 3 | "Matthias Endler ", 4 | ] 5 | categories = [ 6 | "development-tools", 7 | "development-tools::cargo-plugins", 8 | ] 9 | description = "This extends Cargo to allow you to desugar your Rust code and see what happens behind the curtains." 10 | documentation = "https://github.com/mre/cargo-inspect/blob/master/README.md" 11 | edition = "2018" 12 | homepage = "https://github.com/mre/cargo-inspect" 13 | keywords = [ 14 | "cargo", 15 | "cargo-subcommand", 16 | "cli", 17 | "unpretty", 18 | "inspect", 19 | ] 20 | license = "Apache-2.0/MIT" 21 | name = "cargo-inspect" 22 | readme = "README.md" 23 | repository = "https://github.com/mre/cargo-inspect" 24 | version = "0.10.3" 25 | 26 | [[bin]] 27 | name = "cargo-inspect" 28 | path = "src/bin/inspect/main.rs" 29 | 30 | [dependencies] 31 | failure = "0.1.8" 32 | structopt = "0.3.26" 33 | syntect = "4.7.1" 34 | prettyprint = "0.8.1" 35 | indicatif = "0.15.0" 36 | tempfile = "3.3.0" 37 | log = "0.4.17" 38 | env_logger = "0.9.1" 39 | difference = "2.0.0" 40 | ansi_term = "0.12.1" 41 | -------------------------------------------------------------------------------- /LICENSE-MIT: -------------------------------------------------------------------------------- 1 | Copyright (c) 2018 The cargo-inspect Developers 2 | 3 | Permission is hereby granted, free of charge, to any person obtaining a copy 4 | of this software and associated documentation files (the "Software"), to deal 5 | in the Software without restriction, including without limitation the rights 6 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 7 | copies of the Software, and to permit persons to whom the Software is 8 | furnished to do so, subject to the following conditions: 9 | 10 | The above copyright notice and this permission notice shall be included in all 11 | copies or substantial portions of the Software. 12 | 13 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 14 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 15 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 16 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 17 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 18 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 19 | SOFTWARE. 20 | -------------------------------------------------------------------------------- /src/format.rs: -------------------------------------------------------------------------------- 1 | use crate::errors::InspectError; 2 | use std::io::Write; 3 | use std::process::Command; 4 | use std::process::Stdio; 5 | 6 | use log::debug; 7 | 8 | // TODO: This should not call rustfmt from the commandline. 9 | // Instead, we should use it as a library. Oh well. 10 | pub fn format(input: &str) -> Result { 11 | let mut builder = Command::new("rustfmt"); 12 | builder 13 | .arg("--emit") 14 | .arg("stdout") 15 | .stdin(Stdio::piped()) 16 | .stderr(Stdio::piped()) 17 | .stdout(Stdio::piped()); 18 | 19 | let mut cmd = builder.spawn()?; 20 | 21 | cmd.stdin 22 | .as_mut() 23 | .ok_or_else(|| InspectError::Rustfmt("Cannot pipe input".to_string()))? 24 | .write_all(input.as_bytes())?; 25 | 26 | let output = cmd.wait_with_output().expect("Failed to read stdout"); 27 | 28 | // Only log formatting errors when `RUST_LOG=debug` is set. 29 | // If the formatting failed, we print out the plain text. 30 | if !output.stderr.is_empty() { 31 | debug!("Formatting failed with following errors:"); 32 | use std::io::BufRead; 33 | for line in output.stderr.lines() { 34 | let line = line?; 35 | debug!("{}", line); 36 | } 37 | } 38 | 39 | Ok(String::from_utf8_lossy(&output.stdout).to_string()) 40 | } 41 | -------------------------------------------------------------------------------- /src/bin/inspect/main.rs: -------------------------------------------------------------------------------- 1 | //! `cargo inspect` 2 | #![warn( 3 | missing_docs, 4 | missing_debug_implementations, 5 | missing_copy_implementations, 6 | trivial_casts, 7 | trivial_numeric_casts, 8 | unsafe_code, 9 | unstable_features, 10 | unused_import_braces, 11 | unused_qualifications 12 | )] 13 | 14 | use failure::Fail; 15 | 16 | use cargo_inspect::{config, errors::InspectError, inspect}; 17 | use std::process; 18 | use structopt::StructOpt; 19 | 20 | use prettyprint::PrettyPrinter; 21 | 22 | fn run() -> Result<(), InspectError> { 23 | let config::Opt::Config(config) = config::Opt::from_args(); 24 | 25 | // Handle list-themes command 26 | if config.list_themes { 27 | let printer = PrettyPrinter::default().build()?; 28 | let themes = printer.get_themes(); 29 | eprintln!("Themes:"); 30 | for (path, _) in themes { 31 | eprintln!(" {}", path); 32 | } 33 | return Ok(()); 34 | } 35 | 36 | inspect(&config) 37 | } 38 | 39 | fn main() { 40 | env_logger::init(); 41 | if let Err(err) = run() { 42 | eprintln!("Command failed:\n{}\n", err); 43 | 44 | for cause in Fail::iter_causes(&err) { 45 | println!("{}", cause); 46 | } 47 | 48 | if let Some(backtrace) = err.backtrace() { 49 | eprintln!("Backtrace: {:?}", backtrace); 50 | } 51 | 52 | process::exit(1); 53 | } 54 | } 55 | -------------------------------------------------------------------------------- /src/errors.rs: -------------------------------------------------------------------------------- 1 | use failure::Fail; 2 | 3 | use prettyprint::PrettyPrintError; 4 | use std::io::Error as IoError; 5 | use std::string::FromUtf8Error; 6 | 7 | #[derive(Debug, Fail)] 8 | /// Custom type for inspection errors 9 | pub enum InspectError { 10 | /// Error during I/O handling 11 | #[fail(display = "{}", _0)] 12 | Io(#[fail(cause)] IoError), 13 | /// Error when invoking rustc 14 | #[fail(display = "{}", _0)] 15 | Rustc(String), 16 | /// Error when converting data to UTF8 17 | #[fail(display = "{}", _0)] 18 | Utf8(#[fail(cause)] FromUtf8Error), 19 | /// Error while invoking rustfmt 20 | #[fail(display = "{}", _0)] 21 | Rustfmt(String), 22 | /// Error while invoking prettyprint 23 | #[fail(display = "{}", _0)] 24 | PrettyPrint(String), 25 | /// Error while trying to generate a flowgraph 26 | #[fail(display = "{}", _0)] 27 | Flowgraph(String), 28 | /// Error invoking `dot` 29 | #[fail(display = "{}", _0)] 30 | DotExec(#[fail(cause)] IoError), 31 | /// Other error 32 | #[fail(display = "{}", _0)] 33 | Generic(String), 34 | } 35 | 36 | impl From for InspectError { 37 | fn from(e: IoError) -> Self { 38 | InspectError::Io(e) 39 | } 40 | } 41 | 42 | impl From for InspectError { 43 | fn from(e: FromUtf8Error) -> Self { 44 | InspectError::Utf8(e) 45 | } 46 | } 47 | 48 | impl From for InspectError { 49 | fn from(e: String) -> Self { 50 | InspectError::Generic(e) 51 | } 52 | } 53 | 54 | impl From for InspectError { 55 | fn from(e: PrettyPrintError) -> Self { 56 | InspectError::PrettyPrint(e.description().to_string()) 57 | } 58 | } 59 | -------------------------------------------------------------------------------- /src/diff.rs: -------------------------------------------------------------------------------- 1 | use ansi_term::Colour::{Green, Red, White}; 2 | use difference::{Changeset, Difference}; 3 | 4 | pub use crate::errors::InspectError; 5 | 6 | /// Compare two strings and return a Github-style diff output 7 | pub fn diff(text1: String, text2: String) -> Result { 8 | let Changeset { diffs, .. } = Changeset::new(&text1, &text2, "\n"); 9 | 10 | let mut t = String::new(); 11 | 12 | for i in 0..diffs.len() { 13 | match diffs[i] { 14 | Difference::Same(ref x) => { 15 | t.push_str(&format!("\n{}", x)); 16 | } 17 | Difference::Add(ref x) => { 18 | match diffs[i - 1] { 19 | Difference::Rem(ref y) => { 20 | t.push_str(&Green.paint("\n+").to_string()); 21 | let Changeset { diffs, .. } = Changeset::new(y, x, " "); 22 | for c in diffs { 23 | match c { 24 | Difference::Same(ref z) => { 25 | t.push_str(&Green.paint(z).to_string()); 26 | t.push_str(&Green.paint(" ").to_string()); 27 | } 28 | Difference::Add(ref z) => { 29 | t.push_str(&White.on(Green).paint(z).to_string()); 30 | t.push_str(" "); 31 | } 32 | _ => (), 33 | } 34 | } 35 | t.push_str(""); 36 | } 37 | _ => { 38 | t.push_str(&Green.paint(format!("\n+{}", x).to_string())); 39 | } 40 | }; 41 | } 42 | Difference::Rem(ref x) => { 43 | t.push_str(&Red.paint(format!("\n-{}", x)).to_string()); 44 | } 45 | } 46 | } 47 | Ok(t) 48 | } 49 | -------------------------------------------------------------------------------- /CHANGELOG.md: -------------------------------------------------------------------------------- 1 | # Changelog 2 | 3 | All notable changes to this project will be documented in this file. 4 | 5 | The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), 6 | and this project adheres to [Semantic 7 | Versioning](https://semver.org/spec/v2.0.0.html). 8 | 9 | ## [Unreleased] 10 | 11 | ## [0.10.0] - 2019-02-21 12 | 13 | ### Added 14 | 15 | - Ability to choose what kind of format a flowgraph is rendered to using the `--format` argument. 16 | 17 | ### Changed 18 | 19 | - Default flowgraph format is now `svg`. 20 | 21 | ## [0.9.0] - 2019-02-15 22 | 23 | ### Added 24 | 25 | - Flowgraphs can now be generated by using `cargo inspect 26 | --unpretty=flowgraph=main`. This requires `dot` to be installed on the 27 | machine. Thanks to @[jonathansty](/jonathansty). 28 | 29 | ## [0.8.1] - 2019-02-05 30 | 31 | ### Changed 32 | 33 | - Remove the implicit dependency on git2 caused by prettyprint (see 34 | mre/prettyprint#6). 35 | This fixes compilation on macOS in the case where openssl wasn't installed. 36 | Thanks to @[lilyball](/lilyball) for reporting. 37 | 38 | ## [0.8.0] - 2019-02-05 39 | 40 | ### Added 41 | 42 | - You can now choose different themes! Simply run cargo inspect --list-themes 43 | to get a list of available choices. For example, this will use the GitHub 44 | theme, which should work well on white backgrounds: cargo inspect 45 | examples/file.rs --theme GitHub. Thanks to @[jonathansty](/jonathansty). 46 | 47 | ### Changed 48 | 49 | - The output is now a bit cleaner, because formatting issues are now handled a 50 | little better. Even if rustfmt fails, we print the final output on a 51 | best-effort basis. Most of the time, this should look quite pleasing to the 52 | eye. If you want to see the full debug trace, you can use `RUST_LOG=debug`. 53 | Thanks to @[jonathansty](/jonathansty). 54 | 55 | ## [0.7.0] - 2019-02-03 56 | 57 | - Add logging support 58 | - Add support for diffing files (#11) 59 | 60 | ## [0.6.0] - 2019-01-29 61 | 62 | - Print unformatted text instead of panicking on rustfmt 63 | 64 | ## [0.5.0] - 2018-12-16 65 | 66 | - Move to Rust 2018 edition 67 | - Add crate support 68 | - Adds support for plaintext output. 69 | - More examples 70 | 71 | -------------------------------------------------------------------------------- /src/config.rs: -------------------------------------------------------------------------------- 1 | use std::error::Error; 2 | use std::path::PathBuf; 3 | use structopt::StructOpt; 4 | 5 | fn parse_tuple(s: &str) -> Result<(T, T), Box> 6 | where 7 | T: std::str::FromStr, 8 | T::Err: Error + 'static, 9 | { 10 | let pos = s.find(',').ok_or_else(|| { 11 | format!( 12 | "Expected format: file1.rs,file2.rs. No `,` found in `{}`", 13 | s 14 | ) 15 | })?; 16 | Ok((s[..pos].parse()?, s[pos + 1..].parse()?)) 17 | } 18 | 19 | /// Holds all configuration options when using 20 | /// cargo-inspect as a library. 21 | #[derive(StructOpt, Debug)] 22 | pub struct Config { 23 | /// Input file 24 | #[structopt(name = "INPUT_FILE", parse(from_os_str))] 25 | pub input: Option, 26 | 27 | /// Diff input files 28 | #[structopt(long = "diff", parse(try_from_str = parse_tuple))] 29 | pub files: Option<(String, String)>, 30 | 31 | /// rustc "unpretty" parameters 32 | /// 33 | /// *Note*: For `--unpretty=flowgraph=[symbol]` you need to have `dot` on your PATH. 34 | #[structopt(long = "unpretty", default_value = "hir")] 35 | pub unpretty: String, 36 | 37 | /// Override for the format that gets outputted when the `unpretty` mode 38 | /// is set to `flowgraph` 39 | #[structopt(long = "format", default_value = "svg")] 40 | pub format: String, 41 | 42 | /// Print the original code as a comment above the desugared code 43 | #[structopt(short = "v", long = "verbose")] 44 | pub verbose: bool, 45 | 46 | /// Don't highlight output 47 | #[structopt(long = "plain")] 48 | pub plain: bool, 49 | 50 | /// Specify a theme override for the pretty printer 51 | #[structopt(name = "THEME", long = "theme")] 52 | pub theme: Option, 53 | 54 | /// Should we list all pretty printer themes? 55 | #[structopt(long = "list-themes")] 56 | pub list_themes: bool, 57 | } 58 | 59 | /// The structopt enum, which serves as an adapter so that the config options 60 | /// can be passed to cargo-inspect via cargo 61 | #[derive(StructOpt, Debug)] 62 | #[structopt(bin_name = "cargo")] 63 | pub enum Opt { 64 | #[structopt(name = "inspect")] 65 | /// This extends Cargo to allow you to desugar your Rust code and see what 66 | /// happens behind the curtains. 67 | Config(Config), 68 | } 69 | -------------------------------------------------------------------------------- /src/hir.rs: -------------------------------------------------------------------------------- 1 | use crate::errors::InspectError; 2 | use indicatif::{ProgressBar, ProgressStyle}; 3 | use std::env; 4 | use std::io::{BufRead, BufReader}; 5 | use std::path::{Path, PathBuf}; 6 | use std::process::{self, Command}; 7 | 8 | /// A wrapper around Rust's high-level intermediate representation 9 | pub struct HIR { 10 | /// Source file or crate of HIR 11 | pub source: PathBuf, 12 | /// The actual HIR output 13 | pub output: String, 14 | } 15 | 16 | use log::debug; 17 | 18 | // TODO: This should probably not take a path, 19 | // but take a String as an input. 20 | // Would make testing easier. 21 | pub fn from_file(path: &Path, unpretty: &str) -> Result { 22 | let output = Command::new("rustc") 23 | .arg("+nightly") 24 | .arg(format!("-Zunpretty={}", unpretty)) 25 | .arg(path) 26 | .output()?; 27 | let stderr = String::from_utf8(output.stderr)?; 28 | if !stderr.is_empty() { 29 | return Err(InspectError::Rustc(stderr)); 30 | } 31 | Ok(HIR { 32 | source: path.to_path_buf(), 33 | output: String::from_utf8(output.stdout)?, 34 | }) 35 | } 36 | 37 | pub fn from_crate(unpretty: &str) -> Result { 38 | let pb = ProgressBar::new_spinner(); 39 | pb.enable_steady_tick(100); 40 | pb.set_style(ProgressStyle::default_spinner().template("{spinner} cargo {wide_msg}")); 41 | 42 | let mut p = process::Command::new("cargo") 43 | .arg("+nightly") 44 | .arg("rustc") 45 | .arg("--") 46 | .arg(format!("-Zunpretty={}", unpretty)) 47 | .stderr(process::Stdio::piped()) 48 | .stdout(process::Stdio::piped()) 49 | .spawn()?; 50 | 51 | let stderr = BufReader::new( 52 | p.stderr 53 | .take() 54 | .ok_or_else(|| "Cannot read from stderr".to_string())?, 55 | ); 56 | for line in stderr.lines() { 57 | let line = line?; 58 | debug!("{}", line); 59 | let stripped_line = line.trim(); 60 | if !stripped_line.is_empty() { 61 | pb.set_message(&stripped_line.to_lowercase()); 62 | } 63 | pb.tick(); 64 | } 65 | 66 | let out = p.wait_with_output()?; 67 | pb.finish_and_clear(); 68 | 69 | Ok(HIR { 70 | source: env::current_dir()?, 71 | output: String::from_utf8(out.stdout)?, 72 | }) 73 | } 74 | -------------------------------------------------------------------------------- /src/comment.rs: -------------------------------------------------------------------------------- 1 | use crate::errors::InspectError; 2 | use std::fs::{self, File}; 3 | use std::io::{BufRead, BufReader}; 4 | use std::path::Path; 5 | 6 | /// Add comments to the inspected code. Copy each code line as a comment above 7 | /// the line. This is kind of a crude but effective method. In the long run, 8 | /// this might be a nice feature for rustc however. 9 | pub fn comment_file(input: &Path) -> Result<(), InspectError> { 10 | let file = File::open(input)?; 11 | let commented: String = BufReader::new(file) 12 | .lines() 13 | .filter_map(Result::ok) 14 | .map(|line| line.trim().to_string()) 15 | .map(|line| { 16 | let line = if line.is_empty() || is_comment(&line) || is_block(&line) { 17 | // Don't touch non-code lines. 18 | line 19 | } else { 20 | // Duplicate line (one commented, one uncommented) 21 | format!("{}\n{}", add_marker("before: ", &line), line) 22 | }; 23 | format!("{}\n", line) 24 | }) 25 | .collect(); 26 | 27 | fs::write(input, commented)?; 28 | Ok(()) 29 | } 30 | 31 | fn is_comment(line: &str) -> bool { 32 | let markers = ["//", "//!", "/*", "///"]; 33 | for marker in &markers { 34 | if line.starts_with(marker) { 35 | return true; 36 | } 37 | } 38 | false 39 | } 40 | 41 | fn is_block(line: &str) -> bool { 42 | let blocks = ["(", ")", "[", "]", "{", "}"]; 43 | for block in &blocks { 44 | if &line == block { 45 | return true; 46 | } 47 | } 48 | false 49 | } 50 | 51 | fn add_marker(marker: &str, line: &str) -> String { 52 | format!("// {}{}", marker, line) 53 | } 54 | 55 | #[cfg(test)] 56 | mod tests { 57 | use super::*; 58 | 59 | #[test] 60 | fn test_is_comment() { 61 | assert_eq!(is_comment("a test"), false); 62 | assert_eq!(is_comment("// a test"), true); 63 | assert_eq!(is_comment("/// doc test"), true); 64 | assert_eq!(is_comment("//! doc test"), true); 65 | assert_eq!(is_comment("/* doc test"), true); 66 | } 67 | 68 | #[test] 69 | fn test_add_marker() { 70 | assert_eq!(add_marker("", "a test"), "// a test"); 71 | assert_eq!(add_marker("marker: ", "a test"), "// marker: a test"); 72 | } 73 | 74 | #[test] 75 | fn test_is_block() { 76 | assert_eq!(is_block("("), true); 77 | assert_eq!(is_block("}"), true); 78 | assert_eq!(is_block("( something"), false); 79 | assert_eq!(is_block("{ something"), false); 80 | } 81 | } 82 | -------------------------------------------------------------------------------- /src/lib.rs: -------------------------------------------------------------------------------- 1 | //! A library for inspecting Rust code 2 | #![warn( 3 | missing_docs, 4 | missing_debug_implementations, 5 | missing_copy_implementations, 6 | trivial_casts, 7 | trivial_numeric_casts, 8 | unsafe_code, 9 | unstable_features, 10 | unused_import_braces, 11 | unused_qualifications 12 | )] 13 | 14 | use std::env; 15 | use std::fs; 16 | use std::fs::File; 17 | use std::io::Write; 18 | use std::path::PathBuf; 19 | use std::process::Command; 20 | 21 | /// Available configuration settings when using cargo-inspect as a library 22 | pub mod config; 23 | 24 | /// Contains all types defined for error handling 25 | pub mod errors; 26 | 27 | mod comment; 28 | mod diff; 29 | mod format; 30 | mod hir; 31 | mod tmpfile; 32 | 33 | use prettyprint::PrettyPrinter; 34 | 35 | pub use crate::config::{Config, Opt}; 36 | pub use crate::errors::InspectError; 37 | 38 | use crate::comment::comment_file; 39 | pub use crate::diff::diff; 40 | use crate::format::format; 41 | use crate::hir::HIR; 42 | pub use crate::tmpfile::tmpfile; 43 | 44 | /// inspect takes a Rust file or crate as an input and returns the desugared 45 | /// output. 46 | pub fn inspect(config: &Config) -> Result<(), InspectError> { 47 | let output = match &config.files { 48 | Some(files) => { 49 | let hir0 = inspect_file( 50 | PathBuf::from(files.0.clone()), 51 | config.verbose, 52 | config.unpretty.clone(), 53 | )?; 54 | let hir1 = inspect_file( 55 | PathBuf::from(files.1.clone()), 56 | config.verbose, 57 | config.unpretty.clone(), 58 | )?; 59 | diff(try_format(hir0.output)?, try_format(hir1.output)?)? 60 | } 61 | None => inspect_single(config)?, 62 | }; 63 | 64 | if config.plain { 65 | println!("{}", output); 66 | } else if config.unpretty.starts_with("flowgraph") { 67 | if let Some(path) = &config.input { 68 | let input_path = PathBuf::from(path); 69 | 70 | // Extract the file name from our input path. 71 | let file_name = input_path.file_name().ok_or_else(|| { 72 | InspectError::Flowgraph(String::from( 73 | "Invalid path found. The input path should be a file.", 74 | )) 75 | })?; 76 | 77 | let mut output_path = PathBuf::from(file_name); 78 | let ext = &config.format; 79 | output_path.set_extension(&ext); 80 | 81 | // Create a temporary file to dump out the plain output 82 | let tmp_file_path = tmpfile()?; 83 | let mut file = File::create(&tmp_file_path)?; 84 | file.write_all(output.as_bytes())?; 85 | 86 | // For now setup the correct `dot` arguments to write to a png 87 | let output_str = output_path.to_str().ok_or_else(|| { 88 | InspectError::Flowgraph(String::from("Failed to convert output path to string.")) 89 | })?; 90 | 91 | let input_str = tmp_file_path.to_str().ok_or_else(|| { 92 | InspectError::Flowgraph(String::from("Failed to convert temporary path to string.")) 93 | })?; 94 | 95 | log::info!("Writing \"{}\"...", output_str); 96 | 97 | let args = [&format!("-T{}", ext), "-o", output_str, input_str]; 98 | Command::new("dot") 99 | .args(&args) 100 | .spawn() 101 | .map_err(|e| InspectError::DotExec(e))?; 102 | } 103 | } else { 104 | let mut builder = PrettyPrinter::default(); 105 | builder.language("rust"); 106 | if let Some(theme) = &config.theme { 107 | builder.theme(theme.clone()); 108 | } 109 | 110 | let printer = builder.build()?; 111 | let header = config.input.to_owned().unwrap_or(env::current_dir()?); 112 | printer.string_with_header(output, header.to_string_lossy().to_string())?; 113 | } 114 | Ok(()) 115 | } 116 | 117 | /// Run inspection on a single file or crate. Return the compiler output 118 | /// (preferably formatted with rustfmt) 119 | pub fn inspect_single(config: &Config) -> Result { 120 | let hir = match config.input.clone() { 121 | Some(input) => inspect_file(input, config.verbose, config.unpretty.clone()), 122 | None => inspect_crate(config), 123 | }?; 124 | Ok(try_format(hir.output)?) 125 | } 126 | 127 | /// Run cargo-inspect on a file 128 | fn inspect_file(input: PathBuf, verbose: bool, unpretty: String) -> Result { 129 | let input = if verbose { 130 | // Create a temporary copy of the input file, 131 | // which contains comments for each input line 132 | // to avoid modifying the original input file. 133 | // This will be used as the input of rustc. 134 | let tmp = tmpfile()?; 135 | fs::copy(&input, &tmp)?; 136 | comment_file(&tmp)?; 137 | tmp 138 | } else { 139 | input 140 | }; 141 | hir::from_file(&input, &unpretty) 142 | } 143 | 144 | /// Run cargo-inspect on a crate 145 | fn inspect_crate(config: &Config) -> Result { 146 | if config.verbose { 147 | unimplemented!( 148 | "Verbose option doesn't work for crates yet. \ 149 | See https://github.com/mre/cargo-inspect/issues/5" 150 | ) 151 | // comment_crate()?; 152 | } 153 | hir::from_crate(&config.unpretty) 154 | } 155 | 156 | // TODO: This should really be more idiomatic; 157 | // maybe by having a `Formatted` type and a `let fmt = Formatted::try_from(string);` 158 | fn try_format(input: String) -> Result { 159 | let mut formatted = format(&input)?; 160 | if formatted.is_empty() { 161 | // In case of an error, rustfmt returns an empty string 162 | // and we continue with the unformatted output. 163 | // Not ideal, but better than panicking. 164 | formatted = input; 165 | } 166 | Ok(formatted) 167 | } 168 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # cargo-inspect 2 | 3 | ![Logo](./assets/logo.svg) 4 | 5 | [![docs](https://docs.rs/cargo-inspect/badge.svg)](https://docs.rs/cargo-inspect/) 6 | [![Build Status](https://travis-ci.org/mre/cargo-inspect.svg?branch=master)](https://travis-ci.org/mre/cargo-inspect) 7 | 8 | ## Thanks All! 9 | 10 | ℹ️ This crate was **superceded by [cargo-expand](https://github.com/dtolnay/cargo-expand)**, which added support for all the features that were missing 11 | when we started to work on cargo-inspect. Thanks all for your feedback and support. 12 | 13 | ## What is Rust doing behind the scenes? 14 | 15 | > There are only two ways to live your life. 16 | > One is as though nothing is a miracle. The other is as though everything is a 17 | > miracle. -- Albert Einstein 18 | 19 | ## Installation 20 | 21 | You need Rust nightly and `rustfmt` to get started. 22 | You can install those via [rustup]: 23 | 24 | ``` 25 | rustup install nightly 26 | rustup component add rustfmt 27 | ``` 28 | 29 | All set? Let's get cracking! 30 | 31 | ``` 32 | cargo install cargo-inspect 33 | ``` 34 | 35 | ## Usage 36 | 37 | Call it on any Rust file: 38 | 39 | ``` 40 | cargo inspect main.rs 41 | ``` 42 | 43 | If you don't specify a file, the current crate will be analyzed instead. 44 | 45 | ``` 46 | cargo inspect 47 | ``` 48 | 49 | Depending on the size of the crate, this might take a while. 50 | Please be patient. 51 | 52 | It can also compare two file outputs! Try this: 53 | 54 | ``` 55 | cargo inspect --diff examples/range.rs,examples/range_inclusive.rs --plain 56 | ``` 57 | 58 | ## Configuration 59 | 60 | ``` 61 | USAGE: 62 | cargo inspect [FLAGS] [OPTIONS] [INPUT_FILE] 63 | 64 | FLAGS: 65 | -h, --help 66 | Prints help information 67 | 68 | --list-themes 69 | Should we list all pretty printer themes? 70 | 71 | --plain 72 | Don't highlight output 73 | 74 | -V, --version 75 | Prints version information 76 | 77 | -v, --verbose 78 | Print the original code as a comment above the desugared code 79 | 80 | 81 | OPTIONS: 82 | --theme 83 | Specify a theme override for the pretty printer 84 | 85 | --diff 86 | Diff input files 87 | 88 | --format 89 | Override for the format that gets outputted when the `unpretty` mode is set to `flowgraph` [default: svg] 90 | 91 | --unpretty 92 | rustc "unpretty" parameters 93 | 94 | *Note*: For `--unpretty=flowgraph=[symbol]` you need to have `dot` on your PATH. [default: hir] 95 | 96 | ARGS: 97 | 98 | Input file 99 | ``` 100 | 101 | ## Background 102 | 103 | Rust allows for a lot of syntactic sugar, that makes it a pleasure to write. It 104 | is sometimes hard, however, to look behind the curtain and see what the compiler 105 | is really doing with our code. 106 | 107 | To quote @tshepang, "It is good to know what these conveniences are, to avoid 108 | being mystified by what's going on under the hood... the less magical thinking 109 | we have of the world, the better." 110 | 111 | * lifetime elisions 112 | * type inference 113 | * syntactic sugar 114 | * implicit dereferencing 115 | * type coercions 116 | * hidden code (e.g. the prelude) 117 | 118 | I was always interested in how programming languages work in the background, how 119 | my code was unrolled to make the compiler backend easier to maintain. 120 | 121 | The goal is to make the compiler more approachable for mere mortals. 122 | Mystery! Exploration! Discovery! 123 | 124 | Read more on the background of `cargo-inspect` [on my blog](https://matthias-endler.de/2018/cargo-inspect/). 125 | 126 | ## Code Examples 127 | 128 | ### `If-let` gets desugared into `match` 129 | 130 | Consider the following code snippet: 131 | 132 | ```rust 133 | fn main() { 134 | if let Some(x) = Some(1) { 135 | // Do something with x 136 | } 137 | } 138 | ``` 139 | 140 | When you compile it, the first thing Rust does is desugar it. To see what the 141 | code looks like after this step, run 142 | 143 | ``` 144 | cargo inspect examples/if_let.rs 145 | ``` 146 | 147 | This produces the following output: 148 | 149 | ![Please run the command to reproduce the desugared output](assets/if-let.png) 150 | 151 | You can see that the `if let` was desugared into a `match` statement. 152 | 153 | To change the colorscheme, try `cargo-inspect --list-themes`, e.g. 154 | 155 | ``` 156 | cargo inspect examples/if_let.rs --theme GitHub 157 | ``` 158 | 159 | ![Please run the command to reproduce the desugared output](assets/if-let-white.png) 160 | 161 | Oh, and if you have [`graphviz`](https://graphviz.gitlab.io/download/) installed, you can also print a pretty flowgraph from your code: 162 | 163 | ``` 164 | cargo inspect --unpretty=flowgraph=main examples/if_let.rs 165 | ``` 166 | 167 | ![Please run the command to reproduce the desugared output](assets/if-let-flowgraph.svg) 168 | 169 | ### More examples 170 | 171 | Please find more examples in the `examples` folder. You can also contribute 172 | more. 173 | 174 | ## The Magic Sauce 175 | 176 | The best things in the world are assembled from simple building blocks. This 177 | tool stands on the shoulders of giants. To work its magic, it runs the following 178 | commands: 179 | 180 | 1. `rustc -Zinspect=hir`, for retrieving the HIR. 181 | 2. `rustfmt`, for formatting the output. 182 | 3. [`prettyprint`](https://github.com/mre/prettyprint), for syntax-highlighting, 183 | which is just a wrapper around the awesome 184 | [syntect](https://github.com/trishume/syntect/blob/master/examples/syncat.rs) 185 | and [bat](https://github.com/sharkdp/bat/) crates. 186 | 187 | ## Contributing 188 | 189 | This is a young project, which has downsides and upsides. 190 | 191 | * Everything is in flux and things can break at any time. 😫 192 | * There's plenty of opportunity to shape and form the project. 😊 193 | 194 | Thus, become a contributor today! 195 | 196 | ## Known issues 197 | 198 | As of now, this is a very fragile tool. If it fails, it ~~might~~ will produce 199 | horrible output. You have been warned. That said, it won't eat your code, of 200 | course. :blush: 201 | 202 | ## License 203 | 204 | Licensed under either of 205 | 206 | * Apache License, Version 2.0, (LICENSE-APACHE or 207 | http://www.apache.org/licenses/LICENSE-2.0) 208 | * MIT license (LICENSE-MIT or http://opensource.org/licenses/MIT) 209 | 210 | at your option. 211 | 212 | [rustup]: https://rustup.rs/ 213 | 214 | 215 | ## Credits 216 | 217 | Magnifying glass designed by [Rawpixel.com]( https://www.freepik.com/free-vector/illustration-of-a-magnifying-glass_2945064.htm) 218 | -------------------------------------------------------------------------------- /assets/if-let-flowgraph.svg: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 9 | 10 | node_10 11 | 12 | 13 | N0 14 | 15 | entry 16 | 17 | 18 | N2 19 | 20 | expr Some (id=17) 21 | 22 | 23 | N0->N2 24 | 25 | 26 | 27 | 28 | N1 29 | 30 | exit 31 | 32 | 33 | N3 34 | 35 | expr 1 (id=18) 36 | 37 | 38 | N2->N3 39 | 40 | 41 | 42 | 43 | N4 44 | 45 | expr Some(1) (id=19) 46 | 47 | 48 | N3->N4 49 | 50 | 51 | 52 | 53 | N7 54 | 55 | local _x (id=15) 56 | 57 | 58 | N4->N7 59 | 60 | 61 | 62 | 63 | N12 64 | 65 | pat _ (id=24) 66 | 67 | 68 | N4->N12 69 | 70 | 71 | 72 | 73 | N5 74 | 75 | expr match Some(1) { Some(_x) => { } _ => (), } (id=21) 76 | 77 | 78 | N14 79 | 80 | block { match Some(1) { Some(_x) => { } _ => (), } } (id=12) 81 | 82 | 83 | N5->N14 84 | 85 | 86 | 87 | 88 | N6 89 | 90 | (dummy_node) 91 | 92 | 93 | N9 94 | 95 | block { } (id=20) 96 | 97 | 98 | N6->N9 99 | 100 | 101 | 102 | 103 | N8 104 | 105 | pat Some(_x) (id=13) 106 | 107 | 108 | N7->N8 109 | 110 | 111 | 112 | 113 | N8->N6 114 | 115 | 116 | 117 | 118 | N10 119 | 120 | expr { } (id=23) 121 | 122 | 123 | N9->N10 124 | 125 | 126 | 127 | 128 | N10->N5 129 | 130 | 131 | 132 | 133 | N11 134 | 135 | (dummy_node) 136 | 137 | 138 | N13 139 | 140 | expr () (id=25) 141 | 142 | 143 | N11->N13 144 | 145 | 146 | 147 | 148 | N12->N11 149 | 150 | 151 | 152 | 153 | N13->N5 154 | 155 | 156 | 157 | 158 | N15 159 | 160 | expr { match Some(1) { Some(_x) => { } _ => (), } } (id=26) 161 | 162 | 163 | N14->N15 164 | 165 | 166 | 167 | 168 | N15->N1 169 | 170 | 171 | 172 | 173 | 174 | -------------------------------------------------------------------------------- /LICENSE-APACHE: -------------------------------------------------------------------------------- 1 | Apache License 2 | Version 2.0, January 2004 3 | http://www.apache.org/licenses/ 4 | 5 | TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION 6 | 7 | 1. Definitions. 8 | 9 | "License" shall mean the terms and conditions for use, reproduction, 10 | and distribution as defined by Sections 1 through 9 of this document. 11 | 12 | "Licensor" shall mean the copyright owner or entity authorized by 13 | the copyright owner that is granting the License. 14 | 15 | "Legal Entity" shall mean the union of the acting entity and all 16 | other entities that control, are controlled by, or are under common 17 | control with that entity. For the purposes of this definition, 18 | "control" means (i) the power, direct or indirect, to cause the 19 | direction or management of such entity, whether by contract or 20 | otherwise, or (ii) ownership of fifty percent (50%) or more of the 21 | outstanding shares, or (iii) beneficial ownership of such entity. 22 | 23 | "You" (or "Your") shall mean an individual or Legal Entity 24 | exercising permissions granted by this License. 25 | 26 | "Source" form shall mean the preferred form for making modifications, 27 | including but not limited to software source code, documentation 28 | source, and configuration files. 29 | 30 | "Object" form shall mean any form resulting from mechanical 31 | transformation or translation of a Source form, including but 32 | not limited to compiled object code, generated documentation, 33 | and conversions to other media types. 34 | 35 | "Work" shall mean the work of authorship, whether in Source or 36 | Object form, made available under the License, as indicated by a 37 | copyright notice that is included in or attached to the work 38 | (an example is provided in the Appendix below). 39 | 40 | "Derivative Works" shall mean any work, whether in Source or Object 41 | form, that is based on (or derived from) the Work and for which the 42 | editorial revisions, annotations, elaborations, or other modifications 43 | represent, as a whole, an original work of authorship. For the purposes 44 | of this License, Derivative Works shall not include works that remain 45 | separable from, or merely link (or bind by name) to the interfaces of, 46 | the Work and Derivative Works thereof. 47 | 48 | "Contribution" shall mean any work of authorship, including 49 | the original version of the Work and any modifications or additions 50 | to that Work or Derivative Works thereof, that is intentionally 51 | submitted to Licensor for inclusion in the Work by the copyright owner 52 | or by an individual or Legal Entity authorized to submit on behalf of 53 | the copyright owner. For the purposes of this definition, "submitted" 54 | means any form of electronic, verbal, or written communication sent 55 | to the Licensor or its representatives, including but not limited to 56 | communication on electronic mailing lists, source code control systems, 57 | and issue tracking systems that are managed by, or on behalf of, the 58 | Licensor for the purpose of discussing and improving the Work, but 59 | excluding communication that is conspicuously marked or otherwise 60 | designated in writing by the copyright owner as "Not a Contribution." 61 | 62 | "Contributor" shall mean Licensor and any individual or Legal Entity 63 | on behalf of whom a Contribution has been received by Licensor and 64 | subsequently incorporated within the Work. 65 | 66 | 2. Grant of Copyright License. Subject to the terms and conditions of 67 | this License, each Contributor hereby grants to You a perpetual, 68 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 69 | copyright license to reproduce, prepare Derivative Works of, 70 | publicly display, publicly perform, sublicense, and distribute the 71 | Work and such Derivative Works in Source or Object form. 72 | 73 | 3. Grant of Patent License. Subject to the terms and conditions of 74 | this License, each Contributor hereby grants to You a perpetual, 75 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 76 | (except as stated in this section) patent license to make, have made, 77 | use, offer to sell, sell, import, and otherwise transfer the Work, 78 | where such license applies only to those patent claims licensable 79 | by such Contributor that are necessarily infringed by their 80 | Contribution(s) alone or by combination of their Contribution(s) 81 | with the Work to which such Contribution(s) was submitted. If You 82 | institute patent litigation against any entity (including a 83 | cross-claim or counterclaim in a lawsuit) alleging that the Work 84 | or a Contribution incorporated within the Work constitutes direct 85 | or contributory patent infringement, then any patent licenses 86 | granted to You under this License for that Work shall terminate 87 | as of the date such litigation is filed. 88 | 89 | 4. Redistribution. You may reproduce and distribute copies of the 90 | Work or Derivative Works thereof in any medium, with or without 91 | modifications, and in Source or Object form, provided that You 92 | meet the following conditions: 93 | 94 | (a) You must give any other recipients of the Work or 95 | Derivative Works a copy of this License; and 96 | 97 | (b) You must cause any modified files to carry prominent notices 98 | stating that You changed the files; and 99 | 100 | (c) You must retain, in the Source form of any Derivative Works 101 | that You distribute, all copyright, patent, trademark, and 102 | attribution notices from the Source form of the Work, 103 | excluding those notices that do not pertain to any part of 104 | the Derivative Works; and 105 | 106 | (d) If the Work includes a "NOTICE" text file as part of its 107 | distribution, then any Derivative Works that You distribute must 108 | include a readable copy of the attribution notices contained 109 | within such NOTICE file, excluding those notices that do not 110 | pertain to any part of the Derivative Works, in at least one 111 | of the following places: within a NOTICE text file distributed 112 | as part of the Derivative Works; within the Source form or 113 | documentation, if provided along with the Derivative Works; or, 114 | within a display generated by the Derivative Works, if and 115 | wherever such third-party notices normally appear. The contents 116 | of the NOTICE file are for informational purposes only and 117 | do not modify the License. You may add Your own attribution 118 | notices within Derivative Works that You distribute, alongside 119 | or as an addendum to the NOTICE text from the Work, provided 120 | that such additional attribution notices cannot be construed 121 | as modifying the License. 122 | 123 | You may add Your own copyright statement to Your modifications and 124 | may provide additional or different license terms and conditions 125 | for use, reproduction, or distribution of Your modifications, or 126 | for any such Derivative Works as a whole, provided Your use, 127 | reproduction, and distribution of the Work otherwise complies with 128 | the conditions stated in this License. 129 | 130 | 5. Submission of Contributions. Unless You explicitly state otherwise, 131 | any Contribution intentionally submitted for inclusion in the Work 132 | by You to the Licensor shall be under the terms and conditions of 133 | this License, without any additional terms or conditions. 134 | Notwithstanding the above, nothing herein shall supersede or modify 135 | the terms of any separate license agreement you may have executed 136 | with Licensor regarding such Contributions. 137 | 138 | 6. Trademarks. This License does not grant permission to use the trade 139 | names, trademarks, service marks, or product names of the Licensor, 140 | except as required for reasonable and customary use in describing the 141 | origin of the Work and reproducing the content of the NOTICE file. 142 | 143 | 7. Disclaimer of Warranty. Unless required by applicable law or 144 | agreed to in writing, Licensor provides the Work (and each 145 | Contributor provides its Contributions) on an "AS IS" BASIS, 146 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or 147 | implied, including, without limitation, any warranties or conditions 148 | of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A 149 | PARTICULAR PURPOSE. You are solely responsible for determining the 150 | appropriateness of using or redistributing the Work and assume any 151 | risks associated with Your exercise of permissions under this License. 152 | 153 | 8. Limitation of Liability. In no event and under no legal theory, 154 | whether in tort (including negligence), contract, or otherwise, 155 | unless required by applicable law (such as deliberate and grossly 156 | negligent acts) or agreed to in writing, shall any Contributor be 157 | liable to You for damages, including any direct, indirect, special, 158 | incidental, or consequential damages of any character arising as a 159 | result of this License or out of the use or inability to use the 160 | Work (including but not limited to damages for loss of goodwill, 161 | work stoppage, computer failure or malfunction, or any and all 162 | other commercial damages or losses), even if such Contributor 163 | has been advised of the possibility of such damages. 164 | 165 | 9. Accepting Warranty or Additional Liability. While redistributing 166 | the Work or Derivative Works thereof, You may choose to offer, 167 | and charge a fee for, acceptance of support, warranty, indemnity, 168 | or other liability obligations and/or rights consistent with this 169 | License. However, in accepting such obligations, You may act only 170 | on Your own behalf and on Your sole responsibility, not on behalf 171 | of any other Contributor, and only if You agree to indemnify, 172 | defend, and hold each Contributor harmless for any liability 173 | incurred by, or claims asserted against, such Contributor by reason 174 | of your accepting any such warranty or additional liability. 175 | 176 | END OF TERMS AND CONDITIONS 177 | 178 | APPENDIX: How to apply the Apache License to your work. 179 | 180 | To apply the Apache License to your work, attach the following 181 | boilerplate notice, with the fields enclosed by brackets "{}" 182 | replaced with your own identifying information. (Don't include 183 | the brackets!) The text should be enclosed in the appropriate 184 | comment syntax for the file format. We also recommend that a 185 | file or class name and description of purpose be included on the 186 | same "printed page" as the copyright notice for easier 187 | identification within third-party archives. 188 | 189 | Copyright 2018 The cargo-inspect Developers 190 | 191 | Licensed under the Apache License, Version 2.0 (the "License"); 192 | you may not use this file except in compliance with the License. 193 | You may obtain a copy of the License at 194 | 195 | http://www.apache.org/licenses/LICENSE-2.0 196 | 197 | Unless required by applicable law or agreed to in writing, software 198 | distributed under the License is distributed on an "AS IS" BASIS, 199 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 200 | See the License for the specific language governing permissions and 201 | limitations under the License. 202 | 203 | -------------------------------------------------------------------------------- /assets/logo.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | image/svg+xml -------------------------------------------------------------------------------- /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 = "addr2line" 7 | version = "0.12.1" 8 | source = "registry+https://github.com/rust-lang/crates.io-index" 9 | checksum = "a49806b9dadc843c61e7c97e72490ad7f7220ae249012fbda9ad0609457c0543" 10 | dependencies = [ 11 | "gimli", 12 | ] 13 | 14 | [[package]] 15 | name = "adler32" 16 | version = "1.0.4" 17 | source = "registry+https://github.com/rust-lang/crates.io-index" 18 | checksum = "5d2e7343e7fc9de883d1b0341e0b13970f764c14101234857d2ddafa1cb1cac2" 19 | 20 | [[package]] 21 | name = "aho-corasick" 22 | version = "0.7.10" 23 | source = "registry+https://github.com/rust-lang/crates.io-index" 24 | checksum = "8716408b8bc624ed7f65d223ddb9ac2d044c0547b6fa4b0d554f3a9540496ada" 25 | dependencies = [ 26 | "memchr", 27 | ] 28 | 29 | [[package]] 30 | name = "ansi_colours" 31 | version = "1.0.1" 32 | source = "registry+https://github.com/rust-lang/crates.io-index" 33 | checksum = "1d0f302a81afc6a7f4350c04f0ba7cfab529cc009bca3324b3fb5764e6add8b6" 34 | dependencies = [ 35 | "cc", 36 | ] 37 | 38 | [[package]] 39 | name = "ansi_term" 40 | version = "0.11.0" 41 | source = "registry+https://github.com/rust-lang/crates.io-index" 42 | checksum = "ee49baf6cb617b853aa8d93bf420db2383fab46d314482ca2803b40d5fde979b" 43 | dependencies = [ 44 | "winapi", 45 | ] 46 | 47 | [[package]] 48 | name = "ansi_term" 49 | version = "0.12.1" 50 | source = "registry+https://github.com/rust-lang/crates.io-index" 51 | checksum = "d52a9bb7ec0cf484c551830a7ce27bd20d67eac647e1befb56b0be4ee39a55d2" 52 | dependencies = [ 53 | "winapi", 54 | ] 55 | 56 | [[package]] 57 | name = "arrayref" 58 | version = "0.3.6" 59 | source = "registry+https://github.com/rust-lang/crates.io-index" 60 | checksum = "a4c527152e37cf757a3f78aae5a06fbeefdb07ccc535c980a3208ee3060dd544" 61 | 62 | [[package]] 63 | name = "arrayvec" 64 | version = "0.5.1" 65 | source = "registry+https://github.com/rust-lang/crates.io-index" 66 | checksum = "cff77d8686867eceff3105329d4698d96c2391c176d5d03adc90c7389162b5b8" 67 | 68 | [[package]] 69 | name = "atty" 70 | version = "0.2.14" 71 | source = "registry+https://github.com/rust-lang/crates.io-index" 72 | checksum = "d9b39be18770d11421cdb1b9947a45dd3f37e93092cbf377614828a319d5fee8" 73 | dependencies = [ 74 | "hermit-abi", 75 | "libc", 76 | "winapi", 77 | ] 78 | 79 | [[package]] 80 | name = "autocfg" 81 | version = "1.0.0" 82 | source = "registry+https://github.com/rust-lang/crates.io-index" 83 | checksum = "f8aac770f1885fd7e387acedd76065302551364496e46b3dd00860b2f8359b9d" 84 | 85 | [[package]] 86 | name = "backtrace" 87 | version = "0.3.48" 88 | source = "registry+https://github.com/rust-lang/crates.io-index" 89 | checksum = "0df2f85c8a2abbe3b7d7e748052fdd9b76a0458fdeb16ad4223f5eca78c7c130" 90 | dependencies = [ 91 | "addr2line", 92 | "cfg-if 0.1.10", 93 | "libc", 94 | "object", 95 | "rustc-demangle", 96 | ] 97 | 98 | [[package]] 99 | name = "base64" 100 | version = "0.11.0" 101 | source = "registry+https://github.com/rust-lang/crates.io-index" 102 | checksum = "b41b7ea54a0c9d92199de89e20e58d49f02f8e699814ef3fdf266f6f748d15c7" 103 | 104 | [[package]] 105 | name = "base64" 106 | version = "0.12.1" 107 | source = "registry+https://github.com/rust-lang/crates.io-index" 108 | checksum = "53d1ccbaf7d9ec9537465a97bf19edc1a4e158ecb49fc16178202238c569cc42" 109 | 110 | [[package]] 111 | name = "bincode" 112 | version = "1.2.1" 113 | source = "registry+https://github.com/rust-lang/crates.io-index" 114 | checksum = "5753e2a71534719bf3f4e57006c3a4f0d2c672a4b676eec84161f763eca87dbf" 115 | dependencies = [ 116 | "byteorder", 117 | "serde", 118 | ] 119 | 120 | [[package]] 121 | name = "bitflags" 122 | version = "1.2.1" 123 | source = "registry+https://github.com/rust-lang/crates.io-index" 124 | checksum = "cf1de2fe8c75bc145a2f577add951f8134889b4795d47466a54a5c846d691693" 125 | 126 | [[package]] 127 | name = "blake2b_simd" 128 | version = "0.5.10" 129 | source = "registry+https://github.com/rust-lang/crates.io-index" 130 | checksum = "d8fb2d74254a3a0b5cac33ac9f8ed0e44aa50378d9dbb2e5d83bd21ed1dc2c8a" 131 | dependencies = [ 132 | "arrayref", 133 | "arrayvec", 134 | "constant_time_eq", 135 | ] 136 | 137 | [[package]] 138 | name = "byteorder" 139 | version = "1.3.4" 140 | source = "registry+https://github.com/rust-lang/crates.io-index" 141 | checksum = "08c48aae112d48ed9f069b33538ea9e3e90aa263cfa3d1c24309612b1f7472de" 142 | 143 | [[package]] 144 | name = "cargo-inspect" 145 | version = "0.10.3" 146 | dependencies = [ 147 | "ansi_term 0.12.1", 148 | "difference", 149 | "env_logger", 150 | "failure", 151 | "indicatif", 152 | "log", 153 | "prettyprint", 154 | "structopt", 155 | "syntect", 156 | "tempfile", 157 | ] 158 | 159 | [[package]] 160 | name = "cc" 161 | version = "1.0.54" 162 | source = "registry+https://github.com/rust-lang/crates.io-index" 163 | checksum = "7bbb73db36c1246e9034e307d0fba23f9a2e251faa47ade70c1bd252220c8311" 164 | 165 | [[package]] 166 | name = "cfg-if" 167 | version = "0.1.10" 168 | source = "registry+https://github.com/rust-lang/crates.io-index" 169 | checksum = "4785bdd1c96b2a846b2bd7cc02e86b6b3dbf14e7e53446c4f54c92a361040822" 170 | 171 | [[package]] 172 | name = "cfg-if" 173 | version = "1.0.0" 174 | source = "registry+https://github.com/rust-lang/crates.io-index" 175 | checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" 176 | 177 | [[package]] 178 | name = "chrono" 179 | version = "0.4.11" 180 | source = "registry+https://github.com/rust-lang/crates.io-index" 181 | checksum = "80094f509cf8b5ae86a4966a39b3ff66cd7e2a3e594accec3743ff3fabeab5b2" 182 | dependencies = [ 183 | "num-integer", 184 | "num-traits", 185 | ] 186 | 187 | [[package]] 188 | name = "clap" 189 | version = "2.33.1" 190 | source = "registry+https://github.com/rust-lang/crates.io-index" 191 | checksum = "bdfa80d47f954d53a35a64987ca1422f495b8d6483c0fe9f7117b36c2a792129" 192 | dependencies = [ 193 | "ansi_term 0.11.0", 194 | "atty", 195 | "bitflags", 196 | "strsim 0.8.0", 197 | "textwrap", 198 | "unicode-width", 199 | "vec_map", 200 | ] 201 | 202 | [[package]] 203 | name = "clicolors-control" 204 | version = "1.0.1" 205 | source = "registry+https://github.com/rust-lang/crates.io-index" 206 | checksum = "90082ee5dcdd64dc4e9e0d37fbf3ee325419e39c0092191e0393df65518f741e" 207 | dependencies = [ 208 | "atty", 209 | "lazy_static", 210 | "libc", 211 | "winapi", 212 | ] 213 | 214 | [[package]] 215 | name = "console" 216 | version = "0.10.3" 217 | source = "registry+https://github.com/rust-lang/crates.io-index" 218 | checksum = "2586208b33573b7f76ccfbe5adb076394c88deaf81b84d7213969805b0a952a7" 219 | dependencies = [ 220 | "clicolors-control", 221 | "encode_unicode", 222 | "lazy_static", 223 | "libc", 224 | "regex", 225 | "terminal_size", 226 | "termios", 227 | "unicode-width", 228 | "winapi", 229 | ] 230 | 231 | [[package]] 232 | name = "console" 233 | version = "0.11.3" 234 | source = "registry+https://github.com/rust-lang/crates.io-index" 235 | checksum = "8c0994e656bba7b922d8dd1245db90672ffb701e684e45be58f20719d69abc5a" 236 | dependencies = [ 237 | "encode_unicode", 238 | "lazy_static", 239 | "libc", 240 | "regex", 241 | "terminal_size", 242 | "termios", 243 | "unicode-width", 244 | "winapi", 245 | "winapi-util", 246 | ] 247 | 248 | [[package]] 249 | name = "constant_time_eq" 250 | version = "0.1.5" 251 | source = "registry+https://github.com/rust-lang/crates.io-index" 252 | checksum = "245097e9a4535ee1e3e3931fcfcd55a796a44c643e8596ff6566d68f09b87bbc" 253 | 254 | [[package]] 255 | name = "content_inspector" 256 | version = "0.2.4" 257 | source = "registry+https://github.com/rust-lang/crates.io-index" 258 | checksum = "b7bda66e858c683005a53a9a60c69a4aca7eeaa45d124526e389f7aec8e62f38" 259 | dependencies = [ 260 | "memchr", 261 | ] 262 | 263 | [[package]] 264 | name = "crc32fast" 265 | version = "1.2.0" 266 | source = "registry+https://github.com/rust-lang/crates.io-index" 267 | checksum = "ba125de2af0df55319f41944744ad91c71113bf74a4646efff39afe1f6842db1" 268 | dependencies = [ 269 | "cfg-if 0.1.10", 270 | ] 271 | 272 | [[package]] 273 | name = "crossbeam-utils" 274 | version = "0.7.2" 275 | source = "registry+https://github.com/rust-lang/crates.io-index" 276 | checksum = "c3c7c73a2d1e9fc0886a08b93e98eb643461230d5f1925e4036204d5f2e261a8" 277 | dependencies = [ 278 | "autocfg", 279 | "cfg-if 0.1.10", 280 | "lazy_static", 281 | ] 282 | 283 | [[package]] 284 | name = "darling" 285 | version = "0.10.2" 286 | source = "registry+https://github.com/rust-lang/crates.io-index" 287 | checksum = "0d706e75d87e35569db781a9b5e2416cff1236a47ed380831f959382ccd5f858" 288 | dependencies = [ 289 | "darling_core", 290 | "darling_macro", 291 | ] 292 | 293 | [[package]] 294 | name = "darling_core" 295 | version = "0.10.2" 296 | source = "registry+https://github.com/rust-lang/crates.io-index" 297 | checksum = "f0c960ae2da4de88a91b2d920c2a7233b400bc33cb28453a2987822d8392519b" 298 | dependencies = [ 299 | "fnv", 300 | "ident_case", 301 | "proc-macro2", 302 | "quote", 303 | "strsim 0.9.3", 304 | "syn", 305 | ] 306 | 307 | [[package]] 308 | name = "darling_macro" 309 | version = "0.10.2" 310 | source = "registry+https://github.com/rust-lang/crates.io-index" 311 | checksum = "d9b5a2f4ac4969822c62224815d069952656cadc7084fdca9751e6d959189b72" 312 | dependencies = [ 313 | "darling_core", 314 | "quote", 315 | "syn", 316 | ] 317 | 318 | [[package]] 319 | name = "derive_builder" 320 | version = "0.9.0" 321 | source = "registry+https://github.com/rust-lang/crates.io-index" 322 | checksum = "a2658621297f2cf68762a6f7dc0bb7e1ff2cfd6583daef8ee0fed6f7ec468ec0" 323 | dependencies = [ 324 | "darling", 325 | "derive_builder_core", 326 | "proc-macro2", 327 | "quote", 328 | "syn", 329 | ] 330 | 331 | [[package]] 332 | name = "derive_builder_core" 333 | version = "0.9.0" 334 | source = "registry+https://github.com/rust-lang/crates.io-index" 335 | checksum = "2791ea3e372c8495c0bc2033991d76b512cd799d07491fbd6890124db9458bef" 336 | dependencies = [ 337 | "darling", 338 | "proc-macro2", 339 | "quote", 340 | "syn", 341 | ] 342 | 343 | [[package]] 344 | name = "difference" 345 | version = "2.0.0" 346 | source = "registry+https://github.com/rust-lang/crates.io-index" 347 | checksum = "524cbf6897b527295dff137cec09ecf3a05f4fddffd7dfcd1585403449e74198" 348 | 349 | [[package]] 350 | name = "directories" 351 | version = "2.0.2" 352 | source = "registry+https://github.com/rust-lang/crates.io-index" 353 | checksum = "551a778172a450d7fc12e629ca3b0428d00f6afa9a43da1b630d54604e97371c" 354 | dependencies = [ 355 | "cfg-if 0.1.10", 356 | "dirs-sys", 357 | ] 358 | 359 | [[package]] 360 | name = "dirs-sys" 361 | version = "0.3.4" 362 | source = "registry+https://github.com/rust-lang/crates.io-index" 363 | checksum = "afa0b23de8fd801745c471deffa6e12d248f962c9fd4b4c33787b055599bde7b" 364 | dependencies = [ 365 | "cfg-if 0.1.10", 366 | "libc", 367 | "redox_users", 368 | "winapi", 369 | ] 370 | 371 | [[package]] 372 | name = "encode_unicode" 373 | version = "0.3.6" 374 | source = "registry+https://github.com/rust-lang/crates.io-index" 375 | checksum = "a357d28ed41a50f9c765dbfe56cbc04a64e53e5fc58ba79fbc34c10ef3df831f" 376 | 377 | [[package]] 378 | name = "encoding" 379 | version = "0.2.33" 380 | source = "registry+https://github.com/rust-lang/crates.io-index" 381 | checksum = "6b0d943856b990d12d3b55b359144ff341533e516d94098b1d3fc1ac666d36ec" 382 | dependencies = [ 383 | "encoding-index-japanese", 384 | "encoding-index-korean", 385 | "encoding-index-simpchinese", 386 | "encoding-index-singlebyte", 387 | "encoding-index-tradchinese", 388 | ] 389 | 390 | [[package]] 391 | name = "encoding-index-japanese" 392 | version = "1.20141219.5" 393 | source = "registry+https://github.com/rust-lang/crates.io-index" 394 | checksum = "04e8b2ff42e9a05335dbf8b5c6f7567e5591d0d916ccef4e0b1710d32a0d0c91" 395 | dependencies = [ 396 | "encoding_index_tests", 397 | ] 398 | 399 | [[package]] 400 | name = "encoding-index-korean" 401 | version = "1.20141219.5" 402 | source = "registry+https://github.com/rust-lang/crates.io-index" 403 | checksum = "4dc33fb8e6bcba213fe2f14275f0963fd16f0a02c878e3095ecfdf5bee529d81" 404 | dependencies = [ 405 | "encoding_index_tests", 406 | ] 407 | 408 | [[package]] 409 | name = "encoding-index-simpchinese" 410 | version = "1.20141219.5" 411 | source = "registry+https://github.com/rust-lang/crates.io-index" 412 | checksum = "d87a7194909b9118fc707194baa434a4e3b0fb6a5a757c73c3adb07aa25031f7" 413 | dependencies = [ 414 | "encoding_index_tests", 415 | ] 416 | 417 | [[package]] 418 | name = "encoding-index-singlebyte" 419 | version = "1.20141219.5" 420 | source = "registry+https://github.com/rust-lang/crates.io-index" 421 | checksum = "3351d5acffb224af9ca265f435b859c7c01537c0849754d3db3fdf2bfe2ae84a" 422 | dependencies = [ 423 | "encoding_index_tests", 424 | ] 425 | 426 | [[package]] 427 | name = "encoding-index-tradchinese" 428 | version = "1.20141219.5" 429 | source = "registry+https://github.com/rust-lang/crates.io-index" 430 | checksum = "fd0e20d5688ce3cab59eb3ef3a2083a5c77bf496cb798dc6fcdb75f323890c18" 431 | dependencies = [ 432 | "encoding_index_tests", 433 | ] 434 | 435 | [[package]] 436 | name = "encoding_index_tests" 437 | version = "0.1.4" 438 | source = "registry+https://github.com/rust-lang/crates.io-index" 439 | checksum = "a246d82be1c9d791c5dfde9a2bd045fc3cbba3fa2b11ad558f27d01712f00569" 440 | 441 | [[package]] 442 | name = "env_logger" 443 | version = "0.9.1" 444 | source = "registry+https://github.com/rust-lang/crates.io-index" 445 | checksum = "c90bf5f19754d10198ccb95b70664fc925bd1fc090a0fd9a6ebc54acc8cd6272" 446 | dependencies = [ 447 | "atty", 448 | "humantime", 449 | "log", 450 | "regex", 451 | "termcolor", 452 | ] 453 | 454 | [[package]] 455 | name = "error-chain" 456 | version = "0.12.2" 457 | source = "registry+https://github.com/rust-lang/crates.io-index" 458 | checksum = "d371106cc88ffdfb1eabd7111e432da544f16f3e2d7bf1dfe8bf575f1df045cd" 459 | dependencies = [ 460 | "backtrace", 461 | "version_check", 462 | ] 463 | 464 | [[package]] 465 | name = "failure" 466 | version = "0.1.8" 467 | source = "registry+https://github.com/rust-lang/crates.io-index" 468 | checksum = "d32e9bd16cc02eae7db7ef620b392808b89f6a5e16bb3497d159c6b92a0f4f86" 469 | dependencies = [ 470 | "backtrace", 471 | "failure_derive", 472 | ] 473 | 474 | [[package]] 475 | name = "failure_derive" 476 | version = "0.1.8" 477 | source = "registry+https://github.com/rust-lang/crates.io-index" 478 | checksum = "aa4da3c766cd7a0db8242e326e9e4e081edd567072893ed320008189715366a4" 479 | dependencies = [ 480 | "proc-macro2", 481 | "quote", 482 | "syn", 483 | "synstructure", 484 | ] 485 | 486 | [[package]] 487 | name = "fastrand" 488 | version = "1.6.0" 489 | source = "registry+https://github.com/rust-lang/crates.io-index" 490 | checksum = "779d043b6a0b90cc4c0ed7ee380a6504394cee7efd7db050e3774eee387324b2" 491 | dependencies = [ 492 | "instant", 493 | ] 494 | 495 | [[package]] 496 | name = "flate2" 497 | version = "1.0.14" 498 | source = "registry+https://github.com/rust-lang/crates.io-index" 499 | checksum = "2cfff41391129e0a856d6d822600b8d71179d46879e310417eb9c762eb178b42" 500 | dependencies = [ 501 | "cfg-if 0.1.10", 502 | "crc32fast", 503 | "libc", 504 | "miniz_oxide", 505 | ] 506 | 507 | [[package]] 508 | name = "fnv" 509 | version = "1.0.7" 510 | source = "registry+https://github.com/rust-lang/crates.io-index" 511 | checksum = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1" 512 | 513 | [[package]] 514 | name = "getrandom" 515 | version = "0.1.14" 516 | source = "registry+https://github.com/rust-lang/crates.io-index" 517 | checksum = "7abc8dd8451921606d809ba32e95b6111925cd2906060d2dcc29c070220503eb" 518 | dependencies = [ 519 | "cfg-if 0.1.10", 520 | "libc", 521 | "wasi", 522 | ] 523 | 524 | [[package]] 525 | name = "gimli" 526 | version = "0.21.0" 527 | source = "registry+https://github.com/rust-lang/crates.io-index" 528 | checksum = "bcc8e0c9bce37868955864dbecd2b1ab2bdf967e6f28066d65aaac620444b65c" 529 | 530 | [[package]] 531 | name = "heck" 532 | version = "0.3.1" 533 | source = "registry+https://github.com/rust-lang/crates.io-index" 534 | checksum = "20564e78d53d2bb135c343b3f47714a56af2061f1c928fdb541dc7b9fdd94205" 535 | dependencies = [ 536 | "unicode-segmentation", 537 | ] 538 | 539 | [[package]] 540 | name = "hermit-abi" 541 | version = "0.1.13" 542 | source = "registry+https://github.com/rust-lang/crates.io-index" 543 | checksum = "91780f809e750b0a89f5544be56617ff6b1227ee485bcb06ebe10cdf89bd3b71" 544 | dependencies = [ 545 | "libc", 546 | ] 547 | 548 | [[package]] 549 | name = "humantime" 550 | version = "2.0.1" 551 | source = "registry+https://github.com/rust-lang/crates.io-index" 552 | checksum = "3c1ad908cc71012b7bea4d0c53ba96a8cba9962f048fa68d143376143d863b7a" 553 | 554 | [[package]] 555 | name = "ident_case" 556 | version = "1.0.1" 557 | source = "registry+https://github.com/rust-lang/crates.io-index" 558 | checksum = "b9e0384b61958566e926dc50660321d12159025e767c18e043daf26b70104c39" 559 | 560 | [[package]] 561 | name = "indexmap" 562 | version = "1.4.0" 563 | source = "registry+https://github.com/rust-lang/crates.io-index" 564 | checksum = "c398b2b113b55809ceb9ee3e753fcbac793f1956663f3c36549c1346015c2afe" 565 | dependencies = [ 566 | "autocfg", 567 | ] 568 | 569 | [[package]] 570 | name = "indicatif" 571 | version = "0.15.0" 572 | source = "registry+https://github.com/rust-lang/crates.io-index" 573 | checksum = "7baab56125e25686df467fe470785512329883aab42696d661247aca2a2896e4" 574 | dependencies = [ 575 | "console 0.11.3", 576 | "lazy_static", 577 | "number_prefix", 578 | "regex", 579 | ] 580 | 581 | [[package]] 582 | name = "instant" 583 | version = "0.1.12" 584 | source = "registry+https://github.com/rust-lang/crates.io-index" 585 | checksum = "7a5bbe824c507c5da5956355e86a746d82e0e1464f65d862cc5e71da70e94b2c" 586 | dependencies = [ 587 | "cfg-if 1.0.0", 588 | ] 589 | 590 | [[package]] 591 | name = "itoa" 592 | version = "0.4.5" 593 | source = "registry+https://github.com/rust-lang/crates.io-index" 594 | checksum = "b8b7a7c0c47db5545ed3fef7468ee7bb5b74691498139e4b3f6a20685dc6dd8e" 595 | 596 | [[package]] 597 | name = "lazy_static" 598 | version = "1.4.0" 599 | source = "registry+https://github.com/rust-lang/crates.io-index" 600 | checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646" 601 | 602 | [[package]] 603 | name = "libc" 604 | version = "0.2.71" 605 | source = "registry+https://github.com/rust-lang/crates.io-index" 606 | checksum = "9457b06509d27052635f90d6466700c65095fdf75409b3fbdd903e988b886f49" 607 | 608 | [[package]] 609 | name = "line-wrap" 610 | version = "0.1.1" 611 | source = "registry+https://github.com/rust-lang/crates.io-index" 612 | checksum = "f30344350a2a51da54c1d53be93fade8a237e545dbcc4bdbe635413f2117cab9" 613 | dependencies = [ 614 | "safemem", 615 | ] 616 | 617 | [[package]] 618 | name = "linked-hash-map" 619 | version = "0.5.3" 620 | source = "registry+https://github.com/rust-lang/crates.io-index" 621 | checksum = "8dd5a6d5999d9907cda8ed67bbd137d3af8085216c2ac62de5be860bd41f304a" 622 | 623 | [[package]] 624 | name = "log" 625 | version = "0.4.17" 626 | source = "registry+https://github.com/rust-lang/crates.io-index" 627 | checksum = "abb12e687cfb44aa40f41fc3978ef76448f9b6038cad6aef4259d3c095a2382e" 628 | dependencies = [ 629 | "cfg-if 1.0.0", 630 | ] 631 | 632 | [[package]] 633 | name = "memchr" 634 | version = "2.3.3" 635 | source = "registry+https://github.com/rust-lang/crates.io-index" 636 | checksum = "3728d817d99e5ac407411fa471ff9800a778d88a24685968b36824eaf4bee400" 637 | 638 | [[package]] 639 | name = "miniz_oxide" 640 | version = "0.3.6" 641 | source = "registry+https://github.com/rust-lang/crates.io-index" 642 | checksum = "aa679ff6578b1cddee93d7e82e263b94a575e0bfced07284eb0c037c1d2416a5" 643 | dependencies = [ 644 | "adler32", 645 | ] 646 | 647 | [[package]] 648 | name = "num-integer" 649 | version = "0.1.42" 650 | source = "registry+https://github.com/rust-lang/crates.io-index" 651 | checksum = "3f6ea62e9d81a77cd3ee9a2a5b9b609447857f3d358704331e4ef39eb247fcba" 652 | dependencies = [ 653 | "autocfg", 654 | "num-traits", 655 | ] 656 | 657 | [[package]] 658 | name = "num-traits" 659 | version = "0.2.11" 660 | source = "registry+https://github.com/rust-lang/crates.io-index" 661 | checksum = "c62be47e61d1842b9170f0fdeec8eba98e60e90e5446449a0545e5152acd7096" 662 | dependencies = [ 663 | "autocfg", 664 | ] 665 | 666 | [[package]] 667 | name = "number_prefix" 668 | version = "0.3.0" 669 | source = "registry+https://github.com/rust-lang/crates.io-index" 670 | checksum = "17b02fc0ff9a9e4b35b3342880f48e896ebf69f2967921fe8646bf5b7125956a" 671 | 672 | [[package]] 673 | name = "object" 674 | version = "0.19.0" 675 | source = "registry+https://github.com/rust-lang/crates.io-index" 676 | checksum = "9cbca9424c482ee628fa549d9c812e2cd22f1180b9222c9200fdfa6eb31aecb2" 677 | 678 | [[package]] 679 | name = "once_cell" 680 | version = "1.9.0" 681 | source = "registry+https://github.com/rust-lang/crates.io-index" 682 | checksum = "da32515d9f6e6e489d7bc9d84c71b060db7247dc035bbe44eac88cf87486d8d5" 683 | 684 | [[package]] 685 | name = "onig" 686 | version = "6.0.0" 687 | source = "registry+https://github.com/rust-lang/crates.io-index" 688 | checksum = "bd91ccd8a02fce2f7e8a86655aec67bc6c171e6f8e704118a0e8c4b866a05a8a" 689 | dependencies = [ 690 | "bitflags", 691 | "lazy_static", 692 | "libc", 693 | "onig_sys", 694 | ] 695 | 696 | [[package]] 697 | name = "onig_sys" 698 | version = "69.5.0" 699 | source = "registry+https://github.com/rust-lang/crates.io-index" 700 | checksum = "3814583fad89f3c60ae0701d80e87e1fd3028741723deda72d0d4a0ecf0cb0db" 701 | dependencies = [ 702 | "cc", 703 | "pkg-config", 704 | ] 705 | 706 | [[package]] 707 | name = "pkg-config" 708 | version = "0.3.17" 709 | source = "registry+https://github.com/rust-lang/crates.io-index" 710 | checksum = "05da548ad6865900e60eaba7f589cc0783590a92e940c26953ff81ddbab2d677" 711 | 712 | [[package]] 713 | name = "plist" 714 | version = "1.0.0" 715 | source = "registry+https://github.com/rust-lang/crates.io-index" 716 | checksum = "7b336d94e8e4ce29bf15bba393164629764744c567e8ad306cc1fdd0119967fd" 717 | dependencies = [ 718 | "base64 0.12.1", 719 | "chrono", 720 | "indexmap", 721 | "line-wrap", 722 | "serde", 723 | "xml-rs", 724 | ] 725 | 726 | [[package]] 727 | name = "prettyprint" 728 | version = "0.8.1" 729 | source = "registry+https://github.com/rust-lang/crates.io-index" 730 | checksum = "6d9764c1ec675e49ff70c4f76f0df91875d57220c4e7c8587d659684e91dd0ac" 731 | dependencies = [ 732 | "ansi_colours", 733 | "ansi_term 0.12.1", 734 | "atty", 735 | "clap", 736 | "console 0.10.3", 737 | "content_inspector", 738 | "derive_builder", 739 | "directories", 740 | "encoding", 741 | "error-chain", 742 | "lazy_static", 743 | "shell-words", 744 | "syntect", 745 | ] 746 | 747 | [[package]] 748 | name = "proc-macro-error" 749 | version = "1.0.2" 750 | source = "registry+https://github.com/rust-lang/crates.io-index" 751 | checksum = "98e9e4b82e0ef281812565ea4751049f1bdcdfccda7d3f459f2e138a40c08678" 752 | dependencies = [ 753 | "proc-macro-error-attr", 754 | "proc-macro2", 755 | "quote", 756 | "syn", 757 | "version_check", 758 | ] 759 | 760 | [[package]] 761 | name = "proc-macro-error-attr" 762 | version = "1.0.2" 763 | source = "registry+https://github.com/rust-lang/crates.io-index" 764 | checksum = "4f5444ead4e9935abd7f27dc51f7e852a0569ac888096d5ec2499470794e2e53" 765 | dependencies = [ 766 | "proc-macro2", 767 | "quote", 768 | "syn", 769 | "syn-mid", 770 | "version_check", 771 | ] 772 | 773 | [[package]] 774 | name = "proc-macro2" 775 | version = "1.0.18" 776 | source = "registry+https://github.com/rust-lang/crates.io-index" 777 | checksum = "beae6331a816b1f65d04c45b078fd8e6c93e8071771f41b8163255bbd8d7c8fa" 778 | dependencies = [ 779 | "unicode-xid", 780 | ] 781 | 782 | [[package]] 783 | name = "quote" 784 | version = "1.0.6" 785 | source = "registry+https://github.com/rust-lang/crates.io-index" 786 | checksum = "54a21852a652ad6f610c9510194f398ff6f8692e334fd1145fed931f7fbe44ea" 787 | dependencies = [ 788 | "proc-macro2", 789 | ] 790 | 791 | [[package]] 792 | name = "redox_syscall" 793 | version = "0.1.56" 794 | source = "registry+https://github.com/rust-lang/crates.io-index" 795 | checksum = "2439c63f3f6139d1b57529d16bc3b8bb855230c8efcc5d3a896c8bea7c3b1e84" 796 | 797 | [[package]] 798 | name = "redox_syscall" 799 | version = "0.2.10" 800 | source = "registry+https://github.com/rust-lang/crates.io-index" 801 | checksum = "8383f39639269cde97d255a32bdb68c047337295414940c68bdd30c2e13203ff" 802 | dependencies = [ 803 | "bitflags", 804 | ] 805 | 806 | [[package]] 807 | name = "redox_users" 808 | version = "0.3.4" 809 | source = "registry+https://github.com/rust-lang/crates.io-index" 810 | checksum = "09b23093265f8d200fa7b4c2c76297f47e681c655f6f1285a8780d6a022f7431" 811 | dependencies = [ 812 | "getrandom", 813 | "redox_syscall 0.1.56", 814 | "rust-argon2", 815 | ] 816 | 817 | [[package]] 818 | name = "regex" 819 | version = "1.3.9" 820 | source = "registry+https://github.com/rust-lang/crates.io-index" 821 | checksum = "9c3780fcf44b193bc4d09f36d2a3c87b251da4a046c87795a0d35f4f927ad8e6" 822 | dependencies = [ 823 | "aho-corasick", 824 | "memchr", 825 | "regex-syntax", 826 | "thread_local", 827 | ] 828 | 829 | [[package]] 830 | name = "regex-syntax" 831 | version = "0.6.18" 832 | source = "registry+https://github.com/rust-lang/crates.io-index" 833 | checksum = "26412eb97c6b088a6997e05f69403a802a92d520de2f8e63c2b65f9e0f47c4e8" 834 | 835 | [[package]] 836 | name = "remove_dir_all" 837 | version = "0.5.2" 838 | source = "registry+https://github.com/rust-lang/crates.io-index" 839 | checksum = "4a83fa3702a688b9359eccba92d153ac33fd2e8462f9e0e3fdf155239ea7792e" 840 | dependencies = [ 841 | "winapi", 842 | ] 843 | 844 | [[package]] 845 | name = "rust-argon2" 846 | version = "0.7.0" 847 | source = "registry+https://github.com/rust-lang/crates.io-index" 848 | checksum = "2bc8af4bda8e1ff4932523b94d3dd20ee30a87232323eda55903ffd71d2fb017" 849 | dependencies = [ 850 | "base64 0.11.0", 851 | "blake2b_simd", 852 | "constant_time_eq", 853 | "crossbeam-utils", 854 | ] 855 | 856 | [[package]] 857 | name = "rustc-demangle" 858 | version = "0.1.16" 859 | source = "registry+https://github.com/rust-lang/crates.io-index" 860 | checksum = "4c691c0e608126e00913e33f0ccf3727d5fc84573623b8d65b2df340b5201783" 861 | 862 | [[package]] 863 | name = "ryu" 864 | version = "1.0.5" 865 | source = "registry+https://github.com/rust-lang/crates.io-index" 866 | checksum = "71d301d4193d031abdd79ff7e3dd721168a9572ef3fe51a1517aba235bd8f86e" 867 | 868 | [[package]] 869 | name = "safemem" 870 | version = "0.3.3" 871 | source = "registry+https://github.com/rust-lang/crates.io-index" 872 | checksum = "ef703b7cb59335eae2eb93ceb664c0eb7ea6bf567079d843e09420219668e072" 873 | 874 | [[package]] 875 | name = "same-file" 876 | version = "1.0.6" 877 | source = "registry+https://github.com/rust-lang/crates.io-index" 878 | checksum = "93fc1dc3aaa9bfed95e02e6eadabb4baf7e3078b0bd1b4d7b6b0b68378900502" 879 | dependencies = [ 880 | "winapi-util", 881 | ] 882 | 883 | [[package]] 884 | name = "serde" 885 | version = "1.0.111" 886 | source = "registry+https://github.com/rust-lang/crates.io-index" 887 | checksum = "c9124df5b40cbd380080b2cc6ab894c040a3070d995f5c9dc77e18c34a8ae37d" 888 | 889 | [[package]] 890 | name = "serde_derive" 891 | version = "1.0.111" 892 | source = "registry+https://github.com/rust-lang/crates.io-index" 893 | checksum = "3f2c3ac8e6ca1e9c80b8be1023940162bf81ae3cffbb1809474152f2ce1eb250" 894 | dependencies = [ 895 | "proc-macro2", 896 | "quote", 897 | "syn", 898 | ] 899 | 900 | [[package]] 901 | name = "serde_json" 902 | version = "1.0.53" 903 | source = "registry+https://github.com/rust-lang/crates.io-index" 904 | checksum = "993948e75b189211a9b31a7528f950c6adc21f9720b6438ff80a7fa2f864cea2" 905 | dependencies = [ 906 | "itoa", 907 | "ryu", 908 | "serde", 909 | ] 910 | 911 | [[package]] 912 | name = "shell-words" 913 | version = "0.1.0" 914 | source = "registry+https://github.com/rust-lang/crates.io-index" 915 | checksum = "39acde55a154c4cd3ae048ac78cc21c25f3a0145e44111b523279113dce0d94a" 916 | 917 | [[package]] 918 | name = "strsim" 919 | version = "0.8.0" 920 | source = "registry+https://github.com/rust-lang/crates.io-index" 921 | checksum = "8ea5119cdb4c55b55d432abb513a0429384878c15dde60cc77b1c99de1a95a6a" 922 | 923 | [[package]] 924 | name = "strsim" 925 | version = "0.9.3" 926 | source = "registry+https://github.com/rust-lang/crates.io-index" 927 | checksum = "6446ced80d6c486436db5c078dde11a9f73d42b57fb273121e160b84f63d894c" 928 | 929 | [[package]] 930 | name = "structopt" 931 | version = "0.3.26" 932 | source = "registry+https://github.com/rust-lang/crates.io-index" 933 | checksum = "0c6b5c64445ba8094a6ab0c3cd2ad323e07171012d9c98b0b15651daf1787a10" 934 | dependencies = [ 935 | "clap", 936 | "lazy_static", 937 | "structopt-derive", 938 | ] 939 | 940 | [[package]] 941 | name = "structopt-derive" 942 | version = "0.4.18" 943 | source = "registry+https://github.com/rust-lang/crates.io-index" 944 | checksum = "dcb5ae327f9cc13b68763b5749770cb9e048a99bd9dfdfa58d0cf05d5f64afe0" 945 | dependencies = [ 946 | "heck", 947 | "proc-macro-error", 948 | "proc-macro2", 949 | "quote", 950 | "syn", 951 | ] 952 | 953 | [[package]] 954 | name = "syn" 955 | version = "1.0.30" 956 | source = "registry+https://github.com/rust-lang/crates.io-index" 957 | checksum = "93a56fabc59dce20fe48b6c832cc249c713e7ed88fa28b0ee0a3bfcaae5fe4e2" 958 | dependencies = [ 959 | "proc-macro2", 960 | "quote", 961 | "unicode-xid", 962 | ] 963 | 964 | [[package]] 965 | name = "syn-mid" 966 | version = "0.5.0" 967 | source = "registry+https://github.com/rust-lang/crates.io-index" 968 | checksum = "7be3539f6c128a931cf19dcee741c1af532c7fd387baa739c03dd2e96479338a" 969 | dependencies = [ 970 | "proc-macro2", 971 | "quote", 972 | "syn", 973 | ] 974 | 975 | [[package]] 976 | name = "synstructure" 977 | version = "0.12.3" 978 | source = "registry+https://github.com/rust-lang/crates.io-index" 979 | checksum = "67656ea1dc1b41b1451851562ea232ec2e5a80242139f7e679ceccfb5d61f545" 980 | dependencies = [ 981 | "proc-macro2", 982 | "quote", 983 | "syn", 984 | "unicode-xid", 985 | ] 986 | 987 | [[package]] 988 | name = "syntect" 989 | version = "4.7.1" 990 | source = "registry+https://github.com/rust-lang/crates.io-index" 991 | checksum = "ec9c431748126d4e82a8ee28a29fddcc276357ebb9a67d01175633b307413496" 992 | dependencies = [ 993 | "bincode", 994 | "bitflags", 995 | "flate2", 996 | "fnv", 997 | "lazy_static", 998 | "once_cell", 999 | "onig", 1000 | "plist", 1001 | "regex-syntax", 1002 | "serde", 1003 | "serde_derive", 1004 | "serde_json", 1005 | "walkdir", 1006 | "yaml-rust", 1007 | ] 1008 | 1009 | [[package]] 1010 | name = "tempfile" 1011 | version = "3.3.0" 1012 | source = "registry+https://github.com/rust-lang/crates.io-index" 1013 | checksum = "5cdb1ef4eaeeaddc8fbd371e5017057064af0911902ef36b39801f67cc6d79e4" 1014 | dependencies = [ 1015 | "cfg-if 1.0.0", 1016 | "fastrand", 1017 | "libc", 1018 | "redox_syscall 0.2.10", 1019 | "remove_dir_all", 1020 | "winapi", 1021 | ] 1022 | 1023 | [[package]] 1024 | name = "termcolor" 1025 | version = "1.1.3" 1026 | source = "registry+https://github.com/rust-lang/crates.io-index" 1027 | checksum = "bab24d30b911b2376f3a13cc2cd443142f0c81dda04c118693e35b3835757755" 1028 | dependencies = [ 1029 | "winapi-util", 1030 | ] 1031 | 1032 | [[package]] 1033 | name = "terminal_size" 1034 | version = "0.1.12" 1035 | source = "registry+https://github.com/rust-lang/crates.io-index" 1036 | checksum = "8038f95fc7a6f351163f4b964af631bd26c9e828f7db085f2a84aca56f70d13b" 1037 | dependencies = [ 1038 | "libc", 1039 | "winapi", 1040 | ] 1041 | 1042 | [[package]] 1043 | name = "termios" 1044 | version = "0.3.2" 1045 | source = "registry+https://github.com/rust-lang/crates.io-index" 1046 | checksum = "6f0fcee7b24a25675de40d5bb4de6e41b0df07bc9856295e7e2b3a3600c400c2" 1047 | dependencies = [ 1048 | "libc", 1049 | ] 1050 | 1051 | [[package]] 1052 | name = "textwrap" 1053 | version = "0.11.0" 1054 | source = "registry+https://github.com/rust-lang/crates.io-index" 1055 | checksum = "d326610f408c7a4eb6f51c37c330e496b08506c9457c9d34287ecc38809fb060" 1056 | dependencies = [ 1057 | "unicode-width", 1058 | ] 1059 | 1060 | [[package]] 1061 | name = "thread_local" 1062 | version = "1.0.1" 1063 | source = "registry+https://github.com/rust-lang/crates.io-index" 1064 | checksum = "d40c6d1b69745a6ec6fb1ca717914848da4b44ae29d9b3080cbee91d72a69b14" 1065 | dependencies = [ 1066 | "lazy_static", 1067 | ] 1068 | 1069 | [[package]] 1070 | name = "unicode-segmentation" 1071 | version = "1.6.0" 1072 | source = "registry+https://github.com/rust-lang/crates.io-index" 1073 | checksum = "e83e153d1053cbb5a118eeff7fd5be06ed99153f00dbcd8ae310c5fb2b22edc0" 1074 | 1075 | [[package]] 1076 | name = "unicode-width" 1077 | version = "0.1.7" 1078 | source = "registry+https://github.com/rust-lang/crates.io-index" 1079 | checksum = "caaa9d531767d1ff2150b9332433f32a24622147e5ebb1f26409d5da67afd479" 1080 | 1081 | [[package]] 1082 | name = "unicode-xid" 1083 | version = "0.2.0" 1084 | source = "registry+https://github.com/rust-lang/crates.io-index" 1085 | checksum = "826e7639553986605ec5979c7dd957c7895e93eabed50ab2ffa7f6128a75097c" 1086 | 1087 | [[package]] 1088 | name = "vec_map" 1089 | version = "0.8.2" 1090 | source = "registry+https://github.com/rust-lang/crates.io-index" 1091 | checksum = "f1bddf1187be692e79c5ffeab891132dfb0f236ed36a43c7ed39f1165ee20191" 1092 | 1093 | [[package]] 1094 | name = "version_check" 1095 | version = "0.9.2" 1096 | source = "registry+https://github.com/rust-lang/crates.io-index" 1097 | checksum = "b5a972e5669d67ba988ce3dc826706fb0a8b01471c088cb0b6110b805cc36aed" 1098 | 1099 | [[package]] 1100 | name = "walkdir" 1101 | version = "2.3.1" 1102 | source = "registry+https://github.com/rust-lang/crates.io-index" 1103 | checksum = "777182bc735b6424e1a57516d35ed72cb8019d85c8c9bf536dccb3445c1a2f7d" 1104 | dependencies = [ 1105 | "same-file", 1106 | "winapi", 1107 | "winapi-util", 1108 | ] 1109 | 1110 | [[package]] 1111 | name = "wasi" 1112 | version = "0.9.0+wasi-snapshot-preview1" 1113 | source = "registry+https://github.com/rust-lang/crates.io-index" 1114 | checksum = "cccddf32554fecc6acb585f82a32a72e28b48f8c4c1883ddfeeeaa96f7d8e519" 1115 | 1116 | [[package]] 1117 | name = "winapi" 1118 | version = "0.3.8" 1119 | source = "registry+https://github.com/rust-lang/crates.io-index" 1120 | checksum = "8093091eeb260906a183e6ae1abdba2ef5ef2257a21801128899c3fc699229c6" 1121 | dependencies = [ 1122 | "winapi-i686-pc-windows-gnu", 1123 | "winapi-x86_64-pc-windows-gnu", 1124 | ] 1125 | 1126 | [[package]] 1127 | name = "winapi-i686-pc-windows-gnu" 1128 | version = "0.4.0" 1129 | source = "registry+https://github.com/rust-lang/crates.io-index" 1130 | checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6" 1131 | 1132 | [[package]] 1133 | name = "winapi-util" 1134 | version = "0.1.5" 1135 | source = "registry+https://github.com/rust-lang/crates.io-index" 1136 | checksum = "70ec6ce85bb158151cae5e5c87f95a8e97d2c0c4b001223f33a334e3ce5de178" 1137 | dependencies = [ 1138 | "winapi", 1139 | ] 1140 | 1141 | [[package]] 1142 | name = "winapi-x86_64-pc-windows-gnu" 1143 | version = "0.4.0" 1144 | source = "registry+https://github.com/rust-lang/crates.io-index" 1145 | checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" 1146 | 1147 | [[package]] 1148 | name = "xml-rs" 1149 | version = "0.8.3" 1150 | source = "registry+https://github.com/rust-lang/crates.io-index" 1151 | checksum = "b07db065a5cf61a7e4ba64f29e67db906fb1787316516c4e6e5ff0fea1efcd8a" 1152 | 1153 | [[package]] 1154 | name = "yaml-rust" 1155 | version = "0.4.5" 1156 | source = "registry+https://github.com/rust-lang/crates.io-index" 1157 | checksum = "56c1936c4cc7a1c9ab21a1ebb602eb942ba868cbd44a99cb7cdc5892335e1c85" 1158 | dependencies = [ 1159 | "linked-hash-map", 1160 | ] 1161 | --------------------------------------------------------------------------------