<commit_before>/*!
These are some docs.
*/

#![allow(deprecated)] // for connect -> join rename

extern crate byteorder;
extern crate chan;
extern crate csv;
extern crate docopt;
extern crate filetime;
extern crate num_cpus;
extern crate rand;
extern crate regex;
extern crate rustc_serialize;
extern crate stats;
extern crate tabwriter;
extern crate threadpool;

use std::borrow::ToOwned;
use std::env;
use std::fmt;
use std::io;
use std::process;

use docopt::Docopt;

macro_rules! wout {
    ($($arg:tt)*) => ({
        use std::io::Write;
        (writeln!(&mut ::std::io::stdout(), $($arg)*)).unwrap();
    });
}

macro_rules! werr {
    ($($arg:tt)*) => ({
        use std::io::Write;
        (writeln!(&mut ::std::io::stderr(), $($arg)*)).unwrap();
    });
}

macro_rules! fail {
    ($e:expr) => (Err(::std::convert::From::from($e)));
}

macro_rules! command_list {
    () => (
"
    cat         Concatenate by row or column
    count       Count records
    fixlengths  Makes all records have same length
    flatten     Show one field per line
    fmt         Format CSV output (change field delimiter)
    frequency   Show frequency tables
    headers     Show header names
    help        Show this usage message.
    index       Create CSV index for faster access
    input       Read CSV data with special quoting rules
    join        Join CSV files
    sample      Randomly sample CSV data
    search      Search CSV data with regexes
    select      Select columns from CSV
    slice       Slice records from CSV
    sort        Sort CSV data
    split       Split CSV data into many files
    stats       Compute basic statistics
    table       Align CSV data into columns
"
    )
}

mod cmd;
mod config;
mod select;
mod util;

static USAGE: &'static str = concat!("
Usage:
    xsv <command> [<args>...]
    xsv [options]

Options:
    --list        List all commands available.
    -h, --help    Display this message
    --version     Print version info and exit

Commands:", command_list!());

#[derive(RustcDecodable)]
struct Args {
    arg_command: Option<Command>,
    flag_list: bool,
}

fn main() {
    let args: Args = Docopt::new(USAGE)
                            .and_then(|d| d.options_first(true)
                                           .version(Some(util::version()))
                                           .decode())
                            .unwrap_or_else(|e| e.exit());
    if args.flag_list {
        wout!(concat!("Installed commands:", command_list!()));
        return;
    }
    match args.arg_command {
        None => {
            werr!(concat!(
                "xsv is a suite of CSV command line utilities.

Please choose one of the following commands:",
                command_list!()));
            process::exit(0);
        }
        Some(cmd) => {
            match cmd.run() {
                Ok(()) => process::exit(0),
                Err(CliError::Flag(err)) => err.exit(),
                Err(CliError::Csv(err)) => {
                    werr!("{}", err);
                    process::exit(1);
                }
                Err(CliError::Io(ref err))
                        if err.kind() == io::ErrorKind::BrokenPipe => {
                    process::exit(0);
                }
                Err(CliError::Io(err)) => {
                    werr!("{}", err);
                    process::exit(1);
                }
                Err(CliError::Other(msg)) => {
                    werr!("{}", msg);
                    process::exit(1);
                }
            }
        }
    }
}

#[derive(Debug, RustcDecodable)]
enum Command {
    Cat,
    Count,
    FixLengths,
    Flatten,
    Fmt,
    Frequency,
    Headers,
    Help,
    Index,
    Input,
    Join,
    Sample,
    Search,
    Select,
    Slice,
    Sort,
    Split,
    Stats,
    Table,
}

impl Command {
    fn run(self) -> CliResult<()> {
        let argv: Vec<_> = env::args().map(|v| v.to_owned()).collect();
        let argv: Vec<_> = argv.iter().map(|s| &**s).collect();
        let argv = &*argv;
        match self {
            Command::Cat => cmd::cat::run(argv),
            Command::Count => cmd::count::run(argv),
            Command::FixLengths => cmd::fixlengths::run(argv),
            Command::Flatten => cmd::flatten::run(argv),
            Command::Fmt => cmd::fmt::run(argv),
            Command::Frequency => cmd::frequency::run(argv),
            Command::Headers => cmd::headers::run(argv),
            Command::Help => { wout!("{}", USAGE); Ok(()) }
            Command::Index => cmd::index::run(argv),
            Command::Input => cmd::input::run(argv),
            Command::Join => cmd::join::run(argv),
            Command::Sample => cmd::sample::run(argv),
            Command::Search => cmd::search::run(argv),
            Command::Select => cmd::select::run(argv),
            Command::Slice => cmd::slice::run(argv),
            Command::Sort => cmd::sort::run(argv),
            Command::Split => cmd::split::run(argv),
            Command::Stats => cmd::stats::run(argv),
            Command::Table => cmd::table::run(argv),
        }
    }
}

pub type CliResult<T> = Result<T, CliError>;

#[derive(Debug)]
pub enum CliError {
    Flag(docopt::Error),
    Csv(csv::Error),
    Io(io::Error),
    Other(String),
}

impl fmt::Display for CliError {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        match *self {
            CliError::Flag(ref e) => { e.fmt(f) }
            CliError::Csv(ref e) => { e.fmt(f) }
            CliError::Io(ref e) => { e.fmt(f) }
            CliError::Other(ref s) => { f.write_str(&**s) }
        }
    }
}

impl From<docopt::Error> for CliError {
    fn from(err: docopt::Error) -> CliError {
        CliError::Flag(err)
    }
}

impl From<csv::Error> for CliError {
    fn from(err: csv::Error) -> CliError {
        match err {
            csv::Error::Io(v) => From::from(v),
            v => CliError::Csv(v),
        }
    }
}

impl From<io::Error> for CliError {
    fn from(err: io::Error) -> CliError {
        CliError::Io(err)
    }
}

impl From<String> for CliError {
    fn from(err: String) -> CliError {
        CliError::Other(err)
    }
}

impl<'a> From<&'a str> for CliError {
    fn from(err: &'a str) -> CliError {
        CliError::Other(err.to_owned())
    }
}

impl From<regex::Error> for CliError {
    fn from(err: regex::Error) -> CliError {
        CliError::Other(format!("{:?}", err))
    }
}
<commit_msg>Add help message for "<command> -h"<commit_after>/*!
These are some docs.
*/

#![allow(deprecated)] // for connect -> join rename

extern crate byteorder;
extern crate chan;
extern crate csv;
extern crate docopt;
extern crate filetime;
extern crate num_cpus;
extern crate rand;
extern crate regex;
extern crate rustc_serialize;
extern crate stats;
extern crate tabwriter;
extern crate threadpool;

use std::borrow::ToOwned;
use std::env;
use std::fmt;
use std::io;
use std::process;

use docopt::Docopt;

macro_rules! wout {
    ($($arg:tt)*) => ({
        use std::io::Write;
        (writeln!(&mut ::std::io::stdout(), $($arg)*)).unwrap();
    });
}

macro_rules! werr {
    ($($arg:tt)*) => ({
        use std::io::Write;
        (writeln!(&mut ::std::io::stderr(), $($arg)*)).unwrap();
    });
}

macro_rules! fail {
    ($e:expr) => (Err(::std::convert::From::from($e)));
}

macro_rules! command_list {
    () => (
"
    cat         Concatenate by row or column
    count       Count records
    fixlengths  Makes all records have same length
    flatten     Show one field per line
    fmt         Format CSV output (change field delimiter)
    frequency   Show frequency tables
    headers     Show header names
    help        Show this usage message.
    index       Create CSV index for faster access
    input       Read CSV data with special quoting rules
    join        Join CSV files
    sample      Randomly sample CSV data
    search      Search CSV data with regexes
    select      Select columns from CSV
    slice       Slice records from CSV
    sort        Sort CSV data
    split       Split CSV data into many files
    stats       Compute basic statistics
    table       Align CSV data into columns
"
    )
}

mod cmd;
mod config;
mod select;
mod util;

static USAGE: &'static str = concat!("
Usage:
    xsv <command> [<args>...]
    xsv [options]

Options:
    --list        List all commands available.
    -h, --help    Display this message
    <command> -h  Display the command help message
    --version     Print version info and exit

Commands:", command_list!());

#[derive(RustcDecodable)]
struct Args {
    arg_command: Option<Command>,
    flag_list: bool,
}

fn main() {
    let args: Args = Docopt::new(USAGE)
                            .and_then(|d| d.options_first(true)
                                           .version(Some(util::version()))
                                           .decode())
                            .unwrap_or_else(|e| e.exit());
    if args.flag_list {
        wout!(concat!("Installed commands:", command_list!()));
        return;
    }
    match args.arg_command {
        None => {
            werr!(concat!(
                "xsv is a suite of CSV command line utilities.

Please choose one of the following commands:",
                command_list!()));
            process::exit(0);
        }
        Some(cmd) => {
            match cmd.run() {
                Ok(()) => process::exit(0),
                Err(CliError::Flag(err)) => err.exit(),
                Err(CliError::Csv(err)) => {
                    werr!("{}", err);
                    process::exit(1);
                }
                Err(CliError::Io(ref err))
                        if err.kind() == io::ErrorKind::BrokenPipe => {
                    process::exit(0);
                }
                Err(CliError::Io(err)) => {
                    werr!("{}", err);
                    process::exit(1);
                }
                Err(CliError::Other(msg)) => {
                    werr!("{}", msg);
                    process::exit(1);
                }
            }
        }
    }
}

#[derive(Debug, RustcDecodable)]
enum Command {
    Cat,
    Count,
    FixLengths,
    Flatten,
    Fmt,
    Frequency,
    Headers,
    Help,
    Index,
    Input,
    Join,
    Sample,
    Search,
    Select,
    Slice,
    Sort,
    Split,
    Stats,
    Table,
}

impl Command {
    fn run(self) -> CliResult<()> {
        let argv: Vec<_> = env::args().map(|v| v.to_owned()).collect();
        let argv: Vec<_> = argv.iter().map(|s| &**s).collect();
        let argv = &*argv;
        match self {
            Command::Cat => cmd::cat::run(argv),
            Command::Count => cmd::count::run(argv),
            Command::FixLengths => cmd::fixlengths::run(argv),
            Command::Flatten => cmd::flatten::run(argv),
            Command::Fmt => cmd::fmt::run(argv),
            Command::Frequency => cmd::frequency::run(argv),
            Command::Headers => cmd::headers::run(argv),
            Command::Help => { wout!("{}", USAGE); Ok(()) }
            Command::Index => cmd::index::run(argv),
            Command::Input => cmd::input::run(argv),
            Command::Join => cmd::join::run(argv),
            Command::Sample => cmd::sample::run(argv),
            Command::Search => cmd::search::run(argv),
            Command::Select => cmd::select::run(argv),
            Command::Slice => cmd::slice::run(argv),
            Command::Sort => cmd::sort::run(argv),
            Command::Split => cmd::split::run(argv),
            Command::Stats => cmd::stats::run(argv),
            Command::Table => cmd::table::run(argv),
        }
    }
}

pub type CliResult<T> = Result<T, CliError>;

#[derive(Debug)]
pub enum CliError {
    Flag(docopt::Error),
    Csv(csv::Error),
    Io(io::Error),
    Other(String),
}

impl fmt::Display for CliError {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        match *self {
            CliError::Flag(ref e) => { e.fmt(f) }
            CliError::Csv(ref e) => { e.fmt(f) }
            CliError::Io(ref e) => { e.fmt(f) }
            CliError::Other(ref s) => { f.write_str(&**s) }
        }
    }
}

impl From<docopt::Error> for CliError {
    fn from(err: docopt::Error) -> CliError {
        CliError::Flag(err)
    }
}

impl From<csv::Error> for CliError {
    fn from(err: csv::Error) -> CliError {
        match err {
            csv::Error::Io(v) => From::from(v),
            v => CliError::Csv(v),
        }
    }
}

impl From<io::Error> for CliError {
    fn from(err: io::Error) -> CliError {
        CliError::Io(err)
    }
}

impl From<String> for CliError {
    fn from(err: String) -> CliError {
        CliError::Other(err)
    }
}

impl<'a> From<&'a str> for CliError {
    fn from(err: &'a str) -> CliError {
        CliError::Other(err.to_owned())
    }
}

impl From<regex::Error> for CliError {
    fn from(err: regex::Error) -> CliError {
        CliError::Other(format!("{:?}", err))
    }
}
<|endoftext|>


<commit_before>extern crate rand;

use std::string::String;
use std::collections::HashMap;
use std::vec::Vec;
use std::fs::{File};
use std::env;
use std::path::{Path};
use std::io::{self, BufReader, BufRead};

use rand::{random, Closed01, Rng};
use rand::distributions::{IndependentSample, Range, Sample, Gamma};

type Bag = HashMap<usize, usize>;

