<commit_before>#[macro_use]
extern crate clap;
extern crate env_logger;
extern crate failure;
extern crate log;
extern crate pb_rs;

use clap::{App, Arg};
use pb_rs::types::FileDescriptor;
use pb_rs::ConfigBuilder;
use std::path::{Path, PathBuf};

fn run() -> Result<(), ::failure::Error> {
    let matches = App::new(crate_name!())
        .about(crate_description!())
        .author(crate_authors!("\n"))
        .version(crate_version!())
        .arg(
            Arg::with_name("OUTPUT")
                .required(false)
                .long("output")
                .short("o")
                .takes_value(true)
                .help("Generated file name, defaults to INPUT with 'rs' extension, cannot be used with --output_directory")
                .validator(|x| extension_matches(x, "rs")),
        ).arg(
            Arg::with_name("OUTPUT_DIR")
                .required(false)
                .long("output_directory")
                .short("d")
                .takes_value(true)
                .help("Output directory of generated code, cannot be used with --output"),
        ).arg(
            Arg::with_name("INCLUDE_PATH")
                .required(false)
                .long("include")
                .short("I")
                .takes_value(true)
                .help("Path to search for imported protobufs"),
        ).arg(
            Arg::with_name("SINGLE_MOD")
                .required(false)
                .long("single-mod")
                .short("s")
                .help("Omit generation of modules for each package when there is only one package"),
        ).arg(
            Arg::with_name("NO_OUTPUT")
                .required(false)
                .long("no-output")
                .short("n")
                .help(
                    "Show enums and messages in this .proto file, including those imported. \
                     No code generated",
                ),
        ).arg(
            Arg::with_name("INPUT")
                .multiple(true)
                .help("The .proto files used to generate quick-protobuf code")
                .validator(|x| extension_matches(x, "proto")),
        ).arg(
            Arg::with_name("CYCLE")
                .long("error-cycle")
                .short("e")
                .required(false)
                .help("Error out if recursive messages do not have optional fields"),
        ).arg(
            Arg::with_name("HEADERS")
                .long("no-headers")
                .short("H")
                .required(false)
                .help("Do not add module comments and module attributes in generated file"),
        ).arg(
            Arg::with_name("CUSTOM_STRUCT_DERIVE")
                .long("custom_struct_derive")
                .short("C")
                .required(false)
                .help("The comma separated values to add to #[derive(...)] for every struct"),
        ).arg(
            Arg::with_name("DONT_USE_COW")
                .required(false)
                .long("dont_use_cow")
                .short("c")
                .help("Don't use Cow for String and Byte types"),
        ).get_matches();

    let in_files = path_vec(values_t!(matches, "INPUT", String));
    let include_paths = path_vec(values_t!(matches, "INCLUDE_PATH", String));
    let out_file = matches.value_of("OUTPUT").map(|o| PathBuf::from(o));
    let out_dir = matches.value_of("OUTPUT_DIR").map(|o| PathBuf::from(o));
    let custom_struct_derive: Vec<String> = matches.value_of("CUSTOM_STRUCT_DERIVE").unwrap_or("")
        .split(",").map(|s| s.to_string()).collect();

    let compiler = ConfigBuilder::new(
        &in_files,
        out_file.as_ref(),
        out_dir.as_ref(),
        &include_paths,
    )?
    .single_module(matches.is_present("SINGLE_MOD"))
    .no_output(matches.is_present("NO_OUTPUT"))
    .error_cycle(matches.is_present("CYCLE"))
    .headers(!matches.is_present("HEADERS"))
    .dont_use_cow(matches.is_present("DONT_USE_COW"))
    .custom_struct_derive(custom_struct_derive);

    FileDescriptor::run(&compiler.build()).map_err(|e| e.into())
}

fn extension_matches<P: AsRef<Path>>(path: P, expected: &str) -> std::result::Result<(), String> {
    match path.as_ref().extension() {
        Some(x) if x == expected => Ok(()),
        Some(x) => Err(format!(
            "Expected path with extension '{}', not: '{}'",
            expected,
            x.to_string_lossy()
        )),
        None => Err(format!("Expected path with extension '{}'", expected)),
    }
}

fn path_vec(maybe_vec: std::result::Result<Vec<String>, clap::Error>) -> Vec<PathBuf> {
    maybe_vec
        .unwrap_or_else(|_| Vec::new())
        .iter()
        .map(|s| s.into())
        .collect()
}

fn main() {
    env_logger::init();
    ::std::process::exit({
        if let Err(e) = run() {
            eprintln!("pb-rs fatal error");
            for e in e.iter_chain() {
                eprintln!("  - {}", e);
            }
            1
        } else {
            0
        }
    });
}
<commit_msg>cmd line now uses -D for not using cow<commit_after>#[macro_use]
extern crate clap;
extern crate env_logger;
extern crate failure;
extern crate log;
extern crate pb_rs;

use clap::{App, Arg};
use pb_rs::types::FileDescriptor;
use pb_rs::ConfigBuilder;
use std::path::{Path, PathBuf};

fn run() -> Result<(), ::failure::Error> {
    let matches = App::new(crate_name!())
        .about(crate_description!())
        .author(crate_authors!("\n"))
        .version(crate_version!())
        .arg(
            Arg::with_name("OUTPUT")
                .required(false)
                .long("output")
                .short("o")
                .takes_value(true)
                .help("Generated file name, defaults to INPUT with 'rs' extension, cannot be used with --output_directory")
                .validator(|x| extension_matches(x, "rs")),
        ).arg(
            Arg::with_name("OUTPUT_DIR")
                .required(false)
                .long("output_directory")
                .short("d")
                .takes_value(true)
                .help("Output directory of generated code, cannot be used with --output"),
        ).arg(
            Arg::with_name("INCLUDE_PATH")
                .required(false)
                .long("include")
                .short("I")
                .takes_value(true)
                .help("Path to search for imported protobufs"),
        ).arg(
            Arg::with_name("SINGLE_MOD")
                .required(false)
                .long("single-mod")
                .short("s")
                .help("Omit generation of modules for each package when there is only one package"),
        ).arg(
            Arg::with_name("NO_OUTPUT")
                .required(false)
                .long("no-output")
                .short("n")
                .help(
                    "Show enums and messages in this .proto file, including those imported. \
                     No code generated",
                ),
        ).arg(
            Arg::with_name("INPUT")
                .multiple(true)
                .help("The .proto files used to generate quick-protobuf code")
                .validator(|x| extension_matches(x, "proto")),
        ).arg(
            Arg::with_name("CYCLE")
                .long("error-cycle")
                .short("e")
                .required(false)
                .help("Error out if recursive messages do not have optional fields"),
        ).arg(
            Arg::with_name("HEADERS")
                .long("no-headers")
                .short("H")
                .required(false)
                .help("Do not add module comments and module attributes in generated file"),
        ).arg(
            Arg::with_name("CUSTOM_STRUCT_DERIVE")
                .long("custom_struct_derive")
                .short("C")
                .required(false)
                .help("The comma separated values to add to #[derive(...)] for every struct"),
        ).arg(
            Arg::with_name("DONT_USE_COW")
                .required(false)
                .long("dont_use_cow")
                .short("D")
                .help("Don't use Cow for String and Byte types"),
        ).get_matches();

    let in_files = path_vec(values_t!(matches, "INPUT", String));
    let include_paths = path_vec(values_t!(matches, "INCLUDE_PATH", String));
    let out_file = matches.value_of("OUTPUT").map(|o| PathBuf::from(o));
    let out_dir = matches.value_of("OUTPUT_DIR").map(|o| PathBuf::from(o));
    let custom_struct_derive: Vec<String> = matches.value_of("CUSTOM_STRUCT_DERIVE").unwrap_or("")
        .split(",").map(|s| s.to_string()).collect();

    let compiler = ConfigBuilder::new(
        &in_files,
        out_file.as_ref(),
        out_dir.as_ref(),
        &include_paths,
    )?
    .single_module(matches.is_present("SINGLE_MOD"))
    .no_output(matches.is_present("NO_OUTPUT"))
    .error_cycle(matches.is_present("CYCLE"))
    .headers(!matches.is_present("HEADERS"))
    .dont_use_cow(matches.is_present("DONT_USE_COW"))
    .custom_struct_derive(custom_struct_derive);

    FileDescriptor::run(&compiler.build()).map_err(|e| e.into())
}

fn extension_matches<P: AsRef<Path>>(path: P, expected: &str) -> std::result::Result<(), String> {
    match path.as_ref().extension() {
        Some(x) if x == expected => Ok(()),
        Some(x) => Err(format!(
            "Expected path with extension '{}', not: '{}'",
            expected,
            x.to_string_lossy()
        )),
        None => Err(format!("Expected path with extension '{}'", expected)),
    }
}

fn path_vec(maybe_vec: std::result::Result<Vec<String>, clap::Error>) -> Vec<PathBuf> {
    maybe_vec
        .unwrap_or_else(|_| Vec::new())
        .iter()
        .map(|s| s.into())
        .collect()
}

fn main() {
    env_logger::init();
    ::std::process::exit({
        if let Err(e) = run() {
            eprintln!("pb-rs fatal error");
            for e in e.iter_chain() {
                eprintln!("  - {}", e);
            }
            1
        } else {
            0
        }
    });
}
<|endoftext|>


<commit_before>#[macro_use]
extern crate clap;
extern crate env_logger;
extern crate failure;
extern crate log;
extern crate pb_rs;

use clap::{App, Arg};
use pb_rs::types::FileDescriptor;
use pb_rs::ConfigBuilder;
use std::path::{Path, PathBuf};

