<commit_before>#[macro_use]
extern crate clap;
#[macro_use]
extern crate error_chain;
extern crate mhost;
extern crate resolv_conf;
extern crate tokio_core;
extern crate trust_dns;

use mhost::{multiple_lookup, DnsQuery};

use clap::{App, Arg, ArgMatches, Shell};
use std::fmt;
use std::fs::File;
use std::io::Read;
use std::net::IpAddr;
use std::str::FromStr;
use std::time::Duration;
use tokio_core::reactor::Core;
use trust_dns::rr::{RData, RecordType};

// Arbitrary list of public DNS servers
static DEFAULT_DNS_SERVERS: &'static [&str] = &[
    // "Level3",
    "209.244.0.3",
    "209.244.0.4",
    // "Verisign",
    "64.6.64.6",
    "64.6.65.6",
    // "Google",
    "8.8.8.8",
    "8.8.4.4",
    // "DNS.WATCH",
    "84.200.69.80",
    "84.200.70.40",
    // "OpenDNS Home",
    "208.67.222.222",
    "208.67.220.220",
    // "SafeDNS",
    "195.46.39.39",
    "195.46.39.40",
    // "Dyn",
    "216.146.35.35",
    "216.146.36.36",
    // "FreeDNS",
    "37.235.1.174",
    "37.235.1.177",
    // "Alternate DNS",
    "198.101.242.72",
    "23.253.163.53",
];

static DEFAULT_RECORD_TYPES: &'static [&str] = &["a", "aaaa", "mx"];

fn run() -> Result<()> {
    let args = build_cli().get_matches();

    if args.is_present("completions") {
        return generate_completion(&args);
    }

    let dns_endpoints = get_dns_servers(&args)
        .chain_err(|| ErrorKind::ServerIpAddrParsingError)?
        .into_iter()
        .map(|s| (s, 53))
        .collect();

    let timeout = value_t!(args, "timeout", u64)
        .map(Duration::from_secs)
        .unwrap();

    let mut query = match IpAddr::from_str(args.value_of("domain name").unwrap()) {
        Ok(ip) => DnsQuery::from(ip, vec![RecordType::PTR]),
        Err(_) => {
            let record_types = get_record_types(&args).chain_err(|| {
                ErrorKind::ResoureRecordTypeParsingError
            })?;
            DnsQuery::new(args.value_of("domain name").unwrap(), record_types)
        }
    };
    query = query.set_timeout(timeout);

    let mut io_loop = Core::new().unwrap();
    let lookup = multiple_lookup(&io_loop.handle(), query, dns_endpoints);
    let result = io_loop.run(lookup);

    match result {
        Ok(ref responses) => {
            for response in responses {
                match *response {
                    Ok(ref x) => println!("{}", DnsResponse(x)),
                    Err(ref e) => println!("Error: {}", e),
                }
            }
        }
        Err(_) => {
            println!("General Error");
        }
    }

    Ok(())
}

fn build_cli() -> App<'static, 'static> {
    let name = env!("CARGO_PKG_NAME");
    let version = env!("CARGO_PKG_VERSION");
    let about = env!("CARGO_PKG_DESCRIPTION");

    App::new(name)
        .version(version)
        .about(about)
        .arg(
            Arg::with_name("domain name")
                .index(1)
                .required(true)
                .conflicts_with("completions")
                .help("domain name or IP address to look up"),
        )
        .arg(
            Arg::with_name("timeout")
                .long("timeout")
                .default_value("5")
                .help("timeout for server responses in sec")
                .takes_value(true),
        )
        .arg(
            Arg::with_name("record types")
                .long("type")
                .short("t")
                .takes_value(true)
                .multiple(true)
                .number_of_values(1)
                .possible_values(
                    &[
                        "a",
                        "aaaa",
                        "any",
                        "cname",
                        "dnskey",
                        "mx",
                        "ns",
                        "opt",
                        "ptr",
                        "soa",
                        "srv",
                        "txt",
                    ],
                )
                .help("Select resource record type [default: a, aaaa, mx]"),
        )
        .arg(
            Arg::with_name("dont use local dns servers")
                .short("L")
                .help("Do not use local (/etc/resolv.conf) DNS servers"),
        )
        .arg(Arg::with_name("predefined server").short("S").help(
            "use predefined DNS server set",
        ))
        .arg(
            Arg::with_name("DNS servers")
                .long("server")
                .short("s")
                .takes_value(true)
                .multiple(true)
                .number_of_values(1)
                .help(
                    "DNS servers to use; if empty use predefined, public DNS server",
                ),
        )
        .arg(
            Arg::with_name("completions")
                .long("completions")
                .takes_value(true)
                .hidden(true)
                .possible_values(&["bash", "fish", "zsh"])
                .help("The shell to generate the script for"),
        )
}

fn generate_completion(args: &ArgMatches) -> Result<()> {
    let bin_name = env!("CARGO_PKG_NAME");
    let shell = args.value_of("completions").ok_or(
        ErrorKind::CliArgsParsingError,
    )?;
    build_cli().gen_completions_to(
        bin_name,
        shell.parse::<Shell>().unwrap(),
        &mut std::io::stdout(),
    );
    Ok(())
}

fn get_local_dns_servers() -> Result<Vec<IpAddr>> {
    let mut buf = Vec::with_capacity(4096);
    let mut f = File::open("/etc/resolv.conf").chain_err(
        || ErrorKind::ResolvConfError,
    )?;
    f.read_to_end(&mut buf).unwrap();
    let cfg = resolv_conf::Config::parse(&buf[..]).chain_err(|| {
        ErrorKind::ResolvConfError
    })?;
    Ok(cfg.nameservers)
}

fn get_dns_servers(args: &ArgMatches) -> Result<Vec<IpAddr>> {
    let mut dns_servers: Vec<IpAddr> = Vec::new();
    if let Some(servers) = args.values_of_lossy("DNS servers") {
        dns_servers.extend(servers.into_iter().map(|server| {
            IpAddr::from_str(&server).unwrap()
        }));
    }
    if args.is_present("predefined server") {
        dns_servers.extend(DEFAULT_DNS_SERVERS.iter().map(|server| {
            IpAddr::from_str(server).unwrap()
        }));
    }
    if !args.is_present("dont use local dns servers") {
        dns_servers.extend(get_local_dns_servers()?);
    }

    Ok(dns_servers)
}

fn get_record_types(args: &ArgMatches) -> Result<Vec<RecordType>> {
    let record_types = if let Some(record_types) = args.values_of_lossy("record types") {
        record_types
            .iter()
            .map(|rt| RecordType::from_str(&rt.to_uppercase()).unwrap())
            .collect()
    } else {
        DEFAULT_RECORD_TYPES
            .iter()
            .map(|rt| RecordType::from_str(&rt.to_uppercase()).unwrap())
            .collect()
    };

    Ok(record_types)
}

// Newtype pattern for Display implementation
struct DnsResponse<'a>(pub &'a mhost::DnsResponse);

// Display impl for plain, basic output
impl<'a> fmt::Display for DnsResponse<'a> {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        let DnsResponse(dns_response) = *self;
        if dns_response.answers.is_empty() {
            return write!(f, "DNS server {} has not records.", dns_response.server);
        }
        let _ = write!(f, "DNS server {} responded with\n", dns_response.server);
        let mut answers: Vec<String> = dns_response
            .answers
            .iter()
            .map(|answer| match *answer.rdata() {
                RData::A(ip) => format!(" * IPv4: {}", ip),
                RData::AAAA(ip) => format!(" * IPv6: {}", ip),
                RData::CNAME(ref name) => format!(" * CNAME: {}", name),
                RData::MX(ref mx) => {
                    format!(
                        " * MX: {} with preference {}",
                        mx.exchange(),
                        mx.preference()
                    )
                }
                RData::NS(ref name) => format!(" * NS: {}", name),
                RData::SOA(ref soa) => {
                    format!(
                        " * SOA: {} {} {} {} {} {} {}",
                        soa.mname(),
                        soa.rname(),
                        soa.serial(),
                        soa.refresh(),
                        soa.retry(),
                        soa.expire(),
                        soa.minimum()
                    )
                }
                RData::TXT(ref txt) => format!(" * TXT: {}", txt.txt_data().join(" ")),
                RData::PTR(ref ptr) => format!(" * PTR: {}", ptr.to_string()),
                ref x => format!(" * unclassified answer: {:?}", x),
            })
            .collect();
        answers.sort();
        write!(f, "{}", answers.join("\n"))
    }
}

error_chain! {
    errors {
        CliArgsParsingError {
            description("failed to parse CLI arguments")
            display("failed to parse CLI arguments")
        }

        ResolvConfError {
            description("failed to parse /etc/resolv.conf")
            display("failed to parse /etc/resolv.cons")
        }

        ServerIpAddrParsingError {
            description("failed to parse server IP address")
            display("failed to parse server IP address")
        }

        ResoureRecordTypeParsingError {
            description("failed to parse resource record type")
            display("failed to parse resource record type")
        }
    }
}

quick_main!(run);
<commit_msg>Fix typo in output<commit_after>#[macro_use]
extern crate clap;
#[macro_use]
extern crate error_chain;
extern crate mhost;
extern crate resolv_conf;
extern crate tokio_core;
extern crate trust_dns;

use mhost::{multiple_lookup, DnsQuery};

use clap::{App, Arg, ArgMatches, Shell};
use std::fmt;
use std::fs::File;
use std::io::Read;
use std::net::IpAddr;
use std::str::FromStr;
use std::time::Duration;
use tokio_core::reactor::Core;
use trust_dns::rr::{RData, RecordType};

// Arbitrary list of public DNS servers
static DEFAULT_DNS_SERVERS: &'static [&str] = &[
    // "Level3",
    "209.244.0.3",
    "209.244.0.4",
    // "Verisign",
    "64.6.64.6",
    "64.6.65.6",
    // "Google",
    "8.8.8.8",
    "8.8.4.4",
    // "DNS.WATCH",
    "84.200.69.80",
    "84.200.70.40",
    // "OpenDNS Home",
    "208.67.222.222",
    "208.67.220.220",
    // "SafeDNS",
    "195.46.39.39",
    "195.46.39.40",
    // "Dyn",
    "216.146.35.35",
    "216.146.36.36",
    // "FreeDNS",
    "37.235.1.174",
    "37.235.1.177",
    // "Alternate DNS",
    "198.101.242.72",
    "23.253.163.53",
];

static DEFAULT_RECORD_TYPES: &'static [&str] = &["a", "aaaa", "mx"];