fn load_bags<P: AsRef<Path>>(path: P) -> io::Result<(Vec<usize>, Vec<Bag>)> {
    let mut bags = Vec::new();
    let mut labels = Vec::new();
    let file = try!(File::open(path));
    let file = BufReader::new(file);
    for line in file.lines() {
        let line = line.unwrap();
        let mut iter = line.split_whitespace();
        let label = iter.next().unwrap().parse::<usize>().unwrap();
        let mut bag = Bag::new();
        for elm in iter {
            let mut iter = elm.split(':');
            let index = iter.next().unwrap().parse::<usize>().unwrap();
            let value = iter.next().unwrap().parse::<usize>().unwrap();
            bag.insert(index - 1, value);
        }
        labels.push(label);
        bags.push(bag);
    }
    Ok((labels, bags))
}

fn load_text_vocabulary<P: AsRef<Path>>(path: P) -> io::Result<Vec<String>> {
    let mut vocab = Vec::new();
    let file = try!(File::open(path));
    let file = BufReader::new(file);
    for line in file.lines() {
        let line = line.unwrap();
        vocab.push(line);
    }
    Ok(vocab)
}

#[derive(Clone)]
struct Categorical {
    prop: Vec<f64>,
}

impl Categorical {
    fn new(weights: Vec<f64>) -> Categorical {
        let sum: f64 = weights.iter().sum();
        let prop: Vec<f64> = weights.iter().map(|w| w / sum).collect();
        Categorical {
            prop: prop,
        }
    }
}

impl Sample<usize> for Categorical {
    fn sample<R: Rng>(&mut self, rng: &mut R) -> usize {
        self.ind_sample(rng)
    }
}

impl IndependentSample<usize> for Categorical {
    fn ind_sample<R: Rng>(&self, rng: &mut R) -> usize {
        let Closed01(x) = random::<Closed01<f64>>();

        let mut sum = 0.0;
        let mut ret = self.prop.len() - 1;
        for (k, &p) in self.prop.iter().enumerate() {
            sum += p;
            if x <= sum {
                ret = k;
            }
        }
        ret
    }
}

#[derive(Clone)]
struct Dirichlet {
    alpha: Vec<f64>,
}

impl Dirichlet {
    fn new(alpha: Vec<f64>) -> Dirichlet {
        Dirichlet {
            alpha: alpha,
        }
    }
}

impl Sample<Vec<f64>> for Dirichlet {
    fn sample<R: Rng>(&mut self, rng: &mut R) -> Vec<f64> {
        self.ind_sample(rng)
    }
}

impl IndependentSample<Vec<f64>> for Dirichlet {
    fn ind_sample<R: Rng>(&self, rng: &mut R) -> Vec<f64> {
        let mut sum = 0.0;
        let mut xs = Vec::new();
        for &a in &self.alpha {
            let gamma = Gamma::new(a, 1.0);
            let y = gamma.ind_sample(rng);
            xs.push(y);
            sum += y;
        }
        for x in xs.iter_mut() {
            *x /= sum;
        }
        xs
    }
}

fn lda(num_topics: usize, dataset: Vec<Bag>, alpha: Vec<f64>, beta: Vec<f64>, num_samples: usize) {
    // Initialization
    let mut rng = rand::thread_rng();
    let topics = Range::new(0, num_topics);

    let vocab_size: usize = {
        let mut have_some = false;
        let mut max_index = 0;
        for bag in &dataset {
            for &index in bag.keys() {
                have_some = true;
                if index > max_index {
                    max_index = index;
                }
            }
        }
        if have_some {
            max_index + 1
        }
        else {
            0
        }
    };
    println!("K = {}", num_topics);
    println!("M = {}", &dataset.len());
    println!("V = {}", vocab_size);

    let mut w: Vec<Vec<usize>> = Vec::new();
    let mut z: Vec<Vec<usize>> = Vec::new();
    let mut theta: Vec<Vec<f64>> = Vec::new();
    let mut ndk: Vec<Vec<usize>> = Vec::new();
    for bag in &dataset {
        // w
        let mut w_d = Vec::new();
        for (&index, &count) in bag {
            for _ in 0..count {
                w_d.push(index);
            }
        }
        w.push(w_d);
        // z
        let mut z_d = Vec::new();
        for &count in bag.values() {
            for _ in 0..count {
                z_d.push(0);
            }
        }
        let n_d = z_d.len();
        z.push(z_d);
        // theta
        let mut theta_d = Vec::with_capacity(num_topics);
        for _k in 0..num_topics {
            theta_d.push(1.0 / num_topics as f64);
        }
        theta.push(theta_d);
        // ndk
        let mut ndk_d = Vec::with_capacity(num_topics);
        ndk_d.push(n_d);
        for _k in 1..num_topics {
            ndk_d.push(0);
        }
        ndk.push(ndk_d);
    }
    println!("z = {:?}", z);
    println!("theta = {:?}", theta);
    println!("ndk = {:?}", ndk);

    let mut phi: Vec<Vec<f64>> = Vec::new();
    let mut nkv: Vec<Vec<usize>> = Vec::new();
    // phi
    for _k in 0..num_topics {
        let mut phi_k = Vec::new();
        for _v in 0..vocab_size {
            phi_k.push(1.0 / vocab_size as f64);
        }
        phi.push(phi_k);
    }
    // nkv
    let mut nkv_0 = Vec::new();
    for _v in 0..vocab_size {
        nkv_0.push(0);
    }
    for bag in &dataset {
        for (&index, &count) in bag {
            nkv_0[index] += count;
        }
    }
    nkv.push(nkv_0);
    for _k in 1..num_topics {
        let mut nkv_k = Vec::new();
        for _v in 0..vocab_size {
            nkv_k.push(0);
        }
        nkv.push(nkv_k);
    }
    println!("phi = {:?}", phi);
    println!("nkv = {:?}", nkv);

    // Sampling
    for s in 0..num_samples {
        for (d, w_d) in w.iter().enumerate() {
            for (i, &w_di) in w_d.iter().enumerate() {
                let v = w_di;
                // Sample z_di
                let mut weights: Vec<f64> = Vec::new();
                for k in 0..num_topics {
                    weights.push(theta[d][k] * phi[k][v]);
                }
                let cat = Categorical::new(weights);
                z[d][i] = cat.ind_sample(&mut rand::thread_rng());
            }
        }
    }
}

fn main() {
    let args: Vec<String> = env::args().collect();
    let (labels, dataset) = load_bags(&args[1]).unwrap();
    let vocab: Option<Vec<String>> = if args.len() < 3 {
        None
    }
    else {
        Some(load_text_vocabulary(&args[2]).unwrap())
    };
    println!("{:?}", labels);
    println!("{:?}", dataset);
    println!("{:?}", vocab);

    lda(3, dataset, vec![1.0, 1.0, 1.0], vec![1.0, 1.0, 1.0], 100);
}
<commit_msg>Fix the dimension of beta<commit_after>extern crate rand;

use std::string::String;
use std::collections::HashMap;
use std::vec::Vec;
use std::fs::{File};
use std::env;
use std::path::{Path};
use std::io::{self, BufReader, BufRead};

use rand::{random, Closed01, Rng};
use rand::distributions::{IndependentSample, Range, Sample, Gamma};

type Bag = HashMap<usize, usize>;

fn load_bags<P: AsRef<Path>>(path: P) -> io::Result<(Vec<usize>, Vec<Bag>)> {
    let mut bags = Vec::new();
    let mut labels = Vec::new();
    let file = try!(File::open(path));
    let file = BufReader::new(file);
    for line in file.lines() {
        let line = line.unwrap();
        let mut iter = line.split_whitespace();
        let label = iter.next().unwrap().parse::<usize>().unwrap();
        let mut bag = Bag::new();
        for elm in iter {
            let mut iter = elm.split(':');
            let index = iter.next().unwrap().parse::<usize>().unwrap();
            let value = iter.next().unwrap().parse::<usize>().unwrap();
            bag.insert(index - 1, value);
        }
        labels.push(label);
        bags.push(bag);
    }
    Ok((labels, bags))
}

fn load_text_vocabulary<P: AsRef<Path>>(path: P) -> io::Result<Vec<String>> {
    let mut vocab = Vec::new();
    let file = try!(File::open(path));
    let file = BufReader::new(file);
    for line in file.lines() {
        let line = line.unwrap();
        vocab.push(line);
    }
    Ok(vocab)
}

#[derive(Clone)]
struct Categorical {
    prop: Vec<f64>,
}

impl Categorical {
    fn new(weights: Vec<f64>) -> Categorical {
        let sum: f64 = weights.iter().sum();
        let prop: Vec<f64> = weights.iter().map(|w| w / sum).collect();
        Categorical {
            prop: prop,
        }
    }
}

impl Sample<usize> for Categorical {
    fn sample<R: Rng>(&mut self, rng: &mut R) -> usize {
        self.ind_sample(rng)
    }
}

impl IndependentSample<usize> for Categorical {
    fn ind_sample<R: Rng>(&self, rng: &mut R) -> usize {
        let Closed01(x) = random::<Closed01<f64>>();

        let mut sum = 0.0;
        let mut ret = self.prop.len() - 1;
        for (k, &p) in self.prop.iter().enumerate() {
            sum += p;
            if x <= sum {
                ret = k;
            }
        }
        ret
    }
}

#[derive(Clone)]
struct Dirichlet {
    alpha: Vec<f64>,
}

impl Dirichlet {
    fn new(alpha: Vec<f64>) -> Dirichlet {
        Dirichlet {
            alpha: alpha,
        }
    }
}

impl Sample<Vec<f64>> for Dirichlet {
    fn sample<R: Rng>(&mut self, rng: &mut R) -> Vec<f64> {
        self.ind_sample(rng)
    }
}

impl IndependentSample<Vec<f64>> for Dirichlet {
    fn ind_sample<R: Rng>(&self, rng: &mut R) -> Vec<f64> {
        let mut sum = 0.0;
        let mut xs = Vec::new();
        for &a in &self.alpha {
            let gamma = Gamma::new(a, 1.0);
            let y = gamma.ind_sample(rng);
            xs.push(y);
            sum += y;
        }
        for x in xs.iter_mut() {
            *x /= sum;
        }
        xs
    }
}

fn lda(num_topics: usize, dataset: Vec<Bag>, alpha: Vec<f64>, beta: Vec<f64>, num_samples: usize) {
    // Initialization
    let mut rng = rand::thread_rng();
    let topics = Range::new(0, num_topics);

    let vocab_size: usize = {
        let mut have_some = false;
        let mut max_index = 0;
        for bag in &dataset {
            for &index in bag.keys() {
                have_some = true;
                if index > max_index {
                    max_index = index;
                }
            }
        }
        if have_some {
            max_index + 1
        }
        else {
            0
        }
    };
    println!("K = {}", num_topics);
    println!("M = {}", &dataset.len());
    println!("V = {}", vocab_size);

    let mut w: Vec<Vec<usize>> = Vec::new();
    let mut z: Vec<Vec<usize>> = Vec::new();
    let mut theta: Vec<Vec<f64>> = Vec::new();
    let mut ndk: Vec<Vec<usize>> = Vec::new();
    for bag in &dataset {
        // w
        let mut w_d = Vec::new();
        for (&index, &count) in bag {
            for _ in 0..count {
                w_d.push(index);
            }
        }
        w.push(w_d);
        // z
        let mut z_d = Vec::new();
        for &count in bag.values() {
            for _ in 0..count {
                z_d.push(0);
            }
        }
        let n_d = z_d.len();
        z.push(z_d);
        // theta
        let mut theta_d = Vec::with_capacity(num_topics);
        for _k in 0..num_topics {
            theta_d.push(1.0 / num_topics as f64);
        }
        theta.push(theta_d);
        // ndk
        let mut ndk_d = Vec::with_capacity(num_topics);
        ndk_d.push(n_d);
        for _k in 1..num_topics {
            ndk_d.push(0);
        }
        ndk.push(ndk_d);
    }
    println!("z = {:?}", z);
    println!("theta = {:?}", theta);
    println!("ndk = {:?}", ndk);

    let mut phi: Vec<Vec<f64>> = Vec::new();
    let mut nkv: Vec<Vec<usize>> = Vec::new();
    // phi
    for _k in 0..num_topics {
        let mut phi_k = Vec::new();
        for _v in 0..vocab_size {
            phi_k.push(1.0 / vocab_size as f64);
        }
        phi.push(phi_k);
    }
    // nkv
    let mut nkv_0 = Vec::new();
    for _v in 0..vocab_size {
        nkv_0.push(0);
    }
    for bag in &dataset {
        for (&index, &count) in bag {
            nkv_0[index] += count;
        }
    }
    nkv.push(nkv_0);
    for _k in 1..num_topics {
        let mut nkv_k = Vec::new();
        for _v in 0..vocab_size {
            nkv_k.push(0);
        }
        nkv.push(nkv_k);
    }
    println!("phi = {:?}", phi);
    println!("nkv = {:?}", nkv);

    // Sampling
    for s in 0..num_samples {
        for (d, w_d) in w.iter().enumerate() {
            for (i, &w_di) in w_d.iter().enumerate() {
                let v = w_di;
                // Sample z_di
                let mut weights: Vec<f64> = Vec::new();
                for k in 0..num_topics {
                    weights.push(theta[d][k] * phi[k][v]);
                }
                let cat = Categorical::new(weights);
                z[d][i] = cat.ind_sample(&mut rand::thread_rng());
            }
        }
    }
}