fn run() -> Result<(), ::failure::Error> {
    let matches = App::new(crate_name!())
        .about(crate_description!())
        .author(crate_authors!("\n"))
        .version(crate_version!())
        .arg(
            Arg::with_name("OUTPUT")
                .required(false)
                .long("output")
                .short("o")
                .takes_value(true)
                .help("Generated file name, defaults to INPUT with 'rs' extension, cannot be used with --output_directory")
                .validator(|x| extension_matches(x, "rs")),
        ).arg(
            Arg::with_name("OUTPUT_DIR")
                .required(false)
                .long("output_directory")
                .short("d")
                .takes_value(true)
                .help("Output directory of generated code, cannot be used with --output"),
        ).arg(
            Arg::with_name("INCLUDE_PATH")
                .required(false)
                .long("include")
                .short("I")
                .takes_value(true)
                .help("Path to search for imported protobufs"),
        ).arg(
            Arg::with_name("SINGLE_MOD")
                .required(false)
                .long("single-mod")
                .short("s")
                .help("Omit generation of modules for each package when there is only one package"),
        ).arg(
            Arg::with_name("NO_OUTPUT")
                .required(false)
                .long("no-output")
                .short("n")
                .help(
                    "Show enums and messages in this .proto file, including those imported. \
                     No code generated",
                ),
        ).arg(
            Arg::with_name("INPUT")
                .multiple(true)
                .help("The .proto files used to generate quick-protobuf code")
                .validator(|x| extension_matches(x, "proto")),
        ).arg(
            Arg::with_name("CYCLE")
                .long("error-cycle")
                .short("e")
                .required(false)
                .help("Error out if recursive messages do not have optional fields"),
        ).arg(
            Arg::with_name("HEADERS")
                .long("no-headers")
                .short("H")
                .required(false)
                .help("Do not add module comments and module attributes in generated file"),
        ).arg(
            Arg::with_name("CUSTOMSTRUCTDERIVE")
                .long("custom_struct_derive")
                .short("C")
                .required(false)
                .help("The comma separated values to add to #[derive(...)] for every struct"),
        .get_matches();

    let in_files = path_vec(values_t!(matches, "INPUT", String));
    let include_paths = path_vec(values_t!(matches, "INCLUDE_PATH", String));
    let out_file = matches.value_of("OUTPUT").map(|o| PathBuf::from(o));
    let out_dir = matches.value_of("OUTPUT_DIR").map(|o| PathBuf::from(o));
    let custom_struct_derive: Vec<String> = matches.value_of("CUSTOMSTRUCTDERIVE").map(|o| o.split(","));

    let compiler = ConfigBuilder::new(
        &in_files,
        out_file.as_ref(),
        out_dir.as_ref(),
        &include_paths,
    )?
    .single_module(matches.is_present("SINGLE_MOD"))
    .no_output(matches.is_present("NO_OUTPUT"))
    .error_cycle(matches.is_present("CYCLE"))
    .headers(matches.is_present("HEADERS"));
    .custom_struct_derive(custom_struct_derive)

    FileDescriptor::run(&compiler.build()).map_err(|e| e.into())
}

fn extension_matches<P: AsRef<Path>>(path: P, expected: &str) -> std::result::Result<(), String> {
    match path.as_ref().extension() {
        Some(x) if x == expected => Ok(()),
        Some(x) => Err(format!(
            "Expected path with extension '{}', not: '{}'",
            expected,
            x.to_string_lossy()
        )),
        None => Err(format!("Expected path with extension '{}'", expected)),
    }
}

fn path_vec(maybe_vec: std::result::Result<Vec<String>, clap::Error>) -> Vec<PathBuf> {
    maybe_vec
        .unwrap_or_else(|_| Vec::new())
        .iter()
        .map(|s| s.into())
        .collect()
}

fn main() {
    env_logger::init();
    ::std::process::exit({
        if let Err(e) = run() {
            eprintln!("pb-rs fatal error");
            for e in e.iter_chain() {
                eprintln!("  - {}", e);
            }
            1
        } else {
            0
        }
    });
}
<commit_msg>Fixed compile error<commit_after>#[macro_use]
extern crate clap;
extern crate env_logger;
extern crate failure;
extern crate log;
extern crate pb_rs;

use clap::{App, Arg};
use pb_rs::types::FileDescriptor;
use pb_rs::ConfigBuilder;
use std::path::{Path, PathBuf};

fn run() -> Result<(), ::failure::Error> {
    let matches = App::new(crate_name!())
        .about(crate_description!())
        .author(crate_authors!("\n"))
        .version(crate_version!())
        .arg(
            Arg::with_name("OUTPUT")
                .required(false)
                .long("output")
                .short("o")
                .takes_value(true)
                .help("Generated file name, defaults to INPUT with 'rs' extension, cannot be used with --output_directory")
                .validator(|x| extension_matches(x, "rs")),
        ).arg(
            Arg::with_name("OUTPUT_DIR")
                .required(false)
                .long("output_directory")
                .short("d")
                .takes_value(true)
                .help("Output directory of generated code, cannot be used with --output"),
        ).arg(
            Arg::with_name("INCLUDE_PATH")
                .required(false)
                .long("include")
                .short("I")
                .takes_value(true)
                .help("Path to search for imported protobufs"),
        ).arg(
            Arg::with_name("SINGLE_MOD")
                .required(false)
                .long("single-mod")
                .short("s")
                .help("Omit generation of modules for each package when there is only one package"),
        ).arg(
            Arg::with_name("NO_OUTPUT")
                .required(false)
                .long("no-output")
                .short("n")
                .help(
                    "Show enums and messages in this .proto file, including those imported. \
                     No code generated",
                ),
        ).arg(
            Arg::with_name("INPUT")
                .multiple(true)
                .help("The .proto files used to generate quick-protobuf code")
                .validator(|x| extension_matches(x, "proto")),
        ).arg(
            Arg::with_name("CYCLE")
                .long("error-cycle")
                .short("e")
                .required(false)
                .help("Error out if recursive messages do not have optional fields"),
        ).arg(
            Arg::with_name("HEADERS")
                .long("no-headers")
                .short("H")
                .required(false)
                .help("Do not add module comments and module attributes in generated file"),
        ).arg(
            Arg::with_name("CUSTOMSTRUCTDERIVE")
                .long("custom_struct_derive")
                .short("C")
                .required(false)
                .help("The comma separated values to add to #[derive(...)] for every struct"),
        ).get_matches();

    let in_files = path_vec(values_t!(matches, "INPUT", String));
    let include_paths = path_vec(values_t!(matches, "INCLUDE_PATH", String));
    let out_file = matches.value_of("OUTPUT").map(|o| PathBuf::from(o));
    let out_dir = matches.value_of("OUTPUT_DIR").map(|o| PathBuf::from(o));
    let custom_struct_derive: Vec<String> = matches.value_of("CUSTOMSTRUCTDERIVE").unwrap_or("")
        .split(",").map(|s| s.to_string()).collect();

    let compiler = ConfigBuilder::new(
        &in_files,
        out_file.as_ref(),
        out_dir.as_ref(),
        &include_paths,
    )?
    .single_module(matches.is_present("SINGLE_MOD"))
    .no_output(matches.is_present("NO_OUTPUT"))
    .error_cycle(matches.is_present("CYCLE"))
    .headers(matches.is_present("HEADERS"))
    .custom_struct_derive(custom_struct_derive);

    FileDescriptor::run(&compiler.build()).map_err(|e| e.into())
}

fn extension_matches<P: AsRef<Path>>(path: P, expected: &str) -> std::result::Result<(), String> {
    match path.as_ref().extension() {
        Some(x) if x == expected => Ok(()),
        Some(x) => Err(format!(
            "Expected path with extension '{}', not: '{}'",
            expected,
            x.to_string_lossy()
        )),
        None => Err(format!("Expected path with extension '{}'", expected)),
    }
}

fn path_vec(maybe_vec: std::result::Result<Vec<String>, clap::Error>) -> Vec<PathBuf> {
    maybe_vec
        .unwrap_or_else(|_| Vec::new())
        .iter()
        .map(|s| s.into())
        .collect()
}

fn main() {
    env_logger::init();
    ::std::process::exit({
        if let Err(e) = run() {
            eprintln!("pb-rs fatal error");
            for e in e.iter_chain() {
                eprintln!("  - {}", e);
            }
            1
        } else {
            0
        }
    });
}
<|endoftext|>


<commit_before><commit_msg>Print arguments to creduce.<commit_after><|endoftext|>


<commit_before>extern crate poloniex;
extern crate tokio_core;
extern crate futures;

use poloniex::push::subscribe;
use tokio_core::reactor::Core;
use futures::future::{ok, Future};
use futures::Stream;

static PAIRS: [&str; 1] = ["BTC_BCH"];

fn main() {
  let mut core = Core::new().unwrap();
  let pairs = PAIRS.iter().map(|p| String::from(*p)).collect();
  let updates = subscribe(pairs, &core.handle());
  let printed_updates = updates
    .and_then(|(s, _)| s.into_future().map_err(|e| e.0))
    .and_then(|(msg, _)| {
      println!("{:?}", msg);
      ok(msg)
    } );
  core.run(printed_updates).unwrap();
}<commit_msg>print channel updates<commit_after>extern crate poloniex;
extern crate tokio_core;
extern crate futures;

use poloniex::push::subscribe;
use tokio_core::reactor::Core;
use futures::future::{Future, ok};
use futures::Stream;

static PAIRS: [&str; 1] = ["BTC_BCH"];

fn main() {
  let mut core = Core::new().unwrap();
  let pairs = PAIRS.iter().map(|p| String::from(*p)).collect();
  let updates = subscribe(pairs, &core.handle());
  let printed_updates = updates
    .and_then(|(s, _)|
      s.for_each(|msg| { println!("{:?}", msg); ok(()) })
    );
  core.run(printed_updates).unwrap();
}<|endoftext|>


<commit_before>#[macro_use]
extern crate clap;
extern crate chrono;
extern crate chrono_humanize;
extern crate itertools;
extern crate json;
extern crate requests;

mod crates;

use clap::{App, SubCommand, Arg, AppSettings, ArgMatches};

const CARGO: &'static str = "cargo";

#[derive(Debug, PartialEq)]
enum Flag {
    Repository,
    Documentation,
    Downloads,
    Homepage,
    Default,
}

#[derive(Debug)]
struct Report {
    flags: Vec<Flag>,
    verbose: bool,
    json: bool,
    versions: usize,
    keywords: bool,
}

impl Report {
    pub fn new(info: &ArgMatches) -> Self {

        let mut flags: Vec<Flag> = vec![];
        if info.is_present("repository") {
            flags.push(Flag::Repository);
        }
        if info.is_present("documentation") {
            flags.push(Flag::Documentation);
        }
        if info.is_present("downloads") {
            flags.push(Flag::Downloads);
        }
        if info.is_present("homepage") {
            flags.push(Flag::Homepage);
        }

        if flags.is_empty() {
            flags.push(Flag::Default);
        }

        let versions = match info.occurrences_of("versions") {
            0 => 0, // No flags - nothing to do
            1 => 5, // Single -V - show 5 last versions
            _ => usize::max_value(), // All the other cases - show everything
        };

        Report {
            flags: flags,
            verbose: info.is_present("verbose"),
            json: info.is_present("json"),
            versions: versions,
            keywords: info.is_present("keywords"),
        }
    }

    pub fn report(&self, name: &str) {
        println!("");
        if let Ok(response) = query(name) {
            if self.json {
                self.report_json(&response)
            } else if let Some(krate) = get_crate(&response) {
                if self.versions > 0 {
                    self.report_versions(&krate, self.versions);
                } else if self.keywords {
                    self.report_keywords(&krate);
                } else {
                    self.report_crate(&krate);
                }
            }
        }
        println!("");
    }

    pub fn report_json(&self, response: &requests::Response) {
        if self.verbose {
            if let Ok(json) = response.json() {
                println!("{:#}", json);
            }
        } else if let Some(json) = response.text() {
            println!("{}", json);
        }
    }

    pub fn report_crate(&self, krate: &crates::Crate) {
        for flag in &self.flags {
            match *flag {
                Flag::Repository => krate.print_repository(self.verbose),
                Flag::Documentation => krate.print_documentation(self.verbose),
                Flag::Downloads => krate.print_downloads(self.verbose),
                Flag::Homepage => krate.print_homepage(self.verbose),
                Flag::Default => reportv(krate, self.verbose),
            }
        }
    }

    pub fn report_versions(&self, krate: &crates::Crate, limit: usize) {
        if limit > 0 {
            krate.print_last_versions(limit, self.verbose)
        }
    }

    pub fn report_keywords(&self, krate: &crates::Crate) {
        krate.print_keywords(self.verbose)
    }
}

fn reportv(krate: &crates::Crate, verbose: bool) {
    if verbose {
        println!("{:#}", krate);
    } else {
        println!("{}", krate);
    }
}

fn query(krate: &str) -> requests::RequestsResult {
    requests::get(&format!("http://crates.io/api/v1/crates/{}", krate))
}

fn get_crate(response: &requests::Response) -> Option<crates::Crate> {
    response.json().ok().map(|k| crates::Crate::new(&k))
}

// use std::fmt;
// fn debug<T>(item: &T)
//     where T: fmt::Debug
// {
//     println!("{:#?}", item);
// }

fn main() {

    let matches = App::new(CARGO)
        .bin_name(CARGO)
        .author(crate_authors!())
        .version(crate_version!())
        .about("Query crates.io registry for crates details")
        .setting(AppSettings::GlobalVersion)
        .setting(AppSettings::VersionlessSubcommands)
        .setting(AppSettings::SubcommandRequiredElseHelp)
        .subcommand(SubCommand::with_name("info")
            .setting(AppSettings::ArgRequiredElseHelp)
            .setting(AppSettings::TrailingVarArg)
            .arg(Arg::with_name("documentation")
                .short("d")
                .long("documentation")
                .help("Report documentation URL"))
            .arg(Arg::with_name("downloads")
                .short("D")
                .long("downloads")
                .help("Report number of crate downloads"))
            .arg(Arg::with_name("homepage")
                .short("H")
                .long("homepage")
                .help("Report home page URL"))
            .arg(Arg::with_name("repository")
                .short("r")
                .long("repository")
                .help("Report crate repository URL"))
            .arg(Arg::with_name("json")
                .short("j")
                .long("json")
                .help("Report raw JSON data from crates.io")
                .conflicts_with_all(&["documentation", "downloads", "homepage", "repository"]))
            .arg(Arg::with_name("verbose")
                .short("v")
                .long("verbose")
                .help("Report more details"))
            .arg(Arg::with_name("versions")
                .short("V")
                .long("versions")
                .multiple(true)
                .help("Report version history of the crate (5 last versions), twice for full \
                       history"))
            .arg_from_usage("<crate>... 'crate to query'"))
        .get_matches();

    if let Some(info) = matches.subcommand_matches("info") {
        if let Some(crates) = info.values_of("crate") {
            let rep = Report::new(info);
            for krate in crates {
                // debug(&krate);
                rep.report(krate);
            }
        }
    }
}
<commit_msg>Emit empty lines only if actually reporting crate<commit_after>#[macro_use]
extern crate clap;
extern crate chrono;
extern crate chrono_humanize;
extern crate itertools;
extern crate json;
extern crate requests;

mod crates;

use clap::{App, SubCommand, Arg, AppSettings, ArgMatches};

const CARGO: &'static str = "cargo";

#[derive(Debug, PartialEq)]
enum Flag {
    Repository,
    Documentation,
    Downloads,
    Homepage,
    Default,
}

#[derive(Debug)]
struct Report {
    flags: Vec<Flag>,
    verbose: bool,
    json: bool,
    versions: usize,
    keywords: bool,
}

impl Report {
    pub fn new(info: &ArgMatches) -> Self {

        let mut flags: Vec<Flag> = vec![];
        if info.is_present("repository") {
            flags.push(Flag::Repository);
        }
        if info.is_present("documentation") {
            flags.push(Flag::Documentation);
        }
        if info.is_present("downloads") {
            flags.push(Flag::Downloads);
        }
        if info.is_present("homepage") {
            flags.push(Flag::Homepage);
        }

        if flags.is_empty() {
            flags.push(Flag::Default);
        }

        let versions = match info.occurrences_of("versions") {
            0 => 0, // No flags - nothing to do
            1 => 5, // Single -V - show 5 last versions
            _ => usize::max_value(), // All the other cases - show everything
        };

        Report {
            flags: flags,
            verbose: info.is_present("verbose"),
            json: info.is_present("json"),
            versions: versions,
            keywords: info.is_present("keywords"),
        }
    }

    pub fn report(&self, name: &str) {
        if let Ok(response) = query(name) {
            println!("");
            if self.json {
                self.report_json(&response)
            } else if let Some(krate) = get_crate(&response) {
                if self.versions > 0 {
                    self.report_versions(&krate, self.versions);
                } else if self.keywords {
                    self.report_keywords(&krate);
                } else {
                    self.report_crate(&krate);
                }
            }
            println!("");
        }
    }

    pub fn report_json(&self, response: &requests::Response) {
        if self.verbose {
            if let Ok(json) = response.json() {
                println!("{:#}", json);
            }
        } else if let Some(json) = response.text() {
            println!("{}", json);
        }
    }

    pub fn report_crate(&self, krate: &crates::Crate) {
        for flag in &self.flags {
            match *flag {
                Flag::Repository => krate.print_repository(self.verbose),
                Flag::Documentation => krate.print_documentation(self.verbose),
                Flag::Downloads => krate.print_downloads(self.verbose),
                Flag::Homepage => krate.print_homepage(self.verbose),
                Flag::Default => reportv(krate, self.verbose),
            }
        }
    }

    pub fn report_versions(&self, krate: &crates::Crate, limit: usize) {
        if limit > 0 {
            krate.print_last_versions(limit, self.verbose)
        }
    }

    pub fn report_keywords(&self, krate: &crates::Crate) {
        krate.print_keywords(self.verbose)
    }
}

fn reportv(krate: &crates::Crate, verbose: bool) {
    if verbose {
        println!("{:#}", krate);
    } else {
        println!("{}", krate);
    }
}

fn query(krate: &str) -> requests::RequestsResult {
    requests::get(&format!("http://crates.io/api/v1/crates/{}", krate))
}

fn get_crate(response: &requests::Response) -> Option<crates::Crate> {
    response.json().ok().map(|k| crates::Crate::new(&k))
}

// use std::fmt;
// fn debug<T>(item: &T)
//     where T: fmt::Debug
// {
//     println!("{:#?}", item);
// }

fn main() {

    let matches = App::new(CARGO)
        .bin_name(CARGO)
        .author(crate_authors!())
        .version(crate_version!())
        .about("Query crates.io registry for crates details")
        .setting(AppSettings::GlobalVersion)
        .setting(AppSettings::VersionlessSubcommands)
        .setting(AppSettings::SubcommandRequiredElseHelp)
        .subcommand(SubCommand::with_name("info")
            .setting(AppSettings::ArgRequiredElseHelp)
            .setting(AppSettings::TrailingVarArg)
            .arg(Arg::with_name("documentation")
                .short("d")
                .long("documentation")
                .help("Report documentation URL"))
            .arg(Arg::with_name("downloads")
                .short("D")
                .long("downloads")
                .help("Report number of crate downloads"))
            .arg(Arg::with_name("homepage")
                .short("H")
                .long("homepage")
                .help("Report home page URL"))
            .arg(Arg::with_name("repository")
                .short("r")
                .long("repository")
                .help("Report crate repository URL"))
            .arg(Arg::with_name("json")
                .short("j")
                .long("json")
                .help("Report raw JSON data from crates.io")
                .conflicts_with_all(&["documentation", "downloads", "homepage", "repository"]))
            .arg(Arg::with_name("verbose")
                .short("v")
                .long("verbose")
                .help("Report more details"))
            .arg(Arg::with_name("versions")
                .short("V")
                .long("versions")
                .multiple(true)
                .help("Report version history of the crate (5 last versions), twice for full \
                       history"))
            .arg_from_usage("<crate>... 'crate to query'"))
        .get_matches();

    if let Some(info) = matches.subcommand_matches("info") {
        if let Some(crates) = info.values_of("crate") {
            let rep = Report::new(info);
            for krate in crates {
                // debug(&krate);
                rep.report(krate);
            }
        }
    }
}
<|endoftext|>


<commit_before>#[macro_use] extern crate log;
extern crate env_logger;
extern crate rustylnk;
extern crate clap;
extern crate seek_bufread;
extern crate jmespath;
extern crate serde_json;
extern crate serde;
use clap::{App, Arg, ArgMatches};
use jmespath::{Expression};
use seek_bufread::BufReader;
use rustylnk::lnkpkg::lnk::{Lnk};
use std::fs;

fn process_directory(directory: &str, options: &ArgMatches) {
    for dir_reader in fs::read_dir(directory) {
        for entry_result in dir_reader {
            match entry_result {
                Ok(entry) => {
                    let path = entry.path();
                    if path.is_file() {
                        let path_string = path.into_os_string().into_string().unwrap();
                        if path_string.to_lowercase().ends_with(".lnk"){
                            process_file(&path_string, &options);
                        }
                    } else if path.is_dir(){
                        let path_string = path.into_os_string().into_string().unwrap();
                        process_directory(&path_string, &options);
                    }
                },
                Err(error) => {
                    error!("Error reading {} [{:?}]",directory,error);
                }
            }
        }
    }
}

fn process_file(filename: &str, options: &ArgMatches) -> bool {
    // JMES Expression if needed
    let mut expr: Option<Expression> = None;
    if options.is_present("query") {
        expr = Some(jmespath::compile(
            options.value_of("query").unwrap()
        ).unwrap());
    }

    // Expression bool flag
    let mut expr_as_bool = false;
    if options.is_present("bool_expr"){
        expr_as_bool = true;
    }

    let file = match fs::File::open(filename) {
        Ok(file) => file,
        Err(error) => {
            error!("Could not open file: {} [error: {}]", filename, error);
            return false;
        }
    };

    let reader = BufReader::new(file);

    info!("Parsing file: {}",filename);
    let lnk = match Lnk::new(reader) {
        Ok(lnk) => lnk,
        Err(error) => {
            error!("Could not parse file: {} [{}]", filename, error);
            return false;
        }
    };

    let json_str = serde_json::to_string(&lnk).unwrap();
    match expr {
        Some(ref j_expr) => {
            let data = jmespath::Variable::from_json(&json_str).unwrap();
            let result = j_expr.search(data).unwrap();
            if expr_as_bool {
                match result.as_boolean() {
                    Some(bool_value) => {
                        match bool_value {
                            true => println!("{}",json_str),
                            false => {}
                        }
                    },
                    None => {
                        error!("Query expression is not a bool expression! [{}]",options.value_of("query").unwrap());
                    }
                }
            } else {
                println!("{}",result)
            }
        },
        None => {
            println!("{}",json_str);
        }
    }

    return true;
}

fn is_directory(source: &str)->bool{
    let metadata = fs::metadata(source).unwrap();

    let file_type = metadata.file_type();

    file_type.is_dir()
}

fn main() {
    env_logger::init().unwrap();

    let source_arg = Arg::with_name("source")
        .short("s")
        .long("source")
        .value_name("PATH")
        .help("The LNK file or folder with LNK files to parse.")
        .takes_value(true);

    let jmes_arg = Arg::with_name("query")
        .short("q")
        .long("query")
        .value_name("QUERY")
        .help("JMES Query")
        .takes_value(true);

    let bool_arg = Arg::with_name("bool_expr")
        .short("b")
        .long("bool_expr")
        .help("JMES Query as bool only. (Prints whole record if true.)");

    let options = App::new("RusyLnk")
        .version("0.1.0")
        .author("Matthew Seyer <https://github.com/forensicmatt/RustyUsn>")
        .about("LNK Parser written in Rust.")
        .arg(source_arg)
        .arg(jmes_arg)
        .arg(bool_arg)
        .get_matches();

    let source = options.value_of("source").unwrap();

    if is_directory(source) {
        process_directory(source,&options);
    } else {
        process_file(source,&options);
    }
}
<commit_msg>fixed author link<commit_after>#[macro_use] extern crate log;
extern crate env_logger;
extern crate rustylnk;
extern crate clap;
extern crate seek_bufread;
extern crate jmespath;
extern crate serde_json;
extern crate serde;
use clap::{App, Arg, ArgMatches};
use jmespath::{Expression};
use seek_bufread::BufReader;
use rustylnk::lnkpkg::lnk::{Lnk};
use std::fs;

fn process_directory(directory: &str, options: &ArgMatches) {
    for dir_reader in fs::read_dir(directory) {
        for entry_result in dir_reader {
            match entry_result {
                Ok(entry) => {
                    let path = entry.path();
                    if path.is_file() {
                        let path_string = path.into_os_string().into_string().unwrap();
                        if path_string.to_lowercase().ends_with(".lnk"){
                            process_file(&path_string, &options);
                        }
                    } else if path.is_dir(){
                        let path_string = path.into_os_string().into_string().unwrap();
                        process_directory(&path_string, &options);
                    }
                },
                Err(error) => {
                    error!("Error reading {} [{:?}]",directory,error);
                }
            }
        }
    }
}

fn process_file(filename: &str, options: &ArgMatches) -> bool {
    // JMES Expression if needed
    let mut expr: Option<Expression> = None;
    if options.is_present("query") {
        expr = Some(jmespath::compile(
            options.value_of("query").unwrap()
        ).unwrap());
    }

    // Expression bool flag
    let mut expr_as_bool = false;
    if options.is_present("bool_expr"){
        expr_as_bool = true;
    }

    let file = match fs::File::open(filename) {
        Ok(file) => file,
        Err(error) => {
            error!("Could not open file: {} [error: {}]", filename, error);
            return false;
        }
    };

    let reader = BufReader::new(file);

    info!("Parsing file: {}",filename);
    let lnk = match Lnk::new(reader) {
        Ok(lnk) => lnk,
        Err(error) => {
            error!("Could not parse file: {} [{}]", filename, error);
            return false;
        }
    };

    let json_str = serde_json::to_string(&lnk).unwrap();
    match expr {
        Some(ref j_expr) => {
            let data = jmespath::Variable::from_json(&json_str).unwrap();
            let result = j_expr.search(data).unwrap();
            if expr_as_bool {
                match result.as_boolean() {
                    Some(bool_value) => {
                        match bool_value {
                            true => println!("{}",json_str),
                            false => {}
                        }
                    },
                    None => {
                        error!("Query expression is not a bool expression! [{}]",options.value_of("query").unwrap());
                    }
                }
            } else {
                println!("{}",result)
            }
        },
        None => {
            println!("{}",json_str);
        }
    }

    return true;
}

fn is_directory(source: &str)->bool{
    let metadata = fs::metadata(source).unwrap();

    let file_type = metadata.file_type();

    file_type.is_dir()
}

fn main() {
    env_logger::init().unwrap();

    let source_arg = Arg::with_name("source")
        .short("s")
        .long("source")
        .value_name("PATH")
        .help("The LNK file or folder with LNK files to parse.")
        .takes_value(true);

    let jmes_arg = Arg::with_name("query")
        .short("q")
        .long("query")
        .value_name("QUERY")
        .help("JMES Query")
        .takes_value(true);

    let bool_arg = Arg::with_name("bool_expr")
        .short("b")
        .long("bool_expr")
        .help("JMES Query as bool only. (Prints whole record if true.)");

    let options = App::new("RusyLnk")
        .version("0.1.0")
        .author("Matthew Seyer <https://github.com/forensicmatt/RustyLnk>")
        .about("LNK Parser written in Rust.")
        .arg(source_arg)
        .arg(jmes_arg)
        .arg(bool_arg)
        .get_matches();

    let source = options.value_of("source").unwrap();

    if is_directory(source) {
        process_directory(source,&options);
    } else {
        process_file(source,&options);
    }
}
<|endoftext|>


<commit_before>#[macro_use(handler)]
extern crate chatbot;
extern crate getopts;

use std::env;

use chatbot::Chatbot;
use chatbot::adapter::CliAdapter;
use chatbot::adapter::SlackAdapter;
use chatbot::adapter::IrcAdapter;
use chatbot::handler::GithubIssueLinker;

use getopts::Options;
use getopts::ParsingStyle;

#[allow(dead_code)]
fn main() {

    let args = env::args().collect::<Vec<String>>();
    let mut opts = Options::new();
    opts.parsing_style(ParsingStyle::StopAtFirstFree);
    opts.optopt("a", "adapter", "Chat Adapter to use", "slack|cli");

    let matches = match opts.parse(&args[1..]) {
        Ok(m) => m,
        Err(f) => panic!(f.to_string())
    };

    let adapter_name = matches.opt_str("a").unwrap_or("cli".to_owned());

    let name = "chatbotbot";
    let mut bot = Chatbot::new(name);

    // Add adapter based on command line argument
    match adapter_name.as_ref() {
        "slack" => bot.add_adapter(SlackAdapter::new()),
        "cli" => bot.add_adapter(CliAdapter::new()),
        "irc" => {
            let config = chatbot::adapter::IrcConfig {
                nickname: Some(format!("{}", name)),
                alt_nicks: Some(vec![format!("{}_", name), format!("{}__", name)]),
                server: Some(format!("irc.mozilla.org")),
                channels: Some(vec![format!("#chatbot")]),
                .. Default::default()
            };
            bot.add_adapter(IrcAdapter::new(config))
        },
        _ => panic!("Unexpected adapter name. Use 'cli' or 'slack'.")
    };

    let ping = handler!("PingHandler", r"ping", |_, _| { Some("pong".to_owned()) });

    let trout = handler!("TroutSlap", r"slap (?P<user>.+)", move |matches, _| {
        match matches.name("user") {
            Some(user) => {
                Some(format!("{} slaps {} around a bit with a large trout",
                             name, user))
            },
            None => None
        }
    });

    let echo = handler!("EchoHandler", r"echo (?P<msg>.+)", |matches, _| {
        matches.name("msg").map(|msg| { msg.to_owned() })
    });

    bot.add_handler(ping);
    bot.add_handler(trout);
    bot.add_handler(echo);
    bot.add_handler(GithubIssueLinker::new());

    bot.run();
}
<commit_msg>Add PrintLadder handler to main.rs<commit_after>#[macro_use(handler)]
extern crate chatbot;
extern crate getopts;

use std::env;

use chatbot::Chatbot;
use chatbot::adapter::{CliAdapter, SlackAdapter, IrcAdapter};
use chatbot::handler::GithubIssueLinker;
use chatbot::handler::sup::{self, PrintLadder};

use getopts::Options;
use getopts::ParsingStyle;

#[allow(dead_code)]
fn main() {

    let args = env::args().collect::<Vec<String>>();
    let mut opts = Options::new();
    opts.parsing_style(ParsingStyle::StopAtFirstFree);
    opts.optopt("a", "adapter", "Chat Adapter to use", "slack|cli");

    let matches = match opts.parse(&args[1..]) {
        Ok(m) => m,
        Err(f) => panic!(f.to_string())
    };

    let adapter_name = matches.opt_str("a").unwrap_or("cli".to_owned());

    let name = "chatbotbot";
    let mut bot = Chatbot::new(name);

    // Add adapter based on command line argument
    match adapter_name.as_ref() {
        "slack" => bot.add_adapter(SlackAdapter::new()),
        "cli" => bot.add_adapter(CliAdapter::new()),
        "irc" => {
            let config = chatbot::adapter::IrcConfig {
                nickname: Some(format!("{}", name)),
                alt_nicks: Some(vec![format!("{}_", name), format!("{}__", name)]),
                server: Some(format!("irc.mozilla.org")),
                channels: Some(vec![format!("#chatbot")]),
                .. Default::default()
            };
            bot.add_adapter(IrcAdapter::new(config))
        },
        _ => panic!("Unexpected adapter name. Use 'cli' or 'slack'.")
    };

    let ping = handler!("PingHandler", r"ping", |_, _| { Some("pong".to_owned()) });

    let trout = handler!("TroutSlap", r"slap (?P<user>.+)", move |matches, _| {
        match matches.name("user") {
            Some(user) => {
                Some(format!("{} slaps {} around a bit with a large trout",
                             name, user))
            },
            None => None
        }
    });

    let echo = handler!("EchoHandler", r"echo (?P<msg>.+)", |matches, _| {
        matches.name("msg").map(|msg| { msg.to_owned() })
    });

    // Add ping pong leaderboard handlers if environment variables are set
    let sup_account = sup::account_from_env();
    match sup_account {
        Ok(account) => {
            let list_handler = PrintLadder::new(account, 5);
            bot.add_handler(list_handler);
        }
        _ => ()
    }

    bot.add_handler(ping);
    bot.add_handler(trout);
    bot.add_handler(echo);
    bot.add_handler(GithubIssueLinker::new());

    bot.run();
}
<|endoftext|>


<commit_before>use std::io;
use std::io::prelude::*;
use std::net::TcpStream;
use std::fs::File;
use std::env;

extern crate chrono;
use chrono::*;

extern crate aggregated_stats;

#[macro_use]
extern crate clap;

extern crate env_logger;
#[macro_use]
extern crate log;

extern crate stats;

extern crate prometheus;
extern crate hyper;

mod timing_analyzer;
mod error_analyzer;
mod args;
mod filter;
mod log_parser;
use log_parser::log_events::*;
mod render;
mod request_response_matcher;
use request_response_matcher::*;
mod http_handler;
mod result;

fn main() {
    env_logger::init().expect("Failed to initialize logging.");

    let args = args::parse_args(env::args()).expect("Failed to parse arguments.");

    let result = run(&args);

    let mut stream;
    let mut renderer: Box<render::Renderer>;

    renderer = match args.graphite_server {
        Some(ref graphite_server) => {
            stream = TcpStream::connect((graphite_server.as_ref(), args.graphite_port.unwrap()))
                .expect("Could not connect to the Graphite server");

            Box::new(render::graphite::GraphiteRenderer::new(UTC::now(),
                                                             args.graphite_prefix.clone(),
                                                             &mut stream))
        }
        None => Box::new(render::TerminalRenderer::new()),
    };

    renderer.render(result);

    if args.prometheus_listen.is_some() {
        let binding_address = args.prometheus_listen.clone().unwrap();
        http_handler::listen_http(args, &binding_address);
    }

}

fn run(args: &args::RequestLogAnalyzerArgs) -> result::RequestLogAnalyzerResult {
    let input: Box<io::Read> = match args.filename.as_ref() {
        "-" => Box::new(io::stdin()),
        _ => Box::new(File::open(&args.filename).expect("Failed to open file.")),
    };

    let reader = io::BufReader::new(input);

    let mut events_iterator = reader.lines()
        .map(parse_event)
        .filter(|event| event.is_ok())
        .map(|event| event.unwrap());

    let pairs_iterator =
        request_response_matcher::RequestResponsePairIterator::new(&mut events_iterator);

    let pairs: Vec<Box<RequestResponsePair>> =
        pairs_iterator.filter(|pair| filter::matches_filter(pair, &args.conditions))
            .map(|pair| Box::new(pair))
            .collect();

    let timing_result = timing_analyzer::analyze(&pairs);
    let error_result = error_analyzer::analyze(&pairs);

    result::RequestLogAnalyzerResult {
        count: pairs.len(),
        timing: timing_result,
        error: error_result,
    }
}

fn parse_event(line: Result<String, std::io::Error>) -> Result<LogEvent, &'static str> {
    match line {
        Ok(line) => log_parser::parse_line(&line),
        Err(_) => Err("Failed to read line."),
    }
}