fn run() -> Result<()> {
    let args = build_cli().get_matches();

    if args.is_present("completions") {
        return generate_completion(&args);
    }

    let dns_endpoints = get_dns_servers(&args)
        .chain_err(|| ErrorKind::ServerIpAddrParsingError)?
        .into_iter()
        .map(|s| (s, 53))
        .collect();

    let timeout = value_t!(args, "timeout", u64)
        .map(Duration::from_secs)
        .unwrap();

    let mut query = match IpAddr::from_str(args.value_of("domain name").unwrap()) {
        Ok(ip) => DnsQuery::from(ip, vec![RecordType::PTR]),
        Err(_) => {
            let record_types = get_record_types(&args).chain_err(|| {
                ErrorKind::ResoureRecordTypeParsingError
            })?;
            DnsQuery::new(args.value_of("domain name").unwrap(), record_types)
        }
    };
    query = query.set_timeout(timeout);

    let mut io_loop = Core::new().unwrap();
    let lookup = multiple_lookup(&io_loop.handle(), query, dns_endpoints);
    let result = io_loop.run(lookup);

    match result {
        Ok(ref responses) => {
            for response in responses {
                match *response {
                    Ok(ref x) => println!("{}", DnsResponse(x)),
                    Err(ref e) => println!("Error: {}", e),
                }
            }
        }
        Err(_) => {
            println!("General Error");
        }
    }

    Ok(())
}

fn build_cli() -> App<'static, 'static> {
    let name = env!("CARGO_PKG_NAME");
    let version = env!("CARGO_PKG_VERSION");
    let about = env!("CARGO_PKG_DESCRIPTION");

    App::new(name)
        .version(version)
        .about(about)
        .arg(
            Arg::with_name("domain name")
                .index(1)
                .required(true)
                .conflicts_with("completions")
                .help("domain name or IP address to look up"),
        )
        .arg(
            Arg::with_name("timeout")
                .long("timeout")
                .default_value("5")
                .help("timeout for server responses in sec")
                .takes_value(true),
        )
        .arg(
            Arg::with_name("record types")
                .long("type")
                .short("t")
                .takes_value(true)
                .multiple(true)
                .number_of_values(1)
                .possible_values(
                    &[
                        "a",
                        "aaaa",
                        "any",
                        "cname",
                        "dnskey",
                        "mx",
                        "ns",
                        "opt",
                        "ptr",
                        "soa",
                        "srv",
                        "txt",
                    ],
                )
                .help("Select resource record type [default: a, aaaa, mx]"),
        )
        .arg(
            Arg::with_name("dont use local dns servers")
                .short("L")
                .help("Do not use local (/etc/resolv.conf) DNS servers"),
        )
        .arg(Arg::with_name("predefined server").short("S").help(
            "use predefined DNS server set",
        ))
        .arg(
            Arg::with_name("DNS servers")
                .long("server")
                .short("s")
                .takes_value(true)
                .multiple(true)
                .number_of_values(1)
                .help(
                    "DNS servers to use; if empty use predefined, public DNS server",
                ),
        )
        .arg(
            Arg::with_name("completions")
                .long("completions")
                .takes_value(true)
                .hidden(true)
                .possible_values(&["bash", "fish", "zsh"])
                .help("The shell to generate the script for"),
        )
}

fn generate_completion(args: &ArgMatches) -> Result<()> {
    let bin_name = env!("CARGO_PKG_NAME");
    let shell = args.value_of("completions").ok_or(
        ErrorKind::CliArgsParsingError,
    )?;
    build_cli().gen_completions_to(
        bin_name,
        shell.parse::<Shell>().unwrap(),
        &mut std::io::stdout(),
    );
    Ok(())
}

fn get_local_dns_servers() -> Result<Vec<IpAddr>> {
    let mut buf = Vec::with_capacity(4096);
    let mut f = File::open("/etc/resolv.conf").chain_err(
        || ErrorKind::ResolvConfError,
    )?;
    f.read_to_end(&mut buf).unwrap();
    let cfg = resolv_conf::Config::parse(&buf[..]).chain_err(|| {
        ErrorKind::ResolvConfError
    })?;
    Ok(cfg.nameservers)
}

fn get_dns_servers(args: &ArgMatches) -> Result<Vec<IpAddr>> {
    let mut dns_servers: Vec<IpAddr> = Vec::new();
    if let Some(servers) = args.values_of_lossy("DNS servers") {
        dns_servers.extend(servers.into_iter().map(|server| {
            IpAddr::from_str(&server).unwrap()
        }));
    }
    if args.is_present("predefined server") {
        dns_servers.extend(DEFAULT_DNS_SERVERS.iter().map(|server| {
            IpAddr::from_str(server).unwrap()
        }));
    }
    if !args.is_present("dont use local dns servers") {
        dns_servers.extend(get_local_dns_servers()?);
    }

    Ok(dns_servers)
}

fn get_record_types(args: &ArgMatches) -> Result<Vec<RecordType>> {
    let record_types = if let Some(record_types) = args.values_of_lossy("record types") {
        record_types
            .iter()
            .map(|rt| RecordType::from_str(&rt.to_uppercase()).unwrap())
            .collect()
    } else {
        DEFAULT_RECORD_TYPES
            .iter()
            .map(|rt| RecordType::from_str(&rt.to_uppercase()).unwrap())
            .collect()
    };

    Ok(record_types)
}

// Newtype pattern for Display implementation
struct DnsResponse<'a>(pub &'a mhost::DnsResponse);

// Display impl for plain, basic output
impl<'a> fmt::Display for DnsResponse<'a> {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        let DnsResponse(dns_response) = *self;
        if dns_response.answers.is_empty() {
            return write!(f, "DNS server {} has no records.", dns_response.server);
        }
        let _ = write!(f, "DNS server {} responded with\n", dns_response.server);
        let mut answers: Vec<String> = dns_response
            .answers
            .iter()
            .map(|answer| match *answer.rdata() {
                RData::A(ip) => format!(" * IPv4: {}", ip),
                RData::AAAA(ip) => format!(" * IPv6: {}", ip),
                RData::CNAME(ref name) => format!(" * CNAME: {}", name),
                RData::MX(ref mx) => {
                    format!(
                        " * MX: {} with preference {}",
                        mx.exchange(),
                        mx.preference()
                    )
                }
                RData::NS(ref name) => format!(" * NS: {}", name),
                RData::SOA(ref soa) => {
                    format!(
                        " * SOA: {} {} {} {} {} {} {}",
                        soa.mname(),
                        soa.rname(),
                        soa.serial(),
                        soa.refresh(),
                        soa.retry(),
                        soa.expire(),
                        soa.minimum()
                    )
                }
                RData::TXT(ref txt) => format!(" * TXT: {}", txt.txt_data().join(" ")),
                RData::PTR(ref ptr) => format!(" * PTR: {}", ptr.to_string()),
                ref x => format!(" * unclassified answer: {:?}", x),
            })
            .collect();
        answers.sort();
        write!(f, "{}", answers.join("\n"))
    }
}

error_chain! {
    errors {
        CliArgsParsingError {
            description("failed to parse CLI arguments")
            display("failed to parse CLI arguments")
        }

        ResolvConfError {
            description("failed to parse /etc/resolv.conf")
            display("failed to parse /etc/resolv.cons")
        }

        ServerIpAddrParsingError {
            description("failed to parse server IP address")
            display("failed to parse server IP address")
        }

        ResoureRecordTypeParsingError {
            description("failed to parse resource record type")
            display("failed to parse resource record type")
        }
    }
}

quick_main!(run);
<|endoftext|>


<commit_before>use std::io::Timer;
use grid_builder::build_from_file_contents;

use std::io::Reader;
use std::io::File;
use std::io::BufferedReader;
use std::path::Path;
use std::os;
mod grid_builder;
mod grid;

fn main() {
  let args = os::args();
  let path = match args {
    [_, filename, ..] => {
      Path::new(filename)
    },
    _                 => fail!("Could not open file :(")
  };

  // todo: I'm not sure how to handle a failure to open the file ..
  let mut reader = BufferedReader::new(File::open(&path));

  // note: trim() returns a borrowed StrSlice: &StrSlice.
  // Calling to_owned() copies the StrSlice returned from .trim() and returns an
  // owned string ~str. Bascially we're copying the sliced values from the
  // reader, and stuffing them into lines (using collect()).
  let lines: ~[~str] = reader.lines()
      .map(|x| x.trim().to_owned())
      .collect();

  let grid_from_file = grid_builder::build_from_file_contents(lines);
  grid_from_file.print();

  // The fn expect() is shorthand for pattern matching on Some/None.
  let mut timer = Timer::new().unwrap();
  let mut next = grid_from_file;

  loop {
    timer.sleep(100);
    next = grid_builder::build_from_grid(&next);
    println!("");
    next.print();
    println!("");
  }
}  // fn main
<commit_msg>Remove unused 'use' statement.<commit_after>use std::io::Timer;
use grid_builder::build_from_file_contents;

use std::io::File;
use std::io::BufferedReader;
use std::path::Path;
use std::os;
mod grid_builder;
mod grid;

fn main() {
  let args = os::args();
  let path = match args {
    [_, filename, ..] => {
      Path::new(filename)
    },
    _                 => fail!("Could not open file :(")
  };

  // todo: I'm not sure how to handle a failure to open the file ..
  let mut reader = BufferedReader::new(File::open(&path));

  // note: trim() returns a borrowed StrSlice: &StrSlice.
  // Calling to_owned() copies the StrSlice returned from .trim() and returns an
  // owned string ~str. Bascially we're copying the sliced values from the
  // reader, and stuffing them into lines (using collect()).
  let lines: ~[~str] = reader.lines()
      .map(|x| x.trim().to_owned())
      .collect();

  let grid_from_file = grid_builder::build_from_file_contents(lines);
  grid_from_file.print();

  // The fn expect() is shorthand for pattern matching on Some/None.
  let mut timer = Timer::new().unwrap();
  let mut next = grid_from_file;

  loop {
    timer.sleep(100);
    next = grid_builder::build_from_grid(&next);
    println!("");
    next.print();
    println!("");
  }
}  // fn main
<|endoftext|>


<commit_before>#![feature(globs)]
#![feature(phase)]
#![feature(unboxed_closures)]
#![feature(macro_rules)]
extern crate regex;
#[phase(plugin)] extern crate peruse;
extern crate peruse;
extern crate test;

use std::mem::replace;
use test::Bencher;

use std::collections::HashMap;
use peruse::parsers::*;
use grammar::*;
use parser::block;
use lexer::token;
use std::os;
use std::io::File;