fn main() {
    let args: Vec<String> = env::args().collect();
    let (labels, dataset) = load_bags(&args[1]).unwrap();
    let vocab: Option<Vec<String>> = if args.len() < 3 {
        None
    }
    else {
        Some(load_text_vocabulary(&args[2]).unwrap())
    };
    println!("{:?}", labels);
    println!("{:?}", dataset);
    println!("{:?}", vocab);

    lda(3, dataset, vec![1.0, 1.0, 1.0], vec![1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0], 100);
}
<|endoftext|>


<commit_before>use std::f64::consts;
use std::vec::Vec;
use std::fs::File;
use std::path::Path;
use std::error::Error;
use std::io::{Read, Write};

const LENGTH: f64 = 2.0*consts::PI; //length of PIC box
const NG: i32 = 64; //number of zones for mesh
const MASS: i32 = 1; //mass of each particle
const CHARGE: i32 = -1; //charge of each particle
const V_STREAM: f64 = 4.0; //initial velocity of each stream, this number will turned into positive and negative!

fn main() {
	let particle_loading: i32 = 4; //particle loading
	let np: i32 = particle_loading*NG; //number of particles
	let k: i32 = 1; //used for the peturbation of the sin wave
	let dt: f64 = LENGTH/(NG as f64)/(4.0); //timestep
	let delta_x: f64 = LENGTH/(np as f64); //L/np, or the delta x of the lattice
	let t_max: f64 = 16 as f64*consts::PI/((2 as f64*(np as f64)/LENGTH).sqrt()); //maximum time
	let mut velocity: Vec<f64> = Vec::new(); //velocities of each particle, index is
	let mut x_position: Vec<f64> = Vec::new(); //x-position of each particle

	//seed the initial positions and velocities
	for i in 0..(np*2) {
		if i < np {
			x_position.push(i as f64*LENGTH/np as f64);
			velocity.push(-V_STREAM);
		}
		else {
			x_position.push((i-np) as f64*LENGTH/np as f64);
			velocity.push(V_STREAM);
		}
		//rust only accepts usize for indexes, sanity check
		// println!("x: {}, v: {}", x_position[i as usize], velocity[i as usize]);
	}

	//peturb the x positions
	perturb(&mut x_position, k);

	let mut rho: Vec<f64> = vec![0.0; NG as usize]; //mesh densities
	let mut phi: Vec<f64> = vec![0.0; NG as usize]; //vector of phi's to solve for the poisson
	let mut electric_mesh: Vec<f64> = vec![0.0; NG as usize]; //vector of electric field from potential

	let solnSize = np*2;
	let mut solution: Vec<f64> = vec![0.0; solnSize as usize];
	catch(&x_position, &velocity, &mut solution, np);
	let timestep = (t_max/delta_x).ceil() as u32;

	for k in 0..timestep {
		//unload from the solution
		release(&mut x_position, &mut velocity, &solution, np);
		write_out(&x_position, &velocity, &rho, k);
		//find the particle number density
		density(&mut rho, &mut x_position, np);
		//solve the poisson equation
		poisson1d(&mut phi, &mut rho);
		//find the mesh
		electric_field(&mut phi, &mut electric_mesh);
		for i in 0..x_position.len() {
			let idx = i as usize;

		}

	}
}

//evaluates the particle number density using CIC weight.
//Each mesh loops through all the particles to add in their contribution, calculates the electron density for that mesh block alone.
fn density(rho: &mut Vec<f64>, x_position: & Vec<f64>, np: i32) {
	for rho_i in 0..rho.len() {
		let mut sum: f64 = 0.0;
		for x_p in 0..np*2 {
			sum += (MASS as f64)*cic_weight(rho_i as f64 - x_position[x_p as usize], np);
		}
		// println!("rho_i is {}", rho_i);
		rho[rho_i as usize] = 1.0/(LENGTH/NG as f64)*sum;
	}
}

//Cloud in Cell weighting
//			  { 1 + x/deltaX for -deltaX < x
// W_cic(X) = | 1 - x/deltaX for x < deltaX
//			  } 0 otherwise
fn cic_weight(x: f64, np: i32) -> f64{
	let delta_x: f64 = LENGTH/(np as f64);
	if x > -delta_x {
		return 1.0 + x/delta_x;
	}
	else if x < delta_x {
		return 1.0 - x/delta_x;
	}
	else {
		return 0.0;
	}
}

//solves the 1D poisson equation using the Gauss-Seidel relaxation
fn poisson1d<'a>(phi: &'a mut Vec<f64>, rho: &Vec<f64>) {
	let dx_g: f64 = LENGTH as f64/NG as f64;
	let error_tolerance: f64 = 0.000001; //10^-6
	let source = source_l2_norm(&rho, dx_g);
	let mut residual = residual_l2_norm(&rho, &phi, dx_g);
	// println!("R: {}, eS: {}", residual, error_tolerance*source);
	while residual > error_tolerance*source {
		// println!("R: {}, eS: {}", residual, error_tolerance*source);
		for i in 0..NG-1 {
			// rust uses C-like functions, so % is remainder (don't go negative!)

			let im: i32 = ((i - 1 + NG) % NG);
			let ip: i32 = ((i + 1) % NG);

			println!("Old Phi: {}", phi[i as usize]);
			//println!("New Phi: {}", 0.5*(phi[im as usize] + phi[ip as usize]) + dx_g.powi(2)/2.0*rho[i as usize]);
			// println!("i: {}, ng: {}, im: {}, ip: {}", i, NG, im, ip);
			phi[i as usize] = 0.5*(phi[im as usize] + phi[ip as usize]) + dx_g.powi(2)/2.0*rho[i as usize];
			println!("New Phi: {}", phi[i as usize]);
		}
		residual = residual_l2_norm(&rho, &phi, dx_g);
	}
}

//calculates the L2Norm for the source
//probably don't want to call this outside of the poisson solver?
fn source_l2_norm(rho: &Vec<f64>, dx_g: f64) -> f64 {
	let mut source: f64 = 0.0;
	//sum the entire array
	for i in 0..rho.len() {
		source += rho[i as usize].powi(2);
	}
	//divide it by 1/Ng
	source /= dx_g;
	//then square root it
	source = source.sqrt();
	return source;
}

//calculates the L2Norm for the residual
fn residual_l2_norm(rho: &Vec<f64>, phi: &Vec<f64>, dx_g: f64) -> f64 {
	let mut residual: f64 = 0.0;
	for i in 0..rho.len() {
		residual += rho[i as usize];
		if i == 0 {
			residual += (phi[i+1 as usize] - 2.0*phi[i as usize] + phi[(rho.len()-1) as usize])/dx_g.powi(2);
		}
		else if i+1 == rho.len() as usize {
			residual += (phi[0] - 2.0*phi[i as usize] + phi[(i-1) as usize])/dx_g.powi(2);
		}
		else {
			residual += (phi[(i+1 as usize)] - 2.0*phi[i as usize] + phi[(i-1) as usize])/dx_g.powi(2);
		}
	}
	residual /= dx_g;
	residual = residual.sqrt();

	return residual;
}

//calculates the electric field from potential, where
//E is the potential
//uses the second order finite difference
fn electric_field (phi: &mut Vec<f64>, electric_mesh: & mut Vec<f64>) {
	//get dx_g
	let dx: f64 = LENGTH/(NG as f64);
	//set the iteration length for easier reference
	let iter_length = phi.len();
	println!("Phi Length: {}", phi.len());
	println!("Electric Mesh Length: {}", electric_mesh.len());
	for i in 1..iter_length-1 {
		// println!("Hit {}", i);
		//finite difference
		let phi_next = phi[i+1 as usize];
		let phi_prev = phi[i-1 as usize];
		electric_mesh[i] = (phi_next - 2.0*phi[i as usize] + phi_prev)/(dx.powi(2));
	}
	//particles at the edge need to wrap around, so wrap them around
	electric_mesh[0] = (phi[1] - 2.0*phi[0] + phi[iter_length-1])/(dx.powi(2));
	electric_mesh[iter_length-1] = (phi[0] - 2.0*phi[iter_length-1] + phi[iter_length-2])/(dx.powi(2));
}

//gets called whenever a timestep is taken, extrapolates x and v for a particle for a single timestep
fn leapfrog(electric_mesh: &Vec<f64>, x_position: &mut Vec<f64>, velocity: &mut Vec<f64>, dt: f64, delta_x: f64) {
	for i in 0..x_position.len() {
		let (x_new, v_new) = leap(x_position[i as usize], delta_x, velocity[i as usize], dt, electric_mesh);
		x_position[i as usize] = x_new;
		velocity[i as usize] = v_new;
	}
}

//calculates the drift/kick/drift for a specific value
//returns the new X and new V
//THIS SHOULD *ONLY* BE CALLED FROM THE LEAPFROG METHOD
fn leap(x: f64, delta_x: f64, v: f64, dt: f64, electric_mesh: &Vec<f64>) -> (f64, f64) {
	let j: i32 = (x/delta_x).floor() as i32;
	let y: f64 = x/delta_x - j as f64;
	//drift
	let x_half: f64 = x + 0.5*v*dt;
	//kick
	let v_new: f64 = v + accel(j, y, x_half, electric_mesh)*dt;
	//drift
	let x_new: f64 = x_half + 0.5*v_new*dt;
	return (x_new, v_new)
}

//calculates the accleration
fn accel(j: i32, y: f64, x_value: f64, electric_mesh: &Vec<f64>) -> f64{
	let mut dphi_dx: f64 = 0.0;
	if j+1 == NG {
		dphi_dx = electric_mesh[j as usize]*(1.0-y) + electric_mesh[0]*y;
	}
	else {
		dphi_dx = electric_mesh[j as usize]*(1.0-y) + electric_mesh[(j+1) as usize]*y;
	}
	let a: f64 = -CHARGE as f64/MASS as f64*dphi_dx;
	return a;
}

//petrubs the function by a sine wave with waveLENGTH = L/k and amplitude of .01K
fn perturb(x_position: &mut Vec<f64>, k: i32) {
	let wavelength: f64 = LENGTH/(k as f64);
	let amplitude: f64 = 0.01 * LENGTH;
	for i in 0..x_position.len() {
		x_position[i as usize] = x_position[i as usize] + amplitude*(wavelength*x_position[i as usize]*2.0*consts::PI).sin();
	}
}

// catches particles into a temp array
fn catch(x_position: &Vec<f64>, velocity: &Vec<f64>, solution: &mut Vec<f64>, np: i32) {
	for i in 0..np {
		let pos = i as usize;
		solution[pos] = x_position[pos];
		solution[pos + np as usize] = velocity[pos];
	}
}

//dumps the temp array back into the particle vectors
fn release(x_position: &mut Vec<f64>, velocity: &mut Vec<f64>, solution: &Vec<f64>, np: i32) {
	for i in 0..np {
		let pos = i as usize;
		x_position[pos] = solution[pos];
		velocity[pos] = solution[pos + np as usize];
	}
}

//prints the list of X positions. THIS IS A COPY, NOT A DIRECT REFERENCE
fn print_vec(vector: &Vec<f64>) {
	for i in 0..vector.len() {
		println!("Item {}: {}", i, vector[i as usize])
	}
}

//writes the output to a file
fn write_out(x_position: &Vec<f64>, velocity: &Vec<f64>, rho: &Vec<f64>, timestep: u32) {
	let path = format!("{}-pvv", timestep);
	let pos_vs_velocity = Path::new(&path);
	//let pos_vs_rho = Path::new(format!("out/{}-pvr", timestep));
	let mut outStr = "x,v \n".to_owned();
	for i in 0..x_position.len() {
		let idx = i as usize;
		let tmp = (format!("{}, {}\n", x_position[idx], velocity[idx])).to_owned();
		outStr.push_str(&tmp);
	}
	println!("{}", path);
	let mut f = File::create(&pos_vs_velocity).unwrap();
	f.write_all(&outStr.as_bytes());
}<commit_msg>Still need to test poisson function<commit_after>use std::f64::consts;
use std::vec::Vec;
use std::fs::File;
use std::path::Path;
use std::error::Error;
use std::io::{Read, Write};

const LENGTH: f64 = 2.0*consts::PI; //length of PIC box
const NG: i32 = 64; //number of zones for mesh
const MASS: i32 = 1; //mass of each particle
const CHARGE: i32 = -1; //charge of each particle
const V_STREAM: f64 = 4.0; //initial velocity of each stream, this number will turned into positive and negative!