#[cfg(test)]
mod tests {
    use super::*;

    #[test]
    fn test_run() {
        let args = args::RequestLogAnalyzerArgs {
            filename: String::from("src/test/simple-1.log"),
            conditions: filter::FilterConditions {
                include_terms: None,
                exclude_terms: None,
                latest_time: None,
            },
            graphite_server: None,
            graphite_port: Some(2003),
            graphite_prefix: None,
            prometheus_listen: None,
        };

        let result = run(&args);
        assert_eq!(result.count, 2);

        let timing = result.timing.unwrap();
        assert_eq!(timing.min, 7);
        assert_eq!(timing.max, 10);
    }

    #[test]
    fn test_run_ignore_broken_lines() {
        let args = args::RequestLogAnalyzerArgs {
            filename: String::from("src/test/broken.log"),
            conditions: filter::FilterConditions {
                include_terms: None,
                exclude_terms: None,
                latest_time: None,
            },
            graphite_server: None,
            graphite_port: Some(2003),
            graphite_prefix: None,
            prometheus_listen: None,
        };

        let result = run(&args);
        assert_eq!(result.count, 1);
    }

    #[test]
    fn test_parse_event() {
        let lines = vec![Ok(String::from("08/Apr/2016:09:57:47 +0200 [001] -> GET \
                                          /content/some/page.html HTTP/1.1")),
                         Ok(String::from("08/Apr/2016:09:57:47 +0200 [001] <- 200 text/html 7ms"))];

        let result: Vec<Result<LogEvent, &str>> = lines.into_iter().map(parse_event).collect();
        assert_eq!(result.len(), 2);
    }
}
<commit_msg>Use iterator for final result<commit_after>use std::io;
use std::io::prelude::*;
use std::net::TcpStream;
use std::fs::File;
use std::env;