pub mod lexer;
pub mod grammar;
pub mod parser;

fn main() {

  let args = os::args();

  let file = &args[1];

  let contents = File::open(&Path::new(file.as_slice())).read_to_string();

  match contents {
    Ok(raw) => {
      interp(raw.as_slice());
    }
    Err(err) => {println!("Error Reading File: {}", err);}
  }

}

type Environment = HashMap<String, int>;

fn interp<'a>(raw: &'a str) {
  let lexer = token();
  match lexer.parse(raw) {
    Ok((tokens, rest)) => {
      if rest != "" {
        println!("Parser error at: {}", rest)
      } else {
        let parser = block();
        match parser.parse(tokens.as_slice()) {
          Ok((Block(stmts), rest)) => {
            if rest.len() > 0 {
              println!("Error: unexpected token {}", rest[0]);
            } else {
              run(&stmts);
            }
          }
          Err(err) => {println!("Parse Error: {}", err);}
        };
      }
    },
    Err(err) => {
      println!("Lexer error: {}", err);
    }
  }

}

fn run(prog: &Vec<Statement>) {
  fn run_internal(prog: &Vec<Statement>, env: &mut Environment) {
    for s in prog.iter() {
      match *s {
        Assign(ref var, ref expr) => {
          match eval(expr, env) {
            Ok(res)   => {env.insert(var.clone(), res);}
            Err(err)  => {
              println!("ERROR: {}", err);
              return;
            }
          }
        },
        Output(ref expr) => match eval(expr, env) {
          Ok(val) => {println!("{}", val)}
          Err(err) => {
            println!("ERROR: {}", err)
            return;
          }
        },
        If(ref lhs, ref cmp, ref rhs, ref then_block, ref else_block) => {
          let is_true = compare(lhs, cmp, rhs, env);
          if (is_true) {
            let &Block(ref p) = then_block;
            run_internal(p, env);
          } else {
            match else_block {
              &Some(Block(ref p)) => {run_internal(p, env);}
              &None => {}
            }
          }
        }
        While(ref lhs, ref cmp, ref rhs, ref block) => {
          let &Block(ref stmts) = block;
          while(compare(lhs, cmp, rhs, env)) {
            run_internal(stmts, env);
          }
        }
      }
    }
  }
  let mut env: HashMap<String, int> = HashMap::new();
  run_internal(prog, &mut env);
}

fn compare(lhs: &Expr, cmp: &Comparator, rhs: &Expr, env: &Environment) -> bool {
  let l = eval(lhs, env);
  let r = eval(rhs, env);
  match *cmp {
    CEq   => l == r,
    CNeq  => l != r,
    CLt   => l < r,
    CGt   => l > r,
    CLeq  => l <= r,
    CGeq  => l >= r,
  }
}

fn eval(expr: &Expr, env: &HashMap<String, int>) -> Result<int, String> {
  match *expr {
    Variable(ref var) => match env.find(var) {
      Some(val) => Ok(*val),
      None => Err(format!("Undefined var {}", var)),
    },
    Num(val) => Ok(val),
    AddSub(ref ops) => {
      let mut sum = 0i;
      for &AddTerm(ref sign, ref op) in ops.iter() {
        match eval(op, env) {
          Ok(value) => match *sign {
            Add => {sum += value;}
            Subtract => {sum -= value;}
          },
          Err(err) => {
            return Err(err);
          }
        }
      }
      Ok(sum)
    },
    MultDiv(ref ops) => {
      let mut total = 1i;
      for &MultTerm(ref sign,ref op) in ops.iter() {
        match eval(op, env) {
          Ok(value) => match *sign{
            Multiply  => {total *= value;}
            Divide    => {total /= value;}
            Modulo    => {total %= value;}
          },
          Err(err) => {
            return Err(err);
          }
        }
      }
      Ok(total)
    }
  }
}

#[bench]
fn bench_run(b: &mut Bencher) {
    let prog = "n1 = 1
n2 = 1
n = n1 + n2
i = 0

while i < 30 {
  n2 = n1
  n1 = n
  n = n1 + n2
  i = i + 1
}
";
  let lexer = token();
  let (tokens, rest) = lexer.parse(prog).unwrap();
  let parser = block();
  b.iter(|| {
    parser.parse(tokens.as_slice());
  })
}

<commit_msg>adding benchmark<commit_after>#![feature(globs)]
#![feature(phase)]
#![feature(unboxed_closures)]
#![feature(macro_rules)]
extern crate regex;
#[phase(plugin)] extern crate peruse;
extern crate peruse;
extern crate test;

use std::mem::replace;
use test::Bencher;

use std::collections::HashMap;
use peruse::parsers::*;
use grammar::*;
use parser::block;
use lexer::token;
use std::os;
use std::io::File;

pub mod lexer;
pub mod grammar;
pub mod parser;

fn main() {

  let args = os::args();

  let file = &args[1];

  let contents = File::open(&Path::new(file.as_slice())).read_to_string();

  match contents {
    Ok(raw) => {
      interp(raw.as_slice());
    }
    Err(err) => {println!("Error Reading File: {}", err);}
  }

}

type Environment = HashMap<String, int>;

fn interp<'a>(raw: &'a str) {
  let lexer = token();
  match lexer.parse(raw) {
    Ok((tokens, rest)) => {
      if rest != "" {
        println!("Parser error at: {}", rest)
      } else {
        let parser = block();
        match parser.parse(tokens.as_slice()) {
          Ok((Block(stmts), rest)) => {
            if rest.len() > 0 {
              println!("Error: unexpected token {}", rest[0]);
            } else {
              run(&stmts);
            }
          }
          Err(err) => {println!("Parse Error: {}", err);}
        };
      }
    },
    Err(err) => {
      println!("Lexer error: {}", err);
    }
  }

}

fn run(prog: &Vec<Statement>) {
  fn run_internal(prog: &Vec<Statement>, env: &mut Environment) {
    for s in prog.iter() {
      match *s {
        Assign(ref var, ref expr) => {
          match eval(expr, env) {
            Ok(res)   => {env.insert(var.clone(), res);}
            Err(err)  => {
              println!("ERROR: {}", err);
              return;
            }
          }
        },
        Output(ref expr) => match eval(expr, env) {
          Ok(val) => {println!("{}", val)}
          Err(err) => {
            println!("ERROR: {}", err)
            return;
          }
        },
        If(ref lhs, ref cmp, ref rhs, ref then_block, ref else_block) => {
          let is_true = compare(lhs, cmp, rhs, env);
          if (is_true) {
            let &Block(ref p) = then_block;
            run_internal(p, env);
          } else {
            match else_block {
              &Some(Block(ref p)) => {run_internal(p, env);}
              &None => {}
            }
          }
        }
        While(ref lhs, ref cmp, ref rhs, ref block) => {
          let &Block(ref stmts) = block;
          while(compare(lhs, cmp, rhs, env)) {
            run_internal(stmts, env);
          }
        }
      }
    }
  }
  let mut env: HashMap<String, int> = HashMap::new();
  run_internal(prog, &mut env);
}

fn compare(lhs: &Expr, cmp: &Comparator, rhs: &Expr, env: &Environment) -> bool {
  let l = eval(lhs, env);
  let r = eval(rhs, env);
  match *cmp {
    CEq   => l == r,
    CNeq  => l != r,
    CLt   => l < r,
    CGt   => l > r,
    CLeq  => l <= r,
    CGeq  => l >= r,
  }
}

fn eval(expr: &Expr, env: &HashMap<String, int>) -> Result<int, String> {
  match *expr {
    Variable(ref var) => match env.find(var) {
      Some(val) => Ok(*val),
      None => Err(format!("Undefined var {}", var)),
    },
    Num(val) => Ok(val),
    AddSub(ref ops) => {
      let mut sum = 0i;
      for &AddTerm(ref sign, ref op) in ops.iter() {
        match eval(op, env) {
          Ok(value) => match *sign {
            Add => {sum += value;}
            Subtract => {sum -= value;}
          },
          Err(err) => {
            return Err(err);
          }
        }
      }
      Ok(sum)
    },
    MultDiv(ref ops) => {
      let mut total = 1i;
      for &MultTerm(ref sign,ref op) in ops.iter() {
        match eval(op, env) {
          Ok(value) => match *sign{
            Multiply  => {total *= value;}
            Divide    => {total /= value;}
            Modulo    => {total %= value;}
          },
          Err(err) => {
            return Err(err);
          }
        }
      }
      Ok(total)
    }
  }
}

#[bench]
fn bench_run(b: &mut Bencher) {
    let prog = "n1 = 1
n2 = 1
n = n1 + n2
i = 0

while i < 30 {
  n2 = n1
  n1 = n
  n = n1 + n2
  i = i + 1
}
";
  let lexer = token();
  let (tokens, rest) = lexer.parse(prog).unwrap();
  let parser = block();
  b.iter(|| {
    parser.parse(tokens.as_slice());
  })
}

#[bench]
fn bench_fizzbuzz(b: &mut Bencher) {
    let prog = "n = 1

while n <= 100 {
  if n % 3 == 0 {
    if n % 5 == 0 {
      out 10
    } else {
      out 1
    }
  } else if n % 5 == 0 {
    out 0
  }
  n = n + 1
}
";
  let lexer = token();
  let (tokens, rest) = lexer.parse(prog).unwrap();
  let parser = block();
  b.iter(|| {
    parser.parse(tokens.as_slice());
  })
}
<|endoftext|>


<commit_before>extern crate glutin_window;
extern crate graphics;
extern crate opengl_graphics;
extern crate piston;

#[macro_use]
pub mod common;
pub mod dragon;
mod glwindow;

use dragon::DragonFractal;
use glwindow::{WindowHandler};

fn main() {
    let window = WindowHandler::new();
    let dr = DragonFractal::new(17).unwrap();
    window.run(&dr);
}
<commit_msg>Allowing dragon iteration to be specified via command line<commit_after>extern crate glutin_window;
extern crate graphics;
extern crate opengl_graphics;
extern crate piston;

use std::env;

#[macro_use]
pub mod common;
pub mod dragon;
mod glwindow;

use dragon::DragonFractal;
use glwindow::{WindowHandler};

fn main() {
    let args = env::args().collect::<Vec<String>>();
    if args.len() <= 1 {
        panic!("You must provide an iteration number");
    }
    let iterations = args.get(1).unwrap().parse::<u64>().unwrap();

    let window = WindowHandler::new();
    let dr = DragonFractal::new(iterations).unwrap();
    window.run(&dr);
}
<|endoftext|>