fn main() {
	let particle_loading: i32 = 4; //particle loading
	let np: i32 = particle_loading*NG; //number of particles
	let k: i32 = 1; //used for the peturbation of the sin wave
	let dt: f64 = LENGTH/(NG as f64)/(4.0); //timestep
	let delta_x: f64 = LENGTH/(np as f64); //L/np, or the delta x of the lattice
	let t_max: f64 = 16 as f64*consts::PI/((2 as f64*(np as f64)/LENGTH).sqrt()); //maximum time
	let mut velocity: Vec<f64> = Vec::new(); //velocities of each particle, index is
	let mut x_position: Vec<f64> = Vec::new(); //x-position of each particle

	//seed the initial positions and velocities
	for i in 0..(np*2) {
		if i < np {
			x_position.push(i as f64*LENGTH/np as f64);
			velocity.push(-V_STREAM);
		}
		else {
			x_position.push((i-np) as f64*LENGTH/np as f64);
			velocity.push(V_STREAM);
		}
		//rust only accepts usize for indexes, sanity check
		// println!("x: {}, v: {}", x_position[i as usize], velocity[i as usize]);
	}

	//peturb the x positions
	perturb(&mut x_position, k);

	let mut rho: Vec<f64> = vec![0.0; NG as usize]; //mesh densities
	let mut phi: Vec<f64> = vec![0.0; NG as usize]; //vector of phi's to solve for the poisson
	let mut electric_mesh: Vec<f64> = vec![0.0; NG as usize]; //vector of electric field from potential

	let solnSize = np*2;
	let mut solution: Vec<f64> = vec![0.0; solnSize as usize];
	catch(&x_position, &velocity, &mut solution, np);
	let timestep = (t_max/delta_x).ceil() as u32;

	for k in 0..timestep {
		//unload from the solution
		release(&mut x_position, &mut velocity, &solution, np);
		write_out(&x_position, &velocity, &rho, k);
		//find the particle number density
		density(&mut rho, &mut x_position, np);
		//solve the poisson equation
		poisson1d(&mut phi, &mut rho);
		//find the mesh
		electric_field(&mut phi, &mut electric_mesh);
		for i in 0..x_position.len() {
			let idx = i as usize;

		}

	}
}

//evaluates the particle number density using CIC weight.
//Each mesh loops through all the particles to add in their contribution, calculates the electron density for that mesh block alone.
fn density(rho: &mut Vec<f64>, x_position: & Vec<f64>, np: i32) {
	for rho_i in 0..rho.len() {
		let mut sum: f64 = 0.0;
		for x_p in 0..np*2 {
			sum += (MASS as f64)*cic_weight(rho_i as f64 - x_position[x_p as usize], np);
		}
		// println!("rho_i is {}", rho_i);
		rho[rho_i as usize] = 1.0/(LENGTH/NG as f64)*sum;
	}
}

//Cloud in Cell weighting
//			  { 1 + x/deltaX for -deltaX < x
// W_cic(X) = | 1 - x/deltaX for x < deltaX
//			  } 0 otherwise
fn cic_weight(x: f64, np: i32) -> f64{
	let delta_x: f64 = LENGTH/(np as f64);
	if x > -delta_x {
		return 1.0 + x/delta_x;
	}
	else if x < delta_x {
		return 1.0 - x/delta_x;
	}
	else {
		return 0.0;
	}
}

//solves the 1D poisson equation using the Gauss-Seidel relaxation
fn poisson1d<'a>(phi: &'a mut Vec<f64>, rho: &Vec<f64>) {
	let dx_g: f64 = LENGTH as f64/NG as f64;
	let error_tolerance: f64 = 0.000001; //10^-6
	let source = source_l2_norm(&rho, dx_g);
	let mut residual = residual_l2_norm(&rho, &phi, dx_g);
	// println!("R: {}, eS: {}", residual, error_tolerance*source);
	while residual > error_tolerance*source {
		// println!("R: {}, eS: {}", residual, error_tolerance*source);
		//print_vec(&phi);
		for i in 0..NG-1 {
			// rust uses C-like functions, so % is remainder (don't go negative!)
			let im: i32 = ((i - 1 + NG) % NG);
			let ip: i32 = ((i + 1) % NG);

			//println!("Old Phi: {}", phi[i as usize]);
			//println!("New Phi: {}", 0.5*(phi[im as usize] + phi[ip as usize]) + dx_g.powi(2)/2.0*rho[i as usize]);
			// println!("i: {}, ng: {}, im: {}, ip: {}", i, NG, im, ip);
			phi[i as usize] = 0.5*(phi[im as usize] + phi[ip as usize]) + dx_g.powi(2)/2.0*rho[i as usize];
			//println!("New Phi: {}", phi[i as usize]);
		}
		//print_vec(&phi);
		residual = residual_l2_norm(&rho, &phi, dx_g);
	}
}

//calculates the L2Norm for the source
//probably don't want to call this outside of the poisson solver?
fn source_l2_norm(rho: &Vec<f64>, dx_g: f64) -> f64 {
	let mut source: f64 = 0.0;
	//sum the entire array
	for i in 0..rho.len() {
		source += rho[i as usize].powi(2);
	}
	//divide it by 1/Ng
	source /= dx_g;
	//then square root it
	source = source.sqrt();
	return source;
}

//calculates the L2Norm for the residual
fn residual_l2_norm(rho: &Vec<f64>, phi: &Vec<f64>, dx_g: f64) -> f64 {
	let mut residual: f64 = 0.0;
	for i in 0..rho.len() {
		residual += rho[i as usize];
		if i == 0 {
			residual += (phi[i+1 as usize] - 2.0*phi[i as usize] + phi[(rho.len()-1) as usize])/dx_g.powi(2);
		}
		else if i+1 == rho.len() as usize {
			residual += (phi[0] - 2.0*phi[i as usize] + phi[(i-1) as usize])/dx_g.powi(2);
		}
		else {
			residual += (phi[(i+1 as usize)] - 2.0*phi[i as usize] + phi[(i-1) as usize])/dx_g.powi(2);
		}
	}
	residual /= dx_g;
	residual = residual.sqrt();

	return residual;
}

//calculates the electric field from potential, where
//E is the potential
//uses the second order finite difference
fn electric_field (phi: &mut Vec<f64>, electric_mesh: & mut Vec<f64>) {
	//get dx_g
	let dx: f64 = LENGTH/(NG as f64);
	//set the iteration length for easier reference
	let iter_length = phi.len();
	println!("Phi Length: {}", phi.len());
	println!("Electric Mesh Length: {}", electric_mesh.len());
	for i in 1..iter_length-1 {
		// println!("Hit {}", i);
		//finite difference
		let phi_next = phi[i+1 as usize];
		let phi_prev = phi[i-1 as usize];
		electric_mesh[i] = (phi_next - 2.0*phi[i as usize] + phi_prev)/(dx.powi(2));
	}
	//particles at the edge need to wrap around, so wrap them around
	electric_mesh[0] = (phi[1] - 2.0*phi[0] + phi[iter_length-1])/(dx.powi(2));
	electric_mesh[iter_length-1] = (phi[0] - 2.0*phi[iter_length-1] + phi[iter_length-2])/(dx.powi(2));
}

//gets called whenever a timestep is taken, extrapolates x and v for a particle for a single timestep
fn leapfrog(electric_mesh: &Vec<f64>, x_position: &mut Vec<f64>, velocity: &mut Vec<f64>, dt: f64, delta_x: f64) {
	for i in 0..x_position.len() {
		let (x_new, v_new) = leap(x_position[i as usize], delta_x, velocity[i as usize], dt, electric_mesh);
		x_position[i as usize] = x_new;
		velocity[i as usize] = v_new;
	}
}

//calculates the drift/kick/drift for a specific value
//returns the new X and new V
//THIS SHOULD *ONLY* BE CALLED FROM THE LEAPFROG METHOD
fn leap(x: f64, delta_x: f64, v: f64, dt: f64, electric_mesh: &Vec<f64>) -> (f64, f64) {
	let j: i32 = (x/delta_x).floor() as i32;
	let y: f64 = x/delta_x - j as f64;
	//drift
	let x_half: f64 = x + 0.5*v*dt;
	//kick
	let v_new: f64 = v + accel(j, y, x_half, electric_mesh)*dt;
	//drift
	let x_new: f64 = x_half + 0.5*v_new*dt;
	return (x_new, v_new)
}

//calculates the accleration
fn accel(j: i32, y: f64, x_value: f64, electric_mesh: &Vec<f64>) -> f64{
	let mut dphi_dx: f64 = 0.0;
	if j+1 == NG {
		dphi_dx = electric_mesh[j as usize]*(1.0-y) + electric_mesh[0]*y;
	}
	else {
		dphi_dx = electric_mesh[j as usize]*(1.0-y) + electric_mesh[(j+1) as usize]*y;
	}
	let a: f64 = -CHARGE as f64/MASS as f64*dphi_dx;
	return a;
}

//petrubs the function by a sine wave with waveLENGTH = L/k and amplitude of .01K
fn perturb(x_position: &mut Vec<f64>, k: i32) {
	let wavelength: f64 = LENGTH/(k as f64);
	let amplitude: f64 = 0.01 * LENGTH;
	for i in 0..x_position.len() {
		x_position[i as usize] = x_position[i as usize] + amplitude*(wavelength*x_position[i as usize]*2.0*consts::PI).sin();
	}
}

// catches particles into a temp array
fn catch(x_position: &Vec<f64>, velocity: &Vec<f64>, solution: &mut Vec<f64>, np: i32) {
	for i in 0..np {
		let pos = i as usize;
		solution[pos] = x_position[pos];
		solution[pos + np as usize] = velocity[pos];
	}
}

//dumps the temp array back into the particle vectors
fn release(x_position: &mut Vec<f64>, velocity: &mut Vec<f64>, solution: &Vec<f64>, np: i32) {
	for i in 0..np {
		let pos = i as usize;
		x_position[pos] = solution[pos];
		velocity[pos] = solution[pos + np as usize];
	}
}

//prints the list of X positions. THIS IS A COPY, NOT A DIRECT REFERENCE
fn print_vec(vector: &Vec<f64>) {
	for i in 0..vector.len() {
		println!("Item {}: {}", i, vector[i as usize])
	}
}

//writes the output to a file
fn write_out(x_position: &Vec<f64>, velocity: &Vec<f64>, rho: &Vec<f64>, timestep: u32) {
	let path = format!("{}-pvv", timestep);
	let pos_vs_velocity = Path::new(&path);
	//let pos_vs_rho = Path::new(format!("out/{}-pvr", timestep));
	let mut outStr = "x,v \n".to_owned();
	for i in 0..x_position.len() {
		let idx = i as usize;
		let tmp = (format!("{}, {}\n", x_position[idx], velocity[idx])).to_owned();
		outStr.push_str(&tmp);
	}
	println!("{}", path);
	let mut f = File::create(&pos_vs_velocity).unwrap();
	f.write_all(&outStr.as_bytes());
}<|endoftext|>


<commit_before>extern crate rustc_serialize;
extern crate docopt;
use docopt::Docopt;

#[macro_use]
extern crate serde_derive;
extern crate serde_json;

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

use std::{process, env};
use std::io::{self, Read, Write};
use std::path::PathBuf;
use std::fs::{self, File};
use std::error::Error;

mod keepasshttp;

const VERSION: &'static str = "0.1.1";
const USAGE: &'static str = "
cmdipass

Usage:
  cmdipass get <search-string>
  cmdipass get-one <search-string> (--index=<index> | --uuid=<uuid>) [--password-only | --username-only]
  cmdipass --version
  cmdipass (-h | --help)

Options:
  -h --help         Show this screen.
  --version         Show version.
  --index=<index>   Select the entry at this 0-indexed location.
  --uuid=<uuid>     Select the entry with this uuid.
  --password-only   Print only the password.
  --username-only   Print only the username.
";

#[derive(Debug, RustcDecodable)]
struct Args {
    cmd_get: bool,
    cmd_get_one: bool,
    flag_version: bool,
    flag_help: bool,
    arg_search_string: String,
    flag_index: Option<usize>,
    flag_uuid: Option<String>,
    flag_password_only: bool,
    flag_username_only: bool
}

fn config_path() -> PathBuf {
    env::var("CMDIPASS_CONFIG").map(|e| PathBuf::from(e)).unwrap_or_else(|_| {
        let mut pathbuf = env::home_dir().unwrap_or(PathBuf::from(""));
        pathbuf.push(".cmdipass");
        pathbuf
    })
}

fn config_exists() -> bool {
    config_path().as_path().exists()
}