extern crate chrono;
use chrono::*;

extern crate aggregated_stats;

#[macro_use]
extern crate clap;

extern crate env_logger;
#[macro_use]
extern crate log;

extern crate stats;

extern crate prometheus;
extern crate hyper;

mod timing_analyzer;
mod error_analyzer;
mod args;
mod filter;
mod log_parser;
use log_parser::log_events::*;
mod render;
mod request_response_matcher;
use request_response_matcher::*;
mod http_handler;
mod result;

fn main() {
    env_logger::init().expect("Failed to initialize logging.");

    let args = args::parse_args(env::args()).expect("Failed to parse arguments.");

    let result = run(&args);

    let mut stream;
    let mut renderer: Box<render::Renderer>;

    renderer = match args.graphite_server {
        Some(ref graphite_server) => {
            stream = TcpStream::connect((graphite_server.as_ref(), args.graphite_port.unwrap()))
                .expect("Could not connect to the Graphite server");

            Box::new(render::graphite::GraphiteRenderer::new(UTC::now(),
                                                             args.graphite_prefix.clone(),
                                                             &mut stream))
        }
        None => Box::new(render::TerminalRenderer::new()),
    };

    renderer.render(result);

    if args.prometheus_listen.is_some() {
        let binding_address = args.prometheus_listen.clone().unwrap();
        http_handler::listen_http(args, &binding_address);
    }

}

