├── .gitignore ├── .travis.yml ├── .circleci └── config.yml ├── src ├── message.rs ├── bench.rs ├── plan.rs ├── runner.rs ├── collector.rs ├── chart.rs ├── content_length.rs ├── main.rs ├── engine.rs └── stats.rs ├── Cargo.toml ├── LICENSE ├── CHANGELOG.md ├── README.md └── Cargo.lock /.gitignore: -------------------------------------------------------------------------------- 1 | 2 | /target/ 3 | **/*.rs.bk 4 | -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | language: rust 2 | rust: 3 | - stable 4 | - beta 5 | - nightly 6 | -------------------------------------------------------------------------------- /.circleci/config.yml: -------------------------------------------------------------------------------- 1 | version: 2 2 | jobs: 3 | build: 4 | docker: 5 | - image: rust:latest 6 | steps: 7 | - checkout 8 | - run: 9 | name: Test 10 | command: cargo test 11 | -------------------------------------------------------------------------------- /src/message.rs: -------------------------------------------------------------------------------- 1 | /// Represents a message that can be sent along the channel from a runner 2 | /// to a collector. It needs to be returning via a join handle so the data 3 | /// is static. 4 | pub enum Message 5 | where 6 | T: 'static + Send, 7 | { 8 | Body(T), 9 | EOF, 10 | } 11 | -------------------------------------------------------------------------------- /src/bench.rs: -------------------------------------------------------------------------------- 1 | use std::time::{Duration, Instant}; 2 | 3 | /// Executes a closure once and returns how long that closure took 4 | /// as a duration. 5 | pub fn time_it(f: F) -> (U, Duration) 6 | where 7 | F: FnOnce() -> U, 8 | { 9 | let start = Instant::now(); 10 | (f(), start.elapsed()) 11 | } 12 | 13 | #[cfg(test)] 14 | mod tests { 15 | use super::*; 16 | 17 | #[test] 18 | fn reports_duration_and_response() { 19 | let (u, d) = time_it(|| 123); 20 | assert_eq!(u, 123); 21 | assert!(d > Duration::new(0, 0)); 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "rench" 3 | version = "0.3.0" 4 | readme = "README.md" 5 | 6 | repository = "https://github.com/kbacha/rench" 7 | homepage = "https://github.com/kbacha/rench" 8 | 9 | description = "A simple http benchmark utility. Written in rust... rust + bench = rench" 10 | 11 | authors = ["Kevin Choubacha "] 12 | keywords = [ 13 | "http", 14 | "benchmark", 15 | "cli" 16 | ] 17 | 18 | categories = [ 19 | "web-programming", 20 | "command-line-utilities", 21 | "command-line-interface" 22 | ] 23 | 24 | license = "MIT" 25 | 26 | [badges] 27 | circle-ci = { repository = "kbacha/rench" } 28 | travis-ci = { repository = "kbacha/rench" } 29 | 30 | [dependencies] 31 | clap = "2.29" 32 | reqwest = "0.9.9" 33 | hyper = "0.11" 34 | hyper-tls = "0.1" 35 | tokio-core = "0.1" 36 | futures = "0.1" 37 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2018 Kevin Choubacha 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 | -------------------------------------------------------------------------------- /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](http://keepachangelog.com/en/1.0.0/) 6 | and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.html). 7 | 8 | ## [Unreleased] 9 | 10 | ## [0.3.0] - 2018-06-01 11 | 12 | ### Added 13 | 14 | * Chart size option was added allowing specification of large, medium, small, or none. 15 | * Added the calculations and renderings of the standard deviation of the request latency. 16 | 17 | ### Changed 18 | 19 | * Swapped hyper for reqwest as the engine. 20 | 21 | ## [0.2.0] - 2018-04-08 22 | 23 | ### Added 24 | 25 | * Counts up the returned status codes and presents them to the user. 26 | * Can specify `-i` or `--head` to use the http method HEAD instead of GET. 27 | * Add ability to use different engines. Specifically, the `hyper` crate can now be used to issue requests as opposed to `reqwest` which wraps it. 28 | 29 | ### Fixed 30 | 31 | * Uses the byte length of the body to calculate data transferred instead of the Content-Length header which can be absent for certain encodings. 32 | -------------------------------------------------------------------------------- /src/plan.rs: -------------------------------------------------------------------------------- 1 | #[derive(Clone, Copy)] 2 | pub struct Plan { 3 | threads: usize, 4 | requests: usize, 5 | } 6 | 7 | impl Plan { 8 | pub fn new(threads: usize, requests: usize) -> Self { 9 | Self { threads, requests } 10 | } 11 | 12 | pub fn threads(&self) -> usize { 13 | self.threads 14 | } 15 | 16 | pub fn requests(&self) -> usize { 17 | self.requests 18 | } 19 | 20 | pub fn distribute(&self) -> Vec { 21 | // Every thread should get even work: 22 | let base_work = self.requests / self.threads; 23 | let remaining_work = self.requests % self.threads; 24 | 25 | (0..self.threads) 26 | .map(|thread| { 27 | // The remainder means that we don't have enough for 28 | // every thread to get 1. So we just add one until 29 | // we've used up the entire remainder 30 | if thread < remaining_work { 31 | base_work + 1 32 | } else { 33 | base_work 34 | } 35 | }) 36 | .collect() 37 | } 38 | } 39 | 40 | #[cfg(test)] 41 | mod tests { 42 | use super::*; 43 | 44 | #[test] 45 | fn it_can_distribute_all_work_as_evenly_as_possible() { 46 | assert_eq!(Plan::new(3, 1000).distribute(), vec![334, 333, 333]); 47 | assert_eq!(Plan::new(2, 1000).distribute(), vec![500, 500]); 48 | assert_eq!( 49 | Plan::new(20, 39).distribute(), 50 | vec![2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 1] 51 | ); 52 | } 53 | } 54 | -------------------------------------------------------------------------------- /src/runner.rs: -------------------------------------------------------------------------------- 1 | use engine::Engine; 2 | use plan::Plan; 3 | use message::Message; 4 | use stats::Fact; 5 | use std::{thread, sync::mpsc::Sender}; 6 | 7 | /// The runner struct represents an ongoing run time of the engine. 8 | pub struct Runner { 9 | handles: Vec>, 10 | } 11 | 12 | impl Runner { 13 | /// Launches the runner with a plan. It will tell the engine to run and broadcast the 14 | /// facts that the engine produces. The plan tells the runner how many threads to run 15 | /// on and how to distribute the work. 16 | pub fn start(plan: Plan, eng: &Engine, collector: &Sender>) -> Runner { 17 | let handles = plan.distribute() 18 | .into_iter() 19 | .map(|work| { 20 | let collector = collector.clone(); 21 | let eng = eng.clone(); 22 | thread::spawn(move || Self::run(work, eng, &collector)) 23 | }) 24 | .collect(); 25 | Runner { handles } 26 | } 27 | 28 | /// After the runner has been started, it just be joined so that all of the work can 29 | /// be finished. 30 | pub fn join(self) { 31 | self.handles 32 | .into_iter() 33 | .for_each(|h| h.join().expect("Sending thread to finish")); 34 | } 35 | 36 | fn run(work: usize, eng: Engine, collector: &Sender>) { 37 | eng.run(work, |fact| { 38 | collector 39 | .send(Message::Body(fact)) 40 | .expect("to send the fact correctly"); 41 | }); 42 | collector 43 | .send(Message::EOF) 44 | .expect("to send None correctly"); 45 | } 46 | } 47 | -------------------------------------------------------------------------------- /src/collector.rs: -------------------------------------------------------------------------------- 1 | use std::{cmp, thread, sync::mpsc::{channel, Receiver, Sender}}; 2 | use message::Message; 3 | use plan::Plan; 4 | 5 | /// Kicks off the collector which is a background thread. The collector will capture 6 | /// all data sent to the sender and then will return on the handle the entire dataset. 7 | /// 8 | /// The plan is essential to pre-allocating the array. 9 | pub fn start(plan: Plan) -> (Sender>, thread::JoinHandle>) 10 | where 11 | T: 'static + Send, 12 | { 13 | let (sender, receiver) = channel::>(); 14 | (sender, thread::spawn(move || collect(&receiver, plan))) 15 | } 16 | 17 | fn collect(receiver: &Receiver>, plan: Plan) -> Vec 18 | where 19 | T: 'static + Send, 20 | { 21 | let chunk_size = cmp::max(plan.requests() / 10, 1); 22 | let mut eof_count = 0; 23 | let mut messages: Vec = Vec::with_capacity(plan.requests()); 24 | 25 | while eof_count < plan.threads() { 26 | match receiver.recv().expect("To receive correctly") { 27 | Message::Body(message) => { 28 | messages.push(message); 29 | if (messages.len() % (chunk_size)) == 0 { 30 | println!("{} requests", messages.len()); 31 | } 32 | } 33 | Message::EOF => eof_count += 1, 34 | } 35 | } 36 | messages 37 | } 38 | 39 | #[cfg(test)] 40 | mod message_collection_tests { 41 | use super::*; 42 | 43 | #[test] 44 | fn it_ends_when_all_nones_are_received() { 45 | let plan = Plan::new(4, 0); 46 | let (tx, handle) = start::(plan); 47 | for _ in 0..4 { 48 | let _ = tx.send(Message::EOF); 49 | } 50 | assert_eq!(handle.join().unwrap(), Vec::::new()); 51 | } 52 | 53 | #[test] 54 | fn it_collects_all_data_received() { 55 | let plan = Plan::new(1, 0); 56 | let (tx, handle) = start::(plan); 57 | for n in 0..5 { 58 | let _ = tx.send(Message::Body(n as usize)); 59 | } 60 | let _ = tx.send(Message::EOF); 61 | assert_eq!(handle.join().unwrap(), vec![0, 1, 2, 3, 4]); 62 | } 63 | } 64 | -------------------------------------------------------------------------------- /src/chart.rs: -------------------------------------------------------------------------------- 1 | /// A chart that can be used to render some set of data. 2 | pub struct Chart { 3 | height: u32, 4 | full: char, 5 | half_full: char, 6 | space: char, 7 | } 8 | 9 | impl Chart { 10 | /// Creates a new chart. 11 | pub fn new() -> Chart { 12 | Chart { 13 | height: 10, 14 | full: '▌', 15 | half_full: '▖', 16 | space: ' ', 17 | } 18 | } 19 | 20 | /// Configure the height of the chart. 21 | pub fn height(mut self, h: u32) -> Chart { 22 | self.height = h; 23 | self 24 | } 25 | 26 | /// Build the chart into a string. 27 | pub fn make(&self, data: &[N]) -> String 28 | where 29 | N: Into + Clone, 30 | { 31 | let data: Vec = data.into_iter().map(|d| d.clone().into()).collect(); 32 | let (min, max): (f64, f64) = data.iter().fold((0., 0.), |(min, max), datum| { 33 | let datum = *datum; 34 | ( 35 | if datum < min { datum } else { min }, 36 | if max < datum { datum } else { max }, 37 | ) 38 | }); 39 | let row_increment = (max - min) / f64::from(self.height); 40 | let mut ret = String::with_capacity(self.height as usize * data.len() * 2); 41 | for row in 0..self.height { 42 | let floor = max - (f64::from(row + 1) * row_increment); 43 | for datum in &data { 44 | ret.push(if *datum > floor { 45 | if *datum > (floor + row_increment / 2.) { 46 | self.full 47 | } else { 48 | self.half_full 49 | } 50 | } else { 51 | self.space 52 | }); 53 | } 54 | if row == 0 { 55 | ret.push_str(&format!(" {}", max)); 56 | } 57 | if row == self.height - 1 { 58 | ret.push_str(&format!(" {}", min)); 59 | } 60 | ret.push('\n'); 61 | } 62 | ret 63 | } 64 | } 65 | 66 | #[cfg(test)] 67 | mod tests { 68 | use super::*; 69 | 70 | #[test] 71 | fn it_makes_a_chart_of_default_height() { 72 | let chart = Chart::new().make(&vec![1, 2, 3, 4, 3, 2, 1]); 73 | assert_eq!( 74 | chart, 75 | " ▌ 4 76 | ▌ 77 | ▖▌▖ 78 | ▌▌▌ 79 | ▌▌▌ 80 | ▌▌▌▌▌ 81 | ▌▌▌▌▌ 82 | ▌▌▌▌▌▌▌ 83 | ▌▌▌▌▌▌▌ 84 | ▌▌▌▌▌▌▌ 0 85 | " 86 | ); 87 | } 88 | 89 | #[test] 90 | fn it_can_change_the_height() { 91 | let chart = Chart::new().height(4).make(&vec![1, 2, 3, 4, 3, 2, 1]); 92 | assert_eq!( 93 | chart, 94 | " ▌ 4 95 | ▌▌▌ 96 | ▌▌▌▌▌ 97 | ▌▌▌▌▌▌▌ 0 98 | " 99 | ); 100 | } 101 | } 102 | -------------------------------------------------------------------------------- /src/content_length.rs: -------------------------------------------------------------------------------- 1 | use std::ops::Add; 2 | use std::fmt; 3 | 4 | /// Represents the content length of an http request. The ContentLength is 5 | /// a scalar value that represents the number of bytes (octets) in the 6 | /// payload of the request. This does not include header sizes. 7 | #[derive(Debug, Eq, PartialEq, Ord, PartialOrd)] 8 | pub struct ContentLength(u64); 9 | 10 | impl ContentLength { 11 | /// Returns a zero lengths content length 12 | pub fn zero() -> ContentLength { 13 | ContentLength(0) 14 | } 15 | 16 | /// Creates a new content length from a number of bytes 17 | pub fn new(bytes: u64) -> ContentLength { 18 | ContentLength(bytes) 19 | } 20 | 21 | /// Returns the bytes associated with the content length 22 | pub fn bytes(&self) -> u64 { 23 | self.0 24 | } 25 | } 26 | 27 | impl fmt::Display for ContentLength { 28 | fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { 29 | const GIGS: u64 = 1024 * 1024 * 1024; 30 | const MEGS: u64 = 1024 * 1024; 31 | const KILO: u64 = 1024; 32 | 33 | if self.0 > GIGS { 34 | write!(f, "{:0.2} GB", self.0 as f64 / GIGS as f64)?; 35 | } else if self.0 > MEGS { 36 | write!(f, "{:0.2} MB", self.0 as f64 / MEGS as f64)?; 37 | } else if self.0 > KILO { 38 | write!(f, "{:0.2} KB", self.0 as f64 / KILO as f64)?; 39 | } else { 40 | write!(f, "{} B", self.0)?; 41 | } 42 | Ok(()) 43 | } 44 | } 45 | 46 | impl Add for ContentLength { 47 | type Output = ContentLength; 48 | 49 | fn add(self, rhs: ContentLength) -> ContentLength { 50 | ContentLength(self.0 + rhs.0) 51 | } 52 | } 53 | 54 | impl<'a> Add for &'a ContentLength { 55 | type Output = ContentLength; 56 | 57 | fn add(self, rhs: &ContentLength) -> ContentLength { 58 | ContentLength(self.0 + rhs.0) 59 | } 60 | } 61 | 62 | impl<'a> Add<&'a ContentLength> for ContentLength { 63 | type Output = ContentLength; 64 | 65 | fn add(self, rhs: &ContentLength) -> ContentLength { 66 | ContentLength(self.0 + rhs.0) 67 | } 68 | } 69 | 70 | impl<'a> Add for &'a ContentLength { 71 | type Output = ContentLength; 72 | 73 | fn add(self, rhs: ContentLength) -> ContentLength { 74 | ContentLength(self.0 + rhs.0) 75 | } 76 | } 77 | 78 | #[cfg(test)] 79 | mod content_length_tests { 80 | use super::ContentLength; 81 | 82 | #[test] 83 | fn it_can_add_two_content_lengths() { 84 | assert_eq!(ContentLength(1) + ContentLength(2), ContentLength(3)); 85 | assert_eq!(&ContentLength(1) + &ContentLength(2), ContentLength(3)); 86 | assert_eq!(ContentLength(1) + &ContentLength(2), ContentLength(3)); 87 | assert_eq!(&ContentLength(1) + ContentLength(2), ContentLength(3)); 88 | } 89 | 90 | #[test] 91 | fn it_returns_bytes() { 92 | assert_eq!(ContentLength::new(1).bytes(), 1) 93 | } 94 | 95 | #[test] 96 | fn can_pretty_print_content_length() { 97 | assert_eq!(format!("{}", ContentLength(500)), "500 B"); 98 | assert_eq!(format!("{}", ContentLength(500_000)), "488.28 KB"); 99 | assert_eq!(format!("{}", ContentLength(500_000_000)), "476.84 MB"); 100 | assert_eq!(format!("{}", ContentLength(500_000_000_000)), "465.66 GB"); 101 | } 102 | } 103 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # RENCH 2 | 3 | A benchmark utility for end points. Written in rust... rust + bench = rench 4 | 5 | [![CircleCI](https://img.shields.io/circleci/project/github/kbacha/rench.svg)](https://circleci.com/gh/kbacha/rench) 6 | [![Travis](https://img.shields.io/travis/kbacha/rench.svg)](https://travis-ci.org/kbacha/rench) 7 | [![Crates.io](https://img.shields.io/crates/v/rench.svg)](https://crates.io/crates/rench) 8 | [![Crates.io](https://img.shields.io/crates/d/rench.svg)](https://crates.io/crates/rench) 9 | [![Crates.io](https://img.shields.io/crates/l/rench.svg)](https://crates.io/crates/rench) 10 | 11 | # Installation 12 | 13 | Installation requires either git or cargo. 14 | 15 | ### From Source 16 | Clone or fork the repo and run the following: 17 | 18 | ``` 19 | cargo install -f 20 | ``` 21 | 22 | ### From crates 23 | 24 | ``` 25 | cargo install -f rench 26 | ``` 27 | 28 | This should install and download from the latest release version. 29 | 30 | # Usage 31 | 32 | The gist of a http benchmarker is to run a series of queries against an endpoint 33 | and collect the facts from it. These facts then are summarized for the user to 34 | examine. To really maximize an end point, we use a simple threading model to make 35 | many requests at the same time. This allows us to generate a large number of 36 | requests and try to fully saturate the http end point. 37 | 38 | You can change the number of threads and the number of requests to suit your needs. 39 | You can even specify multiple URLs and it will round-robin the requests between them. 40 | 41 | ```bash 42 | $ ./target/release/rench -c 4 --engine=hyper -n 10000 http://0.0.0.0:6767 43 | Beginning requests 44 | 1000 requests 45 | 2000 requests 46 | 3000 requests 47 | 4000 requests 48 | 5000 requests 49 | 6000 requests 50 | 7000 requests 51 | 8000 requests 52 | 9000 requests 53 | 10000 requests 54 | Finished! 55 | 56 | Took 4.813263821 seconds 57 | 2077.5923306697964 requests / second 58 | 59 | Summary 60 | Average: 1.88827 ms (std: 0.763338 ms) 61 | Median: 1.012478 ms 62 | Longest: 1005.942426 ms 63 | Shortest: 0.403114 ms 64 | Requests: 10000 65 | Data: 234.38 KB 66 | 67 | Status codes: 68 | 200: 10000 69 | 70 | Latency Percentiles (2% of requests per bar): 71 | ▌ 7.399224 72 | ▌ 73 | ▌ 74 | ▌▌ 75 | ▖▌▌ 76 | ▖▌▌▌ 77 | ▖▌▌▌▌ 78 | ▖▖▖▌▌▌▌▌▌▌ 79 | ▖▖▖▖▖▖▖▖▖▖▖▖▖▖▖▖▖▖▖▖▖▌▌▌▌▌▌▌▌▌▌▌▌▌▌▌▌▌▌▌▌ 80 | ▌▌▌▌▌▌▌▌▌▌▌▌▌▌▌▌▌▌▌▌▌▌▌▌▌▌▌▌▌▌▌▌▌▌▌▌▌▌▌▌▌▌▌▌▌▌▌▌▌▌ 0 81 | 82 | 83 | Latency Histogram (each bar is 2% of max latency) 84 | ▌ 9862 85 | ▌ 86 | ▌ 87 | ▌ 88 | ▌ 89 | ▌ 90 | ▌ 91 | ▌ 92 | ▌ 93 | ▌▖ 0 94 | ``` 95 | 96 | ### Options 97 | 98 | ```bash 99 | $ rench --help 100 | Git Release Names 101 | Kevin Choubacha 102 | 103 | USAGE: 104 | rench [FLAGS] [OPTIONS] ... 105 | 106 | FLAGS: 107 | -h, --help Prints help information 108 | -i, --head The issue head requests instead of get 109 | -V, --version Prints version information 110 | 111 | OPTIONS: 112 | --chart-size The size of the chart to render [possible values: none, n, small, s, medium, m, 113 | large, l] 114 | -c The number of concurrent requests to make 115 | -e, --engine The engine to use [default: hyper] [possible values: hyper, reqwest] 116 | --header
... Headers to inject in the request. Example '--header user-agent:rust-rench' 117 | -n The number of requests in total to make 118 | 119 | ARGS: 120 | ... Each url specified will be round robined. 121 | ``` 122 | -------------------------------------------------------------------------------- /src/main.rs: -------------------------------------------------------------------------------- 1 | extern crate clap; 2 | extern crate futures; 3 | extern crate hyper; 4 | extern crate hyper_tls; 5 | extern crate reqwest; 6 | extern crate tokio_core; 7 | 8 | use clap::{App, Arg}; 9 | 10 | mod bench; 11 | mod chart; 12 | mod collector; 13 | mod content_length; 14 | mod engine; 15 | mod message; 16 | mod plan; 17 | mod runner; 18 | mod stats; 19 | use stats::{ChartSize, Fact, Summary}; 20 | use plan::Plan; 21 | use runner::Runner; 22 | 23 | fn main() { 24 | let matches = App::new("Git Release Names") 25 | .author("Kevin Choubacha ") 26 | .arg( 27 | Arg::with_name("URL") 28 | .required(true) 29 | .multiple(true) 30 | .help("Each url specified will be round robined."), 31 | ) 32 | .arg( 33 | Arg::with_name("concurrency") 34 | .short("c") 35 | .takes_value(true) 36 | .help("The number of concurrent requests to make"), 37 | ) 38 | .arg( 39 | Arg::with_name("requests") 40 | .short("n") 41 | .takes_value(true) 42 | .help("The number of requests in total to make"), 43 | ) 44 | .arg( 45 | Arg::with_name("head-requests") 46 | .short("i") 47 | .long("head") 48 | .help("The issue head requests instead of get"), 49 | ) 50 | .arg( 51 | Arg::with_name("engine") 52 | .long("engine") 53 | .short("e") 54 | .takes_value(true) 55 | .possible_values(&["hyper", "reqwest"]) 56 | .default_value("hyper") 57 | .help("The engine to use"), 58 | ) 59 | .arg( 60 | Arg::with_name("header") 61 | .long("header") 62 | .multiple(true) 63 | .takes_value(true) 64 | .number_of_values(1) 65 | .help("Headers to inject in the request. Example '--header user-agent:rust-rench'"), 66 | ) 67 | .arg( 68 | Arg::with_name("chart-size") 69 | .long("chart-size") 70 | .takes_value(true) 71 | .possible_values(&["none", "n", "small", "s", "medium", "m", "large", "l"]) 72 | .help("The size of the chart to render"), 73 | ) 74 | .get_matches(); 75 | 76 | let urls: Vec = matches 77 | .values_of("URL") 78 | .expect("URLs are required") 79 | .map(|v| v.to_string()) 80 | .collect(); 81 | 82 | let threads = matches 83 | .value_of("concurrency") 84 | .unwrap_or("1") 85 | .parse::() 86 | .expect("Expected valid number for threads"); 87 | 88 | let requests = matches 89 | .value_of("requests") 90 | .unwrap_or("1000") 91 | .parse::() 92 | .expect("Expected valid number for number of requests"); 93 | 94 | let chart_size = match matches.value_of("chart-size").unwrap_or("medium") { 95 | "none" | "n" => ChartSize::None, 96 | "small" | "s" => ChartSize::Small, 97 | "medium" | "m" => ChartSize::Medium, 98 | "large" | "l" => ChartSize::Large, 99 | _ => unreachable!(), 100 | }; 101 | 102 | let headers: Vec<(String, String)> = matches 103 | .values_of("header") 104 | .unwrap_or(Default::default()) 105 | .map(|v| { 106 | let m = v.splitn(2, ":").collect::>(); 107 | if m.len() != 2 { 108 | panic!("Invalid header."); 109 | } 110 | let k = m[0].to_string().to_lowercase(); 111 | let v = m[1].to_string(); 112 | (k, v) 113 | }) 114 | .collect(); 115 | 116 | let plan = Plan::new(threads, requests); 117 | 118 | let eng = match matches.value_of("engine").unwrap_or("hyper") { 119 | "hyper" => engine::Engine::new(urls.clone(), headers).with_hyper(), 120 | "reqwest" | _ => engine::Engine::new(urls.clone(), headers), 121 | }; 122 | 123 | let eng = if matches.is_present("head-requests") { 124 | eng.with_method(engine::Method::Head) 125 | } else { 126 | eng 127 | }; 128 | 129 | let (collector, rec_handle) = collector::start::(plan); 130 | let runner = Runner::start(plan, &eng, &collector); 131 | 132 | println!("Beginning requests"); 133 | let ((), duration) = bench::time_it(|| runner.join()); 134 | let facts = rec_handle.join().expect("Receiving thread to finish"); 135 | let seconds = 136 | duration.as_secs() as f64 + (f64::from(duration.subsec_nanos()) / 1_000_000_000f64); 137 | 138 | println!("Finished!"); 139 | println!(); 140 | println!("Took {} seconds", seconds); 141 | println!("{} requests / second", requests as f64 / seconds); 142 | println!(); 143 | println!( 144 | "{}", 145 | Summary::from_facts(&facts).with_chart_size(chart_size) 146 | ); 147 | } 148 | -------------------------------------------------------------------------------- /src/engine.rs: -------------------------------------------------------------------------------- 1 | use bench; 2 | use stats::Fact; 3 | use content_length::ContentLength; 4 | 5 | /// The engine of making requests. The engine implements making the requests and producing 6 | /// facts for the stats collector to process. 7 | #[derive(Clone)] 8 | pub struct Engine { 9 | urls: Vec, 10 | method: Method, 11 | headers: Vec<(String, String)>, 12 | kind: Kind, 13 | } 14 | 15 | /// The methods that are supported by the current implementations. These are currently 16 | /// body-less methods so that we don't need to load up any additional content. 17 | #[derive(Clone, Copy)] 18 | pub enum Method { 19 | Get, 20 | Head, 21 | } 22 | const DEFAULT_METHOD: Method = Method::Get; 23 | 24 | #[derive(Clone, Copy)] 25 | enum Kind { 26 | Reqwest, 27 | Hyper, 28 | } 29 | const DEFAULT_KIND: Kind = Kind::Reqwest; 30 | 31 | impl Engine { 32 | /// Creates a new engine. The engine will default to using `reqwest` 33 | pub fn new(urls: Vec, headers: Vec<(String, String)>) -> Engine { 34 | Engine { 35 | urls, 36 | method: DEFAULT_METHOD, 37 | headers, 38 | kind: DEFAULT_KIND, 39 | } 40 | } 41 | 42 | /// Sets the method to use with the requests 43 | pub fn with_method(mut self, method: Method) -> Self { 44 | self.method = method; 45 | self 46 | } 47 | 48 | /// Sets the engine to be a hyper engine 49 | pub fn with_hyper(mut self) -> Self { 50 | self.kind = Kind::Hyper; 51 | self 52 | } 53 | 54 | /// Consumes self to start up the engine and begins making requests. It will callback 55 | /// to the collector to allow the caller to capture requests. 56 | pub fn run(self, requests: usize, collect: F) 57 | where 58 | F: FnMut(Fact), 59 | { 60 | match self.kind { 61 | Kind::Reqwest => self.run_reqwest(requests, collect), 62 | Kind::Hyper => self.run_hyper(requests, collect), 63 | }; 64 | } 65 | 66 | fn run_reqwest(&self, requests: usize, mut collect: F) 67 | where 68 | F: FnMut(Fact), 69 | { 70 | use reqwest::{self, Client, Request, header}; 71 | 72 | let mut headers = header::HeaderMap::new(); 73 | self.headers.iter().for_each(|(k, v)| { 74 | headers.insert( 75 | header::HeaderName::from_lowercase(k.as_bytes()).expect("invalid header name."), 76 | header::HeaderValue::from_str(&v).expect("invalid header value.") 77 | ); 78 | }); 79 | 80 | let client = Client::builder() 81 | .default_headers(headers) 82 | .build().expect("Failed to build reqwest client"); 83 | 84 | let method = match self.method { 85 | Method::Get => reqwest::Method::GET, 86 | Method::Head => reqwest::Method::HEAD, 87 | }; 88 | 89 | for n in 0..requests { 90 | let url = &self.urls[n % self.urls.len()]; 91 | 92 | let request = Request::new(method.clone(), url.parse().expect("Invalid url")); 93 | let mut len = 0; 94 | let (resp, duration) = bench::time_it(|| { 95 | let mut resp = client 96 | .execute(request) 97 | .expect("Failure to even connect is no good"); 98 | if let Ok(body) = resp.text() { 99 | len = body.len(); 100 | } 101 | resp 102 | }); 103 | 104 | collect(Fact::record( 105 | ContentLength::new(len as u64), 106 | resp.status().as_u16(), 107 | duration, 108 | )); 109 | } 110 | } 111 | 112 | fn run_hyper(&self, requests: usize, mut collect: F) 113 | where 114 | F: FnMut(Fact), 115 | { 116 | use hyper::{self, Client, Request, Uri}; 117 | use hyper_tls::HttpsConnector; 118 | use tokio_core::reactor::Core; 119 | use futures::{Future, Stream}; 120 | 121 | let mut core = Core::new().expect("Setting up tokio core failed"); 122 | let handle = core.handle(); 123 | let client = Client::configure() 124 | .connector(HttpsConnector::new(1, &handle).expect("To set up a http connector")) 125 | .build(&handle); 126 | 127 | let urls: Vec = self.urls.iter().map(|url| url.parse().unwrap()).collect(); 128 | 129 | let method = match self.method { 130 | Method::Get => hyper::Method::Get, 131 | Method::Head => hyper::Method::Head, 132 | }; 133 | 134 | for n in 0..requests { 135 | let uri = &urls[n % urls.len()]; 136 | 137 | let mut req = Request::new(method.clone(), uri.clone()); 138 | { 139 | let mut headers = req.headers_mut(); 140 | self.headers.iter().for_each(|(k,v)| { 141 | headers.set_raw(k.to_string(), v.as_str()); 142 | }); 143 | } 144 | 145 | let request = client.request(req) 146 | .and_then(|response| { 147 | let status = response.status().as_u16(); 148 | response 149 | .body() 150 | .concat2() 151 | .map(move |body| (status, body.len() as u64)) 152 | }); 153 | let ((status, content_length), duration) = 154 | bench::time_it(|| core.run(request).expect("reactor run")); 155 | collect(Fact::record( 156 | ContentLength::new(content_length), 157 | status, 158 | duration, 159 | )); 160 | } 161 | } 162 | } 163 | 164 | #[cfg(test)] 165 | mod tests { 166 | use super::*; 167 | use stats::Summary; 168 | 169 | #[test] 170 | fn reqwest_engine_can_collect_facts() { 171 | let eng = Engine::new(vec!["https://www.google.com".to_string()], vec![]); 172 | let mut fact: Option = None; 173 | eng.run(1, |f| fact = Some(f)); 174 | assert!(fact.is_some()); 175 | } 176 | 177 | #[test] 178 | fn hyper_engine_can_collect_facts() { 179 | let eng = Engine::new(vec!["https://www.google.com".to_string()], vec![]).with_hyper(); 180 | let mut fact: Option = None; 181 | eng.run(1, |f| fact = Some(f)); 182 | assert!(fact.is_some()); 183 | } 184 | 185 | #[test] 186 | fn reqwest_engine_can_pass_headers() { 187 | // Request without headers first 188 | let eng = Engine::new(vec!["https://httpbin.org/headers".to_string()], vec![]); 189 | let mut fact: Option = None; 190 | eng.run(1, |f| fact = Some(f)); 191 | 192 | let mut without_headers_size = 0; 193 | if let Some(f) = fact { 194 | without_headers_size = Summary::from_facts(&[f]).content_length().bytes(); 195 | } 196 | 197 | // Request with headers 198 | let (k, v) = ("key", "val"); 199 | let eng = Engine::new( 200 | vec!["https://httpbin.org/headers".to_string()], 201 | vec![(k.to_string(), v.to_string())] 202 | ); 203 | let mut fact: Option = None; 204 | eng.run(1, |f| fact = Some(f)); 205 | 206 | // Sample response 207 | // { 208 | // "headers": { 209 | // "Accept": "*/*", 210 | // "Connection": "close", 211 | // "Host": "httpbin.org", 212 | // "Key": "val", 213 | // "User-Agent": "curl/7.47.0" 214 | // } 215 | // } 216 | // The 13 bytes represent the extra characters returned by 217 | // httpbin to pretty print the output of the header key and val. 218 | let extra_char_bytes = 13; 219 | 220 | if let Some(f) = fact { 221 | assert_eq!( 222 | Summary::from_facts(&[f]).content_length().bytes() as usize, 223 | (without_headers_size as usize)+ k.as_bytes().len() + k.as_bytes().len() + extra_char_bytes 224 | ) 225 | } 226 | 227 | let (k, v) = ("key1", "val1"); 228 | let eng = Engine::new( 229 | vec!["https://httpbin.org/headers".to_string()], 230 | vec![(k.to_string(), v.to_string())] 231 | ); 232 | let mut fact: Option = None; 233 | eng.run(1, |f| fact = Some(f)); 234 | 235 | if let Some(f) = fact { 236 | assert_eq!( 237 | Summary::from_facts(&[f]).content_length().bytes() as usize, 238 | (without_headers_size as usize)+ k.as_bytes().len() + k.as_bytes().len() + extra_char_bytes 239 | ) 240 | } 241 | } 242 | 243 | #[test] 244 | fn hyper_engine_can_pass_headers() { 245 | // Request without headers first 246 | let eng = Engine::new(vec!["https://httpbin.org/headers".to_string()], vec![]).with_hyper(); 247 | let mut fact: Option = None; 248 | eng.run(1, |f| fact = Some(f)); 249 | 250 | let mut without_headers_size = 0; 251 | if let Some(f) = fact { 252 | without_headers_size = Summary::from_facts(&[f]).content_length().bytes(); 253 | } 254 | 255 | // Request with headers 256 | let (k, v) = ("key", "val"); 257 | let eng = Engine::new( 258 | vec!["https://httpbin.org/headers".to_string()], 259 | vec![(k.to_string(), v.to_string())] 260 | ).with_hyper(); 261 | let mut fact: Option = None; 262 | eng.run(1, |f| fact = Some(f)); 263 | 264 | // Sample response 265 | // { 266 | // "headers": { 267 | // "Accept": "*/*", 268 | // "Connection": "close", 269 | // "Host": "httpbin.org", 270 | // "Key": "val", 271 | // "User-Agent": "curl/7.47.0" 272 | // } 273 | // } 274 | // The 13 bytes represent the extra characters returned by 275 | // httpbin to pretty print the output of the header key and val. 276 | let extra_char_bytes = 13; 277 | 278 | if let Some(f) = fact { 279 | assert_eq!( 280 | Summary::from_facts(&[f]).content_length().bytes() as usize, 281 | (without_headers_size as usize)+ k.as_bytes().len() + k.as_bytes().len() + extra_char_bytes 282 | ) 283 | } 284 | 285 | let (k, v) = ("key1", "val1"); 286 | let eng = Engine::new( 287 | vec!["https://httpbin.org/headers".to_string()], 288 | vec![(k.to_string(), v.to_string())] 289 | ).with_hyper(); 290 | let mut fact: Option = None; 291 | eng.run(1, |f| fact = Some(f)); 292 | 293 | if let Some(f) = fact { 294 | assert_eq!( 295 | Summary::from_facts(&[f]).content_length().bytes() as usize, 296 | (without_headers_size as usize)+ k.as_bytes().len() + k.as_bytes().len() + extra_char_bytes 297 | ) 298 | } 299 | } 300 | } 301 | -------------------------------------------------------------------------------- /src/stats.rs: -------------------------------------------------------------------------------- 1 | use std::time::Duration; 2 | use std::{cmp, fmt}; 3 | use chart::Chart; 4 | use content_length::ContentLength; 5 | use std::collections::HashMap; 6 | 7 | trait ToMilliseconds { 8 | fn to_ms(&self) -> f64; 9 | } 10 | 11 | impl ToMilliseconds for Duration { 12 | fn to_ms(&self) -> f64 { 13 | (self.as_secs() as f64 * 1_000f64) + (f64::from(self.subsec_nanos()) / 1_000_000f64) 14 | } 15 | } 16 | 17 | #[derive(Debug, Clone, Copy, PartialEq)] 18 | struct MS(f64); 19 | impl From for MS { 20 | fn from(d: Duration) -> MS { 21 | let ms = (d.as_secs() as f64 * 1_000f64) + (f64::from(d.subsec_nanos()) / 1_000_000f64); 22 | MS(ms) 23 | } 24 | } 25 | 26 | impl From for Duration { 27 | fn from(ms: MS) -> Duration { 28 | let MS(ms) = ms; 29 | let duration = Duration::from_millis(ms.trunc() as u64); 30 | let nanos = (ms.fract() * 1_000_000f64) as u32; 31 | duration + Duration::new(0, nanos) 32 | } 33 | } 34 | 35 | #[cfg(test)] 36 | mod millisecond_tests { 37 | use super::*; 38 | 39 | #[test] 40 | fn exchange_duration_to_ms() { 41 | assert_eq!(Duration::new(1, 500000).to_ms(), 1000.5f64); 42 | } 43 | 44 | #[test] 45 | fn convert_to_ms() { 46 | let ms: MS = Duration::new(1, 500000).into(); 47 | assert_eq!(ms, MS(1000.5f64)); 48 | } 49 | 50 | #[test] 51 | fn convert_from_ms() { 52 | let duration: Duration = MS(1000.5).into(); 53 | assert_eq!(duration, Duration::new(1, 500000)); 54 | } 55 | } 56 | 57 | /// A single datum or "fact" about the requests 58 | #[derive(Debug)] 59 | pub struct Fact { 60 | status: u16, 61 | duration: Duration, 62 | content_length: ContentLength, 63 | } 64 | 65 | impl Fact { 66 | pub fn record(content_length: ContentLength, status: u16, duration: Duration) -> Fact { 67 | Fact { 68 | duration, 69 | status, 70 | content_length, 71 | } 72 | } 73 | } 74 | 75 | struct DurationStats { 76 | sorted: Vec, 77 | } 78 | 79 | impl DurationStats { 80 | fn from_facts(facts: &[Fact]) -> DurationStats { 81 | let mut sorted: Vec = facts.iter().map(|f| f.duration).collect(); 82 | sorted.sort(); 83 | Self { sorted } 84 | } 85 | 86 | fn max(&self) -> Option { 87 | self.sorted.last().cloned() 88 | } 89 | 90 | fn min(&self) -> Option { 91 | self.sorted.first().cloned() 92 | } 93 | 94 | fn median(&self) -> Duration { 95 | let mid = self.sorted.len() / 2; 96 | if self.sorted.len() % 2 == 0 { 97 | // even 98 | (self.sorted[mid - 1] + self.sorted[mid]) / 2 99 | } else { 100 | // odd 101 | self.sorted[mid] 102 | } 103 | } 104 | 105 | fn average(&self) -> Duration { 106 | self.total() / (self.sorted.len() as u32) 107 | } 108 | 109 | fn stddev(&self) -> Duration { 110 | let mean = self.average(); 111 | let MS(mean) = mean.into(); 112 | let summed_squares = self.sorted.iter().fold(0f64, |acc, duration| { 113 | let MS(ms) = (*duration).into(); 114 | acc + (ms - mean).powi(2) 115 | }); 116 | let ratio = summed_squares / (self.sorted.len() - 1) as f64; 117 | let std_ms = ratio.sqrt(); 118 | MS(std_ms).into() 119 | } 120 | 121 | fn latency_histogram(&self) -> Vec { 122 | let mut latency_histogram = vec![0; 100]; 123 | 124 | if let Some(max) = self.max() { 125 | let bin_size = max.to_ms() / 100.; 126 | 127 | for duration in &self.sorted { 128 | let index = (duration.to_ms() / bin_size) as usize; 129 | latency_histogram[cmp::min(index, 49)] += 1; 130 | } 131 | } 132 | latency_histogram 133 | } 134 | 135 | fn percentiles(&self) -> Vec { 136 | (0..100) 137 | .map(|n| { 138 | let mut index = ((f64::from(n) / 100.0) * (self.sorted.len() as f64)) as usize; 139 | index = cmp::max(index, 0); 140 | index = cmp::min(index, self.sorted.len() - 1); 141 | self.sorted[index] 142 | }) 143 | .collect() 144 | } 145 | 146 | fn total(&self) -> Duration { 147 | self.sorted.iter().sum() 148 | } 149 | } 150 | 151 | #[derive(Debug, Eq, PartialEq)] 152 | pub enum ChartSize { 153 | None, 154 | Small, 155 | Medium, 156 | Large, 157 | } 158 | 159 | /// Represents the statistics around a given set of facts. 160 | #[derive(Debug)] 161 | pub struct Summary { 162 | average: Duration, 163 | median: Duration, 164 | max: Duration, 165 | min: Duration, 166 | stddev: Duration, 167 | count: u32, 168 | content_length: ContentLength, 169 | percentiles: Vec, 170 | latency_histogram: Vec, 171 | status_counts: HashMap, 172 | chart_size: ChartSize, 173 | } 174 | 175 | impl Summary { 176 | /// From a set of facts, calculate the statistics. 177 | pub fn from_facts(facts: &[Fact]) -> Summary { 178 | if facts.is_empty() { 179 | return Summary::zero(); 180 | } 181 | let content_length = Self::total_content_length(&facts); 182 | let count = facts.len() as u32; 183 | let status_counts = facts.iter().fold( 184 | HashMap::with_capacity(699), 185 | |mut acc: HashMap, fact| { 186 | let count = if let Some(current) = acc.get(&fact.status) { 187 | current + 1 188 | } else { 189 | 1 190 | }; 191 | acc.insert(fact.status, count); 192 | acc 193 | }, 194 | ); 195 | 196 | Summary { 197 | count, 198 | content_length, 199 | status_counts, 200 | ..Summary::from_durations(&DurationStats::from_facts(&facts)) 201 | } 202 | } 203 | 204 | #[allow(dead_code)] 205 | pub fn content_length(self, ) -> ContentLength { 206 | self.content_length 207 | } 208 | 209 | pub fn with_chart_size(mut self, size: ChartSize) -> Self { 210 | self.chart_size = size; 211 | self 212 | } 213 | 214 | fn from_durations(stats: &DurationStats) -> Summary { 215 | let average = stats.average(); 216 | let stddev = stats.stddev(); 217 | let median = stats.median(); 218 | let min = stats.min().expect("Returned early if empty"); 219 | let max = stats.max().expect("Returned early if empty"); 220 | let latency_histogram = stats.latency_histogram(); 221 | let percentiles = stats.percentiles(); 222 | 223 | Summary { 224 | average, 225 | stddev, 226 | median, 227 | min, 228 | max, 229 | percentiles, 230 | latency_histogram, 231 | ..Summary::zero() 232 | } 233 | } 234 | 235 | fn zero() -> Summary { 236 | Summary { 237 | average: Duration::new(0, 0), 238 | stddev: Duration::new(0, 0), 239 | median: Duration::new(0, 0), 240 | max: Duration::new(0, 0), 241 | min: Duration::new(0, 0), 242 | count: 0, 243 | content_length: ContentLength::zero(), 244 | percentiles: vec![Duration::new(0, 0); 100], 245 | latency_histogram: vec![0; 0], 246 | status_counts: HashMap::new(), 247 | chart_size: ChartSize::Medium, 248 | } 249 | } 250 | 251 | fn total_content_length(facts: &[Fact]) -> ContentLength { 252 | facts.iter().fold(ContentLength::zero(), |len, fact| { 253 | len + &fact.content_length 254 | }) 255 | } 256 | 257 | fn chart(&self, vec: &[T]) -> String 258 | where 259 | T: Copy + Into, 260 | { 261 | let (height, scale) = match self.chart_size { 262 | ChartSize::None => return String::new(), 263 | ChartSize::Small => (7, 3), 264 | ChartSize::Medium => (10, 2), 265 | ChartSize::Large => (20, 1), 266 | }; 267 | use stats::scale_array; 268 | Chart::new().height(height).make(&scale_array(&vec, scale)) 269 | } 270 | } 271 | 272 | fn scale_array(vec: &[T], scale_array: usize) -> Vec 273 | where 274 | T: Copy, 275 | { 276 | vec.iter() 277 | .enumerate() 278 | .filter(|&(i, _)| i % scale_array == 0) 279 | .map(|(_, v)| *v) 280 | .collect() 281 | } 282 | 283 | #[cfg(test)] 284 | mod scale_array_tests { 285 | use super::*; 286 | 287 | #[test] 288 | fn it_scale_arrays_an_array() { 289 | let vec = vec![1, 2, 3, 4, 5, 6, 7, 8, 9]; 290 | assert_eq!(scale_array(&vec, 2), vec![1, 3, 5, 7, 9]); 291 | assert_eq!(scale_array(&vec, 3), vec![1, 4, 7]); 292 | } 293 | } 294 | 295 | impl fmt::Display for Summary { 296 | fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { 297 | writeln!(f, "Summary")?; 298 | writeln!( 299 | f, 300 | " Average: {} ms (std: {} ms)", 301 | self.average.to_ms(), 302 | self.stddev.to_ms() 303 | )?; 304 | writeln!(f, " Median: {} ms", self.median.to_ms())?; 305 | writeln!(f, " Longest: {} ms", self.max.to_ms())?; 306 | writeln!(f, " Shortest: {} ms", self.min.to_ms())?; 307 | writeln!(f, " Requests: {}", self.count)?; 308 | writeln!(f, " Data: {}", self.content_length)?; 309 | writeln!(f)?; 310 | writeln!(f, "Status codes:")?; 311 | let mut status_counts: Vec<(&u16, &u32)> = self.status_counts.iter().collect(); 312 | status_counts.sort_by(|&(&code_a, _), &(&code_b, _)| code_a.cmp(&code_b)); 313 | for (k, v) in status_counts { 314 | writeln!(f, " {}: {}", k, v)?; 315 | } 316 | if self.chart_size != ChartSize::None { 317 | writeln!(f)?; 318 | writeln!(f, "Latency Percentiles (2% of requests per bar):")?; 319 | let percentiles: Vec = self.percentiles.iter().map(|d| d.to_ms()).collect(); 320 | writeln!(f, "{}", self.chart(&percentiles))?; 321 | writeln!(f)?; 322 | writeln!(f, "Latency Histogram (each bar is 2% of max latency)")?; 323 | writeln!(f, "{}", self.chart(&self.latency_histogram))?; 324 | } 325 | Ok(()) 326 | } 327 | } 328 | 329 | #[cfg(test)] 330 | mod summary_tests { 331 | use super::*; 332 | 333 | fn ok_zero_length_fact(duration: Duration) -> Fact { 334 | Fact { 335 | status: 200, 336 | duration: duration, 337 | content_length: ContentLength::zero(), 338 | } 339 | } 340 | 341 | fn ok_instant_fact(content_length: ContentLength) -> Fact { 342 | Fact { 343 | status: 200, 344 | duration: Duration::new(0, 0), 345 | content_length, 346 | } 347 | } 348 | 349 | fn zero_length_instant_fact(status: u16) -> Fact { 350 | Fact { 351 | status, 352 | duration: Duration::new(0, 0), 353 | content_length: ContentLength::zero(), 354 | } 355 | } 356 | 357 | #[test] 358 | fn summarizes_to_zero_if_empty() { 359 | let summary = Summary::from_facts(&Vec::new()); 360 | assert_eq!(summary.average, Duration::new(0, 0)); 361 | assert_eq!(summary.median, Duration::new(0, 0)); 362 | assert_eq!(summary.count, 0); 363 | } 364 | 365 | #[test] 366 | fn averages_the_durations() { 367 | let facts = [ 368 | ok_zero_length_fact(Duration::new(2, 0)), 369 | ok_zero_length_fact(Duration::new(1, 0)), 370 | ok_zero_length_fact(Duration::new(4, 0)), 371 | ok_zero_length_fact(Duration::new(3, 0)), 372 | ]; 373 | let summary = Summary::from_facts(&facts); 374 | assert_eq!(summary.average, Duration::new(2, 500000000)); 375 | } 376 | 377 | #[test] 378 | fn stddev_the_durations() { 379 | let facts = [ 380 | ok_zero_length_fact(Duration::new(2, 0)), 381 | ok_zero_length_fact(Duration::new(1, 0)), 382 | ok_zero_length_fact(Duration::new(4, 0)), 383 | ok_zero_length_fact(Duration::new(3, 0)), 384 | ]; 385 | let summary = Summary::from_facts(&facts); 386 | assert_eq!(summary.stddev, Duration::new(1, 290994448)); 387 | } 388 | 389 | #[test] 390 | fn counts_the_facts() { 391 | let facts = [ 392 | ok_zero_length_fact(Duration::new(2, 0)), 393 | ok_zero_length_fact(Duration::new(3, 0)), 394 | ok_zero_length_fact(Duration::new(1, 0)), 395 | ok_zero_length_fact(Duration::new(4, 0)), 396 | ]; 397 | let summary = Summary::from_facts(&facts); 398 | assert_eq!(summary.count, 4); 399 | } 400 | 401 | #[test] 402 | fn calculates_percentiles_from_an_even_number_of_facts() { 403 | let facts = [ 404 | ok_zero_length_fact(Duration::new(2, 0)), 405 | ok_zero_length_fact(Duration::new(3, 0)), 406 | ok_zero_length_fact(Duration::new(1, 0)), 407 | ok_zero_length_fact(Duration::new(100, 0)), 408 | ]; 409 | let summary = Summary::from_facts(&facts); 410 | assert_eq!(summary.median, Duration::new(2, 500000000)); 411 | assert_eq!(summary.max, Duration::new(100, 0)); 412 | assert_eq!(summary.min, Duration::new(1, 0)); 413 | } 414 | 415 | #[test] 416 | fn calculates_percentiles_from_an_odd_number_of_facts() { 417 | let facts = [ 418 | ok_zero_length_fact(Duration::new(2, 0)), 419 | ok_zero_length_fact(Duration::new(1, 0)), 420 | ok_zero_length_fact(Duration::new(100, 0)), 421 | ]; 422 | let summary = Summary::from_facts(&facts); 423 | assert_eq!(summary.median, Duration::new(2, 0)); 424 | assert_eq!(summary.max, Duration::new(100, 0)); 425 | assert_eq!(summary.min, Duration::new(1, 0)); 426 | } 427 | 428 | #[test] 429 | fn counts_the_histogram_of_latencies() { 430 | let facts: Vec = (0..500) 431 | .map(|n| ok_zero_length_fact(Duration::new(n, 0))) 432 | .collect(); 433 | let summary = Summary::from_facts(&facts); 434 | 435 | assert_eq!(summary.latency_histogram.len(), 100); 436 | assert_eq!(summary.latency_histogram.first(), Some(&5)); 437 | assert_eq!(summary.latency_histogram.last(), Some(&0)); 438 | assert_eq!(summary.latency_histogram[50], 0); 439 | } 440 | 441 | #[test] 442 | fn calculates_all_the_percentiles_when_n_less_than_100() { 443 | let facts: Vec = (0..50) 444 | .map(|n| ok_zero_length_fact(Duration::new(n, 0))) 445 | .collect(); 446 | let summary = Summary::from_facts(&facts); 447 | 448 | assert_eq!(summary.percentiles.len(), 100); 449 | assert_eq!(summary.percentiles.first(), Some(&Duration::new(0, 0))); 450 | assert_eq!(summary.percentiles.last(), Some(&Duration::new(49, 0))); 451 | assert_eq!(summary.percentiles[50], Duration::new(25, 0)); 452 | } 453 | 454 | #[test] 455 | fn calculates_all_the_percentiles_when_n_greater_than_100() { 456 | let facts: Vec = (0..500) 457 | .map(|n| ok_zero_length_fact(Duration::new(n, 0))) 458 | .collect(); 459 | let summary = Summary::from_facts(&facts); 460 | 461 | assert_eq!(summary.percentiles.len(), 100); 462 | assert_eq!(summary.percentiles.first(), Some(&Duration::new(0, 0))); 463 | assert_eq!(summary.percentiles.last(), Some(&Duration::new(495, 0))); 464 | assert_eq!(summary.percentiles[50], Duration::new(250, 0)); 465 | } 466 | 467 | #[test] 468 | fn sums_up_the_content_lengths() { 469 | let facts: Vec = (0..500) 470 | .map(|_| ok_instant_fact(ContentLength::new(1))) 471 | .collect(); 472 | let summary = Summary::from_facts(&facts); 473 | assert_eq!(summary.content_length.bytes(), 500); 474 | } 475 | 476 | #[test] 477 | fn counts_status_codes() { 478 | let facts: Vec = vec![ 479 | zero_length_instant_fact(200), 480 | zero_length_instant_fact(202), 481 | zero_length_instant_fact(200), 482 | zero_length_instant_fact(400), 483 | zero_length_instant_fact(200), 484 | zero_length_instant_fact(404), 485 | zero_length_instant_fact(200), 486 | zero_length_instant_fact(504), 487 | ]; 488 | let summary = Summary::from_facts(&facts); 489 | assert_eq!(summary.status_counts.get(&200), Some(&4)); 490 | } 491 | } 492 | -------------------------------------------------------------------------------- /Cargo.lock: -------------------------------------------------------------------------------- 1 | [[package]] 2 | name = "MacTypes-sys" 3 | version = "2.1.0" 4 | source = "registry+https://github.com/rust-lang/crates.io-index" 5 | dependencies = [ 6 | "libc 0.2.48 (registry+https://github.com/rust-lang/crates.io-index)", 7 | ] 8 | 9 | [[package]] 10 | name = "adler32" 11 | version = "1.0.3" 12 | source = "registry+https://github.com/rust-lang/crates.io-index" 13 | 14 | [[package]] 15 | name = "ansi_term" 16 | version = "0.11.0" 17 | source = "registry+https://github.com/rust-lang/crates.io-index" 18 | dependencies = [ 19 | "winapi 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)", 20 | ] 21 | 22 | [[package]] 23 | name = "arrayvec" 24 | version = "0.4.10" 25 | source = "registry+https://github.com/rust-lang/crates.io-index" 26 | dependencies = [ 27 | "nodrop 0.1.13 (registry+https://github.com/rust-lang/crates.io-index)", 28 | ] 29 | 30 | [[package]] 31 | name = "atty" 32 | version = "0.2.11" 33 | source = "registry+https://github.com/rust-lang/crates.io-index" 34 | dependencies = [ 35 | "libc 0.2.48 (registry+https://github.com/rust-lang/crates.io-index)", 36 | "termion 1.5.1 (registry+https://github.com/rust-lang/crates.io-index)", 37 | "winapi 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)", 38 | ] 39 | 40 | [[package]] 41 | name = "autocfg" 42 | version = "0.1.2" 43 | source = "registry+https://github.com/rust-lang/crates.io-index" 44 | 45 | [[package]] 46 | name = "base64" 47 | version = "0.9.3" 48 | source = "registry+https://github.com/rust-lang/crates.io-index" 49 | dependencies = [ 50 | "byteorder 1.3.1 (registry+https://github.com/rust-lang/crates.io-index)", 51 | "safemem 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)", 52 | ] 53 | 54 | [[package]] 55 | name = "base64" 56 | version = "0.10.1" 57 | source = "registry+https://github.com/rust-lang/crates.io-index" 58 | dependencies = [ 59 | "byteorder 1.3.1 (registry+https://github.com/rust-lang/crates.io-index)", 60 | ] 61 | 62 | [[package]] 63 | name = "bitflags" 64 | version = "0.9.1" 65 | source = "registry+https://github.com/rust-lang/crates.io-index" 66 | 67 | [[package]] 68 | name = "bitflags" 69 | version = "1.0.4" 70 | source = "registry+https://github.com/rust-lang/crates.io-index" 71 | 72 | [[package]] 73 | name = "byteorder" 74 | version = "1.3.1" 75 | source = "registry+https://github.com/rust-lang/crates.io-index" 76 | 77 | [[package]] 78 | name = "bytes" 79 | version = "0.4.11" 80 | source = "registry+https://github.com/rust-lang/crates.io-index" 81 | dependencies = [ 82 | "byteorder 1.3.1 (registry+https://github.com/rust-lang/crates.io-index)", 83 | "iovec 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", 84 | ] 85 | 86 | [[package]] 87 | name = "cc" 88 | version = "1.0.28" 89 | source = "registry+https://github.com/rust-lang/crates.io-index" 90 | 91 | [[package]] 92 | name = "cfg-if" 93 | version = "0.1.6" 94 | source = "registry+https://github.com/rust-lang/crates.io-index" 95 | 96 | [[package]] 97 | name = "clap" 98 | version = "2.32.0" 99 | source = "registry+https://github.com/rust-lang/crates.io-index" 100 | dependencies = [ 101 | "ansi_term 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)", 102 | "atty 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)", 103 | "bitflags 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)", 104 | "strsim 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)", 105 | "textwrap 0.10.0 (registry+https://github.com/rust-lang/crates.io-index)", 106 | "unicode-width 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)", 107 | "vec_map 0.8.1 (registry+https://github.com/rust-lang/crates.io-index)", 108 | ] 109 | 110 | [[package]] 111 | name = "cloudabi" 112 | version = "0.0.3" 113 | source = "registry+https://github.com/rust-lang/crates.io-index" 114 | dependencies = [ 115 | "bitflags 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)", 116 | ] 117 | 118 | [[package]] 119 | name = "core-foundation" 120 | version = "0.2.3" 121 | source = "registry+https://github.com/rust-lang/crates.io-index" 122 | dependencies = [ 123 | "core-foundation-sys 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)", 124 | "libc 0.2.48 (registry+https://github.com/rust-lang/crates.io-index)", 125 | ] 126 | 127 | [[package]] 128 | name = "core-foundation" 129 | version = "0.5.1" 130 | source = "registry+https://github.com/rust-lang/crates.io-index" 131 | dependencies = [ 132 | "core-foundation-sys 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)", 133 | "libc 0.2.48 (registry+https://github.com/rust-lang/crates.io-index)", 134 | ] 135 | 136 | [[package]] 137 | name = "core-foundation-sys" 138 | version = "0.2.3" 139 | source = "registry+https://github.com/rust-lang/crates.io-index" 140 | dependencies = [ 141 | "libc 0.2.48 (registry+https://github.com/rust-lang/crates.io-index)", 142 | ] 143 | 144 | [[package]] 145 | name = "core-foundation-sys" 146 | version = "0.5.1" 147 | source = "registry+https://github.com/rust-lang/crates.io-index" 148 | dependencies = [ 149 | "libc 0.2.48 (registry+https://github.com/rust-lang/crates.io-index)", 150 | ] 151 | 152 | [[package]] 153 | name = "crc32fast" 154 | version = "1.1.2" 155 | source = "registry+https://github.com/rust-lang/crates.io-index" 156 | dependencies = [ 157 | "cfg-if 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)", 158 | ] 159 | 160 | [[package]] 161 | name = "crossbeam" 162 | version = "0.6.0" 163 | source = "registry+https://github.com/rust-lang/crates.io-index" 164 | dependencies = [ 165 | "cfg-if 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)", 166 | "crossbeam-channel 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)", 167 | "crossbeam-deque 0.6.3 (registry+https://github.com/rust-lang/crates.io-index)", 168 | "crossbeam-epoch 0.7.1 (registry+https://github.com/rust-lang/crates.io-index)", 169 | "crossbeam-utils 0.6.5 (registry+https://github.com/rust-lang/crates.io-index)", 170 | "lazy_static 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)", 171 | "num_cpus 1.9.0 (registry+https://github.com/rust-lang/crates.io-index)", 172 | "parking_lot 0.7.1 (registry+https://github.com/rust-lang/crates.io-index)", 173 | ] 174 | 175 | [[package]] 176 | name = "crossbeam-channel" 177 | version = "0.3.8" 178 | source = "registry+https://github.com/rust-lang/crates.io-index" 179 | dependencies = [ 180 | "crossbeam-utils 0.6.5 (registry+https://github.com/rust-lang/crates.io-index)", 181 | "smallvec 0.6.8 (registry+https://github.com/rust-lang/crates.io-index)", 182 | ] 183 | 184 | [[package]] 185 | name = "crossbeam-deque" 186 | version = "0.6.3" 187 | source = "registry+https://github.com/rust-lang/crates.io-index" 188 | dependencies = [ 189 | "crossbeam-epoch 0.7.1 (registry+https://github.com/rust-lang/crates.io-index)", 190 | "crossbeam-utils 0.6.5 (registry+https://github.com/rust-lang/crates.io-index)", 191 | ] 192 | 193 | [[package]] 194 | name = "crossbeam-epoch" 195 | version = "0.7.1" 196 | source = "registry+https://github.com/rust-lang/crates.io-index" 197 | dependencies = [ 198 | "arrayvec 0.4.10 (registry+https://github.com/rust-lang/crates.io-index)", 199 | "cfg-if 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)", 200 | "crossbeam-utils 0.6.5 (registry+https://github.com/rust-lang/crates.io-index)", 201 | "lazy_static 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)", 202 | "memoffset 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)", 203 | "scopeguard 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)", 204 | ] 205 | 206 | [[package]] 207 | name = "crossbeam-utils" 208 | version = "0.6.5" 209 | source = "registry+https://github.com/rust-lang/crates.io-index" 210 | dependencies = [ 211 | "cfg-if 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)", 212 | "lazy_static 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)", 213 | ] 214 | 215 | [[package]] 216 | name = "dtoa" 217 | version = "0.4.3" 218 | source = "registry+https://github.com/rust-lang/crates.io-index" 219 | 220 | [[package]] 221 | name = "encoding_rs" 222 | version = "0.8.15" 223 | source = "registry+https://github.com/rust-lang/crates.io-index" 224 | dependencies = [ 225 | "cfg-if 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)", 226 | ] 227 | 228 | [[package]] 229 | name = "fnv" 230 | version = "1.0.6" 231 | source = "registry+https://github.com/rust-lang/crates.io-index" 232 | 233 | [[package]] 234 | name = "foreign-types" 235 | version = "0.3.2" 236 | source = "registry+https://github.com/rust-lang/crates.io-index" 237 | dependencies = [ 238 | "foreign-types-shared 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", 239 | ] 240 | 241 | [[package]] 242 | name = "foreign-types-shared" 243 | version = "0.1.1" 244 | source = "registry+https://github.com/rust-lang/crates.io-index" 245 | 246 | [[package]] 247 | name = "fuchsia-cprng" 248 | version = "0.1.0" 249 | source = "registry+https://github.com/rust-lang/crates.io-index" 250 | 251 | [[package]] 252 | name = "fuchsia-zircon" 253 | version = "0.3.3" 254 | source = "registry+https://github.com/rust-lang/crates.io-index" 255 | dependencies = [ 256 | "bitflags 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)", 257 | "fuchsia-zircon-sys 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)", 258 | ] 259 | 260 | [[package]] 261 | name = "fuchsia-zircon-sys" 262 | version = "0.3.3" 263 | source = "registry+https://github.com/rust-lang/crates.io-index" 264 | 265 | [[package]] 266 | name = "futures" 267 | version = "0.1.25" 268 | source = "registry+https://github.com/rust-lang/crates.io-index" 269 | 270 | [[package]] 271 | name = "futures-cpupool" 272 | version = "0.1.8" 273 | source = "registry+https://github.com/rust-lang/crates.io-index" 274 | dependencies = [ 275 | "futures 0.1.25 (registry+https://github.com/rust-lang/crates.io-index)", 276 | "num_cpus 1.9.0 (registry+https://github.com/rust-lang/crates.io-index)", 277 | ] 278 | 279 | [[package]] 280 | name = "h2" 281 | version = "0.1.16" 282 | source = "registry+https://github.com/rust-lang/crates.io-index" 283 | dependencies = [ 284 | "byteorder 1.3.1 (registry+https://github.com/rust-lang/crates.io-index)", 285 | "bytes 0.4.11 (registry+https://github.com/rust-lang/crates.io-index)", 286 | "fnv 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)", 287 | "futures 0.1.25 (registry+https://github.com/rust-lang/crates.io-index)", 288 | "http 0.1.15 (registry+https://github.com/rust-lang/crates.io-index)", 289 | "indexmap 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)", 290 | "log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", 291 | "slab 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)", 292 | "string 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)", 293 | "tokio-io 0.1.11 (registry+https://github.com/rust-lang/crates.io-index)", 294 | ] 295 | 296 | [[package]] 297 | name = "http" 298 | version = "0.1.15" 299 | source = "registry+https://github.com/rust-lang/crates.io-index" 300 | dependencies = [ 301 | "bytes 0.4.11 (registry+https://github.com/rust-lang/crates.io-index)", 302 | "fnv 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)", 303 | "itoa 0.4.3 (registry+https://github.com/rust-lang/crates.io-index)", 304 | ] 305 | 306 | [[package]] 307 | name = "httparse" 308 | version = "1.3.3" 309 | source = "registry+https://github.com/rust-lang/crates.io-index" 310 | 311 | [[package]] 312 | name = "hyper" 313 | version = "0.11.27" 314 | source = "registry+https://github.com/rust-lang/crates.io-index" 315 | dependencies = [ 316 | "base64 0.9.3 (registry+https://github.com/rust-lang/crates.io-index)", 317 | "bytes 0.4.11 (registry+https://github.com/rust-lang/crates.io-index)", 318 | "futures 0.1.25 (registry+https://github.com/rust-lang/crates.io-index)", 319 | "futures-cpupool 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)", 320 | "httparse 1.3.3 (registry+https://github.com/rust-lang/crates.io-index)", 321 | "iovec 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", 322 | "language-tags 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", 323 | "log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", 324 | "mime 0.3.13 (registry+https://github.com/rust-lang/crates.io-index)", 325 | "net2 0.2.33 (registry+https://github.com/rust-lang/crates.io-index)", 326 | "percent-encoding 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)", 327 | "relay 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", 328 | "time 0.1.42 (registry+https://github.com/rust-lang/crates.io-index)", 329 | "tokio-core 0.1.17 (registry+https://github.com/rust-lang/crates.io-index)", 330 | "tokio-io 0.1.11 (registry+https://github.com/rust-lang/crates.io-index)", 331 | "tokio-proto 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", 332 | "tokio-service 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", 333 | "unicase 2.2.0 (registry+https://github.com/rust-lang/crates.io-index)", 334 | "want 0.0.4 (registry+https://github.com/rust-lang/crates.io-index)", 335 | ] 336 | 337 | [[package]] 338 | name = "hyper" 339 | version = "0.12.23" 340 | source = "registry+https://github.com/rust-lang/crates.io-index" 341 | dependencies = [ 342 | "bytes 0.4.11 (registry+https://github.com/rust-lang/crates.io-index)", 343 | "futures 0.1.25 (registry+https://github.com/rust-lang/crates.io-index)", 344 | "futures-cpupool 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)", 345 | "h2 0.1.16 (registry+https://github.com/rust-lang/crates.io-index)", 346 | "http 0.1.15 (registry+https://github.com/rust-lang/crates.io-index)", 347 | "httparse 1.3.3 (registry+https://github.com/rust-lang/crates.io-index)", 348 | "iovec 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", 349 | "itoa 0.4.3 (registry+https://github.com/rust-lang/crates.io-index)", 350 | "log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", 351 | "net2 0.2.33 (registry+https://github.com/rust-lang/crates.io-index)", 352 | "time 0.1.42 (registry+https://github.com/rust-lang/crates.io-index)", 353 | "tokio 0.1.15 (registry+https://github.com/rust-lang/crates.io-index)", 354 | "tokio-executor 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)", 355 | "tokio-io 0.1.11 (registry+https://github.com/rust-lang/crates.io-index)", 356 | "tokio-reactor 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)", 357 | "tokio-tcp 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)", 358 | "tokio-threadpool 0.1.11 (registry+https://github.com/rust-lang/crates.io-index)", 359 | "tokio-timer 0.2.9 (registry+https://github.com/rust-lang/crates.io-index)", 360 | "want 0.0.6 (registry+https://github.com/rust-lang/crates.io-index)", 361 | ] 362 | 363 | [[package]] 364 | name = "hyper-tls" 365 | version = "0.1.4" 366 | source = "registry+https://github.com/rust-lang/crates.io-index" 367 | dependencies = [ 368 | "futures 0.1.25 (registry+https://github.com/rust-lang/crates.io-index)", 369 | "hyper 0.11.27 (registry+https://github.com/rust-lang/crates.io-index)", 370 | "native-tls 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)", 371 | "tokio-core 0.1.17 (registry+https://github.com/rust-lang/crates.io-index)", 372 | "tokio-io 0.1.11 (registry+https://github.com/rust-lang/crates.io-index)", 373 | "tokio-service 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", 374 | "tokio-tls 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)", 375 | ] 376 | 377 | [[package]] 378 | name = "hyper-tls" 379 | version = "0.3.1" 380 | source = "registry+https://github.com/rust-lang/crates.io-index" 381 | dependencies = [ 382 | "bytes 0.4.11 (registry+https://github.com/rust-lang/crates.io-index)", 383 | "futures 0.1.25 (registry+https://github.com/rust-lang/crates.io-index)", 384 | "hyper 0.12.23 (registry+https://github.com/rust-lang/crates.io-index)", 385 | "native-tls 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", 386 | "tokio-io 0.1.11 (registry+https://github.com/rust-lang/crates.io-index)", 387 | ] 388 | 389 | [[package]] 390 | name = "idna" 391 | version = "0.1.5" 392 | source = "registry+https://github.com/rust-lang/crates.io-index" 393 | dependencies = [ 394 | "matches 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)", 395 | "unicode-bidi 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)", 396 | "unicode-normalization 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)", 397 | ] 398 | 399 | [[package]] 400 | name = "indexmap" 401 | version = "1.0.2" 402 | source = "registry+https://github.com/rust-lang/crates.io-index" 403 | 404 | [[package]] 405 | name = "iovec" 406 | version = "0.1.2" 407 | source = "registry+https://github.com/rust-lang/crates.io-index" 408 | dependencies = [ 409 | "libc 0.2.48 (registry+https://github.com/rust-lang/crates.io-index)", 410 | "winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)", 411 | ] 412 | 413 | [[package]] 414 | name = "itoa" 415 | version = "0.4.3" 416 | source = "registry+https://github.com/rust-lang/crates.io-index" 417 | 418 | [[package]] 419 | name = "kernel32-sys" 420 | version = "0.2.2" 421 | source = "registry+https://github.com/rust-lang/crates.io-index" 422 | dependencies = [ 423 | "winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)", 424 | "winapi-build 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", 425 | ] 426 | 427 | [[package]] 428 | name = "language-tags" 429 | version = "0.2.2" 430 | source = "registry+https://github.com/rust-lang/crates.io-index" 431 | 432 | [[package]] 433 | name = "lazy_static" 434 | version = "0.2.11" 435 | source = "registry+https://github.com/rust-lang/crates.io-index" 436 | 437 | [[package]] 438 | name = "lazy_static" 439 | version = "1.2.0" 440 | source = "registry+https://github.com/rust-lang/crates.io-index" 441 | 442 | [[package]] 443 | name = "lazycell" 444 | version = "1.2.1" 445 | source = "registry+https://github.com/rust-lang/crates.io-index" 446 | 447 | [[package]] 448 | name = "libc" 449 | version = "0.2.48" 450 | source = "registry+https://github.com/rust-lang/crates.io-index" 451 | 452 | [[package]] 453 | name = "libflate" 454 | version = "0.1.19" 455 | source = "registry+https://github.com/rust-lang/crates.io-index" 456 | dependencies = [ 457 | "adler32 1.0.3 (registry+https://github.com/rust-lang/crates.io-index)", 458 | "byteorder 1.3.1 (registry+https://github.com/rust-lang/crates.io-index)", 459 | "crc32fast 1.1.2 (registry+https://github.com/rust-lang/crates.io-index)", 460 | ] 461 | 462 | [[package]] 463 | name = "lock_api" 464 | version = "0.1.5" 465 | source = "registry+https://github.com/rust-lang/crates.io-index" 466 | dependencies = [ 467 | "owning_ref 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", 468 | "scopeguard 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)", 469 | ] 470 | 471 | [[package]] 472 | name = "log" 473 | version = "0.3.9" 474 | source = "registry+https://github.com/rust-lang/crates.io-index" 475 | dependencies = [ 476 | "log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", 477 | ] 478 | 479 | [[package]] 480 | name = "log" 481 | version = "0.4.6" 482 | source = "registry+https://github.com/rust-lang/crates.io-index" 483 | dependencies = [ 484 | "cfg-if 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)", 485 | ] 486 | 487 | [[package]] 488 | name = "matches" 489 | version = "0.1.8" 490 | source = "registry+https://github.com/rust-lang/crates.io-index" 491 | 492 | [[package]] 493 | name = "memoffset" 494 | version = "0.2.1" 495 | source = "registry+https://github.com/rust-lang/crates.io-index" 496 | 497 | [[package]] 498 | name = "mime" 499 | version = "0.3.13" 500 | source = "registry+https://github.com/rust-lang/crates.io-index" 501 | dependencies = [ 502 | "unicase 2.2.0 (registry+https://github.com/rust-lang/crates.io-index)", 503 | ] 504 | 505 | [[package]] 506 | name = "mime_guess" 507 | version = "2.0.0-alpha.6" 508 | source = "registry+https://github.com/rust-lang/crates.io-index" 509 | dependencies = [ 510 | "mime 0.3.13 (registry+https://github.com/rust-lang/crates.io-index)", 511 | "phf 0.7.24 (registry+https://github.com/rust-lang/crates.io-index)", 512 | "phf_codegen 0.7.24 (registry+https://github.com/rust-lang/crates.io-index)", 513 | "unicase 1.4.2 (registry+https://github.com/rust-lang/crates.io-index)", 514 | ] 515 | 516 | [[package]] 517 | name = "mio" 518 | version = "0.6.16" 519 | source = "registry+https://github.com/rust-lang/crates.io-index" 520 | dependencies = [ 521 | "fuchsia-zircon 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)", 522 | "fuchsia-zircon-sys 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)", 523 | "iovec 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", 524 | "kernel32-sys 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", 525 | "lazycell 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)", 526 | "libc 0.2.48 (registry+https://github.com/rust-lang/crates.io-index)", 527 | "log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", 528 | "miow 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)", 529 | "net2 0.2.33 (registry+https://github.com/rust-lang/crates.io-index)", 530 | "slab 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)", 531 | "winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)", 532 | ] 533 | 534 | [[package]] 535 | name = "mio-uds" 536 | version = "0.6.7" 537 | source = "registry+https://github.com/rust-lang/crates.io-index" 538 | dependencies = [ 539 | "iovec 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", 540 | "libc 0.2.48 (registry+https://github.com/rust-lang/crates.io-index)", 541 | "mio 0.6.16 (registry+https://github.com/rust-lang/crates.io-index)", 542 | ] 543 | 544 | [[package]] 545 | name = "miow" 546 | version = "0.2.1" 547 | source = "registry+https://github.com/rust-lang/crates.io-index" 548 | dependencies = [ 549 | "kernel32-sys 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", 550 | "net2 0.2.33 (registry+https://github.com/rust-lang/crates.io-index)", 551 | "winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)", 552 | "ws2_32-sys 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)", 553 | ] 554 | 555 | [[package]] 556 | name = "native-tls" 557 | version = "0.1.5" 558 | source = "registry+https://github.com/rust-lang/crates.io-index" 559 | dependencies = [ 560 | "lazy_static 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)", 561 | "libc 0.2.48 (registry+https://github.com/rust-lang/crates.io-index)", 562 | "openssl 0.9.24 (registry+https://github.com/rust-lang/crates.io-index)", 563 | "schannel 0.1.14 (registry+https://github.com/rust-lang/crates.io-index)", 564 | "security-framework 0.1.16 (registry+https://github.com/rust-lang/crates.io-index)", 565 | "security-framework-sys 0.1.16 (registry+https://github.com/rust-lang/crates.io-index)", 566 | "tempdir 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)", 567 | ] 568 | 569 | [[package]] 570 | name = "native-tls" 571 | version = "0.2.2" 572 | source = "registry+https://github.com/rust-lang/crates.io-index" 573 | dependencies = [ 574 | "lazy_static 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)", 575 | "libc 0.2.48 (registry+https://github.com/rust-lang/crates.io-index)", 576 | "log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", 577 | "openssl 0.10.16 (registry+https://github.com/rust-lang/crates.io-index)", 578 | "openssl-probe 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", 579 | "openssl-sys 0.9.40 (registry+https://github.com/rust-lang/crates.io-index)", 580 | "schannel 0.1.14 (registry+https://github.com/rust-lang/crates.io-index)", 581 | "security-framework 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", 582 | "security-framework-sys 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)", 583 | "tempfile 3.0.5 (registry+https://github.com/rust-lang/crates.io-index)", 584 | ] 585 | 586 | [[package]] 587 | name = "net2" 588 | version = "0.2.33" 589 | source = "registry+https://github.com/rust-lang/crates.io-index" 590 | dependencies = [ 591 | "cfg-if 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)", 592 | "libc 0.2.48 (registry+https://github.com/rust-lang/crates.io-index)", 593 | "winapi 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)", 594 | ] 595 | 596 | [[package]] 597 | name = "nodrop" 598 | version = "0.1.13" 599 | source = "registry+https://github.com/rust-lang/crates.io-index" 600 | 601 | [[package]] 602 | name = "num_cpus" 603 | version = "1.9.0" 604 | source = "registry+https://github.com/rust-lang/crates.io-index" 605 | dependencies = [ 606 | "libc 0.2.48 (registry+https://github.com/rust-lang/crates.io-index)", 607 | ] 608 | 609 | [[package]] 610 | name = "openssl" 611 | version = "0.9.24" 612 | source = "registry+https://github.com/rust-lang/crates.io-index" 613 | dependencies = [ 614 | "bitflags 0.9.1 (registry+https://github.com/rust-lang/crates.io-index)", 615 | "foreign-types 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)", 616 | "lazy_static 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)", 617 | "libc 0.2.48 (registry+https://github.com/rust-lang/crates.io-index)", 618 | "openssl-sys 0.9.40 (registry+https://github.com/rust-lang/crates.io-index)", 619 | ] 620 | 621 | [[package]] 622 | name = "openssl" 623 | version = "0.10.16" 624 | source = "registry+https://github.com/rust-lang/crates.io-index" 625 | dependencies = [ 626 | "bitflags 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)", 627 | "cfg-if 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)", 628 | "foreign-types 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)", 629 | "lazy_static 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)", 630 | "libc 0.2.48 (registry+https://github.com/rust-lang/crates.io-index)", 631 | "openssl-sys 0.9.40 (registry+https://github.com/rust-lang/crates.io-index)", 632 | ] 633 | 634 | [[package]] 635 | name = "openssl-probe" 636 | version = "0.1.2" 637 | source = "registry+https://github.com/rust-lang/crates.io-index" 638 | 639 | [[package]] 640 | name = "openssl-sys" 641 | version = "0.9.40" 642 | source = "registry+https://github.com/rust-lang/crates.io-index" 643 | dependencies = [ 644 | "cc 1.0.28 (registry+https://github.com/rust-lang/crates.io-index)", 645 | "libc 0.2.48 (registry+https://github.com/rust-lang/crates.io-index)", 646 | "pkg-config 0.3.14 (registry+https://github.com/rust-lang/crates.io-index)", 647 | "vcpkg 0.2.6 (registry+https://github.com/rust-lang/crates.io-index)", 648 | ] 649 | 650 | [[package]] 651 | name = "owning_ref" 652 | version = "0.4.0" 653 | source = "registry+https://github.com/rust-lang/crates.io-index" 654 | dependencies = [ 655 | "stable_deref_trait 1.1.1 (registry+https://github.com/rust-lang/crates.io-index)", 656 | ] 657 | 658 | [[package]] 659 | name = "parking_lot" 660 | version = "0.7.1" 661 | source = "registry+https://github.com/rust-lang/crates.io-index" 662 | dependencies = [ 663 | "lock_api 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)", 664 | "parking_lot_core 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", 665 | ] 666 | 667 | [[package]] 668 | name = "parking_lot_core" 669 | version = "0.4.0" 670 | source = "registry+https://github.com/rust-lang/crates.io-index" 671 | dependencies = [ 672 | "libc 0.2.48 (registry+https://github.com/rust-lang/crates.io-index)", 673 | "rand 0.6.5 (registry+https://github.com/rust-lang/crates.io-index)", 674 | "rustc_version 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)", 675 | "smallvec 0.6.8 (registry+https://github.com/rust-lang/crates.io-index)", 676 | "winapi 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)", 677 | ] 678 | 679 | [[package]] 680 | name = "percent-encoding" 681 | version = "1.0.1" 682 | source = "registry+https://github.com/rust-lang/crates.io-index" 683 | 684 | [[package]] 685 | name = "phf" 686 | version = "0.7.24" 687 | source = "registry+https://github.com/rust-lang/crates.io-index" 688 | dependencies = [ 689 | "phf_shared 0.7.24 (registry+https://github.com/rust-lang/crates.io-index)", 690 | ] 691 | 692 | [[package]] 693 | name = "phf_codegen" 694 | version = "0.7.24" 695 | source = "registry+https://github.com/rust-lang/crates.io-index" 696 | dependencies = [ 697 | "phf_generator 0.7.24 (registry+https://github.com/rust-lang/crates.io-index)", 698 | "phf_shared 0.7.24 (registry+https://github.com/rust-lang/crates.io-index)", 699 | ] 700 | 701 | [[package]] 702 | name = "phf_generator" 703 | version = "0.7.24" 704 | source = "registry+https://github.com/rust-lang/crates.io-index" 705 | dependencies = [ 706 | "phf_shared 0.7.24 (registry+https://github.com/rust-lang/crates.io-index)", 707 | "rand 0.6.5 (registry+https://github.com/rust-lang/crates.io-index)", 708 | ] 709 | 710 | [[package]] 711 | name = "phf_shared" 712 | version = "0.7.24" 713 | source = "registry+https://github.com/rust-lang/crates.io-index" 714 | dependencies = [ 715 | "siphasher 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)", 716 | "unicase 1.4.2 (registry+https://github.com/rust-lang/crates.io-index)", 717 | ] 718 | 719 | [[package]] 720 | name = "pkg-config" 721 | version = "0.3.14" 722 | source = "registry+https://github.com/rust-lang/crates.io-index" 723 | 724 | [[package]] 725 | name = "rand" 726 | version = "0.3.23" 727 | source = "registry+https://github.com/rust-lang/crates.io-index" 728 | dependencies = [ 729 | "libc 0.2.48 (registry+https://github.com/rust-lang/crates.io-index)", 730 | "rand 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", 731 | ] 732 | 733 | [[package]] 734 | name = "rand" 735 | version = "0.4.6" 736 | source = "registry+https://github.com/rust-lang/crates.io-index" 737 | dependencies = [ 738 | "fuchsia-cprng 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", 739 | "libc 0.2.48 (registry+https://github.com/rust-lang/crates.io-index)", 740 | "rand_core 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", 741 | "rdrand 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", 742 | "winapi 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)", 743 | ] 744 | 745 | [[package]] 746 | name = "rand" 747 | version = "0.6.5" 748 | source = "registry+https://github.com/rust-lang/crates.io-index" 749 | dependencies = [ 750 | "autocfg 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", 751 | "libc 0.2.48 (registry+https://github.com/rust-lang/crates.io-index)", 752 | "rand_chacha 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", 753 | "rand_core 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", 754 | "rand_hc 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", 755 | "rand_isaac 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", 756 | "rand_jitter 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", 757 | "rand_os 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", 758 | "rand_pcg 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", 759 | "rand_xorshift 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", 760 | "winapi 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)", 761 | ] 762 | 763 | [[package]] 764 | name = "rand_chacha" 765 | version = "0.1.1" 766 | source = "registry+https://github.com/rust-lang/crates.io-index" 767 | dependencies = [ 768 | "autocfg 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", 769 | "rand_core 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", 770 | ] 771 | 772 | [[package]] 773 | name = "rand_core" 774 | version = "0.3.1" 775 | source = "registry+https://github.com/rust-lang/crates.io-index" 776 | dependencies = [ 777 | "rand_core 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", 778 | ] 779 | 780 | [[package]] 781 | name = "rand_core" 782 | version = "0.4.0" 783 | source = "registry+https://github.com/rust-lang/crates.io-index" 784 | 785 | [[package]] 786 | name = "rand_hc" 787 | version = "0.1.0" 788 | source = "registry+https://github.com/rust-lang/crates.io-index" 789 | dependencies = [ 790 | "rand_core 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", 791 | ] 792 | 793 | [[package]] 794 | name = "rand_isaac" 795 | version = "0.1.1" 796 | source = "registry+https://github.com/rust-lang/crates.io-index" 797 | dependencies = [ 798 | "rand_core 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", 799 | ] 800 | 801 | [[package]] 802 | name = "rand_jitter" 803 | version = "0.1.2" 804 | source = "registry+https://github.com/rust-lang/crates.io-index" 805 | dependencies = [ 806 | "libc 0.2.48 (registry+https://github.com/rust-lang/crates.io-index)", 807 | "rand_core 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", 808 | "winapi 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)", 809 | ] 810 | 811 | [[package]] 812 | name = "rand_os" 813 | version = "0.1.2" 814 | source = "registry+https://github.com/rust-lang/crates.io-index" 815 | dependencies = [ 816 | "cloudabi 0.0.3 (registry+https://github.com/rust-lang/crates.io-index)", 817 | "fuchsia-cprng 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", 818 | "libc 0.2.48 (registry+https://github.com/rust-lang/crates.io-index)", 819 | "rand_core 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", 820 | "rdrand 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", 821 | "winapi 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)", 822 | ] 823 | 824 | [[package]] 825 | name = "rand_pcg" 826 | version = "0.1.1" 827 | source = "registry+https://github.com/rust-lang/crates.io-index" 828 | dependencies = [ 829 | "rand_core 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", 830 | "rustc_version 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)", 831 | ] 832 | 833 | [[package]] 834 | name = "rand_xorshift" 835 | version = "0.1.1" 836 | source = "registry+https://github.com/rust-lang/crates.io-index" 837 | dependencies = [ 838 | "rand_core 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", 839 | ] 840 | 841 | [[package]] 842 | name = "rdrand" 843 | version = "0.4.0" 844 | source = "registry+https://github.com/rust-lang/crates.io-index" 845 | dependencies = [ 846 | "rand_core 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", 847 | ] 848 | 849 | [[package]] 850 | name = "redox_syscall" 851 | version = "0.1.51" 852 | source = "registry+https://github.com/rust-lang/crates.io-index" 853 | 854 | [[package]] 855 | name = "redox_termios" 856 | version = "0.1.1" 857 | source = "registry+https://github.com/rust-lang/crates.io-index" 858 | dependencies = [ 859 | "redox_syscall 0.1.51 (registry+https://github.com/rust-lang/crates.io-index)", 860 | ] 861 | 862 | [[package]] 863 | name = "relay" 864 | version = "0.1.1" 865 | source = "registry+https://github.com/rust-lang/crates.io-index" 866 | dependencies = [ 867 | "futures 0.1.25 (registry+https://github.com/rust-lang/crates.io-index)", 868 | ] 869 | 870 | [[package]] 871 | name = "remove_dir_all" 872 | version = "0.5.1" 873 | source = "registry+https://github.com/rust-lang/crates.io-index" 874 | dependencies = [ 875 | "winapi 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)", 876 | ] 877 | 878 | [[package]] 879 | name = "rench" 880 | version = "0.3.0" 881 | dependencies = [ 882 | "clap 2.32.0 (registry+https://github.com/rust-lang/crates.io-index)", 883 | "futures 0.1.25 (registry+https://github.com/rust-lang/crates.io-index)", 884 | "hyper 0.11.27 (registry+https://github.com/rust-lang/crates.io-index)", 885 | "hyper-tls 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)", 886 | "reqwest 0.9.9 (registry+https://github.com/rust-lang/crates.io-index)", 887 | "tokio-core 0.1.17 (registry+https://github.com/rust-lang/crates.io-index)", 888 | ] 889 | 890 | [[package]] 891 | name = "reqwest" 892 | version = "0.9.9" 893 | source = "registry+https://github.com/rust-lang/crates.io-index" 894 | dependencies = [ 895 | "base64 0.10.1 (registry+https://github.com/rust-lang/crates.io-index)", 896 | "bytes 0.4.11 (registry+https://github.com/rust-lang/crates.io-index)", 897 | "encoding_rs 0.8.15 (registry+https://github.com/rust-lang/crates.io-index)", 898 | "futures 0.1.25 (registry+https://github.com/rust-lang/crates.io-index)", 899 | "http 0.1.15 (registry+https://github.com/rust-lang/crates.io-index)", 900 | "hyper 0.12.23 (registry+https://github.com/rust-lang/crates.io-index)", 901 | "hyper-tls 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", 902 | "libflate 0.1.19 (registry+https://github.com/rust-lang/crates.io-index)", 903 | "log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", 904 | "mime 0.3.13 (registry+https://github.com/rust-lang/crates.io-index)", 905 | "mime_guess 2.0.0-alpha.6 (registry+https://github.com/rust-lang/crates.io-index)", 906 | "native-tls 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", 907 | "serde 1.0.86 (registry+https://github.com/rust-lang/crates.io-index)", 908 | "serde_json 1.0.38 (registry+https://github.com/rust-lang/crates.io-index)", 909 | "serde_urlencoded 0.5.4 (registry+https://github.com/rust-lang/crates.io-index)", 910 | "tokio 0.1.15 (registry+https://github.com/rust-lang/crates.io-index)", 911 | "tokio-executor 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)", 912 | "tokio-io 0.1.11 (registry+https://github.com/rust-lang/crates.io-index)", 913 | "tokio-threadpool 0.1.11 (registry+https://github.com/rust-lang/crates.io-index)", 914 | "tokio-timer 0.2.9 (registry+https://github.com/rust-lang/crates.io-index)", 915 | "url 1.7.2 (registry+https://github.com/rust-lang/crates.io-index)", 916 | "uuid 0.7.2 (registry+https://github.com/rust-lang/crates.io-index)", 917 | ] 918 | 919 | [[package]] 920 | name = "rustc_version" 921 | version = "0.2.3" 922 | source = "registry+https://github.com/rust-lang/crates.io-index" 923 | dependencies = [ 924 | "semver 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)", 925 | ] 926 | 927 | [[package]] 928 | name = "ryu" 929 | version = "0.2.7" 930 | source = "registry+https://github.com/rust-lang/crates.io-index" 931 | 932 | [[package]] 933 | name = "safemem" 934 | version = "0.3.0" 935 | source = "registry+https://github.com/rust-lang/crates.io-index" 936 | 937 | [[package]] 938 | name = "schannel" 939 | version = "0.1.14" 940 | source = "registry+https://github.com/rust-lang/crates.io-index" 941 | dependencies = [ 942 | "lazy_static 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)", 943 | "winapi 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)", 944 | ] 945 | 946 | [[package]] 947 | name = "scoped-tls" 948 | version = "0.1.2" 949 | source = "registry+https://github.com/rust-lang/crates.io-index" 950 | 951 | [[package]] 952 | name = "scopeguard" 953 | version = "0.3.3" 954 | source = "registry+https://github.com/rust-lang/crates.io-index" 955 | 956 | [[package]] 957 | name = "security-framework" 958 | version = "0.1.16" 959 | source = "registry+https://github.com/rust-lang/crates.io-index" 960 | dependencies = [ 961 | "core-foundation 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)", 962 | "core-foundation-sys 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)", 963 | "libc 0.2.48 (registry+https://github.com/rust-lang/crates.io-index)", 964 | "security-framework-sys 0.1.16 (registry+https://github.com/rust-lang/crates.io-index)", 965 | ] 966 | 967 | [[package]] 968 | name = "security-framework" 969 | version = "0.2.2" 970 | source = "registry+https://github.com/rust-lang/crates.io-index" 971 | dependencies = [ 972 | "core-foundation 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)", 973 | "core-foundation-sys 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)", 974 | "libc 0.2.48 (registry+https://github.com/rust-lang/crates.io-index)", 975 | "security-framework-sys 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)", 976 | ] 977 | 978 | [[package]] 979 | name = "security-framework-sys" 980 | version = "0.1.16" 981 | source = "registry+https://github.com/rust-lang/crates.io-index" 982 | dependencies = [ 983 | "core-foundation-sys 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)", 984 | "libc 0.2.48 (registry+https://github.com/rust-lang/crates.io-index)", 985 | ] 986 | 987 | [[package]] 988 | name = "security-framework-sys" 989 | version = "0.2.3" 990 | source = "registry+https://github.com/rust-lang/crates.io-index" 991 | dependencies = [ 992 | "MacTypes-sys 2.1.0 (registry+https://github.com/rust-lang/crates.io-index)", 993 | "core-foundation-sys 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)", 994 | "libc 0.2.48 (registry+https://github.com/rust-lang/crates.io-index)", 995 | ] 996 | 997 | [[package]] 998 | name = "semver" 999 | version = "0.9.0" 1000 | source = "registry+https://github.com/rust-lang/crates.io-index" 1001 | dependencies = [ 1002 | "semver-parser 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)", 1003 | ] 1004 | 1005 | [[package]] 1006 | name = "semver-parser" 1007 | version = "0.7.0" 1008 | source = "registry+https://github.com/rust-lang/crates.io-index" 1009 | 1010 | [[package]] 1011 | name = "serde" 1012 | version = "1.0.86" 1013 | source = "registry+https://github.com/rust-lang/crates.io-index" 1014 | 1015 | [[package]] 1016 | name = "serde_json" 1017 | version = "1.0.38" 1018 | source = "registry+https://github.com/rust-lang/crates.io-index" 1019 | dependencies = [ 1020 | "itoa 0.4.3 (registry+https://github.com/rust-lang/crates.io-index)", 1021 | "ryu 0.2.7 (registry+https://github.com/rust-lang/crates.io-index)", 1022 | "serde 1.0.86 (registry+https://github.com/rust-lang/crates.io-index)", 1023 | ] 1024 | 1025 | [[package]] 1026 | name = "serde_urlencoded" 1027 | version = "0.5.4" 1028 | source = "registry+https://github.com/rust-lang/crates.io-index" 1029 | dependencies = [ 1030 | "dtoa 0.4.3 (registry+https://github.com/rust-lang/crates.io-index)", 1031 | "itoa 0.4.3 (registry+https://github.com/rust-lang/crates.io-index)", 1032 | "serde 1.0.86 (registry+https://github.com/rust-lang/crates.io-index)", 1033 | "url 1.7.2 (registry+https://github.com/rust-lang/crates.io-index)", 1034 | ] 1035 | 1036 | [[package]] 1037 | name = "siphasher" 1038 | version = "0.2.3" 1039 | source = "registry+https://github.com/rust-lang/crates.io-index" 1040 | 1041 | [[package]] 1042 | name = "slab" 1043 | version = "0.3.0" 1044 | source = "registry+https://github.com/rust-lang/crates.io-index" 1045 | 1046 | [[package]] 1047 | name = "slab" 1048 | version = "0.4.2" 1049 | source = "registry+https://github.com/rust-lang/crates.io-index" 1050 | 1051 | [[package]] 1052 | name = "smallvec" 1053 | version = "0.2.1" 1054 | source = "registry+https://github.com/rust-lang/crates.io-index" 1055 | 1056 | [[package]] 1057 | name = "smallvec" 1058 | version = "0.6.8" 1059 | source = "registry+https://github.com/rust-lang/crates.io-index" 1060 | dependencies = [ 1061 | "unreachable 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", 1062 | ] 1063 | 1064 | [[package]] 1065 | name = "stable_deref_trait" 1066 | version = "1.1.1" 1067 | source = "registry+https://github.com/rust-lang/crates.io-index" 1068 | 1069 | [[package]] 1070 | name = "string" 1071 | version = "0.1.3" 1072 | source = "registry+https://github.com/rust-lang/crates.io-index" 1073 | 1074 | [[package]] 1075 | name = "strsim" 1076 | version = "0.7.0" 1077 | source = "registry+https://github.com/rust-lang/crates.io-index" 1078 | 1079 | [[package]] 1080 | name = "take" 1081 | version = "0.1.0" 1082 | source = "registry+https://github.com/rust-lang/crates.io-index" 1083 | 1084 | [[package]] 1085 | name = "tempdir" 1086 | version = "0.3.7" 1087 | source = "registry+https://github.com/rust-lang/crates.io-index" 1088 | dependencies = [ 1089 | "rand 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", 1090 | "remove_dir_all 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)", 1091 | ] 1092 | 1093 | [[package]] 1094 | name = "tempfile" 1095 | version = "3.0.5" 1096 | source = "registry+https://github.com/rust-lang/crates.io-index" 1097 | dependencies = [ 1098 | "cfg-if 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)", 1099 | "libc 0.2.48 (registry+https://github.com/rust-lang/crates.io-index)", 1100 | "rand 0.6.5 (registry+https://github.com/rust-lang/crates.io-index)", 1101 | "redox_syscall 0.1.51 (registry+https://github.com/rust-lang/crates.io-index)", 1102 | "remove_dir_all 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)", 1103 | "winapi 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)", 1104 | ] 1105 | 1106 | [[package]] 1107 | name = "termion" 1108 | version = "1.5.1" 1109 | source = "registry+https://github.com/rust-lang/crates.io-index" 1110 | dependencies = [ 1111 | "libc 0.2.48 (registry+https://github.com/rust-lang/crates.io-index)", 1112 | "redox_syscall 0.1.51 (registry+https://github.com/rust-lang/crates.io-index)", 1113 | "redox_termios 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", 1114 | ] 1115 | 1116 | [[package]] 1117 | name = "textwrap" 1118 | version = "0.10.0" 1119 | source = "registry+https://github.com/rust-lang/crates.io-index" 1120 | dependencies = [ 1121 | "unicode-width 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)", 1122 | ] 1123 | 1124 | [[package]] 1125 | name = "time" 1126 | version = "0.1.42" 1127 | source = "registry+https://github.com/rust-lang/crates.io-index" 1128 | dependencies = [ 1129 | "libc 0.2.48 (registry+https://github.com/rust-lang/crates.io-index)", 1130 | "redox_syscall 0.1.51 (registry+https://github.com/rust-lang/crates.io-index)", 1131 | "winapi 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)", 1132 | ] 1133 | 1134 | [[package]] 1135 | name = "tokio" 1136 | version = "0.1.15" 1137 | source = "registry+https://github.com/rust-lang/crates.io-index" 1138 | dependencies = [ 1139 | "bytes 0.4.11 (registry+https://github.com/rust-lang/crates.io-index)", 1140 | "futures 0.1.25 (registry+https://github.com/rust-lang/crates.io-index)", 1141 | "mio 0.6.16 (registry+https://github.com/rust-lang/crates.io-index)", 1142 | "num_cpus 1.9.0 (registry+https://github.com/rust-lang/crates.io-index)", 1143 | "tokio-codec 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", 1144 | "tokio-current-thread 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)", 1145 | "tokio-executor 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)", 1146 | "tokio-fs 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)", 1147 | "tokio-io 0.1.11 (registry+https://github.com/rust-lang/crates.io-index)", 1148 | "tokio-reactor 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)", 1149 | "tokio-sync 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", 1150 | "tokio-tcp 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)", 1151 | "tokio-threadpool 0.1.11 (registry+https://github.com/rust-lang/crates.io-index)", 1152 | "tokio-timer 0.2.9 (registry+https://github.com/rust-lang/crates.io-index)", 1153 | "tokio-udp 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)", 1154 | "tokio-uds 0.2.5 (registry+https://github.com/rust-lang/crates.io-index)", 1155 | ] 1156 | 1157 | [[package]] 1158 | name = "tokio-codec" 1159 | version = "0.1.1" 1160 | source = "registry+https://github.com/rust-lang/crates.io-index" 1161 | dependencies = [ 1162 | "bytes 0.4.11 (registry+https://github.com/rust-lang/crates.io-index)", 1163 | "futures 0.1.25 (registry+https://github.com/rust-lang/crates.io-index)", 1164 | "tokio-io 0.1.11 (registry+https://github.com/rust-lang/crates.io-index)", 1165 | ] 1166 | 1167 | [[package]] 1168 | name = "tokio-core" 1169 | version = "0.1.17" 1170 | source = "registry+https://github.com/rust-lang/crates.io-index" 1171 | dependencies = [ 1172 | "bytes 0.4.11 (registry+https://github.com/rust-lang/crates.io-index)", 1173 | "futures 0.1.25 (registry+https://github.com/rust-lang/crates.io-index)", 1174 | "iovec 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", 1175 | "log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", 1176 | "mio 0.6.16 (registry+https://github.com/rust-lang/crates.io-index)", 1177 | "scoped-tls 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", 1178 | "tokio 0.1.15 (registry+https://github.com/rust-lang/crates.io-index)", 1179 | "tokio-executor 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)", 1180 | "tokio-io 0.1.11 (registry+https://github.com/rust-lang/crates.io-index)", 1181 | "tokio-reactor 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)", 1182 | "tokio-timer 0.2.9 (registry+https://github.com/rust-lang/crates.io-index)", 1183 | ] 1184 | 1185 | [[package]] 1186 | name = "tokio-current-thread" 1187 | version = "0.1.4" 1188 | source = "registry+https://github.com/rust-lang/crates.io-index" 1189 | dependencies = [ 1190 | "futures 0.1.25 (registry+https://github.com/rust-lang/crates.io-index)", 1191 | "tokio-executor 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)", 1192 | ] 1193 | 1194 | [[package]] 1195 | name = "tokio-executor" 1196 | version = "0.1.6" 1197 | source = "registry+https://github.com/rust-lang/crates.io-index" 1198 | dependencies = [ 1199 | "crossbeam-utils 0.6.5 (registry+https://github.com/rust-lang/crates.io-index)", 1200 | "futures 0.1.25 (registry+https://github.com/rust-lang/crates.io-index)", 1201 | ] 1202 | 1203 | [[package]] 1204 | name = "tokio-fs" 1205 | version = "0.1.5" 1206 | source = "registry+https://github.com/rust-lang/crates.io-index" 1207 | dependencies = [ 1208 | "futures 0.1.25 (registry+https://github.com/rust-lang/crates.io-index)", 1209 | "tokio-io 0.1.11 (registry+https://github.com/rust-lang/crates.io-index)", 1210 | "tokio-threadpool 0.1.11 (registry+https://github.com/rust-lang/crates.io-index)", 1211 | ] 1212 | 1213 | [[package]] 1214 | name = "tokio-io" 1215 | version = "0.1.11" 1216 | source = "registry+https://github.com/rust-lang/crates.io-index" 1217 | dependencies = [ 1218 | "bytes 0.4.11 (registry+https://github.com/rust-lang/crates.io-index)", 1219 | "futures 0.1.25 (registry+https://github.com/rust-lang/crates.io-index)", 1220 | "log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", 1221 | ] 1222 | 1223 | [[package]] 1224 | name = "tokio-proto" 1225 | version = "0.1.1" 1226 | source = "registry+https://github.com/rust-lang/crates.io-index" 1227 | dependencies = [ 1228 | "futures 0.1.25 (registry+https://github.com/rust-lang/crates.io-index)", 1229 | "log 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)", 1230 | "net2 0.2.33 (registry+https://github.com/rust-lang/crates.io-index)", 1231 | "rand 0.3.23 (registry+https://github.com/rust-lang/crates.io-index)", 1232 | "slab 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)", 1233 | "smallvec 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)", 1234 | "take 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", 1235 | "tokio-core 0.1.17 (registry+https://github.com/rust-lang/crates.io-index)", 1236 | "tokio-io 0.1.11 (registry+https://github.com/rust-lang/crates.io-index)", 1237 | "tokio-service 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", 1238 | ] 1239 | 1240 | [[package]] 1241 | name = "tokio-reactor" 1242 | version = "0.1.8" 1243 | source = "registry+https://github.com/rust-lang/crates.io-index" 1244 | dependencies = [ 1245 | "crossbeam-utils 0.6.5 (registry+https://github.com/rust-lang/crates.io-index)", 1246 | "futures 0.1.25 (registry+https://github.com/rust-lang/crates.io-index)", 1247 | "lazy_static 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)", 1248 | "log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", 1249 | "mio 0.6.16 (registry+https://github.com/rust-lang/crates.io-index)", 1250 | "num_cpus 1.9.0 (registry+https://github.com/rust-lang/crates.io-index)", 1251 | "parking_lot 0.7.1 (registry+https://github.com/rust-lang/crates.io-index)", 1252 | "slab 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)", 1253 | "tokio-executor 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)", 1254 | "tokio-io 0.1.11 (registry+https://github.com/rust-lang/crates.io-index)", 1255 | ] 1256 | 1257 | [[package]] 1258 | name = "tokio-service" 1259 | version = "0.1.0" 1260 | source = "registry+https://github.com/rust-lang/crates.io-index" 1261 | dependencies = [ 1262 | "futures 0.1.25 (registry+https://github.com/rust-lang/crates.io-index)", 1263 | ] 1264 | 1265 | [[package]] 1266 | name = "tokio-sync" 1267 | version = "0.1.1" 1268 | source = "registry+https://github.com/rust-lang/crates.io-index" 1269 | dependencies = [ 1270 | "futures 0.1.25 (registry+https://github.com/rust-lang/crates.io-index)", 1271 | ] 1272 | 1273 | [[package]] 1274 | name = "tokio-tcp" 1275 | version = "0.1.3" 1276 | source = "registry+https://github.com/rust-lang/crates.io-index" 1277 | dependencies = [ 1278 | "bytes 0.4.11 (registry+https://github.com/rust-lang/crates.io-index)", 1279 | "futures 0.1.25 (registry+https://github.com/rust-lang/crates.io-index)", 1280 | "iovec 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", 1281 | "mio 0.6.16 (registry+https://github.com/rust-lang/crates.io-index)", 1282 | "tokio-io 0.1.11 (registry+https://github.com/rust-lang/crates.io-index)", 1283 | "tokio-reactor 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)", 1284 | ] 1285 | 1286 | [[package]] 1287 | name = "tokio-threadpool" 1288 | version = "0.1.11" 1289 | source = "registry+https://github.com/rust-lang/crates.io-index" 1290 | dependencies = [ 1291 | "crossbeam 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)", 1292 | "crossbeam-channel 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)", 1293 | "crossbeam-deque 0.6.3 (registry+https://github.com/rust-lang/crates.io-index)", 1294 | "crossbeam-utils 0.6.5 (registry+https://github.com/rust-lang/crates.io-index)", 1295 | "futures 0.1.25 (registry+https://github.com/rust-lang/crates.io-index)", 1296 | "log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", 1297 | "num_cpus 1.9.0 (registry+https://github.com/rust-lang/crates.io-index)", 1298 | "rand 0.6.5 (registry+https://github.com/rust-lang/crates.io-index)", 1299 | "slab 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)", 1300 | "tokio-executor 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)", 1301 | ] 1302 | 1303 | [[package]] 1304 | name = "tokio-timer" 1305 | version = "0.2.9" 1306 | source = "registry+https://github.com/rust-lang/crates.io-index" 1307 | dependencies = [ 1308 | "crossbeam-utils 0.6.5 (registry+https://github.com/rust-lang/crates.io-index)", 1309 | "futures 0.1.25 (registry+https://github.com/rust-lang/crates.io-index)", 1310 | "slab 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)", 1311 | "tokio-executor 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)", 1312 | ] 1313 | 1314 | [[package]] 1315 | name = "tokio-tls" 1316 | version = "0.1.4" 1317 | source = "registry+https://github.com/rust-lang/crates.io-index" 1318 | dependencies = [ 1319 | "futures 0.1.25 (registry+https://github.com/rust-lang/crates.io-index)", 1320 | "native-tls 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)", 1321 | "tokio-core 0.1.17 (registry+https://github.com/rust-lang/crates.io-index)", 1322 | "tokio-io 0.1.11 (registry+https://github.com/rust-lang/crates.io-index)", 1323 | ] 1324 | 1325 | [[package]] 1326 | name = "tokio-udp" 1327 | version = "0.1.3" 1328 | source = "registry+https://github.com/rust-lang/crates.io-index" 1329 | dependencies = [ 1330 | "bytes 0.4.11 (registry+https://github.com/rust-lang/crates.io-index)", 1331 | "futures 0.1.25 (registry+https://github.com/rust-lang/crates.io-index)", 1332 | "log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", 1333 | "mio 0.6.16 (registry+https://github.com/rust-lang/crates.io-index)", 1334 | "tokio-codec 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", 1335 | "tokio-io 0.1.11 (registry+https://github.com/rust-lang/crates.io-index)", 1336 | "tokio-reactor 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)", 1337 | ] 1338 | 1339 | [[package]] 1340 | name = "tokio-uds" 1341 | version = "0.2.5" 1342 | source = "registry+https://github.com/rust-lang/crates.io-index" 1343 | dependencies = [ 1344 | "bytes 0.4.11 (registry+https://github.com/rust-lang/crates.io-index)", 1345 | "futures 0.1.25 (registry+https://github.com/rust-lang/crates.io-index)", 1346 | "iovec 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", 1347 | "libc 0.2.48 (registry+https://github.com/rust-lang/crates.io-index)", 1348 | "log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", 1349 | "mio 0.6.16 (registry+https://github.com/rust-lang/crates.io-index)", 1350 | "mio-uds 0.6.7 (registry+https://github.com/rust-lang/crates.io-index)", 1351 | "tokio-codec 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", 1352 | "tokio-io 0.1.11 (registry+https://github.com/rust-lang/crates.io-index)", 1353 | "tokio-reactor 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)", 1354 | ] 1355 | 1356 | [[package]] 1357 | name = "try-lock" 1358 | version = "0.1.0" 1359 | source = "registry+https://github.com/rust-lang/crates.io-index" 1360 | 1361 | [[package]] 1362 | name = "try-lock" 1363 | version = "0.2.2" 1364 | source = "registry+https://github.com/rust-lang/crates.io-index" 1365 | 1366 | [[package]] 1367 | name = "unicase" 1368 | version = "1.4.2" 1369 | source = "registry+https://github.com/rust-lang/crates.io-index" 1370 | dependencies = [ 1371 | "version_check 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)", 1372 | ] 1373 | 1374 | [[package]] 1375 | name = "unicase" 1376 | version = "2.2.0" 1377 | source = "registry+https://github.com/rust-lang/crates.io-index" 1378 | dependencies = [ 1379 | "version_check 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)", 1380 | ] 1381 | 1382 | [[package]] 1383 | name = "unicode-bidi" 1384 | version = "0.3.4" 1385 | source = "registry+https://github.com/rust-lang/crates.io-index" 1386 | dependencies = [ 1387 | "matches 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)", 1388 | ] 1389 | 1390 | [[package]] 1391 | name = "unicode-normalization" 1392 | version = "0.1.8" 1393 | source = "registry+https://github.com/rust-lang/crates.io-index" 1394 | dependencies = [ 1395 | "smallvec 0.6.8 (registry+https://github.com/rust-lang/crates.io-index)", 1396 | ] 1397 | 1398 | [[package]] 1399 | name = "unicode-width" 1400 | version = "0.1.5" 1401 | source = "registry+https://github.com/rust-lang/crates.io-index" 1402 | 1403 | [[package]] 1404 | name = "unreachable" 1405 | version = "1.0.0" 1406 | source = "registry+https://github.com/rust-lang/crates.io-index" 1407 | dependencies = [ 1408 | "void 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)", 1409 | ] 1410 | 1411 | [[package]] 1412 | name = "url" 1413 | version = "1.7.2" 1414 | source = "registry+https://github.com/rust-lang/crates.io-index" 1415 | dependencies = [ 1416 | "idna 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)", 1417 | "matches 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)", 1418 | "percent-encoding 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)", 1419 | ] 1420 | 1421 | [[package]] 1422 | name = "uuid" 1423 | version = "0.7.2" 1424 | source = "registry+https://github.com/rust-lang/crates.io-index" 1425 | dependencies = [ 1426 | "rand 0.6.5 (registry+https://github.com/rust-lang/crates.io-index)", 1427 | ] 1428 | 1429 | [[package]] 1430 | name = "vcpkg" 1431 | version = "0.2.6" 1432 | source = "registry+https://github.com/rust-lang/crates.io-index" 1433 | 1434 | [[package]] 1435 | name = "vec_map" 1436 | version = "0.8.1" 1437 | source = "registry+https://github.com/rust-lang/crates.io-index" 1438 | 1439 | [[package]] 1440 | name = "version_check" 1441 | version = "0.1.5" 1442 | source = "registry+https://github.com/rust-lang/crates.io-index" 1443 | 1444 | [[package]] 1445 | name = "void" 1446 | version = "1.0.2" 1447 | source = "registry+https://github.com/rust-lang/crates.io-index" 1448 | 1449 | [[package]] 1450 | name = "want" 1451 | version = "0.0.4" 1452 | source = "registry+https://github.com/rust-lang/crates.io-index" 1453 | dependencies = [ 1454 | "futures 0.1.25 (registry+https://github.com/rust-lang/crates.io-index)", 1455 | "log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", 1456 | "try-lock 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", 1457 | ] 1458 | 1459 | [[package]] 1460 | name = "want" 1461 | version = "0.0.6" 1462 | source = "registry+https://github.com/rust-lang/crates.io-index" 1463 | dependencies = [ 1464 | "futures 0.1.25 (registry+https://github.com/rust-lang/crates.io-index)", 1465 | "log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", 1466 | "try-lock 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", 1467 | ] 1468 | 1469 | [[package]] 1470 | name = "winapi" 1471 | version = "0.2.8" 1472 | source = "registry+https://github.com/rust-lang/crates.io-index" 1473 | 1474 | [[package]] 1475 | name = "winapi" 1476 | version = "0.3.6" 1477 | source = "registry+https://github.com/rust-lang/crates.io-index" 1478 | dependencies = [ 1479 | "winapi-i686-pc-windows-gnu 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", 1480 | "winapi-x86_64-pc-windows-gnu 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", 1481 | ] 1482 | 1483 | [[package]] 1484 | name = "winapi-build" 1485 | version = "0.1.1" 1486 | source = "registry+https://github.com/rust-lang/crates.io-index" 1487 | 1488 | [[package]] 1489 | name = "winapi-i686-pc-windows-gnu" 1490 | version = "0.4.0" 1491 | source = "registry+https://github.com/rust-lang/crates.io-index" 1492 | 1493 | [[package]] 1494 | name = "winapi-x86_64-pc-windows-gnu" 1495 | version = "0.4.0" 1496 | source = "registry+https://github.com/rust-lang/crates.io-index" 1497 | 1498 | [[package]] 1499 | name = "ws2_32-sys" 1500 | version = "0.2.1" 1501 | source = "registry+https://github.com/rust-lang/crates.io-index" 1502 | dependencies = [ 1503 | "winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)", 1504 | "winapi-build 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", 1505 | ] 1506 | 1507 | [metadata] 1508 | "checksum MacTypes-sys 2.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "eaf9f0d0b1cc33a4d2aee14fb4b2eac03462ef4db29c8ac4057327d8a71ad86f" 1509 | "checksum adler32 1.0.3 (registry+https://github.com/rust-lang/crates.io-index)" = "7e522997b529f05601e05166c07ed17789691f562762c7f3b987263d2dedee5c" 1510 | "checksum ansi_term 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ee49baf6cb617b853aa8d93bf420db2383fab46d314482ca2803b40d5fde979b" 1511 | "checksum arrayvec 0.4.10 (registry+https://github.com/rust-lang/crates.io-index)" = "92c7fb76bc8826a8b33b4ee5bb07a247a81e76764ab4d55e8f73e3a4d8808c71" 1512 | "checksum atty 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)" = "9a7d5b8723950951411ee34d271d99dddcc2035a16ab25310ea2c8cfd4369652" 1513 | "checksum autocfg 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "a6d640bee2da49f60a4068a7fae53acde8982514ab7bae8b8cea9e88cbcfd799" 1514 | "checksum base64 0.10.1 (registry+https://github.com/rust-lang/crates.io-index)" = "0b25d992356d2eb0ed82172f5248873db5560c4721f564b13cb5193bda5e668e" 1515 | "checksum base64 0.9.3 (registry+https://github.com/rust-lang/crates.io-index)" = "489d6c0ed21b11d038c31b6ceccca973e65d73ba3bd8ecb9a2babf5546164643" 1516 | "checksum bitflags 0.9.1 (registry+https://github.com/rust-lang/crates.io-index)" = "4efd02e230a02e18f92fc2735f44597385ed02ad8f831e7c1c1156ee5e1ab3a5" 1517 | "checksum bitflags 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)" = "228047a76f468627ca71776ecdebd732a3423081fcf5125585bcd7c49886ce12" 1518 | "checksum byteorder 1.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "a019b10a2a7cdeb292db131fc8113e57ea2a908f6e7894b0c3c671893b65dbeb" 1519 | "checksum bytes 0.4.11 (registry+https://github.com/rust-lang/crates.io-index)" = "40ade3d27603c2cb345eb0912aec461a6dec7e06a4ae48589904e808335c7afa" 1520 | "checksum cc 1.0.28 (registry+https://github.com/rust-lang/crates.io-index)" = "bb4a8b715cb4597106ea87c7c84b2f1d452c7492033765df7f32651e66fcf749" 1521 | "checksum cfg-if 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)" = "082bb9b28e00d3c9d39cc03e64ce4cea0f1bb9b3fde493f0cbc008472d22bdf4" 1522 | "checksum clap 2.32.0 (registry+https://github.com/rust-lang/crates.io-index)" = "b957d88f4b6a63b9d70d5f454ac8011819c6efa7727858f458ab71c756ce2d3e" 1523 | "checksum cloudabi 0.0.3 (registry+https://github.com/rust-lang/crates.io-index)" = "ddfc5b9aa5d4507acaf872de71051dfd0e309860e88966e1051e462a077aac4f" 1524 | "checksum core-foundation 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)" = "25bfd746d203017f7d5cbd31ee5d8e17f94b6521c7af77ece6c9e4b2d4b16c67" 1525 | "checksum core-foundation 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)" = "286e0b41c3a20da26536c6000a280585d519fd07b3956b43aed8a79e9edce980" 1526 | "checksum core-foundation-sys 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)" = "065a5d7ffdcbc8fa145d6f0746f3555025b9097a9e9cda59f7467abae670c78d" 1527 | "checksum core-foundation-sys 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)" = "716c271e8613ace48344f723b60b900a93150271e5be206212d052bbc0883efa" 1528 | "checksum crc32fast 1.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "e91d5240c6975ef33aeb5f148f35275c25eda8e8a5f95abe421978b05b8bf192" 1529 | "checksum crossbeam 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ad4c7ea749d9fb09e23c5cb17e3b70650860553a0e2744e38446b1803bf7db94" 1530 | "checksum crossbeam-channel 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)" = "0f0ed1a4de2235cabda8558ff5840bffb97fcb64c97827f354a451307df5f72b" 1531 | "checksum crossbeam-deque 0.6.3 (registry+https://github.com/rust-lang/crates.io-index)" = "05e44b8cf3e1a625844d1750e1f7820da46044ff6d28f4d43e455ba3e5bb2c13" 1532 | "checksum crossbeam-epoch 0.7.1 (registry+https://github.com/rust-lang/crates.io-index)" = "04c9e3102cc2d69cd681412141b390abd55a362afc1540965dad0ad4d34280b4" 1533 | "checksum crossbeam-utils 0.6.5 (registry+https://github.com/rust-lang/crates.io-index)" = "f8306fcef4a7b563b76b7dd949ca48f52bc1141aa067d2ea09565f3e2652aa5c" 1534 | "checksum dtoa 0.4.3 (registry+https://github.com/rust-lang/crates.io-index)" = "6d301140eb411af13d3115f9a562c85cc6b541ade9dfa314132244aaee7489dd" 1535 | "checksum encoding_rs 0.8.15 (registry+https://github.com/rust-lang/crates.io-index)" = "fd251508d65030820f3a4317af2248180db337fdb25d89967956242580277813" 1536 | "checksum fnv 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)" = "2fad85553e09a6f881f739c29f0b00b0f01357c743266d478b68951ce23285f3" 1537 | "checksum foreign-types 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)" = "f6f339eb8adc052cd2ca78910fda869aefa38d22d5cb648e6485e4d3fc06f3b1" 1538 | "checksum foreign-types-shared 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "00b0228411908ca8685dba7fc2cdd70ec9990a6e753e89b6ac91a84c40fbaf4b" 1539 | "checksum fuchsia-cprng 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "81f7f8eb465745ea9b02e2704612a9946a59fa40572086c6fd49d6ddcf30bf31" 1540 | "checksum fuchsia-zircon 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)" = "2e9763c69ebaae630ba35f74888db465e49e259ba1bc0eda7d06f4a067615d82" 1541 | "checksum fuchsia-zircon-sys 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)" = "3dcaa9ae7725d12cdb85b3ad99a434db70b468c09ded17e012d86b5c1010f7a7" 1542 | "checksum futures 0.1.25 (registry+https://github.com/rust-lang/crates.io-index)" = "49e7653e374fe0d0c12de4250f0bdb60680b8c80eed558c5c7538eec9c89e21b" 1543 | "checksum futures-cpupool 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)" = "ab90cde24b3319636588d0c35fe03b1333857621051837ed769faefb4c2162e4" 1544 | "checksum h2 0.1.16 (registry+https://github.com/rust-lang/crates.io-index)" = "ddb2b25a33e231484694267af28fec74ac63b5ccf51ee2065a5e313b834d836e" 1545 | "checksum http 0.1.15 (registry+https://github.com/rust-lang/crates.io-index)" = "1a10e5b573b9a0146545010f50772b9e8b1dd0a256564cc4307694c68832a2f5" 1546 | "checksum httparse 1.3.3 (registry+https://github.com/rust-lang/crates.io-index)" = "e8734b0cfd3bc3e101ec59100e101c2eecd19282202e87808b3037b442777a83" 1547 | "checksum hyper 0.11.27 (registry+https://github.com/rust-lang/crates.io-index)" = "34a590ca09d341e94cddf8e5af0bbccde205d5fbc2fa3c09dd67c7f85cea59d7" 1548 | "checksum hyper 0.12.23 (registry+https://github.com/rust-lang/crates.io-index)" = "860faf61a9957c9cb0e23e69f1c8290e92f6eb660fcdd1f2d6777043a2ae1a46" 1549 | "checksum hyper-tls 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)" = "ffb1bd5e518d3065840ab315dbbf44e4420e5f7d80e2cb93fa6ffffc50522378" 1550 | "checksum hyper-tls 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "32cd73f14ad370d3b4d4b7dce08f69b81536c82e39fcc89731930fe5788cd661" 1551 | "checksum idna 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)" = "38f09e0f0b1fb55fdee1f17470ad800da77af5186a1a76c026b679358b7e844e" 1552 | "checksum indexmap 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)" = "7e81a7c05f79578dbc15793d8b619db9ba32b4577003ef3af1a91c416798c58d" 1553 | "checksum iovec 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "dbe6e417e7d0975db6512b90796e8ce223145ac4e33c377e4a42882a0e88bb08" 1554 | "checksum itoa 0.4.3 (registry+https://github.com/rust-lang/crates.io-index)" = "1306f3464951f30e30d12373d31c79fbd52d236e5e896fd92f96ec7babbbe60b" 1555 | "checksum kernel32-sys 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "7507624b29483431c0ba2d82aece8ca6cdba9382bff4ddd0f7490560c056098d" 1556 | "checksum language-tags 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "a91d884b6667cd606bb5a69aa0c99ba811a115fc68915e7056ec08a46e93199a" 1557 | "checksum lazy_static 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)" = "76f033c7ad61445c5b347c7382dd1237847eb1bce590fe50365dcb33d546be73" 1558 | "checksum lazy_static 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "a374c89b9db55895453a74c1e38861d9deec0b01b405a82516e9d5de4820dea1" 1559 | "checksum lazycell 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "b294d6fa9ee409a054354afc4352b0b9ef7ca222c69b8812cbea9e7d2bf3783f" 1560 | "checksum libc 0.2.48 (registry+https://github.com/rust-lang/crates.io-index)" = "e962c7641008ac010fa60a7dfdc1712449f29c44ef2d4702394aea943ee75047" 1561 | "checksum libflate 0.1.19 (registry+https://github.com/rust-lang/crates.io-index)" = "bff3ac7d6f23730d3b533c35ed75eef638167634476a499feef16c428d74b57b" 1562 | "checksum lock_api 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)" = "62ebf1391f6acad60e5c8b43706dde4582df75c06698ab44511d15016bc2442c" 1563 | "checksum log 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)" = "e19e8d5c34a3e0e2223db8e060f9e8264aeeb5c5fc64a4ee9965c062211c024b" 1564 | "checksum log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)" = "c84ec4b527950aa83a329754b01dbe3f58361d1c5efacd1f6d68c494d08a17c6" 1565 | "checksum matches 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)" = "7ffc5c5338469d4d3ea17d269fa8ea3512ad247247c30bd2df69e68309ed0a08" 1566 | "checksum memoffset 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "0f9dc261e2b62d7a622bf416ea3c5245cdd5d9a7fcc428c0d06804dfce1775b3" 1567 | "checksum mime 0.3.13 (registry+https://github.com/rust-lang/crates.io-index)" = "3e27ca21f40a310bd06d9031785f4801710d566c184a6e15bad4f1d9b65f9425" 1568 | "checksum mime_guess 2.0.0-alpha.6 (registry+https://github.com/rust-lang/crates.io-index)" = "30de2e4613efcba1ec63d8133f344076952090c122992a903359be5a4f99c3ed" 1569 | "checksum mio 0.6.16 (registry+https://github.com/rust-lang/crates.io-index)" = "71646331f2619b1026cc302f87a2b8b648d5c6dd6937846a16cc8ce0f347f432" 1570 | "checksum mio-uds 0.6.7 (registry+https://github.com/rust-lang/crates.io-index)" = "966257a94e196b11bb43aca423754d87429960a768de9414f3691d6957abf125" 1571 | "checksum miow 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "8c1f2f3b1cf331de6896aabf6e9d55dca90356cc9960cca7eaaf408a355ae919" 1572 | "checksum native-tls 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)" = "f74dbadc8b43df7864539cedb7bc91345e532fdd913cfdc23ad94f4d2d40fbc0" 1573 | "checksum native-tls 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "ff8e08de0070bbf4c31f452ea2a70db092f36f6f2e4d897adf5674477d488fb2" 1574 | "checksum net2 0.2.33 (registry+https://github.com/rust-lang/crates.io-index)" = "42550d9fb7b6684a6d404d9fa7250c2eb2646df731d1c06afc06dcee9e1bcf88" 1575 | "checksum nodrop 0.1.13 (registry+https://github.com/rust-lang/crates.io-index)" = "2f9667ddcc6cc8a43afc9b7917599d7216aa09c463919ea32c59ed6cac8bc945" 1576 | "checksum num_cpus 1.9.0 (registry+https://github.com/rust-lang/crates.io-index)" = "5a69d464bdc213aaaff628444e99578ede64e9c854025aa43b9796530afa9238" 1577 | "checksum openssl 0.10.16 (registry+https://github.com/rust-lang/crates.io-index)" = "ec7bd7ca4cce6dbdc77e7c1230682740d307d1218a87fb0349a571272be749f9" 1578 | "checksum openssl 0.9.24 (registry+https://github.com/rust-lang/crates.io-index)" = "a3605c298474a3aa69de92d21139fb5e2a81688d308262359d85cdd0d12a7985" 1579 | "checksum openssl-probe 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "77af24da69f9d9341038eba93a073b1fdaaa1b788221b00a69bce9e762cb32de" 1580 | "checksum openssl-sys 0.9.40 (registry+https://github.com/rust-lang/crates.io-index)" = "1bb974e77de925ef426b6bc82fce15fd45bdcbeb5728bffcfc7cdeeb7ce1c2d6" 1581 | "checksum owning_ref 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "49a4b8ea2179e6a2e27411d3bca09ca6dd630821cf6894c6c7c8467a8ee7ef13" 1582 | "checksum parking_lot 0.7.1 (registry+https://github.com/rust-lang/crates.io-index)" = "ab41b4aed082705d1056416ae4468b6ea99d52599ecf3169b00088d43113e337" 1583 | "checksum parking_lot_core 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "94c8c7923936b28d546dfd14d4472eaf34c99b14e1c973a32b3e6d4eb04298c9" 1584 | "checksum percent-encoding 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)" = "31010dd2e1ac33d5b46a5b413495239882813e0369f8ed8a5e266f173602f831" 1585 | "checksum phf 0.7.24 (registry+https://github.com/rust-lang/crates.io-index)" = "b3da44b85f8e8dfaec21adae67f95d93244b2ecf6ad2a692320598dcc8e6dd18" 1586 | "checksum phf_codegen 0.7.24 (registry+https://github.com/rust-lang/crates.io-index)" = "b03e85129e324ad4166b06b2c7491ae27fe3ec353af72e72cd1654c7225d517e" 1587 | "checksum phf_generator 0.7.24 (registry+https://github.com/rust-lang/crates.io-index)" = "09364cc93c159b8b06b1f4dd8a4398984503483891b0c26b867cf431fb132662" 1588 | "checksum phf_shared 0.7.24 (registry+https://github.com/rust-lang/crates.io-index)" = "234f71a15de2288bcb7e3b6515828d22af7ec8598ee6d24c3b526fa0a80b67a0" 1589 | "checksum pkg-config 0.3.14 (registry+https://github.com/rust-lang/crates.io-index)" = "676e8eb2b1b4c9043511a9b7bea0915320d7e502b0a079fb03f9635a5252b18c" 1590 | "checksum rand 0.3.23 (registry+https://github.com/rust-lang/crates.io-index)" = "64ac302d8f83c0c1974bf758f6b041c6c8ada916fbb44a609158ca8b064cc76c" 1591 | "checksum rand 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)" = "552840b97013b1a26992c11eac34bdd778e464601a4c2054b5f0bff7c6761293" 1592 | "checksum rand 0.6.5 (registry+https://github.com/rust-lang/crates.io-index)" = "6d71dacdc3c88c1fde3885a3be3fbab9f35724e6ce99467f7d9c5026132184ca" 1593 | "checksum rand_chacha 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "556d3a1ca6600bfcbab7c7c91ccb085ac7fbbcd70e008a98742e7847f4f7bcef" 1594 | "checksum rand_core 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "7a6fdeb83b075e8266dcc8762c22776f6877a63111121f5f8c7411e5be7eed4b" 1595 | "checksum rand_core 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "d0e7a549d590831370895ab7ba4ea0c1b6b011d106b5ff2da6eee112615e6dc0" 1596 | "checksum rand_hc 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "7b40677c7be09ae76218dc623efbf7b18e34bced3f38883af07bb75630a21bc4" 1597 | "checksum rand_isaac 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "ded997c9d5f13925be2a6fd7e66bf1872597f759fd9dd93513dd7e92e5a5ee08" 1598 | "checksum rand_jitter 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "080723c6145e37503a2224f801f252e14ac5531cb450f4502698542d188cb3c0" 1599 | "checksum rand_os 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "b7c690732391ae0abafced5015ffb53656abfaec61b342290e5eb56b286a679d" 1600 | "checksum rand_pcg 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "086bd09a33c7044e56bb44d5bdde5a60e7f119a9e95b0775f545de759a32fe05" 1601 | "checksum rand_xorshift 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "cbf7e9e623549b0e21f6e97cf8ecf247c1a8fd2e8a992ae265314300b2455d5c" 1602 | "checksum rdrand 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "678054eb77286b51581ba43620cc911abf02758c91f93f479767aed0f90458b2" 1603 | "checksum redox_syscall 0.1.51 (registry+https://github.com/rust-lang/crates.io-index)" = "423e376fffca3dfa06c9e9790a9ccd282fafb3cc6e6397d01dbf64f9bacc6b85" 1604 | "checksum redox_termios 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "7e891cfe48e9100a70a3b6eb652fef28920c117d366339687bd5576160db0f76" 1605 | "checksum relay 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "1576e382688d7e9deecea24417e350d3062d97e32e45d70b1cde65994ff1489a" 1606 | "checksum remove_dir_all 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)" = "3488ba1b9a2084d38645c4c08276a1752dcbf2c7130d74f1569681ad5d2799c5" 1607 | "checksum reqwest 0.9.9 (registry+https://github.com/rust-lang/crates.io-index)" = "09d6e187a58d923ee132fcda141c94e716bcfe301c2ea2bef5c81536e0085376" 1608 | "checksum rustc_version 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)" = "138e3e0acb6c9fb258b19b67cb8abd63c00679d2851805ea151465464fe9030a" 1609 | "checksum ryu 0.2.7 (registry+https://github.com/rust-lang/crates.io-index)" = "eb9e9b8cde282a9fe6a42dd4681319bfb63f121b8a8ee9439c6f4107e58a46f7" 1610 | "checksum safemem 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "8dca453248a96cb0749e36ccdfe2b0b4e54a61bfef89fb97ec621eb8e0a93dd9" 1611 | "checksum schannel 0.1.14 (registry+https://github.com/rust-lang/crates.io-index)" = "0e1a231dc10abf6749cfa5d7767f25888d484201accbd919b66ab5413c502d56" 1612 | "checksum scoped-tls 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "332ffa32bf586782a3efaeb58f127980944bbc8c4d6913a86107ac2a5ab24b28" 1613 | "checksum scopeguard 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)" = "94258f53601af11e6a49f722422f6e3425c52b06245a5cf9bc09908b174f5e27" 1614 | "checksum security-framework 0.1.16 (registry+https://github.com/rust-lang/crates.io-index)" = "dfa44ee9c54ce5eecc9de7d5acbad112ee58755239381f687e564004ba4a2332" 1615 | "checksum security-framework 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "bfab8dda0e7a327c696d893df9ffa19cadc4bd195797997f5223cf5831beaf05" 1616 | "checksum security-framework-sys 0.1.16 (registry+https://github.com/rust-lang/crates.io-index)" = "5421621e836278a0b139268f36eee0dc7e389b784dc3f79d8f11aabadf41bead" 1617 | "checksum security-framework-sys 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)" = "3d6696852716b589dff9e886ff83778bb635150168e83afa8ac6b8a78cb82abc" 1618 | "checksum semver 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)" = "1d7eb9ef2c18661902cc47e535f9bc51b78acd254da71d375c2f6720d9a40403" 1619 | "checksum semver-parser 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = "388a1df253eca08550bef6c72392cfe7c30914bf41df5269b68cbd6ff8f570a3" 1620 | "checksum serde 1.0.86 (registry+https://github.com/rust-lang/crates.io-index)" = "52ab457c27b091c27b887eef7181b3ea11ab4f92f66e3a99b2e556b77f9cc6bd" 1621 | "checksum serde_json 1.0.38 (registry+https://github.com/rust-lang/crates.io-index)" = "27dce848e7467aa0e2fcaf0a413641499c0b745452aaca1194d24dedde9e13c9" 1622 | "checksum serde_urlencoded 0.5.4 (registry+https://github.com/rust-lang/crates.io-index)" = "d48f9f99cd749a2de71d29da5f948de7f2764cc5a9d7f3c97e3514d4ee6eabf2" 1623 | "checksum siphasher 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)" = "0b8de496cf83d4ed58b6be86c3a275b8602f6ffe98d3024a869e124147a9a3ac" 1624 | "checksum slab 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "17b4fcaed89ab08ef143da37bc52adbcc04d4a69014f4c1208d6b51f0c47bc23" 1625 | "checksum slab 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)" = "c111b5bd5695e56cffe5129854aa230b39c93a305372fdbb2668ca2394eea9f8" 1626 | "checksum smallvec 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "4c8cbcd6df1e117c2210e13ab5109635ad68a929fcbb8964dc965b76cb5ee013" 1627 | "checksum smallvec 0.6.8 (registry+https://github.com/rust-lang/crates.io-index)" = "88aea073965ab29f6edb5493faf96ad662fb18aa9eeb186a3b7057951605ed15" 1628 | "checksum stable_deref_trait 1.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "dba1a27d3efae4351c8051072d619e3ade2820635c3958d826bfea39d59b54c8" 1629 | "checksum string 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)" = "b639411d0b9c738748b5397d5ceba08e648f4f1992231aa859af1a017f31f60b" 1630 | "checksum strsim 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = "bb4f380125926a99e52bc279241539c018323fab05ad6368b56f93d9369ff550" 1631 | "checksum take 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "b157868d8ac1f56b64604539990685fa7611d8fa9e5476cf0c02cf34d32917c5" 1632 | "checksum tempdir 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)" = "15f2b5fb00ccdf689e0149d1b1b3c03fead81c2b37735d812fa8bddbbf41b6d8" 1633 | "checksum tempfile 3.0.5 (registry+https://github.com/rust-lang/crates.io-index)" = "7e91405c14320e5c79b3d148e1c86f40749a36e490642202a31689cb1a3452b2" 1634 | "checksum termion 1.5.1 (registry+https://github.com/rust-lang/crates.io-index)" = "689a3bdfaab439fd92bc87df5c4c78417d3cbe537487274e9b0b2dce76e92096" 1635 | "checksum textwrap 0.10.0 (registry+https://github.com/rust-lang/crates.io-index)" = "307686869c93e71f94da64286f9a9524c0f308a9e1c87a583de8e9c9039ad3f6" 1636 | "checksum time 0.1.42 (registry+https://github.com/rust-lang/crates.io-index)" = "db8dcfca086c1143c9270ac42a2bbd8a7ee477b78ac8e45b19abfb0cbede4b6f" 1637 | "checksum tokio 0.1.15 (registry+https://github.com/rust-lang/crates.io-index)" = "e0500b88064f08bebddd0c0bed39e19f5c567a5f30975bee52b0c0d3e2eeb38c" 1638 | "checksum tokio-codec 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "5c501eceaf96f0e1793cf26beb63da3d11c738c4a943fdf3746d81d64684c39f" 1639 | "checksum tokio-core 0.1.17 (registry+https://github.com/rust-lang/crates.io-index)" = "aeeffbbb94209023feaef3c196a41cbcdafa06b4a6f893f68779bb5e53796f71" 1640 | "checksum tokio-current-thread 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)" = "331c8acc267855ec06eb0c94618dcbbfea45bed2d20b77252940095273fb58f6" 1641 | "checksum tokio-executor 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)" = "30c6dbf2d1ad1de300b393910e8a3aa272b724a400b6531da03eed99e329fbf0" 1642 | "checksum tokio-fs 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)" = "0e9cbbc8a3698b7ab652340f46633364f9eaa928ddaaee79d8b8f356dd79a09d" 1643 | "checksum tokio-io 0.1.11 (registry+https://github.com/rust-lang/crates.io-index)" = "b53aeb9d3f5ccf2ebb29e19788f96987fa1355f8fe45ea193928eaaaf3ae820f" 1644 | "checksum tokio-proto 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "8fbb47ae81353c63c487030659494b295f6cb6576242f907f203473b191b0389" 1645 | "checksum tokio-reactor 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)" = "afbcdb0f0d2a1e4c440af82d7bbf0bf91a8a8c0575bcd20c05d15be7e9d3a02f" 1646 | "checksum tokio-service 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "24da22d077e0f15f55162bdbdc661228c1581892f52074fb242678d015b45162" 1647 | "checksum tokio-sync 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "3742b64166c1ee9121f1921aea5a726098458926a6b732d906ef23b1f3ef6f4f" 1648 | "checksum tokio-tcp 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)" = "1d14b10654be682ac43efee27401d792507e30fd8d26389e1da3b185de2e4119" 1649 | "checksum tokio-threadpool 0.1.11 (registry+https://github.com/rust-lang/crates.io-index)" = "c3fd86cb15547d02daa2b21aadaf4e37dee3368df38a526178a5afa3c034d2fb" 1650 | "checksum tokio-timer 0.2.9 (registry+https://github.com/rust-lang/crates.io-index)" = "21c04a314a1f69f73c0227beba6250e06cdc1e9a62e7eff912bf54a59b6d1b94" 1651 | "checksum tokio-tls 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)" = "772f4b04e560117fe3b0a53e490c16ddc8ba6ec437015d91fa385564996ed913" 1652 | "checksum tokio-udp 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)" = "66268575b80f4a4a710ef83d087fdfeeabdce9b74c797535fbac18a2cb906e92" 1653 | "checksum tokio-uds 0.2.5 (registry+https://github.com/rust-lang/crates.io-index)" = "037ffc3ba0e12a0ab4aca92e5234e0dedeb48fddf6ccd260f1f150a36a9f2445" 1654 | "checksum try-lock 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ee2aa4715743892880f70885373966c83d73ef1b0838a664ef0c76fffd35e7c2" 1655 | "checksum try-lock 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "e604eb7b43c06650e854be16a2a03155743d3752dd1c943f6829e26b7a36e382" 1656 | "checksum unicase 1.4.2 (registry+https://github.com/rust-lang/crates.io-index)" = "7f4765f83163b74f957c797ad9253caf97f103fb064d3999aea9568d09fc8a33" 1657 | "checksum unicase 2.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "9d3218ea14b4edcaccfa0df0a64a3792a2c32cc706f1b336e48867f9d3147f90" 1658 | "checksum unicode-bidi 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)" = "49f2bd0c6468a8230e1db229cff8029217cf623c767ea5d60bfbd42729ea54d5" 1659 | "checksum unicode-normalization 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)" = "141339a08b982d942be2ca06ff8b076563cbe223d1befd5450716790d44e2426" 1660 | "checksum unicode-width 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)" = "882386231c45df4700b275c7ff55b6f3698780a650026380e72dabe76fa46526" 1661 | "checksum unreachable 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "382810877fe448991dfc7f0dd6e3ae5d58088fd0ea5e35189655f84e6814fa56" 1662 | "checksum url 1.7.2 (registry+https://github.com/rust-lang/crates.io-index)" = "dd4e7c0d531266369519a4aa4f399d748bd37043b00bde1e4ff1f60a120b355a" 1663 | "checksum uuid 0.7.2 (registry+https://github.com/rust-lang/crates.io-index)" = "0238db0c5b605dd1cf51de0f21766f97fba2645897024461d6a00c036819a768" 1664 | "checksum vcpkg 0.2.6 (registry+https://github.com/rust-lang/crates.io-index)" = "def296d3eb3b12371b2c7d0e83bfe1403e4db2d7a0bba324a12b21c4ee13143d" 1665 | "checksum vec_map 0.8.1 (registry+https://github.com/rust-lang/crates.io-index)" = "05c78687fb1a80548ae3250346c3db86a80a7cdd77bda190189f2d0a0987c81a" 1666 | "checksum version_check 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)" = "914b1a6776c4c929a602fafd8bc742e06365d4bcbe48c30f9cca5824f70dc9dd" 1667 | "checksum void 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)" = "6a02e4885ed3bc0f2de90ea6dd45ebcbb66dacffe03547fadbb0eeae2770887d" 1668 | "checksum want 0.0.4 (registry+https://github.com/rust-lang/crates.io-index)" = "a05d9d966753fa4b5c8db73fcab5eed4549cfe0e1e4e66911e5564a0085c35d1" 1669 | "checksum want 0.0.6 (registry+https://github.com/rust-lang/crates.io-index)" = "797464475f30ddb8830cc529aaaae648d581f99e2036a928877dfde027ddf6b3" 1670 | "checksum winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)" = "167dc9d6949a9b857f3451275e911c3f44255842c1f7a76f33c55103a909087a" 1671 | "checksum winapi 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)" = "92c1eb33641e276cfa214a0522acad57be5c56b10cb348b3c5117db75f3ac4b0" 1672 | "checksum winapi-build 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "2d315eee3b34aca4797b2da6b13ed88266e6d612562a0c46390af8299fc699bc" 1673 | "checksum winapi-i686-pc-windows-gnu 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6" 1674 | "checksum winapi-x86_64-pc-windows-gnu 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" 1675 | "checksum ws2_32-sys 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "d59cefebd0c892fa2dd6de581e937301d8552cb44489cdff035c6187cb63fa5e" 1676 | --------------------------------------------------------------------------------