fn load_config() -> io::Result<keepasshttp::Config> {
    let mut res = File::open(config_path())?;
    let mut buf = String::new();
    res.read_to_string(&mut buf)?;

    let config: keepasshttp::Config = serde_json::from_str(buf.as_str())
        .map_err(|e| io::Error::new(io::ErrorKind::InvalidData, format!("Invalid JSON: {}", e.description())))?;
    Ok(config)
}

#[cfg(any(unix))]
fn write_config_file(config: &keepasshttp::Config) {
    use std::os::unix::fs::OpenOptionsExt;
    let mut file = fs::OpenOptions::new().write(true).create(true).mode(0o600).open(config_path()).unwrap();
    file.write_all(serde_json::to_string(&config).unwrap().as_bytes()).unwrap();
}

#[cfg(any(not(unix)))]
fn write_config_file(config: &keepasshttp::Config) {
    let mut file = fs::OpenOptions::new().write(true).create(true).open(config_path()).unwrap();
    file.write_all(serde_json::to_string(&config).unwrap().as_bytes()).unwrap();
}

fn show_all(entries: &Vec<keepasshttp::Entry>) {
    for(i, entry) in entries.iter().enumerate() {
        println!("{}: {}", i, entry);
    }
}

fn show_one(entries: &Vec<keepasshttp::Entry>, args: &Args) {
    let entry = if args.flag_uuid.is_some() {
        entry_by_uuid(entries, &args.flag_uuid.clone().unwrap())
    } else if args.flag_index.is_some() {
        entry_by_index(entries, &args.flag_index.clone().unwrap())
    } else {
        None
    }.unwrap_or_else(|| {
        process::exit(1);
    });

    if args.flag_password_only {
        println!("{}", entry.password);
    } else if args.flag_username_only {
        println!("{}", entry.login);
    } else {
        println!("{}", entry);
    }

}

fn entry_by_index<'a>(entries: &'a Vec<keepasshttp::Entry>, index: &usize) -> Option<&'a keepasshttp::Entry> {
    let entry = entries.get(*index);

    if entry.is_none() {
        writeln!(io::stderr(), "Could not find an entry at index {}", index).unwrap();
    }

    entry
}

fn entry_by_uuid<'a, T: AsRef<str>>(entries: &'a Vec<keepasshttp::Entry>, uuid: T) -> Option<&'a keepasshttp::Entry> {
    let entry = entries.iter().find(|e| e.uuid == uuid.as_ref());

    if entry.is_none() {
        writeln!(io::stderr(), "Could not find an entry with UUID {}", uuid.as_ref()).unwrap();
    }

    entry
}

fn get_entries<T: AsRef<str>>(search_string: T) -> Vec<keepasshttp::Entry> {
    let config = load_config().unwrap();
    let success = keepasshttp::test_associate(&config);
    if !success {
        writeln!(io::stderr(), "Config rejected by keepasshttp. Make sure that the correct database is open, or delete your config file ({}) and re-associate", config_path().to_string_lossy()).unwrap();
        process::exit(1);
    }

    keepasshttp::get_logins(&config, &search_string).unwrap_or_else(|e| {
        writeln!(io::stderr(), "Error - Server said: '{}'", e).unwrap();
        process::exit(1);
    })
}

fn main() {
    let args: Args = Docopt::new(USAGE).and_then(|d| d.decode()).unwrap_or_else(|e| e.exit());

    env_logger::init().unwrap();

    if args.flag_help {
        println!("{}", USAGE);
        process::exit(0);
    }

    if args.flag_version {
        println!("cmdipass-{}", VERSION);
        process::exit(0);
    }

    if !config_exists() {
        writeln!(io::stderr(), "Config file not found at '{}', generating new key and registering with server", config_path().to_string_lossy()).unwrap();
        write_config_file(&keepasshttp::associate().unwrap());
        writeln!(io::stderr(), "Config file written.").unwrap();
    }

    let entries = get_entries(&args.arg_search_string);

    if args.cmd_get {
        show_all(&entries);
    } else if args.cmd_get_one {
        show_one(&entries, &args);
    }
}
<commit_msg>Exits when file permissions on config file are too open<commit_after>extern crate rustc_serialize;
extern crate docopt;
use docopt::Docopt;

#[macro_use]
extern crate serde_derive;
extern crate serde_json;

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

use std::{process, env};
use std::io::{self, Read, Write};
use std::path::PathBuf;
use std::fs::{self, File};
use std::error::Error;

mod keepasshttp;

const VERSION: &'static str = "0.1.1";
const USAGE: &'static str = "
cmdipass

Usage:
  cmdipass get <search-string>
  cmdipass get-one <search-string> (--index=<index> | --uuid=<uuid>) [--password-only | --username-only]
  cmdipass --version
  cmdipass (-h | --help)

Options:
  -h --help         Show this screen.
  --version         Show version.
  --index=<index>   Select the entry at this 0-indexed location.
  --uuid=<uuid>     Select the entry with this uuid.
  --password-only   Print only the password.
  --username-only   Print only the username.
";

#[derive(Debug, RustcDecodable)]
struct Args {
    cmd_get: bool,
    cmd_get_one: bool,
    flag_version: bool,
    flag_help: bool,
    arg_search_string: String,
    flag_index: Option<usize>,
    flag_uuid: Option<String>,
    flag_password_only: bool,
    flag_username_only: bool
}

fn config_path() -> PathBuf {
    env::var("CMDIPASS_CONFIG").map(|e| PathBuf::from(e)).unwrap_or_else(|_| {
        let mut pathbuf = env::home_dir().unwrap_or(PathBuf::from(""));
        pathbuf.push(".cmdipass");
        pathbuf
    })
}

fn config_exists() -> bool {
    config_path().as_path().exists()
}

#[cfg(any(unix))]
fn ensure_owner_readable_only(f: &File) -> io::Result<()> {
    use std::os::unix::fs::PermissionsExt;
    let metadata = f.metadata()?;
    let mode = metadata.permissions().mode();

    if 0o077 & mode != 0 {
        Err(io::Error::new(io::ErrorKind::Other,
            format!("Permissions {:04o} on '{}' are too open.\nIt is recommended that your cmdipass config file is not accessible to others.", mode, config_path().to_string_lossy())))
    } else {
        Ok(())
    }
}

fn load_config() -> io::Result<keepasshttp::Config> {
    let mut res = File::open(config_path())?;
    if cfg!(any(unix)) {
        ensure_owner_readable_only(&res)?;
    }
    let mut buf = String::new();
    res.read_to_string(&mut buf)?;

    let config: keepasshttp::Config = serde_json::from_str(buf.as_str())
        .map_err(|e| io::Error::new(io::ErrorKind::InvalidData, format!("Invalid JSON: {}", e.description())))?;
    Ok(config)
}

#[cfg(any(unix))]
fn write_config_file(config: &keepasshttp::Config) {
    use std::os::unix::fs::OpenOptionsExt;
    let mut file = fs::OpenOptions::new().write(true).create(true).mode(0o600).open(config_path()).unwrap();
    file.write_all(serde_json::to_string(&config).unwrap().as_bytes()).unwrap();
}

#[cfg(any(not(unix)))]
fn write_config_file(config: &keepasshttp::Config) {
    let mut file = fs::OpenOptions::new().write(true).create(true).open(config_path()).unwrap();
    file.write_all(serde_json::to_string(&config).unwrap().as_bytes()).unwrap();
}

fn show_all(entries: &Vec<keepasshttp::Entry>) {
    for(i, entry) in entries.iter().enumerate() {
        println!("{}: {}", i, entry);
    }
}

fn show_one(entries: &Vec<keepasshttp::Entry>, args: &Args) {
    let entry = if args.flag_uuid.is_some() {
        entry_by_uuid(entries, &args.flag_uuid.clone().unwrap())
    } else if args.flag_index.is_some() {
        entry_by_index(entries, &args.flag_index.clone().unwrap())
    } else {
        None
    }.unwrap_or_else(|| {
        process::exit(1);
    });

    if args.flag_password_only {
        println!("{}", entry.password);
    } else if args.flag_username_only {
        println!("{}", entry.login);
    } else {
        println!("{}", entry);
    }

}

fn entry_by_index<'a>(entries: &'a Vec<keepasshttp::Entry>, index: &usize) -> Option<&'a keepasshttp::Entry> {
    let entry = entries.get(*index);

    if entry.is_none() {
        writeln!(io::stderr(), "Could not find an entry at index {}", index).unwrap();
    }

    entry
}

fn entry_by_uuid<'a, T: AsRef<str>>(entries: &'a Vec<keepasshttp::Entry>, uuid: T) -> Option<&'a keepasshttp::Entry> {
    let entry = entries.iter().find(|e| e.uuid == uuid.as_ref());

    if entry.is_none() {
        writeln!(io::stderr(), "Could not find an entry with UUID {}", uuid.as_ref()).unwrap();
    }

    entry
}

fn get_entries<T: AsRef<str>>(search_string: T) -> Vec<keepasshttp::Entry> {
    let config = load_config().unwrap_or_else(|e| {
        writeln!(io::stderr(), "Could not load config:\n{}", e).unwrap();
        process::exit(1);
    });
    let success = keepasshttp::test_associate(&config);
    if !success {
        writeln!(io::stderr(), "Config rejected by keepasshttp. Make sure that the correct database is open, or delete your config file ({}) and re-associate", config_path().to_string_lossy()).unwrap();
        process::exit(1);
    }

    keepasshttp::get_logins(&config, &search_string).unwrap_or_else(|e| {
        writeln!(io::stderr(), "Error - Server said: '{}'", e).unwrap();
        process::exit(1);
    })
}

fn main() {
    let args: Args = Docopt::new(USAGE).and_then(|d| d.decode()).unwrap_or_else(|e| e.exit());

    env_logger::init().unwrap();

    if args.flag_help {
        println!("{}", USAGE);
        process::exit(0);
    }

    if args.flag_version {
        println!("cmdipass-{}", VERSION);
        process::exit(0);
    }

    if !config_exists() {
        writeln!(io::stderr(), "Config file not found at '{}', generating new key and registering with server", config_path().to_string_lossy()).unwrap();
        write_config_file(&keepasshttp::associate().unwrap());
        writeln!(io::stderr(), "Config file written.").unwrap();
    }

    let entries = get_entries(&args.arg_search_string);

    if args.cmd_get {
        show_all(&entries);
    } else if args.cmd_get_one {
        show_one(&entries, &args);
    }
}
<|endoftext|>


<commit_before>mod entity;
use entity::Entity;
use entity::EntityFunctionality;
fn main() {
    let mut plyr = Entity { name: "Player 1", ..Default::default() };
    plyr.level_up();
    plyr.display_all_stats();
}

<commit_msg>changed plyr back to player<commit_after>mod entity;
use entity::Entity;
use entity::EntityFunctionality;
fn main() {
    let mut player = Entity { name: "Player 1", ..Default::default() };
    player.level_up();
    player.display_all_stats();
}

<|endoftext|>


<commit_before>extern crate getopts;
extern crate rayon;
extern crate libc;
extern crate rff;

mod interface;

use std::env;
use std::io::{self, BufRead, Write, BufWriter};
use std::process;
use rayon::prelude::*;
use getopts::{Options, Fail};
use rff::choice::Choice;
use interface::{Interface, Error};

fn main() {
    let code = run();
    process::exit(code);
}

fn run() -> i32 {
    let args = env::args().skip(1).collect::<Vec<String>>();
    let mut opts = Options::new();

    opts.optopt("s", "search", "Output sorted matches of QUERY", "QUERY");
    opts.optopt("q", "query", "Use QUERY as the initial search string", "QUERY");
    opts.optflag("", "benchmark", "Run search in benchmark mode");
    opts.optflag("h", "help", "Display this help and exit");
    opts.optflag("v", "version", "Display version information and exit");

    let matches = match opts.parse(args).map_err(translate_parse_error) {
        Ok(matches) => matches,
        Err(err) => {
            println!("{}", err);
            print_usage(opts);
            return 1;
        }
    };

    if matches.opt_present("h") {
        print_usage(opts);
        return 0;
    }

    if matches.opt_present("v") {
        print_version();
        return 0;
    }

    let choices = get_choices();

    if matches.opt_present("benchmark") {
        if !matches.opt_present("s") {
            println!("Must specify -s/--search with --benchmark");
            return 1;
        }

        let search = matches.opt_str("s").unwrap();

        for _ in 0..100 {
            let mut choices = choices.
                par_iter().
                filter_map(|choice| Choice::new(&search, &choice)).
                collect::<Vec<Choice>>();

            choices.sort_by(|a, b| b.partial_cmp(a).unwrap());
        }
    } else if matches.opt_present("s") {
        let search = matches.opt_str("s").unwrap();

        let mut choices = choices.
            par_iter().
            filter_map(|choice| Choice::new(&search, &choice)).
            collect::<Vec<Choice>>();

        choices.sort_by(|a, b| b.partial_cmp(a).unwrap());

        let stdout = io::stdout();
        let mut stdout = BufWriter::new(stdout.lock());

        for choice in choices {
            writeln!(stdout, "{}", choice.text()).unwrap();
        }
    } else {
        let choices = choices.iter().map(|x| &x[..]).collect::<Vec<&str>>();

        let opts = interface::Options {
            choices: choices,
            initial: matches.opt_str("q").unwrap_or(String::new())
        };

        let mut interface = Interface::from_opts(opts);

        match interface.run() {
            Ok(result) => println!("{}", result),
            Err(Error::Exit) => return 1,
            Err(e) => {
                println!("error: {:?}", e);
                return 1;
            }
        }
    }

    0
}