fn run(args: &args::RequestLogAnalyzerArgs) -> result::RequestLogAnalyzerResult {
    let input: Box<io::Read> = match args.filename.as_ref() {
        "-" => Box::new(io::stdin()),
        _ => Box::new(File::open(&args.filename).expect("Failed to open file.")),
    };

    let reader = io::BufReader::new(input);

    let mut events_iterator = reader.lines()
        .map(parse_event)
        .filter(|event| event.is_ok())
        .map(|event| event.unwrap());

    let pairs_iterator =
        request_response_matcher::RequestResponsePairIterator::new(&mut events_iterator)
            .filter(|pair| filter::matches_filter(pair, &args.conditions));

    let timing_result = timing_analyzer::analyze_iterator(pairs_iterator);
    // let error_result = error_analyzer::analyze(&pairs);

    result::RequestLogAnalyzerResult {
        count: timing_result.as_ref().unwrap().count,
        timing: timing_result,
        error: None,
    }
}

fn parse_event(line: Result<String, std::io::Error>) -> Result<LogEvent, &'static str> {
    match line {
        Ok(line) => log_parser::parse_line(&line),
        Err(_) => Err("Failed to read line."),
    }
}

#[cfg(test)]
mod tests {
    use super::*;

    #[test]
    fn test_run() {
        let args = args::RequestLogAnalyzerArgs {
            filename: String::from("src/test/simple-1.log"),
            conditions: filter::FilterConditions {
                include_terms: None,
                exclude_terms: None,
                latest_time: None,
            },
            graphite_server: None,
            graphite_port: Some(2003),
            graphite_prefix: None,
            prometheus_listen: None,
        };

        let result = run(&args);
        assert_eq!(result.count, 2);

        let timing = result.timing.unwrap();
        assert_eq!(timing.min, 7);
        assert_eq!(timing.max, 10);
    }