<commit_before>#[macro_use(accepts, to_sql_checked)]
extern crate postgres;
extern crate chrono;
extern crate byteorder;
extern crate num;
extern crate clap;

mod currency;

use postgres::{Connection, SslMode};
use chrono::NaiveDateTime;
use currency::Currency;
use clap::{App, SubCommand, ArgMatches, Arg};

// Define the data in the database.
struct Account {
    id: i32,
    name: String,
    kind: String,
}

struct Balance {
    id: i32,
    account: i32,
    as_of: chrono::NaiveDateTime,
    balance: Currency
}

struct Deposit {
    id: i32,
    account: i32,
    at: chrono::NaiveDateTime,
    amount: Currency
}

fn prepare_interface<'a, 'b>() -> ArgMatches<'a, 'b> {
    // Top level command.
    let mut app = App::new("investments")
                      .about("Keeps track of investments");

    // Subcommands for the 'account' subcommand.
    let mut accounts_sub = SubCommand::with_name("account")
                                  .about("manage accounts");
    let accounts_list = SubCommand::with_name("list")
                                   .about("list accounts");
    accounts_sub = accounts_sub.subcommand(accounts_list);

    // Subcommands for the 'balance' subcommand.
    let mut balances_sub = SubCommand::with_name("balance")
                                  .about("manage balances");
    let balances_list = SubCommand::with_name("list")
                                   .about("list balances by account");
    let balances_update = SubCommand::with_name("update")
                                     .about("add a new balance for an account")
                                     .arg(
                                          Arg::with_name("ACCOUNT_ID")
                                              .help("The account to update")
                                              .required(true)
                                              .index(1)
                                     )
                                     .arg(
                                          Arg::with_name("BALANCE")
                                              .help("The current balance of the account, e.g. £1234.56")
                                              .required(true)
                                              .index(2)
                                     );
    balances_sub = balances_sub.subcommand(balances_list)
                               .subcommand(balances_update);

    // Register top-level subcommands.
    app = app.subcommand(accounts_sub);
    app = app.subcommand(balances_sub);

    return app.get_matches();
}

// List the accounts stored and their balances.
fn list_balances() {
    let conn = Connection::connect("postgres://cory@localhost:5432/finances", &SslMode::None).unwrap();

    let stmt = conn.prepare("
        SELECT DISTINCT ON (balance.account) accounts.id, accounts.name, balance.balance
        FROM balance
        INNER JOIN accounts ON balance.account=accounts.id
        ORDER BY balance.account, balance.as_of DESC"
    ).unwrap();

    println!("Balances:");

    for row in stmt.query(&[]).unwrap() {
        let account_id: i32 = row.get(0);
        let name: String = row.get(1);
        let balance: Currency = row.get(2);
        println!("\t({}) {}: {}", account_id, name, balance);
    }
}

// Show the accounts in the system.
fn list_accounts() {
    let conn = Connection::connect("postgres://cory@localhost:5432/finances", &SslMode::None).unwrap();

    let stmt = conn.prepare("
        SELECT accounts.id, accounts.name
        FROM accounts
        ORDER BY accounts.id"
    ).unwrap();

    println!("Accounts:");

    for row in stmt.query(&[]).unwrap() {
        let account_id: i32 = row.get(0);
        let name: String = row.get(1);
        println!("\t{}: {}", account_id, name);
    }

}

// Handle the account subcommand.
fn handle_accounts(matches: &ArgMatches) {
    match matches.subcommand() {
        ("list", Some(matches)) => {list_accounts()},
        _                       => {},
    }
}

// Handle the balance subcommand.
fn handle_balances(matches: &ArgMatches) {
    match matches.subcommand() {
        ("list", Some(matches)) => {list_balances()},
        _                       => {},
    }
}

fn main() {
    let matches = prepare_interface();

    match matches.subcommand() {
        ("account", Some(matches)) => {handle_accounts(matches)},
        ("balance", Some(matches)) => {handle_balances(matches)},
        _                          => {},
    }
}
<commit_msg>Update balances command.<commit_after>#[macro_use(accepts, to_sql_checked)]
extern crate postgres;
extern crate chrono;
extern crate byteorder;
extern crate num;
#[macro_use(value_t)]
extern crate clap;

mod currency;

use postgres::{Connection, SslMode};
use chrono::{NaiveDateTime, UTC};
use currency::Currency;
use clap::{App, SubCommand, ArgMatches, Arg};

const ACCOUNT_ID_ARG_NAME: &'static str = "ACCOUNT_ID";
const BALANCE_ARG_NAME:    &'static str = "BALANCE";

// Define the data in the database.
struct Account {
    id: i32,
    name: String,
    kind: String,
}

struct Balance {
    id: i32,
    account: i32,
    as_of: chrono::NaiveDateTime,
    balance: Currency
}

struct Deposit {
    id: i32,
    account: i32,
    at: chrono::NaiveDateTime,
    amount: Currency
}

fn prepare_interface<'a, 'b>() -> ArgMatches<'a, 'b> {
    // Top level command.
    let mut app = App::new("investments")
                      .about("Keeps track of investments");

    // Subcommands for the 'account' subcommand.
    let mut accounts_sub = SubCommand::with_name("account")
                                  .about("manage accounts");
    let accounts_list = SubCommand::with_name("list")
                                   .about("list accounts");
    accounts_sub = accounts_sub.subcommand(accounts_list);

    // Subcommands for the 'balance' subcommand.
    let mut balances_sub = SubCommand::with_name("balance")
                                  .about("manage balances");
    let balances_list = SubCommand::with_name("list")
                                   .about("list balances by account");
    let balances_update = SubCommand::with_name("update")
                                     .about("add a new balance for an account")
                                     .arg(
                                          Arg::with_name(ACCOUNT_ID_ARG_NAME)
                                              .help("The account to update")
                                              .required(true)
                                              .index(1)
                                     )
                                     .arg(
                                          Arg::with_name(BALANCE_ARG_NAME)
                                              .help("The current balance of the account, e.g. £1234.56")
                                              .required(true)
                                              .index(2)
                                     );
    balances_sub = balances_sub.subcommand(balances_list)
                               .subcommand(balances_update);

    // Register top-level subcommands.
    app = app.subcommand(accounts_sub);
    app = app.subcommand(balances_sub);

    return app.get_matches();
}

// List the accounts stored and their balances.
fn list_balances() {
    let conn = Connection::connect("postgres://cory@localhost:5432/finances", &SslMode::None).unwrap();

    let stmt = conn.prepare("
        SELECT DISTINCT ON (balance.account) accounts.id, accounts.name, balance.balance
        FROM balance
        INNER JOIN accounts ON balance.account=accounts.id
        ORDER BY balance.account, balance.as_of DESC"
    ).unwrap();

    println!("Balances:");

    for row in stmt.query(&[]).unwrap() {
        let account_id: i32 = row.get(0);
        let name: String = row.get(1);
        let balance: Currency = row.get(2);
        println!("\t({}) {}: {}", account_id, name, balance);
    }
}

fn update_balances(matches: &ArgMatches) {
    let conn = Connection::connect("postgres://cory@localhost:5432/finances", &SslMode::None).unwrap();

    let balance = Balance {
        id: 0,
        account: value_t!(matches.value_of(ACCOUNT_ID_ARG_NAME), i32).unwrap(),
        as_of: UTC::now().naive_utc(),
        balance: value_t!(matches.value_of(BALANCE_ARG_NAME), Currency).unwrap(),
    };

    let stmt = conn.prepare("
        INSERT INTO balance (account, as_of, balance) VALUES
            ($1, $2, $3)
    ").unwrap();
    let updates = stmt.execute(&[&balance.account, &balance.as_of, &balance.balance]).unwrap();
}

// Show the accounts in the system.
fn list_accounts() {
    let conn = Connection::connect("postgres://cory@localhost:5432/finances", &SslMode::None).unwrap();

    let stmt = conn.prepare("
        SELECT accounts.id, accounts.name
        FROM accounts
        ORDER BY accounts.id"
    ).unwrap();

    println!("Accounts:");

    for row in stmt.query(&[]).unwrap() {
        let account_id: i32 = row.get(0);
        let name: String = row.get(1);
        println!("\t{}: {}", account_id, name);
    }

}

// Handle the account subcommand.
fn handle_accounts(matches: &ArgMatches) {
    match matches.subcommand() {
        ("list", Some(matches)) => {list_accounts()},
        _                       => {},
    }
}

// Handle the balance subcommand.
fn handle_balances(matches: &ArgMatches) {
    match matches.subcommand() {
        ("list", Some(matches))   => {list_balances()},
        ("update", Some(matches)) => {update_balances(matches)},
        _                         => {},
    }
}

fn main() {
    let matches = prepare_interface();

    match matches.subcommand() {
        ("account", Some(matches)) => {handle_accounts(matches)},
        ("balance", Some(matches)) => {handle_balances(matches)},
        _                          => {},
    }
}
<|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 convert(inp: String) -> String {
        let outp = inp.to_lowercase();
    outp
}

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 = convert(matches.value_of("COMMAND").unwrap().to_string());
    // 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>rustfmt changes<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 convert(inp: String) -> String {
    let outp = inp.to_lowercase();
    outp
}

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 = convert(matches.value_of("COMMAND").unwrap().to_string());
    // 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);
}
<|endoftext|>


<commit_before>#[macro_use]
extern crate log;
extern crate getopts;
#[macro_use]
extern crate shoop;

use std::str;
use std::env;
use std::path::Path;
use getopts::Options;
use shoop::{ShoopLogger, Server, download};
use shoop::connection::PortRange;

const DEFAULT_PORT_RANGE: &'static str = "55000-55050";