fn get_choices() -> Vec<String> {
    let mut lines = vec![];

    let stdin = io::stdin();

    for line in stdin.lock().lines() {
        lines.push(line.unwrap());
    }

    lines
}

fn translate_parse_error(err: Fail) -> String {
    match err {
        Fail::ArgumentMissing(opt) => format!("Argument missing: {}", opt),
        Fail::UnrecognizedOption(opt) => format!("Invalid option: {}", opt),
        Fail::OptionMissing(opt) => format!("Missing option: {}", opt),
        Fail::OptionDuplicated(opt) => format!("Duplicated option: {}", opt),
        Fail::UnexpectedArgument(opt) => format!("Unexpected argument: {}", opt)
    }
}

fn print_usage(opts: Options) {
    let prelude = format!("Usage: {} [options]", env!("CARGO_PKG_NAME"));
    print!("{}", opts.usage(&prelude));
}

fn print_version() {
    println!("{}", env!("CARGO_PKG_VERSION"));
}
<commit_msg>Eliminate unnecessary variable in benchmark<commit_after>extern crate getopts;
extern crate rayon;
extern crate libc;
extern crate rff;

mod interface;

use std::env;
use std::io::{self, BufRead, Write, BufWriter};
use std::process;
use rayon::prelude::*;
use getopts::{Options, Fail};
use rff::choice::Choice;
use interface::{Interface, Error};

fn main() {
    let code = run();
    process::exit(code);
}

fn run() -> i32 {
    let args = env::args().skip(1).collect::<Vec<String>>();
    let mut opts = Options::new();

    opts.optopt("s", "search", "Output sorted matches of QUERY", "QUERY");
    opts.optopt("q", "query", "Use QUERY as the initial search string", "QUERY");
    opts.optflag("", "benchmark", "Run search in benchmark mode");
    opts.optflag("h", "help", "Display this help and exit");
    opts.optflag("v", "version", "Display version information and exit");

    let matches = match opts.parse(args).map_err(translate_parse_error) {
        Ok(matches) => matches,
        Err(err) => {
            println!("{}", err);
            print_usage(opts);
            return 1;
        }
    };

    if matches.opt_present("h") {
        print_usage(opts);
        return 0;
    }

    if matches.opt_present("v") {
        print_version();
        return 0;
    }

    let choices = get_choices();

    if matches.opt_present("benchmark") {
        if !matches.opt_present("s") {
            println!("Must specify -s/--search with --benchmark");
            return 1;
        }

        let search = matches.opt_str("s").unwrap();

        for _ in 0..100 {
            choices.
                par_iter().
                filter_map(|choice| Choice::new(&search, &choice)).
                collect::<Vec<Choice>>().
                sort_by(|a, b| b.partial_cmp(a).unwrap());
        }
    } else if matches.opt_present("s") {
        let search = matches.opt_str("s").unwrap();

        let mut choices = choices.
            par_iter().
            filter_map(|choice| Choice::new(&search, &choice)).
            collect::<Vec<Choice>>();

        choices.sort_by(|a, b| b.partial_cmp(a).unwrap());

        let stdout = io::stdout();
        let mut stdout = BufWriter::new(stdout.lock());

        for choice in choices {
            writeln!(stdout, "{}", choice.text()).unwrap();
        }
    } else {
        let choices = choices.iter().map(|x| &x[..]).collect::<Vec<&str>>();

        let opts = interface::Options {
            choices: choices,
            initial: matches.opt_str("q").unwrap_or(String::new())
        };

        let mut interface = Interface::from_opts(opts);

        match interface.run() {
            Ok(result) => println!("{}", result),
            Err(Error::Exit) => return 1,
            Err(e) => {
                println!("error: {:?}", e);
                return 1;
            }
        }
    }

    0
}

fn get_choices() -> Vec<String> {
    let mut lines = vec![];

    let stdin = io::stdin();

    for line in stdin.lock().lines() {
        lines.push(line.unwrap());
    }

    lines
}

fn translate_parse_error(err: Fail) -> String {
    match err {
        Fail::ArgumentMissing(opt) => format!("Argument missing: {}", opt),
        Fail::UnrecognizedOption(opt) => format!("Invalid option: {}", opt),
        Fail::OptionMissing(opt) => format!("Missing option: {}", opt),
        Fail::OptionDuplicated(opt) => format!("Duplicated option: {}", opt),
        Fail::UnexpectedArgument(opt) => format!("Unexpected argument: {}", opt)
    }
}

fn print_usage(opts: Options) {
    let prelude = format!("Usage: {} [options]", env!("CARGO_PKG_NAME"));
    print!("{}", opts.usage(&prelude));
}

fn print_version() {
    println!("{}", env!("CARGO_PKG_VERSION"));
}
<|endoftext|>


<commit_before>#![feature(plugin)]
#![plugin(rocket_codegen)]

extern crate reqwest;
extern crate rocket;
extern crate toml;
extern crate semver;

use std::fmt::{Display, Formatter, self};
use std::fs::{File, self};
use std::io::Read;
use std::io::Write;
use std::process;
use std::collections::HashMap;

use semver::Version;

#[derive(PartialEq)]
enum Status {
    Unknown,
    OutOfDate,
    UpToDate
}

impl Display for Status {
    fn fmt(&self, f: &mut Formatter) -> Result<(), fmt::Error> {
        match *self {
            Status::Unknown => write!(f, "unknown"),
            Status::OutOfDate => write!(f, "outofdate"),
            Status::UpToDate => write!(f, "uptodate")
        }
    }
}

#[get("/<owner>/<name>")]
fn index(owner: &str, name: &str) -> File {
    // TODO: HEADER 'Cache-Control': 'no-cache, no-store, must-revalidate',
    // TODO: HEADER 'Expires': new Date().toUTCString()
    let status = get_deps_status(owner, name, "dependencies");
    File::open(format!("public/img/status/{}.png", status)).unwrap()
}

fn get_deps_status(owner: &str, name: &str, deps_type: &str) -> Status {
    let cargo_url = format!("https://raw.githubusercontent.com/{}/{}/master/Cargo.toml", owner, name);

    if let Ok(mut resp) = reqwest::get(&*cargo_url) {
        match resp.status() {
            &reqwest::StatusCode::Ok => {
                let mut body = String::new();
                resp.read_to_string(&mut body).ok();
                deps_status_from_cargo(owner, name, body, deps_type)
            },
            _ => Status::Unknown
        }
    } else {
        Status::Unknown
    }
}

fn deps_status_from_cargo(owner: &str, name: &str, cargo: String, deps_type: &str) -> Status {

    let root = match toml::Parser::new(&*cargo).parse() {
        Some(root) => root,
        None => return Status::Unknown
    };

    let dependencies = match root.get(deps_type)
        .and_then(|val| val.as_table()) {
            Some(dependencies) => dependencies,
            None => return Status::UpToDate
        };

    // TODO:
    // 1- Download the Cargo.toml of the project into /tmp/owner/name/Cargo.toml
    // 2- Create a dummy /tmp/owner/name/src/lib.rs (avoid `cargo update` complaint)
    let tmp_dir = format!("/tmp/{}/{}", owner, name);
    let tmp_manifest = format!("{}/Cargo.toml", tmp_dir);
    let tmp_lockfile = format!("{}/Cargo.lock", tmp_dir);
    let tmp_src_dir = format!("{}/src", tmp_dir);
    let tmp_src_lib = format!("{}/lib.rs", tmp_src_dir);

    if let Err(_) = fs::create_dir_all(tmp_src_dir.as_str())
        .and_then(|_| File::create(tmp_manifest.as_str()))
            .and_then(|mut file| file.write_all(cargo.as_bytes()))
            .and_then(|_| File::create(tmp_src_lib.as_str())) {
                return Status::Unknown;
            }
    // 3- `cargo update --manifest-path /tmp/owner/name/Cargo.toml`
    if let Err(_) = process::Command::new("cargo")
        .arg("update")
            .arg("--manifest-path")
            .arg(tmp_manifest.as_str())
            .output() {
                return Status::Unknown;
            }
    // 4- Parse the /tmp/owner/name/Cargo.lock generated
    let mut buffer = String::new();
    if let Err(_) = File::open(tmp_lockfile)
        .and_then(|mut f| f.read_to_string(&mut buffer)) {
            return Status::Unknown;
        }

    //let updated_raw_deps = match toml::Parser::new(buffer.as_str()).parse()
    //    .and_then(|cargo_lockfile | cargo_lockfile.get("root"))
    //    .and_then(|root| root.lookup("dependencies")) {
    //        Some(&toml::Value::Array(ref raw_deps)) => raw_deps,
    //        Some(_) => unreachable!(),
    //        None => return Status::Unknown
    //    };

    let tmp_root_lockfile = match toml::Parser::new(buffer.as_str()).parse() {
        Some(root) => root,
        None => return Status::Unknown
    };

    let tmp_root_table = match tmp_root_lockfile.get("root") {
        Some(root) => root,
        None => return Status::Unknown
    };

    let updated_raw_deps = match tmp_root_table.lookup("dependencies") {
        Some(&toml::Value::Array(ref raw_deps)) => raw_deps,
        Some(_) => unreachable!(),
        None => return Status::Unknown
    };

    let mut updated_deps = HashMap::new();
    for updated_raw_dep in updated_raw_deps {
         let raw_dep_vec : Vec<_>= updated_raw_dep.as_str().unwrap_or("").split(' ').collect();
         if raw_dep_vec.len() < 2 {
             return Status::Unknown
         }
         updated_deps.insert(raw_dep_vec[0], raw_dep_vec[1]);
    }

    println!("{:?}", updated_deps);

    // 5- Compare each deps with semver
    dependencies.iter().fold(Status::UpToDate, |oldest, (dep, version_value)| {
        let updated_version = match updated_deps.get::<str>(&dep.to_string()) {
            Some(updated_version) => updated_version,
            None => unreachable!()
        };
        let version = match version_value.as_str() {
            Some(version) => version,
            None => return Status::Unknown
        };
        println!("{:?}", dep);
        println!("{:?}", version);

        if Version::parse(updated_version) >  Version::parse(version) {
            Status::OutOfDate
        } else if Status::OutOfDate == oldest {
            Status::OutOfDate
        } else {
            Status::UpToDate
        }
    })
}

fn main() {
    rocket::ignite().mount("/", routes![index]).launch();
}
<commit_msg>Refactoring<commit_after>#![feature(plugin)]
#![plugin(rocket_codegen)]

extern crate reqwest;
extern crate rocket;
extern crate toml;
extern crate semver;

use std::fmt::{Display, Formatter, self};
use std::fs::{File, self};
use std::io::{Read, Write, self};
use std::process;
use std::collections::HashMap;

use semver::Version;

#[derive(PartialEq)]
enum Status {
    Unknown,
    OutOfDate,
    UpToDate
}

impl Display for Status {
    fn fmt(&self, f: &mut Formatter) -> Result<(), fmt::Error> {
        match *self {
            Status::Unknown => write!(f, "unknown"),
            Status::OutOfDate => write!(f, "outofdate"),
            Status::UpToDate => write!(f, "uptodate")
        }
    }
}

#[get("/<owner>/<name>")]
fn index(owner: &str, name: &str) -> io::Result<File> {
    // TODO: HEADER 'Cache-Control': 'no-cache, no-store, must-revalidate',
    // TODO: HEADER 'Expires': new Date().toUTCString()
    let status = get_deps_status(owner, name, "dependencies");
    File::open(format!("public/img/status/{}.png", status))
}

fn get_deps_status(owner: &str, name: &str, deps_type: &str) -> Status {
    let cargo_url = format!("https://raw.githubusercontent.com/{}/{}/master/Cargo.toml", owner, name);

    if let Ok(mut resp) = reqwest::get(&*cargo_url) {
        match resp.status() {
            &reqwest::StatusCode::Ok => {
                let mut body = String::new();
                resp.read_to_string(&mut body).ok();
                deps_status_from_cargo(owner, name, body, deps_type)
            },
            _ => Status::Unknown
        }
    } else {
        Status::Unknown
    }
}