    #[test]
    fn test_run_ignore_broken_lines() {
        let args = args::RequestLogAnalyzerArgs {
            filename: String::from("src/test/broken.log"),
            conditions: filter::FilterConditions {
                include_terms: None,
                exclude_terms: None,
                latest_time: None,
            },
            graphite_server: None,
            graphite_port: Some(2003),
            graphite_prefix: None,
            prometheus_listen: None,
        };

        let result = run(&args);
        assert_eq!(result.count, 1);
    }

    #[test]
    fn test_parse_event() {
        let lines = vec![Ok(String::from("08/Apr/2016:09:57:47 +0200 [001] -> GET \
                                          /content/some/page.html HTTP/1.1")),
                         Ok(String::from("08/Apr/2016:09:57:47 +0200 [001] <- 200 text/html 7ms"))];

        let result: Vec<Result<LogEvent, &str>> = lines.into_iter().map(parse_event).collect();
        assert_eq!(result.len(), 2);
    }
}
<|endoftext|>


<commit_before>#![feature(custom_attribute, custom_derive, plugin)]
#![plugin(serde_macros)]

extern crate hyper;
extern crate serde;

mod entity;
mod error;

use entity::ZipResult;
use error::ZipError;
use hyper::Client;
use serde::json;
use std::io::Read;

fn main() {
    let result = std::env::args().nth(1).ok_or(ZipError::Input)
        .and_then(|candidate| query(candidate))
        .and_then(|(candidate, response)| parse_result(candidate, response));

    match result {
        Ok(zip_result) => println!("{}", zip_result),
        Err(e) => println!("{}", e),
    }
}

fn query(candidate: String) -> Result<(String, String), ZipError> {
    let mut client = Client::new();

    match client.get(&format!("http://api.zippopotam.us/us/{}", candidate)).send() {
        Ok(mut res) => Ok((candidate, read_response(&mut res))),
        _ => Err(ZipError::API),
    }
}

#[allow(unused)]
fn read_response(response: &mut hyper::client::response::Response) -> String {
    let mut buf = String::new();
    response.read_to_string(&mut buf);
    buf.trim().to_string()
}

fn parse_result(candidate: String, result: String) -> Result<ZipResult, ZipError> {
    match json::from_str(&result) {
        Ok(result) => Ok(result),
        Err(_) => Err(ZipError::Invalid(candidate)),
    }
}
<commit_msg>Remove unnecessary trim call<commit_after>#![feature(custom_attribute, custom_derive, plugin)]
#![plugin(serde_macros)]

extern crate hyper;
extern crate serde;

mod entity;
mod error;

use entity::ZipResult;
use error::ZipError;
use hyper::Client;
use serde::json;
use std::io::Read;

fn main() {
    let result = std::env::args().nth(1).ok_or(ZipError::Input)
        .and_then(|candidate| query(candidate))
        .and_then(|(candidate, response)| parse_result(candidate, response));

    match result {
        Ok(zip_result) => println!("{}", zip_result),
        Err(e) => println!("{}", e),
    }
}

fn query(candidate: String) -> Result<(String, String), ZipError> {
    let mut client = Client::new();

    match client.get(&format!("http://api.zippopotam.us/us/{}", candidate)).send() {
        Ok(mut res) => Ok((candidate, read_response(&mut res))),
        _ => Err(ZipError::API),
    }
}

#[allow(unused)]
fn read_response(response: &mut hyper::client::response::Response) -> String {
    let mut buf = String::new();
    response.read_to_string(&mut buf);
    buf
}

fn parse_result(candidate: String, result: String) -> Result<ZipResult, ZipError> {
    match json::from_str(&result) {
        Ok(result) => Ok(result),
        Err(_) => Err(ZipError::Invalid(candidate)),
    }
}
<|endoftext|>


<commit_before>extern crate rand;
extern crate sdl2;

mod opcode;
mod chip8;
use chip8::Chip8;

#[cfg(not(test))]
fn main() {
    use std::env;

    if let Some(rom_file_name) = env::args().nth(1) {
        println!("Reading ROM: {}...", rom_file_name);
        let rom = utils::read_binary(rom_file_name).unwrap_or_else(|err| {
            println!("Could not read ROM: {}!", err);
            Vec::new()
        });

        if !rom.is_empty() {
            println!("Starting CHIP-8 emulator...");
            let mut chip = Chip8::new();
            chip.initialize();
            chip.load_rom(rom);
            chip.run();
        }
    } else {
        println!("Usage: chip8 <rom>");
    }
}

#[cfg(not(test))]
mod utils {
    use std::io;
    use std::path::Path;

    pub fn read_binary<P: AsRef<Path>>(path: P) -> io::Result<Vec<u8>> {
        use std::fs;
        use std::io::Read;

        let mut file = try!(fs::File::open(path));
        let mut file_buffer = Vec::new();
        try!(file.read_to_end(&mut file_buffer));
        Ok(file_buffer)
    }
}<commit_msg>removed use chip8<commit_after>extern crate rand;
extern crate sdl2;

mod opcode;
mod chip8;

#[cfg(not(test))]
fn main() {
    use std::env;

    if let Some(rom_file_name) = env::args().nth(1) {
        println!("Reading ROM: {}...", rom_file_name);
        let rom = utils::read_binary(rom_file_name).unwrap_or_else(|err| {
            println!("Could not read ROM: {}!", err);
            Vec::new()
        });

        if !rom.is_empty() {
            println!("Starting CHIP-8 emulator...");
            let mut chip = chip8::Chip8::new();
            chip.initialize();
            chip.load_rom(rom);
            chip.run();
        }
    } else {
        println!("Usage: chip8 <rom>");
    }
}

#[cfg(not(test))]
mod utils {
    use std::io;
    use std::path::Path;

    pub fn read_binary<P: AsRef<Path>>(path: P) -> io::Result<Vec<u8>> {
        use std::fs;
        use std::io::Read;

        let mut file = try!(fs::File::open(path));
        let mut file_buffer = Vec::new();
        try!(file.read_to_end(&mut file_buffer));
        Ok(file_buffer)
    }
}<|endoftext|>


<commit_before>extern crate iron;
extern crate router;
extern crate rustc_serialize;

use router::Router;
use iron::prelude::*;
use iron::status::Status;
use rustc_serialize::json;
use std::env;
use std::net::SocketAddr;
use std::str::FromStr;

mod memory;
mod helpers;
mod temperature;
mod load;
mod uptime;