fn print_usage(program: &str, opts: Options) {
    let brief = format!("Shoop is a ultrafast, (hopefully) secure file transfer tool, that is
(hopefully) ideal for transferring large files.

Usage: {0} [options] HOST:PATH DEST
...where HOST is an SSH host
...where PATH is the path on the *remote* machine of the file you want
...where DEST is either an existing folder or a location for the new
                 file (\".\" by default)

Example: {0} seedbox.facebook.com:/home/zuck/internalized_sadness.zip .",
                        program);
    print!("{}", opts.usage(&brief));
}

fn main() {
    enum Mode {
        Server,
        Client,
    }
    ShoopLogger::init().expect("Error starting shoop logger.");

    let args: Vec<String> = env::args().collect();
    let program = args[0].clone();
    let mut opts = Options::new();
    // TODO
    // opts.optopt("o", "output", "set output file name", "NAME");
    // opts.optopt("a", "ssh-args", "arguments to pass to ssh directly (at your own risk)", ARGS);
    opts.optopt("p",
                "port-range",
                "server listening port range",
                DEFAULT_PORT_RANGE);
    opts.optflag("s", "server", "server mode (advanced usage only)");
    opts.optflag("h", "help", "print this help menu");

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

    if matches.opt_present("h") {
        print_usage(&program, opts);
        return;
    }

    let input = if !matches.free.is_empty() {
        matches.free[0].clone()
    } else {
        print_usage(&program, opts);
        return;
    };

    let mode: Mode = if matches.opt_present("s") {
        Mode::Server
    } else {
        Mode::Client
    };

    let port_range = {
        let range_opt = &matches.opt_str("p").unwrap_or_else(|| String::from(DEFAULT_PORT_RANGE));
        PortRange::from(range_opt).unwrap()
    };

    match mode {
        Mode::Server => {
            Server::new(port_range, &input).start();
        }
        Mode::Client => {
            let sections: Vec<&str> = input.split(':').collect();
            let remote_addr: String = sections[0].to_owned();
            let remote_path_str = &sections[1].to_owned();
            let remote_path = Path::new(remote_path_str);
            let remote_file_name = match remote_path.file_name() {
                Some(s) => s,
                None => {
                    die!("The remote path specified doesn't look like a path to a file.");
                }
            };

            let output = if matches.free.len() > 1 {
                matches.free[1].clone()
            } else {
                String::from(".")
            };

            let output_path = Path::new(&output);
            let dest_path = if output_path.is_dir() {
                output_path.join(remote_file_name)
            } else {
                output_path.to_path_buf()
            };

            download(&remote_addr, port_range, remote_path_str, dest_path);
        }
    }
}
<commit_msg>precursor for the to/from abstraction<commit_after>#[macro_use]
extern crate log;
extern crate getopts;
#[macro_use]
extern crate shoop;

use std::str;
use std::env;
use std::path::Path;
use getopts::Options;
use shoop::{ShoopLogger, Server, download};
use shoop::connection::PortRange;

const DEFAULT_PORT_RANGE: &'static str = "55000-55050";

fn print_usage(program: &str, opts: Options) {
    let brief = format!("Shoop is a ultrafast, (hopefully) secure file transfer tool, that is
(hopefully) ideal for transferring large files.

Usage: {0} [options] SOURCE DEST
...where HOST is an SSH host
...where PATH is the path on the *remote* machine of the file you want
...where DEST is either an existing folder or a location for the new
                 file (\".\" by default)

Example: {0} seedbox.facebook.com:/home/zuck/internalized_sadness.zip .",
                        program);
    print!("{}", opts.usage(&brief));
}

enum Target {
    Local(String),
    Remote(String, String),
}

impl Target {
    fn from(s: String) -> Target {
        match s.find(':') {
            None => Target::Local(s),
            Some(i) => {
                let owned = s.to_owned();
                let (first, second) = owned.split_at(i);
                if first.contains('/') {
                    Target::Local(s)
                } else {
                    Target::Remote(String::from(first), String::from(second))
                }
            }
        }
    }
}

fn main() {
    enum Mode {
        Server,
        Client,
    }
    ShoopLogger::init().expect("Error starting shoop logger.");

    let args: Vec<String> = env::args().collect();
    let program = args[0].clone();
    let mut opts = Options::new();
    // TODO
    // opts.optopt("o", "output", "set output file name", "NAME");
    // opts.optopt("a", "ssh-args", "arguments to pass to ssh directly (at your own risk)", ARGS);
    opts.optopt("p",
                "port-range",
                "server listening port range",
                DEFAULT_PORT_RANGE);
    opts.optflag("s", "server", "server mode (advanced usage only)");
    opts.optflag("h", "help", "print this help menu");

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

    if matches.opt_present("h") {
        print_usage(&program, opts);
        return;
    }

    let source = if !matches.free.is_empty() {
        matches.free[0].clone()
    } else {
        print_usage(&program, opts);
        return;
    };

    let mode: Mode = if matches.opt_present("s") {
        Mode::Server
    } else {
        Mode::Client
    };

    let port_range = {
        let range_opt = &matches.opt_str("p").unwrap_or_else(|| String::from(DEFAULT_PORT_RANGE));
        PortRange::from(range_opt).unwrap()
    };

    match mode {
        Mode::Server => {
            Server::new(port_range, &source).start();
        }
        Mode::Client => {
            let dest = if matches.free.len() > 1 {
                matches.free[1].clone()
            } else {
                String::from(".")
            };

            match Target::from(source) {
                Target::Local(_) => panic!("Sorry, you can only copy *from* a remote host currently."),
                Target::Remote(source_addr, source_path_str) => {
                    match Target::from(dest) {
                        Target::Remote(_,_) => panic!("Sorry, you can only copy to a local path currently."),
                        Target::Local(dest_path_str) => {
                            let source_path = Path::new(&source_path_str);
                            let source_file_name = match source_path.file_name() {
                                Some(s) => s,
                                None => {
                                    die!("The remote path specified doesn't look like a path to a file.");
                                }
                            };
                            let dest_path = Path::new(&dest_path_str);
                            let final_dest_path = if dest_path.is_dir() {
                                dest_path.join(source_file_name)
                            } else {
                                dest_path.to_path_buf()
                            };

                            download(&source_addr, port_range, &dest_path_str, final_dest_path);
                        }
                    }
                }
            }

        }
    }
}
<|endoftext|>


<commit_before>// Copyright 2014-2018 The Rust Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.

// error-pattern:yummy
#![feature(box_syntax)]
#![feature(rustc_private)]
#![allow(clippy::missing_docs_in_private_items)]

use rustc_tools_util::*;

const CARGO_CLIPPY_HELP: &str = r#"Checks a package to catch common mistakes and improve your Rust code.

Usage:
    cargo clippy [options] [--] [<opts>...]

Common options:
    -h, --help               Print this message
    -V, --version            Print version info and exit

Other options are the same as `cargo check`.

To allow or deny a lint from the command line you can use `cargo clippy --`
with:

    -W --warn OPT       Set lint warnings
    -A --allow OPT      Set lint allowed
    -D --deny OPT       Set lint denied
    -F --forbid OPT     Set lint forbidden

The feature `cargo-clippy` is automatically defined for convenience. You can use
it to allow or deny lints from the code, eg.:

    #[cfg_attr(feature = "cargo-clippy", allow(needless_lifetimes))]
"#;

fn show_help() {
    println!("{}", CARGO_CLIPPY_HELP);
}

fn show_version() {
    let version_info = rustc_tools_util::get_version_info!();
    println!("{}", version_info);
}

pub fn main() {
    // Check for version and help flags even when invoked as 'cargo-clippy'
    if std::env::args().any(|a| a == "--help" || a == "-h") {
        show_help();
        return;
    }

    if std::env::args().any(|a| a == "--version" || a == "-V") {
        show_version();
        return;
    }

    if let Err(code) = process(std::env::args().skip(2)) {
        std::process::exit(code);
    }
}

fn process<I>(mut old_args: I) -> Result<(), i32>
where
    I: Iterator<Item = String>,
{
    let mut args = vec!["check".to_owned()];

    let mut found_dashes = false;
    for arg in old_args.by_ref() {
        found_dashes |= arg == "--";
        if found_dashes {
            break;
        }
        args.push(arg);
    }

    let clippy_args: String = old_args.map(|arg| format!("{}__CLIPPY_HACKERY__", arg)).collect();

    let mut path = std::env::current_exe()
        .expect("current executable path invalid")
        .with_file_name("clippy-driver");
    if cfg!(windows) {
        path.set_extension("exe");
    }

    let target_dir = std::env::var_os("CLIPPY_DOGFOOD")
        .map(|_| {
            std::env::var_os("CARGO_MANIFEST_DIR").map_or_else(
                || {
                    let mut fallback = std::ffi::OsString::new();
                    fallback.push("clippy_dogfood");
                    fallback
                },
                |d| {
                    std::path::PathBuf::from(d)
                        .join("target")
                        .join("dogfood")
                        .into_os_string()
                },
            )
        })
        .map(|p| ("CARGO_TARGET_DIR", p));

    let exit_status = std::process::Command::new("cargo")
        .args(&args)
        .env("RUSTC_WRAPPER", path)
        .env("CLIPPY_ARGS", clippy_args)
        .envs(target_dir)
        .spawn()
        .expect("could not run cargo")
        .wait()
        .expect("failed to wait for cargo?");

    if exit_status.success() {
        Ok(())
    } else {
        Err(exit_status.code().unwrap_or(-1))
    }
}
<commit_msg>update CARGO_CLIPPY_HELP string to suggest tool lints.<commit_after>// Copyright 2014-2018 The Rust Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.

// error-pattern:yummy
#![feature(box_syntax)]
#![feature(rustc_private)]
#![allow(clippy::missing_docs_in_private_items)]

use rustc_tools_util::*;

const CARGO_CLIPPY_HELP: &str = r#"Checks a package to catch common mistakes and improve your Rust code.

Usage:
    cargo clippy [options] [--] [<opts>...]

Common options:
    -h, --help               Print this message
    -V, --version            Print version info and exit

Other options are the same as `cargo check`.

To allow or deny a lint from the command line you can use `cargo clippy --`
with:

    -W --warn OPT       Set lint warnings
    -A --allow OPT      Set lint allowed
    -D --deny OPT       Set lint denied
    -F --forbid OPT     Set lint forbidden

You can use tool lints to allow or deny lints from your code, eg.:

    #[allow(clippy::needless_lifetimes)]
"#;

fn show_help() {
    println!("{}", CARGO_CLIPPY_HELP);
}

fn show_version() {
    let version_info = rustc_tools_util::get_version_info!();
    println!("{}", version_info);
}

pub fn main() {
    // Check for version and help flags even when invoked as 'cargo-clippy'
    if std::env::args().any(|a| a == "--help" || a == "-h") {
        show_help();
        return;
    }

    if std::env::args().any(|a| a == "--version" || a == "-V") {
        show_version();
        return;
    }

    if let Err(code) = process(std::env::args().skip(2)) {
        std::process::exit(code);
    }
}

fn process<I>(mut old_args: I) -> Result<(), i32>
where
    I: Iterator<Item = String>,
{
    let mut args = vec!["check".to_owned()];

    let mut found_dashes = false;
    for arg in old_args.by_ref() {
        found_dashes |= arg == "--";
        if found_dashes {
            break;
        }
        args.push(arg);
    }

    let clippy_args: String = old_args.map(|arg| format!("{}__CLIPPY_HACKERY__", arg)).collect();

    let mut path = std::env::current_exe()
        .expect("current executable path invalid")
        .with_file_name("clippy-driver");
    if cfg!(windows) {
        path.set_extension("exe");
    }

    let target_dir = std::env::var_os("CLIPPY_DOGFOOD")
        .map(|_| {
            std::env::var_os("CARGO_MANIFEST_DIR").map_or_else(
                || {
                    let mut fallback = std::ffi::OsString::new();
                    fallback.push("clippy_dogfood");
                    fallback
                },
                |d| {
                    std::path::PathBuf::from(d)
                        .join("target")
                        .join("dogfood")
                        .into_os_string()
                },
            )
        })
        .map(|p| ("CARGO_TARGET_DIR", p));

    let exit_status = std::process::Command::new("cargo")
        .args(&args)
        .env("RUSTC_WRAPPER", path)
        .env("CLIPPY_ARGS", clippy_args)
        .envs(target_dir)
        .spawn()
        .expect("could not run cargo")
        .wait()
        .expect("failed to wait for cargo?");

    if exit_status.success() {
        Ok(())
    } else {
        Err(exit_status.code().unwrap_or(-1))
    }
}
<|endoftext|>


<commit_before>extern crate rand;
extern crate nalgebra;

#[macro_use]
extern crate log;
extern crate fern;
extern crate time;

mod input;
mod structs;
mod nn;

use input::{read, commands, check_logs};
use std::env;
use structs::{FlowerName, Classifier};

extern crate nalgebra as na;

fn main() {

    // init logger
    init_logger();

    info!("starting_up");

    // parses commands
    let (data, config, subcom) = commands();

    // gets path for data
    let path = env::current_dir().unwrap();
    let filename = path.join(data);

    // tries to open the file
    let input = match read(&filename) {
        Ok(s) => s,
        Err(e) => panic!("paniced at read input:   {:?}", e),
    };

    info!("{:?} {:?}", config, subcom);

    let m = structs::Data::from_flower(input[0]);

    info!("{:?} {:?}",
          m.get_input(),
          FlowerName::declassify(*m.get_classifier()).unwrap());

    // just dummy nn for no warnings
    let nn = nn::Network::new(vec![4, 20, 3]).unwrap();

    // dummy print for no warnings
    info!("{} {} {}",
          nn.get_layers().len(),
          nn.get_weights().len(),
          nn.get_biases().len());

    info!("FF: {:?}",
          nn.feedforward(nalgebra::DVector::from_element(nn.get_layers()[0] as usize, 0 as f32)));
    info!("ended");
}

/// does init a logger that writes into a logfile
fn init_logger() {

    // OutputFilePath
    let str = format!("{}{}{}",
                      "logs/",
                      time::now().strftime("%Y-%m-%d_%H:%M:%S").unwrap(),
                      ".log");
    // init logger
    // write into file: [timestamp] [loglevel] message
    let logger_config = fern::DispatchConfig {
        format: Box::new(|msg: &str, level: &log::LogLevel, _location: &log::LogLocation| {
            format!("[{}][{}] {}",
                    time::now().strftime("%Y-%m-%d][%H:%M:%S").unwrap(),
                    level,
                    msg)
        }),
        // sets output file
        output: vec![fern::OutputConfig::file(str.as_str())],
        level: log::LogLevelFilter::Trace,
    };

    // tries to init logger
    if let Err(e) = fern::init_global_logger(logger_config, log::LogLevelFilter::Trace) {
        panic!("Failed to initialize global logger: {}", e);
    }

    // removes logs if therer are more than 20
    check_logs(20);
}
<commit_msg>output for travis?<commit_after>extern crate rand;
extern crate nalgebra;

#[macro_use]
extern crate log;
extern crate fern;
extern crate time;

mod input;
mod structs;
mod nn;

use input::{read, commands, check_logs};
use std::env;
use structs::{FlowerName, Classifier};

extern crate nalgebra as na;

fn main() {

    // does travis really need output?
    println!("hey travis");

    // init logger
    init_logger();

    info!("starting_up");

    // parses commands
    let (data, config, subcom) = commands();

    // gets path for data
    let path = env::current_dir().unwrap();
    let filename = path.join(data);

    // tries to open the file
    let input = match read(&filename) {
        Ok(s) => s,
        Err(e) => panic!("paniced at read input:   {:?}", e),
    };

    info!("{:?} {:?}", config, subcom);

    let m = structs::Data::from_flower(input[0]);

    info!("{:?} {:?}",
          m.get_input(),
          FlowerName::declassify(*m.get_classifier()).unwrap());

    // just dummy nn for no warnings
    let nn = nn::Network::new(vec![4, 20, 3]).unwrap();

    // dummy print for no warnings
    info!("{} {} {}",
          nn.get_layers().len(),
          nn.get_weights().len(),
          nn.get_biases().len());

    info!("FF: {:?}",
          nn.feedforward(nalgebra::DVector::from_element(nn.get_layers()[0] as usize, 0 as f32)));
    info!("ended");
}

/// does init a logger that writes into a logfile
fn init_logger() {

    // OutputFilePath
    let str = format!("{}{}{}",
                      "logs/",
                      time::now().strftime("%Y-%m-%d_%H:%M:%S").unwrap(),
                      ".log");
    // init logger
    // write into file: [timestamp] [loglevel] message
    let logger_config = fern::DispatchConfig {
        format: Box::new(|msg: &str, level: &log::LogLevel, _location: &log::LogLocation| {
            format!("[{}][{}] {}",
                    time::now().strftime("%Y-%m-%d][%H:%M:%S").unwrap(),
                    level,
                    msg)
        }),
        // sets output file
        output: vec![fern::OutputConfig::file(str.as_str())],
        level: log::LogLevelFilter::Trace,
    };

    // tries to init logger
    if let Err(e) = fern::init_global_logger(logger_config, log::LogLevelFilter::Trace) {
        panic!("Failed to initialize global logger: {}", e);
    }

    // removes logs if therer are more than 20
    check_logs(20);
}
<|endoftext|>


<commit_before>extern crate clap;
extern crate iron;
extern crate pretty_bytes;
extern crate chrono;

use std::env;
use std::fs::{self, File};
use std::path::{PathBuf};
use std::error::Error;
use std::time::{SystemTime, UNIX_EPOCH};
use std::os::unix::ffi::OsStrExt;

use iron::headers;
use iron::status;
use iron::{Iron, Request, Response, IronResult, Set, Chain, Handler, AfterMiddleware};
use pretty_bytes::converter::convert;
use chrono::{DateTime, Local, TimeZone};

fn main() {
    let matches = clap::App::new("Simple HTTP Server")
        .arg(clap::Arg::with_name("root")
             .index(1)
             .validator(|s| {
                 match File::open(s) {
                     Ok(f) => {
                         if f.metadata().unwrap().is_dir() { Ok(()) } else {
                             Err("Not directory".to_owned())
                         }
                     },
                     Err(e) => Err(e.description().to_string())
                 }
             })
             .help("Root directory"))
        .arg(clap::Arg::with_name("port")
             .short("p")
             .long("port")
             .takes_value(true)
             .default_value("8000")
             .validator(|s| {
                 match s.parse::<u16>() {
                     Ok(_) => Ok(()),
                     Err(e) => Err(e.description().to_string())
                 }
             })
             .help("Port number"))
        .arg(clap::Arg::with_name("threads")
             .short("t")
             .long("threads")
             .takes_value(true)
             .default_value("3")
             .validator(|s| {
                 match s.parse::<u8>() {
                     Ok(v) => {
                         if v > 0 { Ok(()) } else {
                             Err("Nagetive threads".to_owned())
                         }
                     }
                     Err(e) => Err(e.description().to_string())
                 }
             })
             .help("How many http threads"))
        .get_matches();
    let root = matches
        .value_of("root")
        .map(|s| PathBuf::from(s))
        .unwrap_or(env::current_dir().unwrap());
    let port = matches
        .value_of("port")
        .unwrap()
        .parse::<u16>()
        .unwrap();
    let threads = matches
        .value_of("threads")
        .unwrap()
        .parse::<u8>()
        .unwrap();

    println!("[Root]: {}", root.to_str().unwrap());
    let addr = format!("0.0.0.0:{}", port);
    println!("[Listening ({} threads)]: http://{}", threads, addr);
    println!("[{}]: ========== Server Started! ==========", now_string());

    let mut chain = Chain::new(MainHandler{root: root});
    chain.link_after(RequestLogger);
    let mut server = Iron::new(chain);
    server.threads = threads as usize;
    server.http(addr).unwrap();
}

struct MainHandler { root: PathBuf }
struct RequestLogger;

impl Handler for MainHandler {
    fn handle(&self, req: &mut Request) -> IronResult<Response> {
        let mut path = self.root.clone();
        for part in req.url.path() {
            path.push(part);
        }
        match File::open(&path) {
            Ok(f) => {
                let mut resp = Response::with(status::Ok);
                let metadata = f.metadata().unwrap();
                let path_prefix = req.url.path()
                    .into_iter()
                    .filter(|s| !s.is_empty())
                    .collect::<Vec<&str>>();
                let root_link = "[root]".to_owned();
                let breadcrumb = if path_prefix.len() > 0 {
                    let mut breadcrumb = path_prefix.clone();
                    let mut bread_links: Vec<String> = Vec::new();
                    bread_links.push(breadcrumb.pop().unwrap().to_owned());
                    while breadcrumb.len() > 0 {
                        let link = breadcrumb.join("/");
                        bread_links.push(format!(
                            "{}",
                            link, breadcrumb.pop().unwrap().to_owned(),
                        ));
                    }
                    bread_links.push(root_link);
                    bread_links.reverse();
                    bread_links.join(" / ")
                } else { root_link };
                if metadata.is_dir() {
                    resp.headers.set(headers::ContentType::html());
                    let mut files = Vec::new();
                    if path_prefix.len() > 0 {
                        let mut link = path_prefix.clone();
                        link.pop();
                        files.push(format!(
                            "
{}
",
                            link.join("/"), ".."
                        ));
                    }
                    for entry in fs::read_dir(&path).unwrap() {
                        let entry = entry.unwrap();
                        let entry_meta = entry.metadata().unwrap();
                        let file_name = entry.file_name().into_string().unwrap();
                        let file_modified = system_time_to_date_time(entry_meta.modified().unwrap())
                            .format("%Y-%m-%d %H:%M:%S").to_string();
                        let file_size = convert(entry_meta.len() as f64);
                        let file_type = entry_meta.file_type();
                        let link_style = if file_type.is_dir() {
                            "style=\"text-decoration: none; font-weight: bold;\"".to_owned()
                        } else {
                            "style=\"text-decoration: none;\"".to_owned()
                        };
                        let mut link = path_prefix.clone();
                        link.push(&file_name);
                        let link = link.join("/");
                        files.push(format!(
                            "
{}	 [{}]	 <bold>{}</bold>
",
                            link_style, link, file_name, file_modified, file_size
                        ));
                    }
                    resp = resp.set(format!(
                        "{}

{}
",
                        breadcrumb, files.join("\n")
                    ));
                } else {
                    resp.headers.set(headers::ContentDisposition {
                        disposition: headers::DispositionType::Attachment,
                        parameters: vec![headers::DispositionParam::Filename(
                            headers::Charset::Ext("utf-8".to_owned()), // The character set for the bytes of the filename
                            None, // The optional language tag (see `language-tag` crate)
                            path.file_name().unwrap().as_bytes().to_vec() // the actual bytes of the filename
                        )]
                    });
                    resp = resp.set(path);
                    let mime: iron::mime::Mime = "application/octet-stream".parse().unwrap();
                    resp.headers.set(headers::ContentType(mime));
                };
                Ok(resp)
            },
            Err(e) => {
                Ok(Response::with((status::NotFound, e.description().to_string())))
            }
        }
    }
}

impl AfterMiddleware for RequestLogger {
    fn after(&self, req: &mut Request, resp: Response) -> IronResult<Response> {
        println!(
            // datetime, remote-addr, status, method, url-path
            "[{}] - {} - {:?} - {} /{}",
            now_string(),
            req.remote_addr.ip(),
            resp.status.unwrap(),
            req.method,
            req.url.as_ref().to_string().splitn(4, '/').collect::<Vec<&str>>().pop().unwrap()
        );
        Ok(resp)
    }
}

fn now_string() -> String {
    Local::now().format("%Y-%m-%d %H:%M:%S").to_string()
}

fn system_time_to_date_time(t: SystemTime) -> DateTime<Local> {
    let (sec, nsec) = match t.duration_since(UNIX_EPOCH) {
        Ok(dur) => (dur.as_secs() as i64, dur.subsec_nanos()),
        Err(e) => { // unlikely but should be handled
            let dur = e.duration();
            let (sec, nsec) = (dur.as_secs() as i64, dur.subsec_nanos());
            if nsec == 0 {
                (-sec, 0)
            } else {
                (-sec - 1, 1_000_000_000 - nsec)
            }
        },
    };
    Local.timestamp(sec, nsec)
}
<commit_msg>Some renames<commit_after>extern crate clap;
extern crate iron;
extern crate pretty_bytes;
extern crate chrono;

use std::env;
use std::fs::{self, File};
use std::path::{PathBuf};
use std::error::Error;
use std::time::{SystemTime, UNIX_EPOCH};
use std::os::unix::ffi::OsStrExt;

use iron::headers;
use iron::status;
use iron::{Iron, Request, Response, IronResult, Set, Chain, Handler, AfterMiddleware};
use pretty_bytes::converter::convert;
use chrono::{DateTime, Local, TimeZone};

fn main() {
    let matches = clap::App::new("Simple HTTP Server")
        .arg(clap::Arg::with_name("root")
             .index(1)
             .validator(|s| {
                 match File::open(s) {
                     Ok(f) => {
                         if f.metadata().unwrap().is_dir() { Ok(()) } else {
                             Err("Not directory".to_owned())
                         }
                     },
                     Err(e) => Err(e.description().to_string())
                 }
             })
             .help("Root directory"))
        .arg(clap::Arg::with_name("port")
             .short("p")
             .long("port")
             .takes_value(true)
             .default_value("8000")
             .validator(|s| {
                 match s.parse::<u16>() {
                     Ok(_) => Ok(()),
                     Err(e) => Err(e.description().to_string())
                 }
             })
             .help("Port number"))
        .arg(clap::Arg::with_name("threads")
             .short("t")
             .long("threads")
             .takes_value(true)
             .default_value("3")
             .validator(|s| {
                 match s.parse::<u8>() {
                     Ok(v) => {
                         if v > 0 { Ok(()) } else {
                             Err("Nagetive threads".to_owned())
                         }
                     }
                     Err(e) => Err(e.description().to_string())
                 }
             })
             .help("How many http threads"))
        .get_matches();
    let root = matches
        .value_of("root")
        .map(|s| PathBuf::from(s))
        .unwrap_or(env::current_dir().unwrap());
    let port = matches
        .value_of("port")
        .unwrap()
        .parse::<u16>()
        .unwrap();
    let threads = matches
        .value_of("threads")
        .unwrap()
        .parse::<u8>()
        .unwrap();

    println!("[Root]: {}", root.to_str().unwrap());
    let addr = format!("0.0.0.0:{}", port);
    println!("[Listening ({} threads)]: http://{}", threads, addr);
    println!("[{}]: ========== Server Started! ==========", now_string());

    let mut chain = Chain::new(MainHandler{root: root});
    chain.link_after(RequestLogger);
    let mut server = Iron::new(chain);
    server.threads = threads as usize;
    server.http(addr).unwrap();
}

struct MainHandler { root: PathBuf }
struct RequestLogger;

impl Handler for MainHandler {
    fn handle(&self, req: &mut Request) -> IronResult<Response> {
        let mut path = self.root.clone();
        for part in req.url.path() {
            path.push(part);
        }
        match File::open(&path) {
            Ok(f) => {
                let mut resp = Response::with(status::Ok);
                let metadata = f.metadata().unwrap();
                let path_prefix = req.url.path()
                    .into_iter()
                    .filter(|s| !s.is_empty())
                    .collect::<Vec<&str>>();
                let root_link = "[ROOT]".to_owned();
                let breadcrumb = if path_prefix.len() > 0 {
                    let mut breadcrumb = path_prefix.clone();
                    let mut bread_links: Vec<String> = Vec::new();
                    bread_links.push(breadcrumb.pop().unwrap().to_owned());
                    while breadcrumb.len() > 0 {
                        let link = breadcrumb.join("/");
                        bread_links.push(format!(
                            "{}",
                            link, breadcrumb.pop().unwrap().to_owned(),
                        ));
                    }
                    bread_links.push(root_link);
                    bread_links.reverse();
                    bread_links.join(" / ")
                } else { root_link };
                if metadata.is_dir() {
                    resp.headers.set(headers::ContentType::html());
                    let mut files = Vec::new();
                    if path_prefix.len() > 0 {
                        let mut link = path_prefix.clone();
                        link.pop();
                        files.push(format!(
                            "
{}
",
                            link.join("/"), "[Parent Directory]"
                        ));
                    }
                    for entry in fs::read_dir(&path).unwrap() {
                        let entry = entry.unwrap();
                        let entry_meta = entry.metadata().unwrap();
                        let file_name = entry.file_name().into_string().unwrap();
                        let file_modified = system_time_to_date_time(entry_meta.modified().unwrap())
                            .format("%Y-%m-%d %H:%M:%S").to_string();
                        let file_size = convert(entry_meta.len() as f64);
                        let file_type = entry_meta.file_type();
                        let link_style = if file_type.is_dir() {
                            "style=\"text-decoration: none; font-weight: bold;\"".to_owned()
                        } else {
                            "style=\"text-decoration: none;\"".to_owned()
                        };
                        let mut link = path_prefix.clone();
                        link.push(&file_name);
                        let link = link.join("/");
                        files.push(format!(
                            "
{}	 [{}]	 <bold>{}</bold>
",
                            link_style, link, file_name, file_modified, file_size
                        ));
                    }
                    resp = resp.set(format!(
                        "{}

{}
",
                        breadcrumb, files.join("\n")
                    ));
                } else {
                    resp.headers.set(headers::ContentDisposition {
                        disposition: headers::DispositionType::Attachment,
                        parameters: vec![headers::DispositionParam::Filename(
                            headers::Charset::Ext("utf-8".to_owned()), // The character set for the bytes of the filename
                            None, // The optional language tag (see `language-tag` crate)
                            path.file_name().unwrap().as_bytes().to_vec() // the actual bytes of the filename
                        )]
                    });
                    resp = resp.set(path);
                    let mime: iron::mime::Mime = "application/octet-stream".parse().unwrap();
                    resp.headers.set(headers::ContentType(mime));
                };
                Ok(resp)
            },
            Err(e) => {
                Ok(Response::with((status::NotFound, e.description().to_string())))
            }
        }
    }
}

impl AfterMiddleware for RequestLogger {
    fn after(&self, req: &mut Request, resp: Response) -> IronResult<Response> {
        println!(
            // datetime, remote-addr, status, method, url-path
            "[{}] - {} - {:?} - {} /{}",
            now_string(),
            req.remote_addr.ip(),
            resp.status.unwrap(),
            req.method,
            req.url.as_ref().to_string().splitn(4, '/').collect::<Vec<&str>>().pop().unwrap()
        );
        Ok(resp)
    }
}

fn now_string() -> String {
    Local::now().format("%Y-%m-%d %H:%M:%S").to_string()
}

fn system_time_to_date_time(t: SystemTime) -> DateTime<Local> {
    let (sec, nsec) = match t.duration_since(UNIX_EPOCH) {
        Ok(dur) => (dur.as_secs() as i64, dur.subsec_nanos()),
        Err(e) => { // unlikely but should be handled
            let dur = e.duration();
            let (sec, nsec) = (dur.as_secs() as i64, dur.subsec_nanos());
            if nsec == 0 {
                (-sec, 0)
            } else {
                (-sec - 1, 1_000_000_000 - nsec)
            }
        },
    };
    Local.timestamp(sec, nsec)
}
<|endoftext|>


<commit_before>extern crate ppbert;
#[macro_use] extern crate clap;

use std::io::{self, BufReader, Read};
use std::fs::File;
use std::process::exit;
use std::time::Instant;

use clap::{Arg, App};

use ppbert::bertterm::{self, BertTerm};
use ppbert::error::Result;
use ppbert::parser;

const DEFAULT_INDENT_WIDTH: &str = "2";
const DEFAULT_MAX_TERMS_PER_LINE: &str = "5";
const PROG_NAME: &str = "ppbert";

fn main() {
    let matches = App::new(PROG_NAME)
        .version(crate_version!())
        .author("Vincent Foley")
        .about("Pretty print structure encoded in Erlang's External Term Format")
        .arg(Arg::with_name("input_files")
             .value_name("FILES")
             .multiple(true))
        .arg(Arg::with_name("indent_width")
             .help("Indents with <num> spaces")
             .value_name("num")
             .short("i")
             .long("indent-width")
             .default_value(DEFAULT_INDENT_WIDTH)
             .takes_value(true))
        .arg(Arg::with_name("max_per_line")
             .help("Prints at most <num> basic terms per line")
             .value_name("num")
             .short("m")
             .long("max-terms-per-line")
             .default_value(DEFAULT_MAX_TERMS_PER_LINE)
             .takes_value(true))
        .arg(Arg::with_name("verbose")
             .help("Enables verbose mode")
             .short("v")
             .long("verbose"))
        .arg(Arg::with_name("parse")
             .help("Parses the input, doesn't pretty print it")
             .short("p")
             .long("parse"))
        .arg(Arg::with_name("bert2")
             .help("Parses .bert2 files")
             .conflicts_with("disk_log")
             .short("2")
             .long("bert2"))
        .arg(Arg::with_name("disk_log")
             .help("Parses disk_log files")
             .conflicts_with("bert2")
             .short("d")
             .long("disk-log"))
        .arg(Arg::with_name("json")
             .help("Outputs in JSON")
             .short("j")
             .long("json"))
        .arg(Arg::with_name("transform-proplists")
             .help("Transforms proplists into JSON objects (only valid with --json)")
             .long("transform-proplists"))
        .get_matches();

    let files: Vec<&str> = match matches.values_of("input_files") {
        Some(files) => files.collect(),
        None => vec!["-"]
    };
    let indent_level = value_t!(matches, "indent_width", usize).unwrap();
    let max_per_line = value_t!(matches, "max_per_line", usize).unwrap();
    let verbose = matches.is_present("verbose");
    let parse_only = matches.is_present("parse");
    let transform_proplists = matches.is_present("transform-proplists");

    let parse_fn =
        if matches.is_present("bert2") {
            parse_bert2
        } else if matches.is_present("disk_log") {
            parse_disk_log
        } else {
            parse_bert1
        };
    let output_fn =
        if matches.is_present("json") {
            if transform_proplists {
                bertterm::pp_json_proplist
            } else {
                bertterm::pp_json
            }
        } else {
            if transform_proplists {
                eprintln!("{}: warning: --transform-proplists is only valid with the --json flag",
                          PROG_NAME);
            }
            bertterm::pp_bert
        };

    let mut return_code = 0;
    for file in files {
        let res = handle_file(file, parse_only, verbose,
                              indent_level, max_per_line,
                              parse_fn, output_fn);
        match res {
            Ok(()) => (),
            Err(e) => {
                return_code = 1;
                eprintln!("{}: {}: {}", PROG_NAME, file, e);
            }
        }
    }
    exit(return_code);
}

fn handle_file<T>(
    file: &str,
    parse_only: bool,
    verbose: bool,
    indent: usize,
    terms_per_line: usize,
    parse_fn: fn(Vec<u8>) -> Result<T>,
    pp_fn: fn(T, usize, usize) -> ()
) -> Result<()> {

    // Read file or stdin into buffer
    let mut buf: Vec<u8> = Vec::new();
    let now = Instant::now();
    if file == "-" {
        let stdin = io::stdin();
        let mut stdin = stdin.lock();
        stdin.read_to_end(&mut buf)?;
    } else {
        let f = File::open(file)?;
        let mut rdr = BufReader::new(f);
        rdr.read_to_end(&mut buf)?;
    }
    let dur = now.elapsed();
    if verbose {
        eprintln!("{}: read time: {}.{:09}",
                  PROG_NAME, dur.as_secs(), dur.subsec_nanos());
    }

    // Parse input
    let now = Instant::now();
    let parse_output = parse_fn(buf)?;
    let dur = now.elapsed();

    if verbose {
        eprintln!("{}: parse time: {}.{:09}",
                  PROG_NAME, dur.as_secs(), dur.subsec_nanos());
    }

    // Early exit if parse-only
    if parse_only {
        return Ok(());
    }

    // Pretty print
    let now = Instant::now();
    pp_fn(parse_output, indent, terms_per_line);
    let dur = now.elapsed();

    if verbose {
        eprintln!("{}: print time: {}.{:09}",
                  PROG_NAME, dur.as_secs(), dur.subsec_nanos());
    }

    return Ok(());
}

fn parse_bert1(buf: Vec<u8>) -> Result<Vec<BertTerm>> {
    let mut parser = parser::Parser::new(buf);
    let term = parser.parse()?;
    return Ok(vec![term]);
}

fn parse_bert2(buf: Vec<u8>) -> Result<Vec<BertTerm>> {
    let mut parser = parser::Parser::new(buf);
    return parser.parse_bert2();
}

fn parse_disk_log(buf: Vec<u8>) -> Result<Vec<BertTerm>> {
    let mut parser = parser::Parser::new(buf);
    return parser.parse_disk_log();
}
<commit_msg>Use `fs::read()` instead of `BufReader::read_to_end()`<commit_after>extern crate ppbert;
#[macro_use] extern crate clap;

use std::io::{self, Read};
use std::fs;
use std::process::exit;
use std::time::Instant;

use clap::{Arg, App};

use ppbert::bertterm::{self, BertTerm};
use ppbert::error::Result;
use ppbert::parser;

const DEFAULT_INDENT_WIDTH: &str = "2";
const DEFAULT_MAX_TERMS_PER_LINE: &str = "5";
const PROG_NAME: &str = "ppbert";

fn main() {
    let matches = App::new(PROG_NAME)
        .version(crate_version!())
        .author("Vincent Foley")
        .about("Pretty print structure encoded in Erlang's External Term Format")
        .arg(Arg::with_name("input_files")
             .value_name("FILES")
             .multiple(true))
        .arg(Arg::with_name("indent_width")
             .help("Indents with <num> spaces")
             .value_name("num")
             .short("i")
             .long("indent-width")
             .default_value(DEFAULT_INDENT_WIDTH)
             .takes_value(true))
        .arg(Arg::with_name("max_per_line")
             .help("Prints at most <num> basic terms per line")
             .value_name("num")
             .short("m")
             .long("max-terms-per-line")
             .default_value(DEFAULT_MAX_TERMS_PER_LINE)
             .takes_value(true))
        .arg(Arg::with_name("verbose")
             .help("Enables verbose mode")
             .short("v")
             .long("verbose"))
        .arg(Arg::with_name("parse")
             .help("Parses the input, doesn't pretty print it")
             .short("p")
             .long("parse"))
        .arg(Arg::with_name("bert2")
             .help("Parses .bert2 files")
             .conflicts_with("disk_log")
             .short("2")
             .long("bert2"))
        .arg(Arg::with_name("disk_log")
             .help("Parses disk_log files")
             .conflicts_with("bert2")
             .short("d")
             .long("disk-log"))
        .arg(Arg::with_name("json")
             .help("Outputs in JSON")
             .short("j")
             .long("json"))
        .arg(Arg::with_name("transform-proplists")
             .help("Transforms proplists into JSON objects (only valid with --json)")
             .long("transform-proplists"))
        .get_matches();

    let files: Vec<&str> = match matches.values_of("input_files") {
        Some(files) => files.collect(),
        None => vec!["-"]
    };
    let indent_level = value_t!(matches, "indent_width", usize).unwrap();
    let max_per_line = value_t!(matches, "max_per_line", usize).unwrap();
    let verbose = matches.is_present("verbose");
    let parse_only = matches.is_present("parse");
    let transform_proplists = matches.is_present("transform-proplists");

    let parse_fn =
        if matches.is_present("bert2") {
            parse_bert2
        } else if matches.is_present("disk_log") {
            parse_disk_log
        } else {
            parse_bert1
        };
    let output_fn =
        if matches.is_present("json") {
            if transform_proplists {
                bertterm::pp_json_proplist
            } else {
                bertterm::pp_json
            }
        } else {
            if transform_proplists {
                eprintln!("{}: warning: --transform-proplists is only valid with the --json flag",
                          PROG_NAME);
            }
            bertterm::pp_bert
        };

    let mut return_code = 0;
    for file in files {
        let res = handle_file(file, parse_only, verbose,
                              indent_level, max_per_line,
                              parse_fn, output_fn);
        match res {
            Ok(()) => (),
            Err(e) => {
                return_code = 1;
                eprintln!("{}: {}: {}", PROG_NAME, file, e);
            }
        }
    }
    exit(return_code);
}

fn handle_file<T>(
    file: &str,
    parse_only: bool,
    verbose: bool,
    indent: usize,
    terms_per_line: usize,
    parse_fn: fn(Vec<u8>) -> Result<T>,
    pp_fn: fn(T, usize, usize) -> ()
) -> Result<()> {

    // Read file or stdin into buffer
    let now = Instant::now();
    let buf = if file == "-" {
        let stdin = io::stdin();
        let mut stdin = stdin.lock();
        let mut buf: Vec<u8> = Vec::with_capacity(4096);
        stdin.read_to_end(&mut buf)?;
        buf
    } else {
        fs::read(file)?
    };
    let dur = now.elapsed();
    if verbose {
        eprintln!("{}: read time: {}.{:09}",
                  PROG_NAME, dur.as_secs(), dur.subsec_nanos());
    }

    // Parse input
    let now = Instant::now();
    let parse_output = parse_fn(buf)?;
    let dur = now.elapsed();

    if verbose {
        eprintln!("{}: parse time: {}.{:09}",
                  PROG_NAME, dur.as_secs(), dur.subsec_nanos());
    }

    // Early exit if parse-only
    if parse_only {
        return Ok(());
    }

    // Pretty print
    let now = Instant::now();
    pp_fn(parse_output, indent, terms_per_line);
    let dur = now.elapsed();

    if verbose {
        eprintln!("{}: print time: {}.{:09}",
                  PROG_NAME, dur.as_secs(), dur.subsec_nanos());
    }

    return Ok(());
}

fn parse_bert1(buf: Vec<u8>) -> Result<Vec<BertTerm>> {
    let mut parser = parser::Parser::new(buf);
    let term = parser.parse()?;
    return Ok(vec![term]);
}

fn parse_bert2(buf: Vec<u8>) -> Result<Vec<BertTerm>> {
    let mut parser = parser::Parser::new(buf);
    return parser.parse_bert2();
}

fn parse_disk_log(buf: Vec<u8>) -> Result<Vec<BertTerm>> {
    let mut parser = parser::Parser::new(buf);
    return parser.parse_disk_log();
}
<|endoftext|>