fn deps_status_from_cargo(owner: &str, name: &str, cargo: String, deps_type: &str) -> Status {

    let root = match toml::Parser::new(&*cargo).parse() {
        Some(root) => root,
        None => return Status::Unknown
    };

    let dependencies = match root.get(deps_type)
        .and_then(|val| val.as_table()) {
            Some(dependencies) => dependencies,
            None => return Status::UpToDate
        };

    // TODO:
    // 1- Download the Cargo.toml of the project into /tmp/owner/name/Cargo.toml
    // 2- Create a dummy /tmp/owner/name/src/lib.rs (avoid `cargo update` complaint)
    let tmp_dir = format!("/tmp/{}/{}", owner, name);
    let tmp_manifest = format!("{}/Cargo.toml", tmp_dir);
    let tmp_lockfile = format!("{}/Cargo.lock", tmp_dir);
    let tmp_src_dir = format!("{}/src", tmp_dir);
    let tmp_src_lib = format!("{}/lib.rs", tmp_src_dir);

    if let Err(_) = fs::create_dir_all(tmp_src_dir.as_str())
        .and_then(|_| File::create(tmp_manifest.as_str()))
            .and_then(|mut file| file.write_all(cargo.as_bytes()))
            .and_then(|_| File::create(tmp_src_lib.as_str())) {
                return Status::Unknown;
            }
    // 3- `cargo update --manifest-path /tmp/owner/name/Cargo.toml`
    if let Err(_) = process::Command::new("cargo")
        .arg("update")
            .arg("--manifest-path")
            .arg(tmp_manifest.as_str())
            .output() {
                return Status::Unknown;
            }
    // 4- Parse the /tmp/owner/name/Cargo.lock generated
    let mut buffer = String::new();
    if let Err(_) = File::open(tmp_lockfile)
        .and_then(|mut f| f.read_to_string(&mut buffer)) {
            return Status::Unknown;
        }

    //let updated_raw_deps = match toml::Parser::new(buffer.as_str()).parse()
    //    .and_then(|cargo_lockfile | cargo_lockfile.get("root"))
    //    .and_then(|root| root.lookup("dependencies")) {
    //        Some(&toml::Value::Array(ref raw_deps)) => raw_deps,
    //        Some(_) => unreachable!(),
    //        None => return Status::Unknown
    //    };

    let tmp_root_lockfile = match toml::Parser::new(buffer.as_str()).parse() {
        Some(root) => root,
        None => return Status::Unknown
    };

    let tmp_root_table = match tmp_root_lockfile.get("root") {
        Some(root) => root,
        None => return Status::Unknown
    };

    let updated_raw_deps = match tmp_root_table.lookup("dependencies") {
        Some(&toml::Value::Array(ref raw_deps)) => raw_deps,
        Some(_) => unreachable!(),
        None => return Status::Unknown
    };

    let mut updated_deps = HashMap::new();
    for updated_raw_dep in updated_raw_deps {
         let raw_dep_vec : Vec<_>= updated_raw_dep.as_str().unwrap_or("").split(' ').collect();
         if raw_dep_vec.len() < 2 {
             return Status::Unknown
         }
         updated_deps.insert(raw_dep_vec[0], raw_dep_vec[1]);
    }

    println!("{:?}", updated_deps);

    // 5- Compare each deps with semver
    dependencies.iter().fold(Status::UpToDate, |oldest, (dep, version_value)| {
        let updated_version = match updated_deps.get::<str>(&dep.to_string()) {
            Some(updated_version) => updated_version,
            None => unreachable!()
        };
        let version = match version_value.as_str() {
            Some(version) => version,
            None => return Status::Unknown
        };
        println!("{:?}", dep);
        println!("{:?}", version);

        if Version::parse(updated_version) >  Version::parse(version) {
            Status::OutOfDate
        } else if Status::OutOfDate == oldest {
            Status::OutOfDate
        } else {
            Status::UpToDate
        }
    })
}

fn main() {
    rocket::ignite().mount("/", routes![index]).launch();
}
<|endoftext|>


<commit_before>use std::env;
use std::process;

extern crate fish;

fn main() {
    let args: Vec<_> = env::args().collect();
    if args.len() < 2 {
        println!("Usage: {} <fish script>\n", args[0]);
        process::exit(1);
    }

    // let codebox = fish::CodeBox::load_from_string("2*n;");

    let codebox = match fish::CodeBox::load_from_file(&args[1]) {
        Ok(cb) => cb,
        Err(e) => {
            println!("Error: {}", e);
            process::exit(2);
        }
    };

    let input = std::io::stdin();
    let output = std::io::stdout();

    let mut fish = fish::Interpreter::new(input, output);

    if fish.run(&codebox).is_err() {
        println!("something smells fishy...")
    }
}
<commit_msg>Fix process exit code<commit_after>use std::env;
use std::process;

extern crate fish;

fn main() {
    let args: Vec<_> = env::args().collect();
    if args.len() < 2 {
        println!("Usage: {} <fish script>\n", args[0]);
        process::exit(1);
    }

    // let codebox = fish::CodeBox::load_from_string("2*n;");

    let codebox = match fish::CodeBox::load_from_file(&args[1]) {
        Ok(cb) => cb,
        Err(e) => {
            println!("Error: {}", e);
            process::exit(2);
        }
    };

    let input = std::io::stdin();
    let output = std::io::stdout();

    let mut fish = fish::Interpreter::new(input, output);

    if fish.run(&codebox).is_err() {
        println!("something smells fishy...");
        process::exit(3);
    }
}
<|endoftext|>


<commit_before>extern crate ansi_term;
extern crate docopt;
extern crate rustc_serialize;

use ansi_term::Colour;
use docopt::Docopt;

use std::fs;
use std::io;
use std::path;

const USAGE: &'static str = "
srch, a command-line file search utility written in Rust.

Usage:
    srch [options] <pattern>
    srch --help
    srch --version

Options:
    -h, --help      Show this help screen
    -v, --version   Show this program's version
";

#[derive(Debug, RustcDecodable)]
struct Args {
    arg_pattern: String,
}

fn main() {
    let args: Args = Docopt::new(USAGE).unwrap()
                            .help(true)
                            .version(Some(String::from("srch, version ") + option_env!("CARGO_PKG_VERSION").unwrap_or("unknown")))
                            .decode()
                            .unwrap_or_else(|e| e.exit());

    let curdir = path::PathBuf::from("./");
    handle(&curdir, &args.arg_pattern);
}

fn ignore (path: &path::PathBuf) -> bool {
    let fname = path.file_name();
    if fname == None {
        return false
    }

    let fname = fname.unwrap().to_str().unwrap();
    if fname.chars().next().unwrap() == '.' {
        return true
    }

    false
}

trait Misc {
    fn is_dir(&self) -> io::Result<bool>;
    fn display_colour(&self) -> io::Result<String>;
    fn matches(&self, pattern: &String) -> bool;
}

impl Misc for path::PathBuf {
    fn is_dir(&self) -> io::Result<bool> {
        let m = try!(fs::metadata(self));
        Ok(m.is_dir())
    }

    fn display_colour(&self) -> io::Result<String> {
        let s: &str = self.to_str().unwrap();

        if try!(self.is_dir()) {
            Ok(Colour::Yellow.bold().paint(s).to_string())
        } else {
            Ok(s.to_string())
        }
    }

    fn matches(&self, pattern: &String) -> bool {
        let fname = self.file_name();
        if fname == None {
            return false
        }

        let fname = fname.unwrap().to_str().unwrap().to_string();
        if fname == *pattern {
            return true
        }
        false
    }
}

fn handle(path: &path::PathBuf, pattern: &String) -> () {
    match explore(path, pattern) {
        Ok(_) => (),
        Err(_) => (),
    }
}

fn explore(path: &path::PathBuf, pattern: &String) -> std::io::Result<()> {
    if !try!(path.is_dir()) || ignore(&path) {
        return Ok(())
    }

    let mut q: Vec<path::PathBuf> = Vec::new();
    for item in try!(fs::read_dir(path)) {
        let f = try!(item); // f is a DirEntry
        if try!(f.path().is_dir()) {
            q.push(f.path());
        };
        if f.path().matches(&pattern) {
            println!("{}", try!(f.path().display_colour()));
        }
    }

    for d in q {
        handle(&d, pattern);
    }
    Ok(())
}
<commit_msg>Ignore symlinks<commit_after>extern crate ansi_term;
extern crate docopt;
extern crate rustc_serialize;

use ansi_term::Colour;
use docopt::Docopt;

use std::fs;
use std::io;
use std::path;

use std::os::unix::fs::FileTypeExt;

const USAGE: &'static str = "
srch, a command-line file search utility written in Rust.

Usage:
    srch [options] <pattern>
    srch --help
    srch --version

Options:
    -h, --help      Show this help screen
    -v, --version   Show this program's version
";

#[derive(RustcDecodable)]
struct Args {
    arg_pattern: String,
}

fn main() {
    let args: Args = Docopt::new(USAGE).unwrap()
                            .help(true)
                            .version(Some(String::from("srch, version ") + option_env!("CARGO_PKG_VERSION").unwrap_or("unknown")))
                            .decode()
                            .unwrap_or_else(|e| e.exit());

    let curdir = path::PathBuf::from("./");
    handle(&curdir, &args.arg_pattern);
}

fn ignore (path: &path::PathBuf) -> io::Result<bool> {
    if !try!(path.is_dir()) {
        return Ok(true)
    }

    let m = try!(fs::symlink_metadata(path)).file_type();
    if m.is_symlink() || m.is_block_device() || m.is_char_device() || m.is_fifo() || m.is_socket() {
        return Ok(true)
    }

    let fname = path.file_name();
    if fname == None {
        return Ok(false)
    }

    let fname = fname.unwrap().to_str().unwrap();
    if fname.chars().next().unwrap() == '.' {
        return Ok(true)
    }

    Ok(false)
}

trait Misc {
    fn is_dir(&self) -> io::Result<bool>;
    fn display_colour(&self) -> io::Result<String>;
    fn matches(&self, pattern: &String) -> bool;
}

impl Misc for path::PathBuf {
    fn is_dir(&self) -> io::Result<bool> {
        let m = try!(fs::metadata(self));
        Ok(m.is_dir())
    }

    fn display_colour(&self) -> io::Result<String> {
        let s: &str = self.to_str().unwrap();

        if try!(self.is_dir()) {
            Ok(Colour::Yellow.bold().paint(s).to_string())
        } else {
            Ok(s.to_string())
        }
    }

    fn matches(&self, pattern: &String) -> bool {
        let fname = self.file_name();
        if fname == None {
            return false
        }

        let fname = fname.unwrap().to_str().unwrap().to_string();
        if fname == *pattern {
            return true
        }
        false
    }
}

fn handle(path: &path::PathBuf, pattern: &String) -> () {
    match explore(path, pattern) {
        Ok(_) => (),
        Err(_) => (),
    }
}

fn explore(path: &path::PathBuf, pattern: &String) -> std::io::Result<()> {
    if try!(ignore(path)) {
        return Ok(())
    }

    let mut q: Vec<path::PathBuf> = Vec::new();
    for item in try!(fs::read_dir(path)) {
        let f = try!(item); // f is a DirEntry
        if try!(f.path().is_dir()) {
            q.push(f.path());
        };
        if f.path().matches(&pattern) {
            println!("{}", try!(f.path().display_colour()));
        }
    }

    for d in q {
        handle(&d, pattern);
    }
    Ok(())
}
<|endoftext|>


<commit_before>use instr::Instr;
use cpu::Cpu;
use time::precise_time_ns;
use std::fs::File;
use std::io::Read;

extern crate time;
extern crate getopts;

mod instr;
mod cpu;

pub struct AddressSpace {
    data: [u8; 0xFFFF],
}

impl AddressSpace {

    pub fn new() -> AddressSpace {
        AddressSpace { data: [0; 0xFFFF] }
    }

    pub fn read(&self, addr: u16) -> u8 {
        self.data[addr as usize]
    }

    pub fn read_u16(&self, addr: u16) -> u16 {
        self.data[addr as usize] as u16 | ((self.data[addr as usize + 1] as u16) << 8)
    }

    pub fn read_slice(&self, addr: u16, bytes: u16) -> &[u8] {
        &self.data[addr as usize .. (addr + bytes) as usize]
    }

    pub fn write(&mut self, addr: u16, data: u8) {
        self.data[addr as usize] = data;
    }

    pub fn write_u16(&mut self, addr: u16, data: u16) {
        let lo = (data & 0xFF) as u8;
        let hi = ((data & 0xFF00) >> 8) as u8;
        self.data[addr as usize] = lo;
        self.data[addr as usize + 1] = hi;
    }

    pub fn load_rom(&mut self, rom: &mut File) -> std::io::Result<()> {
        // Read in header first
        try!(rom.read(&mut self.data[0x000..0x150]));
        // Then read in remaining cart data
        try!(rom.read(&mut self.data[0x0150..0x8000]));
        Ok(())
    }

}