fn main() {
    let mut router = Router::new();
    router.get("/temperature", |_: &mut Request| -> IronResult<Response> {
        let temp = temperature::temperature();
        match temp {
            Err(err) => Ok(Response::with((Status::InternalServerError, err))),
            Ok(val) => Ok(Response::with((Status::Ok, json::encode(&val).unwrap())))
        }
    }, "temperature");

    router.get("/memory", |_: &mut Request| -> IronResult<Response> {
        let mem = memory::read_usage();
        match mem {
            Err(err) => Ok(Response::with((Status::InternalServerError, err))),
            Ok(val) => Ok(Response::with((Status::Ok, json::encode(&val).unwrap())))
        }
    }, "memory");

    router.get("/load", |_: &mut Request| -> IronResult<Response> {
        let mem = load::load();
        match mem {
            Err(err) => Ok(Response::with((Status::InternalServerError, err))),
            Ok(val) => Ok(Response::with((Status::Ok, json::encode(&val).unwrap())))
        }
    }, "load");

    router.get("/uptime", |_: &mut Request| -> IronResult<Response> {
        let uptime = uptime::uptime();
        match uptime {
            Err(err) => Ok(Response::with((Status::InternalServerError, err))),
            Ok(val) => Ok(Response::with((Status::Ok, json::encode(&val).unwrap())))
        }
    }, "uptime");

    router.any("/*", |_: &mut Request| -> IronResult<Response> {
        Ok(Response::with((Status::NotFound, "Page not found")))
    }, "default");

    let router = env::var("BIND_STR").map_err(|e| e.to_string())
        .and_then(|s| SocketAddr::from_str(s.as_str()).map_err(|e| e.to_string()))
        .and_then(|s| Iron::new(router).http(s).map_err(|e| e.to_string()));

    match router {
        Err(err) => println!("Error: {}", err),
        Ok(_) => { /* Router unwrapped */ }
    }
}
<commit_msg>Logging incomming requests<commit_after>extern crate iron;
extern crate router;
extern crate rustc_serialize;

use router::Router;
use iron::prelude::*;
use iron::status::Status;
use rustc_serialize::json;
use std::env;
use std::net::SocketAddr;
use std::str::FromStr;

mod memory;
mod helpers;
mod temperature;
mod load;
mod uptime;

struct RequestLogger {
    router: Router
}

impl iron::middleware::Handler for RequestLogger {
    fn handle(&self, r: &mut Request) -> IronResult<Response> {
        let resp = self.router.handle(r);
        match resp {
            Err(err) => {
                println!("ERROR; method: {}; url: {}", r.method, r.url);
                Err(err)
            },
            Ok(resp) => {
                let status = resp.status.unwrap();
                println!("OK; method: {}; url: {}, status: {}", r.method, r.url, status);
                Ok(resp)
            }
        }
    }
}

fn main() {
    let mut router = Router::new();
    router.get("/temperature", |_: &mut Request| -> IronResult<Response> {
        let temp = temperature::temperature();
        match temp {
            Err(err) => Ok(Response::with((Status::InternalServerError, err))),
            Ok(val) => Ok(Response::with((Status::Ok, json::encode(&val).unwrap())))
        }
    }, "temperature");

    router.get("/memory", |_: &mut Request| -> IronResult<Response> {
        let mem = memory::read_usage();
        match mem {
            Err(err) => Ok(Response::with((Status::InternalServerError, err))),
            Ok(val) => Ok(Response::with((Status::Ok, json::encode(&val).unwrap())))
        }
    }, "memory");

    router.get("/load", |_: &mut Request| -> IronResult<Response> {
        let mem = load::load();
        match mem {
            Err(err) => Ok(Response::with((Status::InternalServerError, err))),
            Ok(val) => Ok(Response::with((Status::Ok, json::encode(&val).unwrap())))
        }
    }, "load");

    router.get("/uptime", |_: &mut Request| -> IronResult<Response> {
        let uptime = uptime::uptime();
        match uptime {
            Err(err) => Ok(Response::with((Status::InternalServerError, err))),
            Ok(val) => Ok(Response::with((Status::Ok, json::encode(&val).unwrap())))
        }
    }, "uptime");

    router.any("/*", |_: &mut Request| -> IronResult<Response> {
        Ok(Response::with((Status::NotFound, "Page not found")))
    }, "default");

    let request_wrapper = RequestLogger { router: router };

    let listener = env::var("BIND_STR").map_err(|e| e.to_string())
        .and_then(|s| SocketAddr::from_str(s.as_str()).map_err(|e| e.to_string()))
        .and_then(|s| Iron::new(request_wrapper).http(s).map_err(|e| e.to_string()));

    match listener {
        Err(err) => println!("Error: {}", err),
        Ok(_) => { /* Router unwrapped */ }
    }
}
<|endoftext|>


<commit_before>// UDP stuff adapted from http://illegalargumentexception.blogspot.co.uk/2015/05/rust-send-and-receive-on-localhost-with.html
use std::net;
#[macro_use]
extern crate clap;
use clap::{Arg, App};

fn socket(listen_on: net::SocketAddr) -> net::UdpSocket {
    let attempt = net::UdpSocket::bind(listen_on);
    let socket;
    match attempt {
        Ok(sock) => {
            socket = sock;
        }
        Err(err) => panic!("Could not bind: {}", err),
    }
    socket
}

pub fn send_message(send_addr: net::SocketAddr, target: net::SocketAddr, data: Vec<u8>) {
    let socket = socket(send_addr);
    let _ = socket.send_to(&data, target);
    drop(socket);
}

fn main() {
    let command_vals = ["white", "red", "orange", "yellow", "green", "cyan", "blue", "purple",
                        "black", "?", "!", "quit"];
    let matches = App::new("rust_anybar")
                      .version(&crate_version!()[..])
                      .author("Stephan Hügel <urschrei@gmail.com>")
                      .about("A Rust command-line client for Anybar")
                      .args_from_usage("-p --port=[PORT] 'Set destination UDP port. Input must \
                                        be 0 – 65535, and defaults to 17388")
                      .arg(Arg::with_name("COMMAND")
                               .help("The command you wish to send to Anybar")
                               .index(1)
                               .possible_values(&command_vals)
                               .required(true))
                      .get_matches();
    let numeric_port = value_t!(matches.value_of("PORT"), u16).unwrap_or(1738);
    let to_send = matches.value_of("COMMAND").unwrap().to_owned().to_lowercase();
    // blam our control message into a vector
    let mut message: Vec<u8> = Vec::new();
    message.extend(to_send.as_bytes()
                          .iter()
                          .cloned());
    // bind to the correct UDP port
    let ip = net::Ipv4Addr::new(127, 0, 0, 1);
    // parse() gives us Result which we need to unwrap
    // it's safe to unwrap here, cos we already checked success
    let listen_addr = net::SocketAddrV4::new(ip, numeric_port);
    let send_addr = net::SocketAddrV4::new(ip, 0);
    // and send our message
    send_message(net::SocketAddr::V4(send_addr),
                 net::SocketAddr::V4(listen_addr),
                 message);
}
<commit_msg>Removing unnecessary comments<commit_after>// UDP stuff adapted from http://illegalargumentexception.blogspot.co.uk/2015/05/rust-send-and-receive-on-localhost-with.html
use std::net;
#[macro_use]
extern crate clap;
use clap::{Arg, App};

fn socket(listen_on: net::SocketAddr) -> net::UdpSocket {
    let attempt = net::UdpSocket::bind(listen_on);
    let socket;
    match attempt {
        Ok(sock) => {
            socket = sock;
        }
        Err(err) => panic!("Could not bind: {}", err),
    }
    socket
}

pub fn send_message(send_addr: net::SocketAddr, target: net::SocketAddr, data: Vec<u8>) {
    let socket = socket(send_addr);
    let _ = socket.send_to(&data, target);
    drop(socket);
}

fn main() {
    let command_vals = ["white", "red", "orange", "yellow", "green", "cyan", "blue", "purple",
                        "black", "?", "!", "quit"];
    let matches = App::new("rust_anybar")
                      .version(&crate_version!()[..])
                      .author("Stephan Hügel <urschrei@gmail.com>")
                      .about("A Rust command-line client for Anybar")
                      .args_from_usage("-p --port=[PORT] 'Set destination UDP port. Input must \
                                        be 0 – 65535, and defaults to 17388")
                      .arg(Arg::with_name("COMMAND")
                               .help("The command you wish to send to Anybar")
                               .index(1)
                               .possible_values(&command_vals)
                               .required(true))
                      .get_matches();
    let numeric_port = value_t!(matches.value_of("PORT"), u16).unwrap_or(1738);
    let to_send = matches.value_of("COMMAND").unwrap().to_owned().to_lowercase();
    // blam our control message into a vector
    let mut message: Vec<u8> = Vec::new();
    message.extend(to_send.as_bytes()
                          .iter()
                          .cloned());
    // bind to the correct UDP port
    let ip = net::Ipv4Addr::new(127, 0, 0, 1);
    let listen_addr = net::SocketAddrV4::new(ip, numeric_port);
    let send_addr = net::SocketAddrV4::new(ip, 0);
    // and send our message
    send_message(net::SocketAddr::V4(send_addr),
                 net::SocketAddr::V4(listen_addr),
                 message);
}
<|endoftext|>


<commit_before>//! # Telegram Groups Bot
//!
//! This bot can be used to manage multiple Telegram topic group chats.
//! Admins can register topic channels, which the users can then list.
//! The users can also request the invite link for one of the topic channels.
//!
//! ## Command API
//!
//! - `/help` Show help
//! - `/groups` Show list of available topic groups, along with the invite link
//! - `/add <name> <invite-url>` Register a new topic group
//!
//! ## Implementation Details
//!
//! This bot builds on top of the [telegram-bot][0] crate. It listens to the Telegram API through
//! LongPoll.
//!
//! When a message comes in, it is first parsed into a `Command`. If that worked out, the command
//! is processed by a command handler in a thread pool.
//!
//! [0]: https://crates.io/crates/telegram-bot

extern crate telegram_bot;
extern crate threadpool;
extern crate conv;
extern crate r2d2;
extern crate r2d2_redis;
extern crate redis;
extern crate url;
#[macro_use] extern crate log;
extern crate env_logger;
#[macro_use] extern crate quick_error;