#[derive(Copy, Clone)]
pub enum RegFlag {
    Zero,
    Subtract,
    HalfCarry,
    Carry,
}

#[derive(Copy, Clone)]
pub enum Register {
    A,
    B,
    C,
    D,
    E,
    F,
    H,
    L,
    AF,
    BC,
    DE,
    HL,
    SP,
    PC,
    Flag,
}

pub struct RegData {
    a: u8,
    b: u8,
    c: u8,
    d: u8,
    e: u8,
    f: u8,
    h: u8,
    l: u8,
    sp: u16,
    pc: u16,
    flag: u8,
}

impl RegData {

    pub fn new() -> RegData {
        RegData {
            a: 0,
            b: 0,
            c: 0,
            d: 0,
            e: 0,
            f: 0,
            h: 0,
            l: 0,
            sp: 0xFFFE,
            pc: 0x100,
            flag: 0,
        }
    }

    pub fn read(&self, reg: Register) -> u8 {
        match reg {
            Register::A => self.a,
            Register::B => self.b,
            Register::C => self.c,
            Register::D => self.d,
            Register::E => self.e,
            Register::F => self.f,
            Register::H => self.h,
            Register::L => self.l,
            Register::Flag => self.flag,
            _ => panic!("Register not available for 8-bit read"),
        }
    }

    pub fn read_u16(&self, reg: Register) -> u16 {
        match reg {
            Register::AF => (self.a as u16) << 8 | self.f as u16,
            Register::BC => (self.b as u16) << 8 | self.c as u16,
            Register::DE => (self.d as u16) << 8 | self.e as u16,
            Register::HL => (self.h as u16) << 8 | self.l as u16,
            Register::SP => self.sp,
            Register::PC => self.pc,
            _ => panic!("Register not available for 16-bit read"),
        }
    }

    pub fn write(&mut self, reg: Register, data: u8) {
        match reg {
            Register::A => self.a = data,
            Register::B => self.b = data,
            Register::C => self.c = data,
            Register::D => self.d = data,
            Register::E => self.e = data,
            Register::F => self.f = data,
            Register::H => self.h = data,
            Register::L => self.l = data,
            _ => panic!("Register not available for 8-bit write"),
        }
    }

    pub fn write_u16(&mut self, reg: Register, data: u16) {
        let (hi, lo) = ((data & 0xFF00 >> 8) as u8, (data & 0xFF) as u8);
        match reg {
            Register::AF => {
                self.a = hi;
                self.f = lo;
            },
            Register::BC => {
                self.b = hi;
                self.c = lo;
            },
            Register::DE => {
                self.d = hi;
                self.c = lo;
            },
            Register::HL => {
                self.h = hi;
                self.l = lo;
            },
            Register::SP => self.sp = data,
            Register::PC => self.pc = data,
            _ => panic!("Register not available for 16-bit write"),
        }
    }

    pub fn copy(&mut self, dst: Register, src: Register) {
        let data = self.read(src);
        self.write(dst, data);
    }

    pub fn copy_u16(&mut self, dst: Register, src: Register) {
        let data = self.read_u16(src);
        self.write_u16(dst, data);
    }

    pub fn set_flag(&mut self, flag: RegFlag, on: bool) {
        let bit = match flag {
            RegFlag::Zero => 0x80,
            RegFlag::Subtract => 0x40,
            RegFlag::HalfCarry => 0x20,
            RegFlag::Carry => 0x10,
        };
        if (on) {
            self.flag |= bit;
        } else {
            self.flag &= bit ^ 0xFF;
        }
    }

    pub fn get_flag(&self, flag: RegFlag) -> bool {
        let bit = match flag {
            RegFlag::Zero => 0x80,
            RegFlag::Subtract => 0x40,
            RegFlag::HalfCarry => 0x20,
            RegFlag::Carry => 0x10,
        };
        self.flag & bit != 0
    }

    pub fn advance_pc(&mut self) -> u16 {
        let pc = self.pc;
        self.pc += 1;
        pc
    }

    pub fn set_pc(&mut self, addr: u16) -> u16 {
        let pc = self.pc;
        self.pc = addr;
        pc
    }

    pub fn add_pc(&mut self, n: i8) -> u16 {
        let pc = self.pc;
        self.pc = ((self.pc as i32) + (n as i32)) as u16;
        pc
    }

}

fn main() {
    let cpu = Cpu::new();
    'main: loop {
        println!("Nothing to do, breaking out of main");
        break 'main;
    }
}
<commit_msg>Provide command line args to load ROM<commit_after>use instr::Instr;
use cpu::Cpu;
use time::precise_time_ns;
use std::fs::File;
use std::io::Read;

extern crate time;
extern crate getopts;

mod instr;
mod cpu;

pub struct AddressSpace {
    data: [u8; 0xFFFF],
}

impl AddressSpace {

    pub fn new() -> AddressSpace {
        AddressSpace { data: [0; 0xFFFF] }
    }

    pub fn read(&self, addr: u16) -> u8 {
        self.data[addr as usize]
    }

    pub fn read_u16(&self, addr: u16) -> u16 {
        self.data[addr as usize] as u16 | ((self.data[addr as usize + 1] as u16) << 8)
    }

    pub fn read_slice(&self, addr: u16, bytes: u16) -> &[u8] {
        &self.data[addr as usize .. (addr + bytes) as usize]
    }

    pub fn write(&mut self, addr: u16, data: u8) {
        self.data[addr as usize] = data;
    }

    pub fn write_u16(&mut self, addr: u16, data: u16) {
        let lo = (data & 0xFF) as u8;
        let hi = ((data & 0xFF00) >> 8) as u8;
        self.data[addr as usize] = lo;
        self.data[addr as usize + 1] = hi;
    }

    pub fn load_rom(&mut self, rom: &mut File) -> std::io::Result<()> {
        // Read in header first
        try!(rom.read(&mut self.data[0x000..0x150]));
        // Then read in remaining cart data
        try!(rom.read(&mut self.data[0x0150..0x8000]));
        Ok(())
    }

}

#[derive(Copy, Clone)]
pub enum RegFlag {
    Zero,
    Subtract,
    HalfCarry,
    Carry,
}

#[derive(Copy, Clone)]
pub enum Register {
    A,
    B,
    C,
    D,
    E,
    F,
    H,
    L,
    AF,
    BC,
    DE,
    HL,
    SP,
    PC,
    Flag,
}

pub struct RegData {
    a: u8,
    b: u8,
    c: u8,
    d: u8,
    e: u8,
    f: u8,
    h: u8,
    l: u8,
    sp: u16,
    pc: u16,
    flag: u8,
}

impl RegData {

    pub fn new() -> RegData {
        RegData {
            a: 0,
            b: 0,
            c: 0,
            d: 0,
            e: 0,
            f: 0,
            h: 0,
            l: 0,
            sp: 0xFFFE,
            pc: 0x100,
            flag: 0,
        }
    }

    pub fn read(&self, reg: Register) -> u8 {
        match reg {
            Register::A => self.a,
            Register::B => self.b,
            Register::C => self.c,
            Register::D => self.d,
            Register::E => self.e,
            Register::F => self.f,
            Register::H => self.h,
            Register::L => self.l,
            Register::Flag => self.flag,
            _ => panic!("Register not available for 8-bit read"),
        }
    }

    pub fn read_u16(&self, reg: Register) -> u16 {
        match reg {
            Register::AF => (self.a as u16) << 8 | self.f as u16,
            Register::BC => (self.b as u16) << 8 | self.c as u16,
            Register::DE => (self.d as u16) << 8 | self.e as u16,
            Register::HL => (self.h as u16) << 8 | self.l as u16,
            Register::SP => self.sp,
            Register::PC => self.pc,
            _ => panic!("Register not available for 16-bit read"),
        }
    }

    pub fn write(&mut self, reg: Register, data: u8) {
        match reg {
            Register::A => self.a = data,
            Register::B => self.b = data,
            Register::C => self.c = data,
            Register::D => self.d = data,
            Register::E => self.e = data,
            Register::F => self.f = data,
            Register::H => self.h = data,
            Register::L => self.l = data,
            _ => panic!("Register not available for 8-bit write"),
        }
    }

    pub fn write_u16(&mut self, reg: Register, data: u16) {
        let (hi, lo) = ((data & 0xFF00 >> 8) as u8, (data & 0xFF) as u8);
        match reg {
            Register::AF => {
                self.a = hi;
                self.f = lo;
            },
            Register::BC => {
                self.b = hi;
                self.c = lo;
            },
            Register::DE => {
                self.d = hi;
                self.c = lo;
            },
            Register::HL => {
                self.h = hi;
                self.l = lo;
            },
            Register::SP => self.sp = data,
            Register::PC => self.pc = data,
            _ => panic!("Register not available for 16-bit write"),
        }
    }

    pub fn copy(&mut self, dst: Register, src: Register) {
        let data = self.read(src);
        self.write(dst, data);
    }

    pub fn copy_u16(&mut self, dst: Register, src: Register) {
        let data = self.read_u16(src);
        self.write_u16(dst, data);
    }

    pub fn set_flag(&mut self, flag: RegFlag, on: bool) {
        let bit = match flag {
            RegFlag::Zero => 0x80,
            RegFlag::Subtract => 0x40,
            RegFlag::HalfCarry => 0x20,
            RegFlag::Carry => 0x10,
        };
        if (on) {
            self.flag |= bit;
        } else {
            self.flag &= bit ^ 0xFF;
        }
    }

    pub fn get_flag(&self, flag: RegFlag) -> bool {
        let bit = match flag {
            RegFlag::Zero => 0x80,
            RegFlag::Subtract => 0x40,
            RegFlag::HalfCarry => 0x20,
            RegFlag::Carry => 0x10,
        };
        self.flag & bit != 0
    }

    pub fn advance_pc(&mut self) -> u16 {
        let pc = self.pc;
        self.pc += 1;
        pc
    }

    pub fn set_pc(&mut self, addr: u16) -> u16 {
        let pc = self.pc;
        self.pc = addr;
        pc
    }

    pub fn add_pc(&mut self, n: i8) -> u16 {
        let pc = self.pc;
        self.pc = ((self.pc as i32) + (n as i32)) as u16;
        pc
    }

}

fn main() {
    let args: Vec<String> = std::env::args().collect();
    let mut opts = getopts::Options::new();
    let matches = match opts.parse(&args[1..]) {
        Ok(m) => { m },
        Err(e) => panic!("Error: {}", e),
    };
    let input = if !matches.free.is_empty() {
        matches.free[0].clone()
    } else {
        println!("No input ROM");
        return;
    };
    let mut cpu = Cpu::new();
    {
        let mut ram = cpu.get_ram();
        let mut romfile = match File::open(std::path::Path::new(&input)) {
            Ok(f) => { f },
            Err(e) => {
                println!("Error opening file: {}", e);
                return;
            }
        };
        ram.load_rom(&mut romfile);
    }
    'main: loop {
        println!("Nothing to do, breaking out of main");
        break 'main;
    }
}
<|endoftext|>


<commit_before>extern crate hyper;

use std::io::{TcpListener, TcpStream};
use std::io::{Acceptor, Listener};

use hyper::http::read_request_line;

fn handle_client(mut stream: TcpStream) {
    match stream.read_to_string() {
        Err(e) => { println!("error reading request: {}", e); }
        Ok(req) => { println!("the request is: {}", req); }
    }
    let resp = b"HTTP/1.1 200 OK\r\nContent-Type: text/html;\r\n\r\nHello!\n";
    match stream.write(resp) {
        Err(e) => { println!("Error writing response: {}", e); }
        Ok(_) => {}
    }
}

fn main() {
    let listener = TcpListener::bind("127.0.0.1:42007");

    let mut acceptor = listener.listen();

    for stream in acceptor.incoming() {
        match stream {
            Err(e) => { println!("Error in stream: {}", e); }
            Ok(stream) => { handle_client(stream) }
        }
    }

    drop(acceptor);
}
<commit_msg>update the response string<commit_after>extern crate hyper;

use std::io::{TcpListener, TcpStream};
use std::io::{Acceptor, Listener};

fn handle_client(mut stream: TcpStream) {
    stream.set_timeout(Some(10));
    match stream.read_to_string() {
        Err(e) => { println!("Error reading request: {}", e); }
        Ok(req) => { println!("The reqeust was: {}", req); }
    }

    let resp = b"HTTP/1.1 200 OK\r\nContent-Type: text/html; Connection: close;\r\n\r\nHello!\n";
    match stream.write(resp) {
        Err(e) => { println!("Error writing response: {}", e); }
        Ok(_) => {}
    }
}

fn main() {
    let listener = TcpListener::bind("127.0.0.1:42007");

    let mut acceptor = listener.listen();

    for stream in acceptor.incoming() {
        match stream {
            Err(e) => { println!("Error in stream: {}", e); }
            Ok(stream) => { handle_client(stream) }
        }
    }

    drop(acceptor);
}
<|endoftext|>