pub mod types;
pub mod errors;
pub mod commands;
pub mod datastore;

use std::process::exit;
use std::time::Duration;

use telegram_bot::{Api, Listener, ListeningMethod, Message, MessageType, ParseMode, ListeningAction};
use threadpool::ThreadPool;
use conv::TryFrom;
use r2d2_redis::RedisConnectionManager;

use types::Command;
use datastore::RedisPool;

/// Initialize and return a `telegram_bot::Listener` instance.
fn get_listener(api: &Api) -> Listener {
    match api.get_me() {
        Ok(user) => println!("Starting {}...", user.first_name),
        Err(e) => {
            println!("Error: Could not fetch information about Telegram bot.");
            println!("  Error details: {:?}", e);
            println!("  Maybe check your TELEGRAM_BOT_TOKEN env var?");
            exit(1);
        },
    }

    api.listener(ListeningMethod::LongPoll(None))
}

/// Get a Redis database connection pool
fn get_redis_pool() -> RedisPool {
    let config = r2d2::Config::builder()
        .pool_size(4)
        .initialization_fail_fast(true)
        .connection_timeout(Duration::from_secs(5))
        .build();
    let manager = RedisConnectionManager::new("redis://localhost").unwrap();
    match r2d2::Pool::new(config, manager) {
        Ok(pool) => pool,
        Err(e) => {
            println!("Error: Could not initialize Redis connection pool.");
            println!("  Error details: {:?}", e);
            println!("  Is the Redis server running?");
            exit(1);
        },
    }
}

fn main() {

    // Initialize env logger
    env_logger::init().unwrap();

    // Get Telegram Api listener
    let api = Api::from_env("TELEGRAM_BOT_TOKEN").unwrap_or_else(|_| {
        println!("Error: TELEGRAM_BOT_TOKEN env var missing");
        exit(1);
    });
    let mut listener = get_listener(&api);

    // Get connection pool
    let redispool = get_redis_pool();

    // Get own username
    let username = match api.get_me() {
        Ok(user) => user.username,
        Err(e) => {
            println!("Error: Could not fetch information about Telegram bot.");
            println!("  Error details: {:?}", e);
            println!("  Maybe check your TELEGRAM_BOT_TOKEN env var?");
            exit(1);
        },
    };

    // Create thread pool for command handlers
    let threadpool = ThreadPool::new(12);

    println!("Up and running!");

    // Fetch new updates via long poll method
    listener.listen(|u| {

        // Dispatch messages
        if let Some(m) = u.message {

            // Get chat id
            let chat_id = m.chat.id();

            // Get copy of API and message
            let api_clone = api.clone();
            let msg_clone = m.clone();

            // Process text messages
            if let MessageType::Text(text) = m.msg {

                // Dispatch command handlers
                let command = Command::try_from(&*text);
                match command {
                    Ok(ref cmd) if cmd.receiver.is_some() && cmd.receiver != username => {
                        debug!("Ignored command, not directed at me: {:?}", cmd);
                    },
                    Ok(cmd) => {
                        debug!("Command: {:?}", cmd);

                        // Choose handler
                        type Handler = Box<Fn(&Command, &Message, Option<RedisPool>)
                                              -> Option<String> + Send>;
                        let handler: Handler = match &*cmd.name {
                            "help" => Box::new(commands::handle_help),
                            "groups" => Box::new(commands::handle_groups),
                            "add" => Box::new(commands::handle_add),
                            _ => Box::new(commands::handle_log),
                        };

                        // Run the handler in a separate thread
                        let redispool_clone = redispool.clone();
                        threadpool.execute(move || {
                            if let Some(reply) = handler(&cmd, &msg_clone,
                                                         Some(redispool_clone)) {
                                debug!("Return msg: {}", reply);
                                let parse_mode = Some(ParseMode::Markdown);
                                let disable_web_page_preview = Some(true);
                                api_clone.send_message(chat_id, reply,
                                                       parse_mode, disable_web_page_preview,
                                                       None, None);
                            };
                        });
                    }
                    Err(_) => debug!("No command."),
                }

            } else {
                println!("Other msg was {:?}", m.msg);
            }
        }

        // If none of the "try!" statements returned an error: It's Ok!
        Ok(ListeningAction::Continue)
    });

}
<commit_msg>Check result on send_message<commit_after>//! # Telegram Groups Bot
//!
//! This bot can be used to manage multiple Telegram topic group chats.
//! Admins can register topic channels, which the users can then list.
//! The users can also request the invite link for one of the topic channels.
//!
//! ## Command API
//!
//! - `/help` Show help
//! - `/groups` Show list of available topic groups, along with the invite link
//! - `/add <name> <invite-url>` Register a new topic group
//!
//! ## Implementation Details
//!
//! This bot builds on top of the [telegram-bot][0] crate. It listens to the Telegram API through
//! LongPoll.
//!
//! When a message comes in, it is first parsed into a `Command`. If that worked out, the command
//! is processed by a command handler in a thread pool.
//!
//! [0]: https://crates.io/crates/telegram-bot

extern crate telegram_bot;
extern crate threadpool;
extern crate conv;
extern crate r2d2;
extern crate r2d2_redis;
extern crate redis;
extern crate url;
#[macro_use] extern crate log;
extern crate env_logger;
#[macro_use] extern crate quick_error;

pub mod types;
pub mod errors;
pub mod commands;
pub mod datastore;

use std::process::exit;
use std::time::Duration;

use telegram_bot::{Api, Listener, ListeningMethod, Message, MessageType, ParseMode, ListeningAction};
use threadpool::ThreadPool;
use conv::TryFrom;
use r2d2_redis::RedisConnectionManager;

use types::Command;
use datastore::RedisPool;

/// Initialize and return a `telegram_bot::Listener` instance.
fn get_listener(api: &Api) -> Listener {
    match api.get_me() {
        Ok(user) => println!("Starting {}...", user.first_name),
        Err(e) => {
            println!("Error: Could not fetch information about Telegram bot.");
            println!("  Error details: {:?}", e);
            println!("  Maybe check your TELEGRAM_BOT_TOKEN env var?");
            exit(1);
        },
    }

    api.listener(ListeningMethod::LongPoll(None))
}

/// Get a Redis database connection pool
fn get_redis_pool() -> RedisPool {
    let config = r2d2::Config::builder()
        .pool_size(4)
        .initialization_fail_fast(true)
        .connection_timeout(Duration::from_secs(5))
        .build();
    let manager = RedisConnectionManager::new("redis://localhost").unwrap();
    match r2d2::Pool::new(config, manager) {
        Ok(pool) => pool,
        Err(e) => {
            println!("Error: Could not initialize Redis connection pool.");
            println!("  Error details: {:?}", e);
            println!("  Is the Redis server running?");
            exit(1);
        },
    }
}

fn main() {

    // Initialize env logger
    env_logger::init().unwrap();

    // Get Telegram Api listener
    let api = Api::from_env("TELEGRAM_BOT_TOKEN").unwrap_or_else(|_| {
        println!("Error: TELEGRAM_BOT_TOKEN env var missing");
        exit(1);
    });
    let mut listener = get_listener(&api);

    // Get connection pool
    let redispool = get_redis_pool();

    // Get own username
    let username = match api.get_me() {
        Ok(user) => user.username,
        Err(e) => {
            println!("Error: Could not fetch information about Telegram bot.");
            println!("  Error details: {:?}", e);
            println!("  Maybe check your TELEGRAM_BOT_TOKEN env var?");
            exit(1);
        },
    };

    // Create thread pool for command handlers
    let threadpool = ThreadPool::new(12);

    println!("Up and running!");

    // Fetch new updates via long poll method
    listener.listen(|u| {

        // Dispatch messages
        if let Some(m) = u.message {

            // Get chat id
            let chat_id = m.chat.id();

            // Get copy of API and message
            let api_clone = api.clone();
            let msg_clone = m.clone();

            // Process text messages
            if let MessageType::Text(text) = m.msg {

                // Dispatch command handlers
                let command = Command::try_from(&*text);
                match command {
                    Ok(ref cmd) if cmd.receiver.is_some() && cmd.receiver != username => {
                        debug!("Ignored command, not directed at me: {:?}", cmd);
                    },
                    Ok(cmd) => {
                        debug!("Command: {:?}", cmd);

                        // Choose handler
                        type Handler = Box<Fn(&Command, &Message, Option<RedisPool>)
                                              -> Option<String> + Send>;
                        let handler: Handler = match &*cmd.name {
                            "help" => Box::new(commands::handle_help),
                            "groups" => Box::new(commands::handle_groups),
                            "add" => Box::new(commands::handle_add),
                            _ => Box::new(commands::handle_log),
                        };

                        // Run the handler in a separate thread
                        let redispool_clone = redispool.clone();
                        threadpool.execute(move || {
                            if let Some(reply) = handler(&cmd, &msg_clone,
                                                         Some(redispool_clone)) {
                                debug!("Return msg: {}", reply);
                                let parse_mode = Some(ParseMode::Markdown);
                                let disable_web_page_preview = Some(true);
                                let result = api_clone.send_message(chat_id, reply,
                                                                    parse_mode,
                                                                    disable_web_page_preview,
                                                                    None, None);
                                if let Err(e) = result {
                                    error!("Could not send message: {:?}", e);
                                }
                            };
                        });
                    }
                    Err(_) => debug!("No command."),
                }

            } else {
                println!("Other msg was {:?}", m.msg);
            }
        }

        // If none of the "try!" statements returned an error: It's Ok!
        Ok(ListeningAction::Continue)
    });

}
<|endoftext|>