<commit_before>extern crate rustc_serialize;

use rustc_serialize::json::{Json, ToJson, ParserError, ErrorCode };
use std::str::FromStr;
use std::io::prelude::*;
use std::fs::{File, OpenOptions};

#[derive(Debug)]
struct ToDoList {
    list: Vec<String>
}

impl ToDoList {

    fn new() -> ToDoList {
        ToDoList { list: Vec::new() }
    }

    fn add(&mut self, s: String) {
        self.list.push(s);
    }

    fn remove(&mut self, id: usize) {
        if id < self.list.len() {
            let task = self.list.remove(id);
            println!("Задача #{} ({}) успешно удалена!", id, task);
        }

        else {
            panic!("Неверный номер элемента TODO-листа -- {}!", id);
        }
    }

    fn print(&self) {
        if self.list.len() == 0 {
            println!("Нет задач в листе!");
        }

        else {
            println!("Задачи:");
            for (i,task) in self.list.iter().enumerate() {
                println!("Задача {}: {}", i, task);
            }
        }
    }

    fn write_to_file(&self, f: &mut File) {
            f.seek(std::io::SeekFrom::Start(0)).unwrap();
            f.set_len(0).unwrap();
            f.write_all(&(self.to_json().to_string().into_bytes())).unwrap();
    }

}

impl ToJson for ToDoList {

    fn to_json(&self) -> Json {
        self.list.to_json()
    }

}

impl FromStr for ToDoList {

    type Err = ParserError;

    fn from_str(s: &str) -> Result<Self, Self::Err> {
        let error = ParserError::SyntaxError(ErrorCode::NotUtf8,0,0);
        if let Ok(object) = s.parse::<Json>() {
            if object.is_array() {
                let mut array: Vec<String> = Vec::new();
                for e in object.as_array().unwrap().iter() {
                    array.push(e.as_string().unwrap().into());
                }
                Ok(ToDoList { list: array })
            }
            else {
                Err(error)
            }
        }
        else {
            Err(error)
        }
    }
}

fn main() {
    use std::env;
    let mut vars = env::vars();
    let args = env::args();
    let mut storage: ToDoList;
    let mut storage_file: File;
    if let Some((_,home)) = vars.find(|&(ref name, _)| name == "HOME") {
        let path = home.clone() + "/.todo";
        if let Ok(mut file) = OpenOptions::new().read(true).write(true).open(path.clone()) {
            let mut string = String::new();
            if let Ok(_) = file.read_to_string(&mut string) {
                if let Ok(s) = string.parse::<ToDoList>() {
                    storage = s;
                }
                else {
                    panic!("Parse storage file error!");
                }
            }
            else {
                panic!("Cannot read from file to string!");
            }
            storage_file = file;
        }
        else if let Ok(mut file) = OpenOptions::new().write(true).create(true).open(path.clone()) {
            storage = ToDoList::new();
            file.write_all(storage.to_json().to_string().as_bytes()).unwrap();
            storage_file = file;
        }
        else {
            panic!("Cannot open or create storage by {}", path);
        }
    }
    else {
        panic!("Cannot find $HOME in your environment!");
    }
    if let Some(_) = env::args().position(|w| w == "list") {
        storage.print();
    }
    else if let Some(add) = env::args().position(|w| w == "add") {
        if add < (args.len() - 1) {
            storage.add(args.skip(add + 1).fold(String::new(), |s,e| s + " " + &e ));
            storage.write_to_file(&mut storage_file);
            println!("Задача успешно добавлена!");
        }
        else {
            panic!("Нет описания после ключевого слова 'add'!");
        }
    }
    else if let Some(remove) = env::args().position(|w| w == "remove") {
        if remove < (args.len() - 1) {
            args.skip(remove + 1).fold((),|_, e| {
                if let Ok(id) = e.parse::<usize>() {
                    storage.remove(id);
                }
                else {
                    panic!("Невозможно удалить элемент {} -- неверный ID", e);
                }
            });
            storage.write_to_file(&mut storage_file);
        }
    }
    else {
        panic!("Нет аргументов!");
    }
}
<commit_msg>Fixed bug with remove by many ID's<commit_after>extern crate rustc_serialize;

use rustc_serialize::json::{Json, ToJson, ParserError, ErrorCode };
use std::str::FromStr;
use std::io::prelude::*;
use std::fs::{File, OpenOptions};

#[derive(Debug)]
struct ToDoList {
    list: Vec<String>
}

impl ToDoList {

    fn new() -> ToDoList {
        ToDoList { list: Vec::new() }
    }

    fn add(&mut self, s: String) {
        self.list.push(s);
    }

    fn remove(&mut self, id: usize) {
        if id < self.list.len() {
            let task = self.list.remove(id);
            println!("Задача #{} ({}) успешно удалена!", id, task);
        }

        else {
            panic!("Неверный номер элемента TODO-листа -- {}!", id);
        }
    }

    fn print(&self) {
        if self.list.len() == 0 {
            println!("Нет задач в листе!");
        }

        else {
            println!("Задачи:");
            for (i,task) in self.list.iter().enumerate() {
                println!("Задача {}: {}", i, task);
            }
        }
    }

    fn write_to_file(&self, f: &mut File) {
            f.seek(std::io::SeekFrom::Start(0)).unwrap();
            f.set_len(0).unwrap();
            f.write_all(&(self.to_json().to_string().into_bytes())).unwrap();
    }

}

impl ToJson for ToDoList {

    fn to_json(&self) -> Json {
        self.list.to_json()
    }

}

impl FromStr for ToDoList {

    type Err = ParserError;

    fn from_str(s: &str) -> Result<Self, Self::Err> {
        let error = ParserError::SyntaxError(ErrorCode::NotUtf8,0,0);
        if let Ok(object) = s.parse::<Json>() {
            if object.is_array() {
                let mut array: Vec<String> = Vec::new();
                for e in object.as_array().unwrap().iter() {
                    array.push(e.as_string().unwrap().into());
                }
                Ok(ToDoList { list: array })
            }
            else {
                Err(error)
            }
        }
        else {
            Err(error)
        }
    }
}

fn main() {
    use std::env;
    let mut vars = env::vars();
    let args = env::args();
    let mut storage: ToDoList;
    let mut storage_file: File;
    if let Some((_,home)) = vars.find(|&(ref name, _)| name == "HOME") {
        let path = home.clone() + "/.todo";
        if let Ok(mut file) = OpenOptions::new().read(true).write(true).open(path.clone()) {
            let mut string = String::new();
            if let Ok(_) = file.read_to_string(&mut string) {
                if let Ok(s) = string.parse::<ToDoList>() {
                    storage = s;
                }
                else {
                    panic!("Parse storage file error!");
                }
            }
            else {
                panic!("Cannot read from file to string!");
            }
            storage_file = file;
        }
        else if let Ok(mut file) = OpenOptions::new().write(true).create(true).open(path.clone()) {
            storage = ToDoList::new();
            file.write_all(storage.to_json().to_string().as_bytes()).unwrap();
            storage_file = file;
        }
        else {
            panic!("Cannot open or create storage by {}", path);
        }
    }
    else {
        panic!("Cannot find $HOME in your environment!");
    }
    if let Some(_) = env::args().position(|w| w == "list") {
        storage.print();
    }
    else if let Some(add) = env::args().position(|w| w == "add") {
        if add < (args.len() - 1) {
            storage.add(args.skip(add + 1).fold(String::new(), |s,e| s + " " + &e ));
            storage.write_to_file(&mut storage_file);
            println!("Задача успешно добавлена!");
        }
        else {
            panic!("Нет описания после ключевого слова 'add'!");
        }
    }
    else if let Some(remove) = env::args().position(|w| w == "remove") {
        if remove < (args.len() - 1) {
            let mut ids: Vec<usize> = Vec::new();
            args.skip(remove + 1).fold((),|_, e| {
                if let Ok(id) = e.parse::<usize>() {
                    ids.push(id);
                }
                else {
                    panic!("Невозможно удалить элемент {} -- неверный ID", e);
                }
            });
            ids.sort();
            let mut i = 0;
            for id in ids.iter() {
                storage.remove(id - i);
                i += 1;
            }
            storage.write_to_file(&mut storage_file);
        }
    }
    else {
        panic!("Нет аргументов!");
    }
}
<|endoftext|>


<commit_before>use std::fs;
use std::env;
use std::collections::HashMap;
use std::os::unix::fs::MetadataExt;

#[derive(Debug)]
struct File {
    inode: u64,
    size: u64,
    dev:  u64,
    path : String,
}

fn collect_files(dir: &String, v: &mut Vec<File>) {
    if let Ok(entries) = fs::read_dir(dir) {
        for entry in entries {
            if let Ok(entry) = entry {
                let path = entry.path();
                if let Some(path_str) = path.to_str() {
                    if let Ok(metadata) = path.symlink_metadata() {
                        let ft = metadata.file_type();
                        if !ft.is_symlink() {
                            if ft.is_file() {
                                v.push(File{ inode : metadata.ino(),
                                             size  : metadata.len(),
                                             dev   : metadata.dev(),
                                             path  : String::from(path_str),
                                        })
                            } else if ft.is_dir() {
                                collect_files(&(String::from(path_str)), v);
                            }
                        }
                    }
                }
            }
        }
    }
    else {
        println!("{}: invalid directory", dir);
    }
}

fn main() {
    let args: Vec<String> = env::args().collect();

    // Print out usage if no directories are given.
    if args.len() == 1 {
        println!("Usage: {} <dir1> [dir2 [dir3 ...]]", args[0]);
        ::std::process::exit(0);
    }

    let mut v: Vec<File>  = Vec::new();

    for dir in &args[1..] {
        collect_files(dir, &mut v);
    }
    println!("{:?}", v);
}
<commit_msg>[HashMap] Use a hashmap and weed out single elements<commit_after>use std::fs;
use std::env;
use std::collections::HashMap;
use std::os::unix::fs::MetadataExt;

#[derive(Debug)]
struct File {
    inode: u64,
    size: u64,
    dev:  u64,
    path : String,
}

fn collect_files(dir: &String, h: &mut HashMap<u64, Vec<File>>) {
    if let Ok(entries) = fs::read_dir(dir) {
        for entry in entries {
            if let Ok(entry) = entry {
                let path = entry.path();
                if let Some(path_str) = path.to_str() {
                    if let Ok(metadata) = path.symlink_metadata() {
                        let ft = metadata.file_type();
                        if !ft.is_symlink() {
                            if ft.is_file() {
                                let file_size = metadata.len();
                                if !h.contains_key(&file_size) {
                                    h.insert(file_size, Vec::new());
                                }
                                if let Some(vec) = h.get_mut(&file_size) {
                                    vec.push(
                                         File{ inode : metadata.ino(),
                                             size  : metadata.len(),
                                             dev   : metadata.dev(),
                                             path  : String::from(path_str),
                                         });
                                }
                            } else if ft.is_dir() {
                                collect_files(&(String::from(path_str)), h);
                            }
                        }
                    }
                }
            }
        }
    }
    else {
        println!("{}: invalid directory", dir);
    }
}

fn main() {
    let args: Vec<String> = env::args().collect();

    // Print out usage if no directories are given.
    if args.len() == 1 {
        println!("Usage: {} <dir1> [dir2 [dir3 ...]]", args[0]);
        ::std::process::exit(0);
    }

    let mut hmap: HashMap<u64, Vec<File> > = HashMap::new();

    for dir in &args[1..] {
        collect_files(dir, &mut hmap);
    }

    // Get rid of all the single entries.
    hmap.retain(|_, v| v.len() >= 2);
    println!("{:?}", hmap);
}
<|endoftext|>


<commit_before>//!
//! A `cargo` subcommand for building GraphViz DOT files of dependency graphs.
//! This subcommand was originally based off and inspired by the project
//! [cargo-dot](https://github.com/maxsnew/cargo-dot) by [Max
//! New](https://github.com/maxsnew)
//!
//!
//! ## Demo
//!
//! Let's say we wanted to build a dependency graph of
//! [cargo-count](https://github.com/kbknapp/cargo-count) but we wanted
//! optional dependencies to use red dashed lines and black boxes, and regular
//! (aka "build") dependencies to use orange lines to green diamonds, one would
//! run the following.
//!
//! **NOTE:** GraphViz `dot` needs to be installed to produce the .PNG from the
//! dotfile
//!
//! ```ignore
//! $ cargo graph --optional-line-style dashed --optional-line-color red
//! --optional-shape box --build-shape diamond --build-color green
//! --build-line-color orange > cargo-count.dot
//! $ dot -Tpng > rainbow-graph.png cargo-count.dot
//! ```
//!
//! **NOTE:** It's also possible to run `cargo graph [options] | dot [options]
//! > [file]` instead of individual commands
//!
//! The above commands would produce the following graph:
//!
//! ![cargo-graph dependencies](rainbow-graph.png)
//!
//! Now, *why* someone would do that to a graph is a different story...but it's
//! possible :)
//!
//! ## Installing
//!
//! `cargo-graph` can be installed with `cargo install`
//!
//! ```ignore
//! $ cargo install cargo-graph
//! ```
//!
//! This may require a nightly version of `cargo` if you get an error about the
//! `install` command not being found. You may also compile and install the
//! traditional way by following the instructions below.
//!
//!
//! ## Compiling
//!
//! Follow these instructions to compile `cargo-count`, then skip down to
//! Installation.
//!
//! 1. Ensure you have current version of `cargo` and
//! [Rust](https://www.rust-lang.org) installed
//! 2. Clone the project `$ git clone https://github.com/kbknapp/cargo-graph
//! && cd cargo-graph`
//! 3. Build the project `$ cargo build --release` (**NOTE:** There is a large
//! performance difference when compiling without optimizations, so I recommend
//! always using `--release` to enable to them)
//! 4. Once complete, the binary will be located at
//! `target/release/cargo-graph`
//!
//! ## Installation and Usage
//!
//! All you need to do is place `cargo-graph` somewhere in your `$PATH`. Then
//! run `cargo graph` anywhere in your project directory. For full details see
//! below.
//!
//! ### Linux / OS X
//!
//! You have two options, place `cargo-graph` into a directory that is already
//! located in your `$PATH` variable (To see which directories those are, open
//! a terminal and type `echo "${PATH//:/\n}"`, the quotation marks are
//! important), or you can add a custom directory to your `$PATH`
//!
//! **Option 1**
//! If you have write permission to a directory listed in your `$PATH` or you
//! have root permission (or via `sudo`), simply copy the `cargo-graph` to that
//! directory `# sudo cp cargo-graph/usr/local/bin`
//!
//! **Option 2**
//! If you do not have root, `sudo`, or write permission to any directory
//! already in `$PATH` you can create a directory inside your home directory,
//! and add that. Many people use `$HOME/.bin` to keep it hidden (and not
//! clutter your home directory), or `$HOME/bin` if you want it to be always
//! visible. Here is an example to make the directory, add it to `$PATH`, and
//! copy `cargo-graph` there.
//!
//! Simply change `bin` to whatever you'd like to name the directory, and
//! `.bashrc` to whatever your shell startup file is (usually `.bashrc`,
//! `.bash_profile`, or `.zshrc`)
//!
//! ```ignore
//! $ mkdir ~/bin
//! $ echo "export PATH=$PATH:$HOME/bin" >> ~/.bashrc
//! $ cp cargo-graph~/bin
//! $ source ~/.bashrc
//! ```
//!
//! ### Windows
//!
//! On Windows 7/8 you can add directory to the `PATH` variable by opening a
//! command line as an administrator and running
//!
//! ```ignore
//! C\:> setx path \"%path%;C:\path\to\cargo-graph\binary\"
//! ```
//!
//! Otherwise, ensure you have the `cargo-graph` binary in the directory which
//! you operating in the command line from, because Windows automatically adds
//! your current directory to PATH (i.e. if you open a command line to
//! `C:\my_project\` to use `cargo-graph` ensure `cargo-graph.exe` is inside
//! that directory as well).
//!
//!
//! ### Options
//!
//! There are a few options for using `cargo-graph` which should be somewhat
//! self explanatory.
//!
//! ```ignore
//! USAGE:
//!     cargo graph [FLAGS] [OPTIONS]
//!
//! FLAGS:
//!     -h, --help       Prints help information
//!     -V, --version    Prints version information
//!
//! OPTIONS:
//! --build-color <COLOR>            Color for regular deps (Defaults
//! to 'black')
//! [values: blue black yellow purple
//! green red white orange]
//! --build-deps <true|false>        Should build deps be in the graph?
//! (Defaults to 'true')
//! ex. --build-deps=false OR
//! --build-deps=no
//! --build-line-color <COLOR>       Line color for regular deps
//! (Defaults to 'black')
//! [values: blue black yellow purple
//! green red white orange]
//! --build-line-style <STYLE>       Line style for build deps
//! (Defaults to 'solid')
//!                                           [values: solid dotted dashed]
//! --build-shape <SHAPE>            Shape for regular deps (Defaults
//! to 'round')
//! [values: box round diamond
//! triangle]
//! --dev-color <COLOR>              Color for dev deps (Defaults to
//! 'black')
//! [values: blue black yellow purple
//! green red white orange]
//! --dev-deps <true|false>          Should dev deps be included in the
//! graph? (Defaults to 'false')
//! ex. --dev-deps=true OR
//! --dev-deps=yes
//! --dev-line-color <COLOR>         Line color for dev deps (Defaults
//! to 'black')
//! [values: blue black yellow purple
//! green red white orange]
//! --dev-line-style <STYLE>         Line style for dev deps (Defaults
//! to 'solid')
//!                                           [values: solid dotted dashed]
//! --dev-shape <SHAPE>              Shape for dev deps (Defaults to
//! 'round')
//! [values: box round diamond
//! triangle]
//!         --dot-file <FILE>                Output file (Default to stdout)
//! --lock-file <FILE>               Specify location of .lock file
//! (Default 'Cargo.lock')
//! --manifest-file <FILE>           Specify location of manifest file
//! (Default 'Cargo.toml')
//! --optional-color <COLOR>         Color for optional deps (Defaults
//! to 'black')
//! [values: blue black yellow purple
//! green red white orange]
//! --optional-deps <true|false>     Should optional deps be in the
//! graph? (Defaults to 'true')
//! ex. --optional-deps=false OR
//! --optional-deps=no
//! --optional-line-color <COLOR>    Line color for optional deps
//! (Defaults to 'black')
//! [values: blue black yellow purple
//! green red white orange]
//! --optional-line-style <STYLE>    Line style for optional deps
//! (Defaults to 'solid')
//!                                           [values: solid dotted dashed]
//! --optional-shape <SHAPE>         Shape for optional deps (Defaults
//! to 'round')
//! [values: box round diamond
//! triangle]
//! ```
//!
//! ## License
//!
//! `cargo-graph` is released under the terms of the MIT. See the LICENSE-MIT
//! file for the details.
//!
//! ## Dependencies Tree
//! ![cargo-graph dependencies](cargo-graph.png)

#![cfg_attr(feature = "nightly", feature(plugin))]
#![cfg_attr(feature = "lints", plugin(clippy))]
#![cfg_attr(feature = "lints", allow(explicit_iter_loop))]
#![cfg_attr(feature = "lints", allow(should_implement_trait))]
#![cfg_attr(feature = "lints", allow(unstable_features))]
#![cfg_attr(feature = "lints", deny(warnings))]
#![cfg_attr(not(any(feature = "nightly", feature = "unstable")), deny(unstable_features))]
#![deny(missing_docs,
        missing_debug_implementations,
        missing_copy_implementations,
        trivial_casts, trivial_numeric_casts,
        unsafe_code,
        unused_import_braces,
        unused_qualifications)]

extern crate toml;
#[macro_use]
extern crate clap;
#[cfg(feature = "color")]
extern crate ansi_term;

use std::fs::File;
use std::io::{self, BufWriter};
use std::path::Path;

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

use error::CliResult;
use config::Config;
use project::Project;

#[macro_use]
mod macros;
mod error;
mod graph;
mod fmt;
mod project;
mod dep;
mod config;
mod util;

static LINE_STYLES: [&'static str; 3] = ["solid", "dotted", "dashed"];
static COLORS: [&'static str; 8] = ["blue", "black", "yellow", "purple", "green", "red", "white",
                                    "orange"];
static DEP_SHAPES: [&'static str; 4] = ["box", "round", "diamond", "triangle"];

fn parse_cli<'a, 'b>() -> ArgMatches<'a, 'b> {
    App::new("cargo-graph")
        .version(&*format!("v{}", crate_version!()))
        .bin_name("cargo")
        .settings(&[AppSettings::GlobalVersion, AppSettings::SubcommandRequired])
        .subcommand(SubCommand::with_name("graph")
                        .author("Kevin K. <kbknapp@gamil.com>\nMax New <maxsnew@gmail.com>")
                        .about("Generate a graph of package dependencies in graphviz format")
                        .args(vec![
                Arg::with_name("include-versions")
                    .help("Include the dependency version on nodes")
                    .long("include-versions")
                    .short("I"),
                Arg::with_name("lock-file")
                    .help("Specify location of .lock file (Default \'Cargo.lock\')")
                    .long("lock-file")
                    .value_name("FILE")
                    .validator(is_file)
                    .takes_value(true),
                Arg::with_name("manifest-file")
                    .help("Specify location of manifest file (Default \'Cargo.toml\')")
                    .long("manifest-file")
                    .value_name("FILE")
                    .validator(is_file)
                    .takes_value(true),
                Arg::with_name("dot-file")
                    .help("Output file (Default to stdout)")
                    .long("dot-file")
                    .takes_value(true)
                    .value_name("FILE"),
                Arg::with_name("dev-deps")
                    .help("Should dev deps be included in the graph? (Defaults to \'false\'){n}\
                           ex. --dev-deps=true OR --dev-deps=yes")
                    .long("--dev-deps")
                    .takes_value(true)
                    .value_name("true|false"),
                Arg::with_name("build-deps")
                    .help("Should build deps be in the graph? (Defaults to \'true\'){n}\
                           ex. --build-deps=false OR --build-deps=no")
                    .long("--build-deps")
                    .takes_value(true)
                    .value_name("true|false"),
                Arg::with_name("optional-deps")
                    .help("Should optional deps be in the graph? (Defaults to \'true\'){n}\
                           ex. --optional-deps=false OR --optional-deps=no")
                    .long("--optional-deps")
                    .takes_value(true)
                    .value_name("true|false"),
                // REGULAR "BUILD" DEP STYLE OPTIONS
                Arg::with_name("build-line-style")
                    .help("Line style for build deps (Defaults to \'solid\'){n}")
                    .long("build-line-style")
                    .takes_value(true)
                    .value_name("STYLE")
                    .possible_values(&LINE_STYLES),
                Arg::with_name("build-line-color")
                    .help("Line color for regular deps (Defaults to \'black\'){n}")
                    .long("build-line-color")
                    .takes_value(true)
                    .value_name("COLOR")
                    .possible_values(&COLORS),
                Arg::with_name("build-shape")
                    .help("Shape for regular deps (Defaults to \'round\'){n}")
                    .long("build-shape")
                    .takes_value(true)
                    .value_name("SHAPE")
                    .possible_values(&DEP_SHAPES),
                Arg::with_name("build-color")
                    .help("Color for regular deps (Defaults to \'black\'){n}")
                    .long("build-color")
                    .takes_value(true)
                    .value_name("COLOR")
                    .possible_values(&COLORS),
                // OPTIONAL DEP STYLE OPTIONS
                Arg::with_name("optional-line-style")
                    .help("Line style for optional deps (Defaults to \'solid\'){n}")
                    .long("optional-line-style")
                    .takes_value(true)
                    .value_name("STYLE")
                    .possible_values(&LINE_STYLES),
                Arg::with_name("optional-line-color")
                    .help("Line color for optional deps (Defaults to \'black\'){n}")
                    .long("optional-line-color")
                    .takes_value(true)
                    .value_name("COLOR")
                    .possible_values(&COLORS),
                Arg::with_name("optional-shape")
                    .help("Shape for optional deps (Defaults to \'round\'){n}")
                    .long("optional-shape")
                    .takes_value(true)
                    .value_name("SHAPE")
                    .possible_values(&DEP_SHAPES),
                Arg::with_name("optional-color")
                    .help("Color for optional deps (Defaults to \'black\'){n}")
                    .long("optional-color")
                    .takes_value(true)
                    .value_name("COLOR")
                    .possible_values(&COLORS),
                // DEV DEP STYLE OPTIONS
                Arg::with_name("dev-line-style")
                    .help("Line style for dev deps (Defaults to \'solid\'){n}")
                    .long("dev-line-style")
                    .takes_value(true)
                    .value_name("STYLE")
                    .possible_values(&LINE_STYLES),
                Arg::with_name("dev-line-color")
                    .help("Line color for dev deps (Defaults to \'black\'){n}")
                    .long("dev-line-color")
                    .takes_value(true)
                    .value_name("COLOR")
                    .possible_values(&COLORS),
                Arg::with_name("dev-shape")
                    .help("Shape for dev deps (Defaults to \'round\'){n}")
                    .long("dev-shape")
                    .takes_value(true)
                    .value_name("SHAPE")
                    .possible_values(&DEP_SHAPES),
                Arg::with_name("dev-color")
                    .help("Color for dev deps (Defaults to \'black\'){n}")
                    .long("dev-color")
                    .takes_value(true)
                    .value_name("COLOR")
                    .possible_values(&COLORS)]))
        .get_matches()
}

fn main() {
    debugln!("parsing cli...");
    let m = parse_cli();

    if let Some(m) = m.subcommand_matches("graph") {
        let cfg = Config::from_matches(m).unwrap_or_else(|e| e.exit());
        debugln!("cfg={:#?}", cfg);
        execute(cfg).map_err(|e| e.exit()).unwrap();
    }
}

fn execute(cfg: Config) -> CliResult<()> {
    let project = try!(Project::with_config(&cfg));
    let graph = try!(project.graph());

    match cfg.dot_file {
        None => {
            let o = io::stdout();
            let mut bw = BufWriter::new(o.lock());
            graph.render_to(&mut bw)
        }
        Some(file) => {
            let o = File::create(&Path::new(&file)).expect("Failed to create file");
            let mut bw = BufWriter::new(o);
            graph.render_to(&mut bw)
        }
    }
}

fn is_file(s: String) -> Result<(), String> {
    let p = Path::new(&*s);
    if let None = p.file_name() {
        return Err(format!("'{}' doesn't appear to be a valid file name", &*s));
    }
    Ok(())
}
<commit_msg>refactor: updates to clap 2x<commit_after>//!
//! A `cargo` subcommand for building GraphViz DOT files of dependency graphs.
//! This subcommand was originally based off and inspired by the project
//! [cargo-dot](https://github.com/maxsnew/cargo-dot) by [Max
//! New](https://github.com/maxsnew)
//!
//!
//! ## Demo
//!
//! Let's say we wanted to build a dependency graph of
//! [cargo-count](https://github.com/kbknapp/cargo-count) but we wanted
//! optional dependencies to use red dashed lines and black boxes, and regular
//! (aka "build") dependencies to use orange lines to green diamonds, one would
//! run the following.
//!
//! **NOTE:** GraphViz `dot` needs to be installed to produce the .PNG from the
//! dotfile
//!
//! ```ignore
//! $ cargo graph --optional-line-style dashed --optional-line-color red
//! --optional-shape box --build-shape diamond --build-color green
//! --build-line-color orange > cargo-count.dot
//! $ dot -Tpng > rainbow-graph.png cargo-count.dot
//! ```
//!
//! **NOTE:** It's also possible to run `cargo graph [options] | dot [options]
//! > [file]` instead of individual commands
//!
//! The above commands would produce the following graph:
//!
//! ![cargo-graph dependencies](rainbow-graph.png)
//!
//! Now, *why* someone would do that to a graph is a different story...but it's
//! possible :)
//!
//! ## Installing
//!
//! `cargo-graph` can be installed with `cargo install`
//!
//! ```ignore
//! $ cargo install cargo-graph
//! ```
//!
//! This may require a nightly version of `cargo` if you get an error about the
//! `install` command not being found. You may also compile and install the
//! traditional way by following the instructions below.
//!
//!
//! ## Compiling
//!
//! Follow these instructions to compile `cargo-count`, then skip down to
//! Installation.
//!
//! 1. Ensure you have current version of `cargo` and
//! [Rust](https://www.rust-lang.org) installed
//! 2. Clone the project `$ git clone https://github.com/kbknapp/cargo-graph
//! && cd cargo-graph`
//! 3. Build the project `$ cargo build --release` (**NOTE:** There is a large
//! performance difference when compiling without optimizations, so I recommend
//! always using `--release` to enable to them)
//! 4. Once complete, the binary will be located at
//! `target/release/cargo-graph`
//!
//! ## Installation and Usage
//!
//! All you need to do is place `cargo-graph` somewhere in your `$PATH`. Then
//! run `cargo graph` anywhere in your project directory. For full details see
//! below.
//!
//! ### Linux / OS X
//!
//! You have two options, place `cargo-graph` into a directory that is already
//! located in your `$PATH` variable (To see which directories those are, open
//! a terminal and type `echo "${PATH//:/\n}"`, the quotation marks are
//! important), or you can add a custom directory to your `$PATH`
//!
//! **Option 1**
//! If you have write permission to a directory listed in your `$PATH` or you
//! have root permission (or via `sudo`), simply copy the `cargo-graph` to that
//! directory `# sudo cp cargo-graph/usr/local/bin`
//!
//! **Option 2**
//! If you do not have root, `sudo`, or write permission to any directory
//! already in `$PATH` you can create a directory inside your home directory,
//! and add that. Many people use `$HOME/.bin` to keep it hidden (and not
//! clutter your home directory), or `$HOME/bin` if you want it to be always
//! visible. Here is an example to make the directory, add it to `$PATH`, and
//! copy `cargo-graph` there.
//!
//! Simply change `bin` to whatever you'd like to name the directory, and
//! `.bashrc` to whatever your shell startup file is (usually `.bashrc`,
//! `.bash_profile`, or `.zshrc`)
//!
//! ```ignore
//! $ mkdir ~/bin
//! $ echo "export PATH=$PATH:$HOME/bin" >> ~/.bashrc
//! $ cp cargo-graph~/bin
//! $ source ~/.bashrc
//! ```
//!
//! ### Windows
//!
//! On Windows 7/8 you can add directory to the `PATH` variable by opening a
//! command line as an administrator and running
//!
//! ```ignore
//! C\:> setx path \"%path%;C:\path\to\cargo-graph\binary\"
//! ```
//!
//! Otherwise, ensure you have the `cargo-graph` binary in the directory which
//! you operating in the command line from, because Windows automatically adds
//! your current directory to PATH (i.e. if you open a command line to
//! `C:\my_project\` to use `cargo-graph` ensure `cargo-graph.exe` is inside
//! that directory as well).
//!
//!
//! ### Options
//!
//! There are a few options for using `cargo-graph` which should be somewhat
//! self explanatory.
//!
//! ```ignore
//! USAGE:
//!     cargo graph [FLAGS] [OPTIONS]
//!
//! FLAGS:
//!     -h, --help       Prints help information
//!     -V, --version    Prints version information
//!
//! OPTIONS:
//! --build-color <COLOR>            Color for regular deps (Defaults
//! to 'black')
//! [values: blue black yellow purple
//! green red white orange]
//! --build-deps <true|false>        Should build deps be in the graph?
//! (Defaults to 'true')
//! ex. --build-deps=false OR
//! --build-deps=no
//! --build-line-color <COLOR>       Line color for regular deps
//! (Defaults to 'black')
//! [values: blue black yellow purple
//! green red white orange]
//! --build-line-style <STYLE>       Line style for build deps
//! (Defaults to 'solid')
//!                                           [values: solid dotted dashed]
//! --build-shape <SHAPE>            Shape for regular deps (Defaults
//! to 'round')
//! [values: box round diamond
//! triangle]
//! --dev-color <COLOR>              Color for dev deps (Defaults to
//! 'black')
//! [values: blue black yellow purple
//! green red white orange]
//! --dev-deps <true|false>          Should dev deps be included in the
//! graph? (Defaults to 'false')
//! ex. --dev-deps=true OR
//! --dev-deps=yes
//! --dev-line-color <COLOR>         Line color for dev deps (Defaults
//! to 'black')
//! [values: blue black yellow purple
//! green red white orange]
//! --dev-line-style <STYLE>         Line style for dev deps (Defaults
//! to 'solid')
//!                                           [values: solid dotted dashed]
//! --dev-shape <SHAPE>              Shape for dev deps (Defaults to
//! 'round')
//! [values: box round diamond
//! triangle]
//!         --dot-file <FILE>                Output file (Default to stdout)
//! --lock-file <FILE>               Specify location of .lock file
//! (Default 'Cargo.lock')
//! --manifest-file <FILE>           Specify location of manifest file
//! (Default 'Cargo.toml')
//! --optional-color <COLOR>         Color for optional deps (Defaults
//! to 'black')
//! [values: blue black yellow purple
//! green red white orange]
//! --optional-deps <true|false>     Should optional deps be in the
//! graph? (Defaults to 'true')
//! ex. --optional-deps=false OR
//! --optional-deps=no
//! --optional-line-color <COLOR>    Line color for optional deps
//! (Defaults to 'black')
//! [values: blue black yellow purple
//! green red white orange]
//! --optional-line-style <STYLE>    Line style for optional deps
//! (Defaults to 'solid')
//!                                           [values: solid dotted dashed]
//! --optional-shape <SHAPE>         Shape for optional deps (Defaults
//! to 'round')
//! [values: box round diamond
//! triangle]
//! ```
//!
//! ## License
//!
//! `cargo-graph` is released under the terms of the MIT. See the LICENSE-MIT
//! file for the details.
//!
//! ## Dependencies Tree
//! ![cargo-graph dependencies](cargo-graph.png)

#![cfg_attr(feature = "nightly", feature(plugin))]
#![cfg_attr(feature = "lints", plugin(clippy))]
#![cfg_attr(feature = "lints", allow(explicit_iter_loop))]
#![cfg_attr(feature = "lints", allow(should_implement_trait))]
#![cfg_attr(feature = "lints", allow(unstable_features))]
#![cfg_attr(feature = "lints", deny(warnings))]
#![cfg_attr(not(any(feature = "nightly", feature = "unstable")), deny(unstable_features))]
#![deny(missing_docs,
        missing_debug_implementations,
        missing_copy_implementations,
        trivial_casts, trivial_numeric_casts,
        unsafe_code,
        unused_import_braces,
        unused_qualifications)]

extern crate toml;
#[macro_use]
extern crate clap;
#[cfg(feature = "color")]
extern crate ansi_term;

use std::fs::File;
use std::io::{self, BufWriter};
use std::path::Path;

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

use error::CliResult;
use config::Config;
use project::Project;

#[macro_use]
mod macros;
mod error;
mod graph;
mod fmt;
mod project;
mod dep;
mod config;
mod util;

static LINE_STYLES: [&'static str; 3] = ["solid", "dotted", "dashed"];
static COLORS: [&'static str; 8] = ["blue", "black", "yellow", "purple", "green", "red", "white",
                                    "orange"];
static DEP_SHAPES: [&'static str; 4] = ["box", "round", "diamond", "triangle"];

fn parse_cli<'a>() -> ArgMatches<'a> {
    App::new("cargo-graph")
        .version(&*format!("v{}", crate_version!()))
        .bin_name("cargo")
        .settings(&[AppSettings::GlobalVersion, AppSettings::SubcommandRequired])
        .subcommand(SubCommand::with_name("graph")
                        .author("Kevin K. <kbknapp@gamil.com>\nMax New <maxsnew@gmail.com>")
                        .about("Generate a graph of package dependencies in graphviz format")
                        .args_from_usage("
                            -I, --include-versions 'Include the dependency version on nodes'
                                --dot-file [PATH] 'Output file (Default stdout)'
                                --dev-deps [true|false] 'Should dev deps be included in the graph? (Default false, also allows yes|no)'
                                --build-deps [true|false] 'Should build deps be in the graph? (Default true, also allows yes|no)'
                                --optional-deps [true|false] 'Should optional deps be in the graph? (Default true, also allows yes|no)'
                        ")
                        .args(&[
                            Arg::from_usage("--lock-file [PATH] 'Specify location of .lock file (Default Cargo.lock)'")
                                .validator(is_file),
                            Arg::from_usage("--manifest-file [PATH] 'Specify location of manifest file (Default Cargo.toml)'")
                                .validator(is_file),
                            Arg::from_usage("--build-line-style [STYLE] 'Line style for build deps (Default solid)'")
                                .possible_values(&LINE_STYLES),
                            Arg::from_usage("--build-line-color [COLOR] 'Line color for regular deps (Default black)'")
                                .possible_values(&COLORS),
                            Arg::from_usage("--build-shape [SHAPE] 'Shape for regular deps (Default round)'")
                                .possible_values(&DEP_SHAPES),
                            Arg::from_usage("--build-color [COLOR] 'Color for regular deps (Default black)'")
                                .possible_values(&COLORS),
                            Arg::from_usage("--optional-line-style [STYLE] 'Line style for optional deps (Default solid)'")
                                .possible_values(&LINE_STYLES),
                            Arg::from_usage("--optional-line-color [COLOR] 'Line color for optional deps (Default black)'")
                                .possible_values(&COLORS),
                            Arg::from_usage("--optional-shape [SHAPE] 'Shape for optional deps (Default round)'")
                                .possible_values(&DEP_SHAPES),
                            Arg::from_usage("--optional-color [COLOR] 'Color for optional deps (Default black)'")
                                .possible_values(&COLORS),
                            Arg::from_usage("--dev-line-style [STYLE] 'Line style for dev deps (Default solid)'")
                                .possible_values(&LINE_STYLES),
                            Arg::from_usage("--dev-line-color [COLOR] 'Line color for dev deps (Default black)'")
                                .possible_values(&COLORS),
                            Arg::from_usage("--dev-shape [SHAPE] 'Shape for dev deps (Default round)'")
                                .possible_values(&DEP_SHAPES),
                            Arg::from_usage("--dev-color [COLOR] 'Color for dev deps (Default black)'")
                                .possible_values(&COLORS)]))
        .get_matches()
}

fn main() {
    debugln!("parsing cli...");
    let m = parse_cli();

    if let Some(m) = m.subcommand_matches("graph") {
        let cfg = Config::from_matches(m).unwrap_or_else(|e| e.exit());
        debugln!("cfg={:#?}", cfg);
        execute(cfg).map_err(|e| e.exit()).unwrap();
    }
}

fn execute(cfg: Config) -> CliResult<()> {
    let project = try!(Project::with_config(&cfg));
    let graph = try!(project.graph());

    match cfg.dot_file {
        None => {
            let o = io::stdout();
            let mut bw = BufWriter::new(o.lock());
            graph.render_to(&mut bw)
        }
        Some(file) => {
            let o = File::create(&Path::new(&file)).expect("Failed to create file");
            let mut bw = BufWriter::new(o);
            graph.render_to(&mut bw)
        }
    }
}

fn is_file(s: String) -> Result<(), String> {
    let p = Path::new(&*s);
    if let None = p.file_name() {
        return Err(format!("'{}' doesn't appear to be a valid file name", &*s));
    }
    Ok(())
}
<|endoftext|>


<commit_before>#![feature(collections)]

extern crate toml;
extern crate iron;
extern crate router;
extern crate core;

//use iron::Iron;
use iron::prelude::*;
use iron::headers::*;
use iron::{status, headers};

//use core::str::Str;

use router::{Router};

struct SbWikiServer<'sbwikisrv> {
    listenaddr: String,
    wikipath: String,
    wikifrontpage: String,
}

impl SbWikiServer {
    //TODO: pass config object instead of bunch of argument
    pub fn new(listenaddr: String, wikipath: String,
           wikifrontpage: String) -> SbWikiServer {
        SbWikiServer {
            listenaddr: listenaddr,
            wikipath: wikipath,
            wikifrontpage: wikifrontpage,
        }
    }

    pub fn open(&self, isTLS: bool) {
        let mut wikidocument = self.wikipath.clone();
        wikidocument.push_str("/*");

        let mut router = Router::new();
        //TODO: fetch it from toml config.

        router.get(self.wikipath.as_str(),
                   |req: &mut Request| -> IronResult<Response>
                   {self.wikiredirect(req)});

        router.get(wikidocument.as_str(),
                   |req: &mut Request| -> IronResult<Response>
                   {self.wikihandler(req)});

        router.get("/",
                   |req: &mut Request| -> IronResult<Response>
                   {self.roothandler(req)});/*
        router.get("/:query",
                        |req: &mut Request| &self.roothandler(req));
        */
        //let mut iron = Iron::new(router);
        //iron.http(self.listenaddr).unwrap();

        //self.iron = iron;

        Iron::new(router).http(
            self.listenaddr.clone().as_str()).unwrap();
    }

    fn roothandler(&self, req: &mut Request)
                   -> IronResult<Response> {
        let ref query = req.extensions.get::<Router>()
            .unwrap().find("query").unwrap_or("/");

        Ok(Response::with((status::Ok, *query)))
    }

    fn wikiredirect(&self, req: &mut Request)
                    -> IronResult<Response> {
        let mut url = req.url.path.clone();
        let mut header = Headers::new();
        let mut newpath = String::new();

        //TODO: customizable root page.
        url.push(self.wikifrontpage);

        for i in url.iter() {
            newpath.push_str("/");
            newpath.push_str(i);
        }

        println!("{}", newpath);
        header.set(Location(newpath));

        let mut resp: Response = Response::with((status::MovedPermanently));
        resp.headers = header;

        Ok(resp)
    }

    fn wikihandler(&self, req: &mut Request)
                   -> IronResult<Response> {
        let ref requrl = req.url.clone();
        let mut urlpath = requrl.path.clone();

        for i in urlpath.iter() {
            println!("{}\n", i);
        }

        Ok(Response::with((status::Ok, "Watch console.")))
    }
}

fn main() {
    let sbwiki: SbWikiServer = SbWikiServer::new(
        String::from_str("localhost:3000"),
        String::from_str("/wiki"),
        String::from_str("FrontPage"));

    sbwiki.open(false);
}
<commit_msg>Fix compile error<commit_after>#![feature(collections)]
#![feature(convert)]

extern crate toml;
extern crate iron;
extern crate router;

//use iron::Iron;
use iron::prelude::*;
use iron::headers::*;
use iron::{status, headers};

//use core::str::Str;

use router::{Router};

#[derive(Clone)]
struct SbWikiServer {
    listenaddr: String,
    wikipath: String,
    wikifrontpage: String,
}

impl SbWikiServer {
    //TODO: pass config object instead of bunch of argument
    pub fn new(listenaddr: String, wikipath: String,
               wikifrontpage: String) -> SbWikiServer {
        SbWikiServer {
            listenaddr: listenaddr,
            wikipath: wikipath,
            wikifrontpage: wikifrontpage,
        }
    }

    pub fn open(self, isTLS: bool) {
        let mut wikidocument = self.wikipath.clone();
        wikidocument.push_str("/*");

        let mut router = Router::new();
        //TODO: fetch it from toml config.
        let wpath = self.wikipath.clone();
        let listenaddr = self.listenaddr.clone();

        let cloned = self.clone();
        router.get(wpath.as_str(),
                   move |req: &mut Request| -> IronResult<Response>
                   {cloned.wikiredirect(req)});

        let cloned = self.clone();
        router.get(wikidocument.as_str(),
                   move |req: &mut Request| -> IronResult<Response>
                   {cloned.wikihandler(req)});

        let cloned = self.clone();
        router.get("/",
                   move |req: &mut Request| -> IronResult<Response>
                   {cloned.roothandler(req)});

        let cloned = self.clone();
        router.get("/:query",
                   move |req: &mut Request| -> IronResult<Response>
                   {cloned.roothandler(req)});

        //let mut iron = Iron::new(router);
        //iron.http(self.listenaddr).unwrap();

        //self.iron = iron;

        Iron::new(router).http(
            listenaddr.as_str()).unwrap();
    }

    fn roothandler(&self, req: &mut Request)
                   -> IronResult<Response> {
        let ref query = req.extensions.get::<Router>()
            .unwrap().find("query").unwrap_or("/");

        Ok(Response::with((status::Ok, *query)))
    }

    fn wikiredirect(&self, req: &mut Request)
                    -> IronResult<Response> {
        let mut url = req.url.path.clone();
        let mut header = Headers::new();
        let mut newpath = String::new();

        //TODO: customizable root page.
        url.push(self.wikifrontpage.clone());

        for i in url.iter() {
            newpath.push_str("/");
            newpath.push_str(i);
        }

        println!("{}", newpath);
        header.set(Location(newpath));

        let mut resp: Response = Response::with((status::MovedPermanently));
        resp.headers = header;

        Ok(resp)
    }

    fn wikihandler(&self, req: &mut Request)
                   -> IronResult<Response> {
        let ref requrl = req.url.clone();
        let mut urlpath = requrl.path.clone();

        for i in urlpath.iter() {
            println!("{}\n", i);
        }

        Ok(Response::with((status::Ok, "Watch console.")))
    }
}

fn main() {
    let sbwiki: SbWikiServer = SbWikiServer::new(
        String::from_str("localhost:3000"),
        String::from_str("/wiki"),
        String::from_str("FrontPage"));

    sbwiki.open(false);
}
<|endoftext|>


<commit_before>extern crate rustless;
extern crate hyper;
extern crate iron;
extern crate rustc_serialize;
extern crate valico;

use hyper::status::StatusCode;
use iron::Iron;
use rustless::{
    Application, Api, Nesting, Versioning
};
use rustless::server::header::AccessControlAllowOrigin;
use rustc_serialize::json::ToJson;
use std::process::Command;

fn main() {

  println!("Starting RPI Management ...");

  let api = Api::build(|api| {

    api.get("ping", |endpoint| {
      endpoint.handle(|mut client, params| {
        client.set_header(AccessControlAllowOrigin::Any);
        client.empty()
      })
    });

    api.post("shutdown", |endpoint| {
        endpoint.handle(|mut client, params| {
            println!("Shutdown requested");
            client.set_header(AccessControlAllowOrigin::Any);

            let output = Command::new("shutdown")
                     .arg("-h")
                     .arg("now")
                     .output()
                     .unwrap_or_else(|e| { panic!("failed to execute process: {}", e) });
            let str_stdout = String::from_utf8(output.stdout).unwrap();
            client.text(str_stdout)
            // client.empty()
        })
    });
  });

  let app = Application::new(api);

  Iron::new(app).http("localhost:4000").unwrap();

}
<commit_msg>Improve error handling<commit_after>extern crate rustless;
extern crate hyper;
extern crate iron;
extern crate rustc_serialize;
extern crate valico;

use iron::Iron;
use rustless::{
    Application, Api, Nesting, Versioning
};
use rustless::server::header::AccessControlAllowOrigin;
use rustless::server::status::StatusCode;
use rustc_serialize::json::ToJson;
use std::process::Command;

fn main() {

  println!("Starting RPI Management ...");

  let api = Api::build(|api| {

    api.get("ping", |endpoint| {
      endpoint.handle(|mut client, params| {
        client.set_header(AccessControlAllowOrigin::Any);
        client.empty()
      })
    });

    api.post("shutdown", |endpoint| {
        endpoint.handle(|mut client, params| {
            println!("Shutdown requested...");
            client.set_header(AccessControlAllowOrigin::Any);

            let output = Command::new("shutdown")
                     .arg("-h")
                     .arg("now")
                     .output()
                     .unwrap_or_else(|e| { panic!("failed to execute process: {}", e) });

            if output.status.success() {
              let str_stdout = String::from_utf8(output.stdout).unwrap();
              println!("Shutdown accepted: {}", str_stdout);

              client.set_status(StatusCode::NoContent);
              client.empty()
            } else {
              let str_stderr = String::from_utf8(output.stderr).unwrap();
              println!("Shutdown rejected: {}", str_stderr);

              client.unauthorized();
              client.text(str_stderr)
            }
        })
    });
  });

  let app = Application::new(api);

  Iron::new(app).http("localhost:4000").unwrap();

}
<|endoftext|>


<commit_before>#![feature(core)]

extern crate rand;

use std::iter::FromIterator;
use rand::distributions::{IndependentSample, Range};

fn schwefel(solution: &Vec<f64>) -> f64 {
    418.9829_f64 * solution.len() as f64
        + solution.iter().fold(0_f64, |sum, x| sum + x * x.abs().sqrt().sin())
}

struct Individual {
    solution: Vec<f64>,
    fitness: f64,
}

impl Individual {
    fn new() -> Individual {
        let n = 50;
        let mut rng = rand::thread_rng();
        let range = Range::new(-512.03_f64, 511.97);

        let mut i = Individual {
            solution: Vec::from_iter((0..n).map(|_| range.ind_sample(&mut rng))),
            fitness: 0_f64,
        };
        i.fitness = schwefel(&i.solution);
        i
    }
}

fn main() {
    let pop_size = 128;

    // initialize population
    let population = Vec::from_iter((0..pop_size).map(|_| Individual::new()));

    let best = population.iter().min_by(|x| schwefel(&x.solution) as i64).unwrap();
    println!("The best solution was {:?}", best.solution);
    println!("Its fitness was {}", schwefel(&best.solution));
}
<commit_msg>More idiomatic Individual::new()<commit_after>#![feature(core)]

extern crate rand;

use std::iter::FromIterator;
use rand::distributions::{IndependentSample, Range};

fn schwefel(solution: &Vec<f64>) -> f64 {
    418.9829_f64 * solution.len() as f64
        + solution.iter().fold(0_f64, |sum, x| sum + x * x.abs().sqrt().sin())
}

struct Individual {
    solution: Vec<f64>,
    fitness: f64,
}

impl Individual {
    fn new() -> Individual {
        let n = 50;
        let mut rng = rand::thread_rng();
        let range = Range::new(-512.03_f64, 511.97);

        let solution = Vec::from_iter((0..n).map(|_| range.ind_sample(&mut rng)));
        let fitness = schwefel(&solution);

        Individual { solution: solution, fitness: fitness }
    }
}

fn main() {
    let pop_size = 128;

    // initialize population
    let population = Vec::from_iter((0..pop_size).map(|_| Individual::new()));

    let best = population.iter().min_by(|x| schwefel(&x.solution) as i64).unwrap();
    println!("The best solution was {:?}", best.solution);
    println!("Its fitness was {}", best.fitness);
}
<|endoftext|>


<commit_before>extern crate rustc_serialize;
extern crate docopt;
#[macro_use]
extern crate aws_abacus;
extern crate walkdir;
extern crate chrono;

use docopt::Docopt;
use std::path;
use aws_abacus::elb_log_files;
use aws_abacus::RuntimeContext;
use chrono::{UTC};

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

    let runtime_context = RuntimeContext {
        debug: args.flag_debug,
    };
    let debug = runtime_context.debug;
    let log_location = &path::Path::new(&args.arg_log_location);
    debug!(debug, "Running summary on {}.", log_location.to_str().unwrap());

    let start = UTC::now(); //TODO put this behind a cli arg
    let mut filenames = Vec::new();
    match elb_log_files::file_list(log_location, &mut filenames) {
        Ok(num_files) => {
            debug!(debug, "Found {} files.", num_files);
            let total_record_count = elb_log_files::process_files(&runtime_context, filenames);
            debug!(debug, "Processed {} records in {} files.", total_record_count, num_files);
        },
        Err(e) => {
            println!("ERROR: {}", e);
        },
    };

    let end = UTC::now(); //TODO put this behind a cli arg

    let time = end - start; //TODO put this behind a cli arg

    println!("TIME: {}", time);  //TODO put this behind a cli arg
}

const USAGE: &'static str = "
aws-abacus

Usage:
  aws-abacus <log-location>
  aws-abacus (-d | --debug) <log-location>
  aws-abacus (-h | --help)

Options:
  -h --help     Show this screen.
  -d --debug    Turn on debug output
";

#[derive(Debug, RustcDecodable)]
struct Args {
    arg_log_location: String,
    flag_debug: bool,
}
<commit_msg>Added a benchmarking option to main.<commit_after>extern crate rustc_serialize;
extern crate docopt;
#[macro_use]
extern crate aws_abacus;
extern crate walkdir;
extern crate chrono;

use docopt::Docopt;
use std::path;
use aws_abacus::elb_log_files;
use aws_abacus::RuntimeContext;
use chrono::{DateTime, UTC};

// chrono::datetime::DateTime<chrono::offset::utc::UTC>

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

    let runtime_context = RuntimeContext {
        debug: args.flag_debug,
    };
    let debug = runtime_context.debug;
    let log_location = &path::Path::new(&args.arg_log_location);
    debug!(debug, "Running summary on {}.", log_location.to_str().unwrap());

    let start: Option<DateTime<UTC>> = if args.flag_benchmark {
        Some(UTC::now())
    } else {
        None
    };

    let mut number_of_files = 0;
    let mut number_of_records = 0;
    let mut filenames = Vec::new();
    match elb_log_files::file_list(log_location, &mut filenames) {
        Ok(num_files) => {
            number_of_files = num_files;
            debug!(debug, "Found {} files.", number_of_files);
            number_of_records = elb_log_files::process_files(&runtime_context, filenames);
            debug!(debug, "Processed {} records in {} files.", number_of_records, num_files);
        },
        Err(e) => {
            println!("ERROR: {}", e);
        },
    };

    match start {
        Some(s) => {
            let end = UTC::now();
            let time = end - s;
            println!("Processed {} files having {} records in {} milliseconds.",
                number_of_files,
                number_of_records,
                time.num_milliseconds()
            );
        },
        None => {},
    };
}

const USAGE: &'static str = "
aws-abacus

Usage:
  aws-abacus <log-location>
  aws-abacus (-d | --debug | -b | --benchmark) <log-location>
  aws-abacus (-h | --help)

Options:
  -h --help     Show this screen.
  -d --debug    Turn on debug output
";

#[derive(Debug, RustcDecodable)]
struct Args {
    arg_log_location: String,
    flag_debug: bool,
    flag_benchmark: bool,
}
<|endoftext|>


<commit_before>#![feature(mpsc_select, box_syntax, fnbox)]
// areyoufuckingkiddingme.jpg
#![cfg_attr(feature = "cargo-clippy", allow(unreadable_literal))]
#![recursion_limit = "1024"]

extern crate serenity;
extern crate xivdb;
extern crate dotenv;
#[macro_use]
extern crate serde_derive;
extern crate serde_json;
extern crate ctrlc;
extern crate chrono;
#[macro_use]
extern crate log;
extern crate fern;
extern crate ansi_term;
extern crate hyper;
extern crate make_hyper_great_again;
extern crate hyper_rustls;
extern crate scraper;
extern crate uuid;
#[macro_use]
extern crate lazy_static;
extern crate envy;
#[macro_use]
extern crate error_chain;
extern crate lalafell;
#[macro_use]
extern crate diesel;
extern crate url;
extern crate url_serde;
extern crate byteorder;
extern crate rand;
extern crate typemap;
extern crate itertools;

macro_rules! some_or {
  ($e: expr, $o: expr) => {{
    #[allow(unused_variables)]
    match $e {
      Some(x) => x,
      None => $o
    }
  }}
}

mod bot;
mod database;
mod listeners;
mod tasks;
mod commands;
mod lodestone;
mod config;
mod filters;
mod error;
mod logging;

use bot::LalafellBot;
use error::*;

use std::sync::{Arc, Mutex};

fn main() {
  if let Err(e) = inner() {
    for err in e.iter() {
      error!("{}", err);
    }
  }
}

fn inner() -> Result<()> {
  if let Err(e) = logging::init_logger() {
    println!("Could not set up logger.");
    for err in e.iter() {
      println!("{}", err);
    }
    return Ok(());
  }

  info!("Loading .env");

  dotenv::dotenv().ok();

  info!("Reading environment variables");

  let environment: Environment = envy::from_env().expect("Invalid or missing environment variables");

  let bot = match bot::create_bot(environment) {
    Ok(b) => b,
    Err(e) => bail!("could not create bot: {}", e)
  };

  let shard_manager = Arc::clone(&bot.discord.shard_manager);

  ctrlc::set_handler(move || {
    info!("Stopping main loop");
    shard_manager.lock().shutdown_all();
  }).expect("could not set interrupt handler");

  let bot = Arc::new(Mutex::new(bot));

  info!("Spinning up bot");
  std::thread::spawn(move || {
    let mut bot = bot.lock().unwrap();
    if let Err(e) = bot.discord.start_autosharded() {
      error!("could not start bot: {}", e);
    }
  }).join().unwrap();

  info!("Exiting");
  Ok(())
}

#[derive(Debug, Deserialize)]
pub struct Environment {
  #[serde(rename = "lb_discord_bot_token")]
  pub discord_bot_token: String,
  #[serde(rename = "lb_database_location")]
  pub database_location: String,
  #[serde(rename = "lb_config_location")]
  pub config_location: String
}
<commit_msg>refactor: use envy prefixes<commit_after>#![feature(mpsc_select, box_syntax, fnbox)]
// areyoufuckingkiddingme.jpg
#![cfg_attr(feature = "cargo-clippy", allow(unreadable_literal))]
#![recursion_limit = "1024"]

extern crate serenity;
extern crate xivdb;
extern crate dotenv;
#[macro_use]
extern crate serde_derive;
extern crate serde_json;
extern crate ctrlc;
extern crate chrono;
#[macro_use]
extern crate log;
extern crate fern;
extern crate ansi_term;
extern crate hyper;
extern crate make_hyper_great_again;
extern crate hyper_rustls;
extern crate scraper;
extern crate uuid;
#[macro_use]
extern crate lazy_static;
extern crate envy;
#[macro_use]
extern crate error_chain;
extern crate lalafell;
#[macro_use]
extern crate diesel;
extern crate url;
extern crate url_serde;
extern crate byteorder;
extern crate rand;
extern crate typemap;
extern crate itertools;

macro_rules! some_or {
  ($e: expr, $o: expr) => {{
    #[allow(unused_variables)]
    match $e {
      Some(x) => x,
      None => $o
    }
  }}
}

mod bot;
mod database;
mod listeners;
mod tasks;
mod commands;
mod lodestone;
mod config;
mod filters;
mod error;
mod logging;

use bot::LalafellBot;
use error::*;

use std::sync::{Arc, Mutex};

fn main() {
  if let Err(e) = inner() {
    for err in e.iter() {
      error!("{}", err);
    }
  }
}

fn inner() -> Result<()> {
  if let Err(e) = logging::init_logger() {
    println!("Could not set up logger.");
    for err in e.iter() {
      println!("{}", err);
    }
    return Ok(());
  }

  info!("Loading .env");

  dotenv::dotenv().ok();

  info!("Reading environment variables");

  let environment: Environment = envy::prefixed("LB_").from_env().expect("Invalid or missing environment variables");

  let bot = match bot::create_bot(environment) {
    Ok(b) => b,
    Err(e) => bail!("could not create bot: {}", e)
  };

  let shard_manager = Arc::clone(&bot.discord.shard_manager);

  ctrlc::set_handler(move || {
    info!("Stopping main loop");
    shard_manager.lock().shutdown_all();
  }).expect("could not set interrupt handler");

  let bot = Arc::new(Mutex::new(bot));

  info!("Spinning up bot");
  std::thread::spawn(move || {
    let mut bot = bot.lock().unwrap();
    if let Err(e) = bot.discord.start_autosharded() {
      error!("could not start bot: {}", e);
    }
  }).join().unwrap();

  info!("Exiting");
  Ok(())
}

#[derive(Debug, Deserialize)]
pub struct Environment {
  pub discord_bot_token: String,
  pub database_location: String,
  pub config_location: String
}
<|endoftext|>


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

pub mod tetris;

use piston::window::WindowSettings;
use piston::event::*;
use glutin_window::GlutinWindow as Glutin_Window;
use opengl_graphics::{ GlGraphics, OpenGL };
use opengl_graphics::glyph_cache::GlyphCache;
use graphics::{ Transformed };
use piston::input::Button::{ Keyboard };
use piston::input::Input;
use piston::input::keyboard::Key;
use std::path::Path;

use tetris::*;

struct App {
    gl: GlGraphics,
    tetris: Tetris,
    elapsed_time: f64,
    cache: GlyphCache<'static>,
    should_redraw: bool
}

const WHITE: [f32; 4] = [1.0, 1.0, 1.0, 1.0];
const BLACK: [f32; 4] = [0.0, 0.0, 0.0, 1.0];
const DARK_GRAY: [f32; 4] = [0.1, 0.1, 0.1, 1.0];
const GREEN: [f32; 4] = [0.0, 1.0, 0.0, 1.0];
const CYAN: [f32; 4] = [0.0, 1.0, 1.0, 1.0];
const RED: [f32; 4] = [1.0, 0.0, 0.0, 1.0];
const BLUE: [f32; 4] = [0.0, 0.0, 1.0, 1.0];
const ORANGE: [f32; 4] = [1.0, 0.5, 0.0, 1.0];
const YELLOW: [f32; 4] = [1.0, 1.0, 0.0, 1.0];
const PURPLE: [f32; 4] = [0.5, 0.0, 1.0, 1.0];

fn get_shape_color(shape_index: i32) -> [f32; 4] {
    match shape_index {
        0 => PURPLE,
        1 => YELLOW,
        2 => RED,
        3 => GREEN,
        4 => ORANGE,
        5 => BLUE,
        6 => CYAN,
        _ => {
            BLACK
        }
    }
}

impl App {
    fn render(&mut self, args: &RenderArgs) {
        self.should_redraw = false;

        const CELL_SIZE: f64 = 30.0;
        const LEFT_MARGIN: f64 = 20f64;
        const TOP_MARGIN: f64 = 30f64;

        const STATUS_LEFT_MARGIN: f64 = 400f64;
        const STATUS_TOP_MARGIN: f64 = 100f64;
        const LINE_HEIGHT: f64 = 40f64;
        const STATUS_PREVIEW_GRID_HEIGHT: f64 = CELL_SIZE * 6f64;

        // so that we can access inside clojure
        let use_cache = &mut self.cache;
        let use_tetris = &mut self.tetris;

        self.gl.draw(args.viewport(), |c, gl| {
            // clear the viewport
            graphics::clear(BLACK, gl);

            // render the current score and level
            let mut text = graphics::Text::new(22);
            text.color = ORANGE;
            let mut transform = c.trans(STATUS_LEFT_MARGIN, STATUS_TOP_MARGIN);
            text.draw(&format!("Level: {}", use_tetris.get_level()), use_cache, &c.draw_state,
                transform.transform, gl);
            transform = transform.trans(0f64, LINE_HEIGHT);

            text.draw(&format!("Score: {}", use_tetris.get_score()), use_cache, &c.draw_state,
                transform.transform, gl);
            transform = transform.trans(0f64, LINE_HEIGHT);

            // render the next shape as a preview of what's coming next
            for point in use_tetris.get_next_shape().iter() {
                let square = graphics::rectangle::square(0f64, 0f64, CELL_SIZE);
                let color = get_shape_color(use_tetris.get_next_shape_index() as i32);
                // render the shape at col 2 and row 2
                let (x, y) = ((2 as i16 + point.x) as f64 * CELL_SIZE,
                    (2 as i16 + point.y) as f64 * CELL_SIZE);
                graphics::rectangle(color, square, transform.trans(x, y).transform, gl);
                let tetromino_border = graphics::Rectangle::new_border(DARK_GRAY, 1.0);
                tetromino_border.draw([0f64, 0f64, CELL_SIZE, CELL_SIZE], &c.draw_state,
                    transform.trans(x, y).transform, gl);
            }
            transform = transform.trans(0f64, STATUS_PREVIEW_GRID_HEIGHT);

            // render GAME OVER text if necessary
            if use_tetris.get_game_over() {
                text.draw(&"GAME OVER", use_cache, &c.draw_state,
                    transform.transform, gl);
                transform = transform.trans(0f64, LINE_HEIGHT);

                text.draw(&"Press 'N' for a new game", use_cache, &c.draw_state,
                    transform.transform, gl);
                transform = transform.trans(0f64, LINE_HEIGHT);

                text.draw(&"Use arrow keys to move and rotate", use_cache, &c.draw_state,
                    transform.transform, gl);
                transform = transform.trans(0f64, LINE_HEIGHT);

                text.draw(&"Press spacebar to drop", use_cache, &c.draw_state,
                    transform.transform, gl);
                transform = transform.trans(0f64, LINE_HEIGHT);

                text.draw(&"Press 'L' to start at level 10", use_cache, &c.draw_state,
                    transform.transform, gl);
                // uncomment if drawing additional text in the status area
                //transform = transform.trans(0f64, LINE_HEIGHT);
            }

            // draw a white border around the game board
            let rect_border = graphics::Rectangle::new_border(WHITE, 1.5);
            rect_border.draw([
                LEFT_MARGIN,
                TOP_MARGIN,
                (CELL_SIZE * COL_COUNT as f64) + 1f64,
                (CELL_SIZE * ROW_COUNT as f64) + 1f64,
            ], &c.draw_state, c.transform, gl);

            // render each cell in the game board
            for col in 0..COL_COUNT as i32 {
                for row in 0..ROW_COUNT as i32 {
                    let cell = use_tetris.get_grid_cell(col, row);
                    if cell.cell_type != GridCellType::Void {
                        let (x, y) = (col as f64 * CELL_SIZE, row as f64 * CELL_SIZE);
                        let square = graphics::rectangle::square(0.0f64, 0.0f64, CELL_SIZE);
                        let color = match cell.cell_type {
                            GridCellType::Shape => get_shape_color(cell.shape_index),
                            GridCellType::Fixed => get_shape_color(cell.shape_index),
                            GridCellType::Ghost => DARK_GRAY,
                            _ => {
                                assert!(false);
                                BLACK
                            }
                        };
                        let transform = c.transform.trans(LEFT_MARGIN, TOP_MARGIN).trans(x, y);
                        graphics::rectangle(color, square, transform, gl);
                        let tetromino_border = graphics::Rectangle::new_border(DARK_GRAY, 1.0);
                        tetromino_border.draw([0f64, 0f64, CELL_SIZE, CELL_SIZE], &c.draw_state, transform, gl);
                    }
                }
            }
        });
    }

    fn update(&mut self, args: &UpdateArgs) {
        if self.tetris.get_game_over() {
            self.elapsed_time = 0.0;
        } else {
            // Here we increment the time elapsed between update()'s
            self.elapsed_time += args.dt;
            // if the elapsed time is now greater than the time allotted between ticks, then invoke tetris.tick()
            if self.elapsed_time > self.tetris.get_tick_time() as f64 {
                self.elapsed_time = 0.0;
                self.tetris.tick();
                self.should_redraw = true;
            }
        }
    }

    fn handle_input(&mut self, i: Input) {
        let prev_should_redraw = self.should_redraw;
        self.should_redraw = true;
        match i {
            Input::Press(Keyboard(Key::Left)) => {
                let col: i32 = self.tetris.get_col();
                self.tetris.set_col(col - 1);
            },

            Input::Press(Keyboard(Key::Right)) => {
                let col: i32 = self.tetris.get_col();
                self.tetris.set_col(col + 1);
            },

            Input::Press(Keyboard(Key::Up)) => {
                self.tetris.rotate(true);
            },

            Input::Press(Keyboard(Key::Down)) => {
                let row: i32 = self.tetris.get_row() + 1;
                self.tetris.set_row(row);
            },

            Input::Press(Keyboard(Key::Space)) => {
                let mut row: i32 = self.tetris.get_row() + 1;
                while self.tetris.set_row(row) {
                    row += 1;
                }
                // hard drop immediately spawns next shape
                self.tetris.tick();
            },

            Input::Press(Keyboard(Key::N)) => {
                self.tetris.start_game();
            },

            Input::Press(Keyboard(Key::L)) => {
                self.tetris.set_starting_level(9);
            },

            _ => {
                self.should_redraw = prev_should_redraw;
            }
        }
    }
}

fn main() {
    start_app();
}

fn start_app() {
    let opengl = OpenGL::_3_2;

    let window = Glutin_Window::new(
        opengl,
        WindowSettings::new("Piston Tetris", [1024, 768])
                       .exit_on_esc(true)
                       .vsync(true)
                       .samples(1)
    );

    let font_path = Path::new("FiraMono-Bold.ttf");

    let mut app = App {
        gl: GlGraphics::new(opengl),
        tetris: Tetris::new(),
        elapsed_time: 0.0,
        cache: GlyphCache::new(font_path).unwrap(),
        should_redraw: true,
    };

    for e in window.events().max_fps(30).ups(30) {
        match e {
            Event::Input(i) => {
                app.handle_input(i);
            }

            Event::Render(args) if app.should_redraw => {
                app.render(&args);
            }

            Event::Update(args) => {
                app.update(&args);
            }

            _ => {}
        }
    }
}<commit_msg>let user set starting level to 10<commit_after>extern crate piston;
extern crate graphics;
extern crate glutin_window;
extern crate opengl_graphics;
extern crate rand;

pub mod tetris;

use piston::window::WindowSettings;
use piston::event::*;
use glutin_window::GlutinWindow as Glutin_Window;
use opengl_graphics::{ GlGraphics, OpenGL };
use opengl_graphics::glyph_cache::GlyphCache;
use graphics::{ Transformed };
use piston::input::Button::{ Keyboard };
use piston::input::Input;
use piston::input::keyboard::Key;
use std::path::Path;

use tetris::*;

struct App {
    gl: GlGraphics,
    tetris: Tetris,
    elapsed_time: f64,
    cache: GlyphCache<'static>,
    should_redraw: bool
}

const WHITE: [f32; 4] = [1.0, 1.0, 1.0, 1.0];
const BLACK: [f32; 4] = [0.0, 0.0, 0.0, 1.0];
const DARK_GRAY: [f32; 4] = [0.1, 0.1, 0.1, 1.0];
const GREEN: [f32; 4] = [0.0, 1.0, 0.0, 1.0];
const CYAN: [f32; 4] = [0.0, 1.0, 1.0, 1.0];
const RED: [f32; 4] = [1.0, 0.0, 0.0, 1.0];
const BLUE: [f32; 4] = [0.0, 0.0, 1.0, 1.0];
const ORANGE: [f32; 4] = [1.0, 0.5, 0.0, 1.0];
const YELLOW: [f32; 4] = [1.0, 1.0, 0.0, 1.0];
const PURPLE: [f32; 4] = [0.5, 0.0, 1.0, 1.0];

fn get_shape_color(shape_index: i32) -> [f32; 4] {
    match shape_index {
        0 => PURPLE,
        1 => YELLOW,
        2 => RED,
        3 => GREEN,
        4 => ORANGE,
        5 => BLUE,
        6 => CYAN,
        _ => {
            BLACK
        }
    }
}

impl App {
    fn render(&mut self, args: &RenderArgs) {
        self.should_redraw = false;

        const CELL_SIZE: f64 = 30.0;
        const LEFT_MARGIN: f64 = 20f64;
        const TOP_MARGIN: f64 = 30f64;

        const STATUS_LEFT_MARGIN: f64 = 400f64;
        const STATUS_TOP_MARGIN: f64 = 100f64;
        const LINE_HEIGHT: f64 = 40f64;
        const STATUS_PREVIEW_GRID_HEIGHT: f64 = CELL_SIZE * 6f64;

        // so that we can access inside clojure
        let use_cache = &mut self.cache;
        let use_tetris = &mut self.tetris;

        self.gl.draw(args.viewport(), |c, gl| {
            // clear the viewport
            graphics::clear(BLACK, gl);

            // render the current score and level
            let mut text = graphics::Text::new(22);
            text.color = ORANGE;
            let mut transform = c.trans(STATUS_LEFT_MARGIN, STATUS_TOP_MARGIN);
            text.draw(&format!("Level: {}", use_tetris.get_level()), use_cache, &c.draw_state,
                transform.transform, gl);
            transform = transform.trans(0f64, LINE_HEIGHT);

            text.draw(&format!("Score: {}", use_tetris.get_score()), use_cache, &c.draw_state,
                transform.transform, gl);
            transform = transform.trans(0f64, LINE_HEIGHT);

            // render the next shape as a preview of what's coming next
            for point in use_tetris.get_next_shape().iter() {
                let square = graphics::rectangle::square(0f64, 0f64, CELL_SIZE);
                let color = get_shape_color(use_tetris.get_next_shape_index() as i32);
                // render the shape at col 2 and row 2
                let (x, y) = ((2 as i16 + point.x) as f64 * CELL_SIZE,
                    (2 as i16 + point.y) as f64 * CELL_SIZE);
                graphics::rectangle(color, square, transform.trans(x, y).transform, gl);
                let tetromino_border = graphics::Rectangle::new_border(DARK_GRAY, 1.0);
                tetromino_border.draw([0f64, 0f64, CELL_SIZE, CELL_SIZE], &c.draw_state,
                    transform.trans(x, y).transform, gl);
            }
            transform = transform.trans(0f64, STATUS_PREVIEW_GRID_HEIGHT);

            // render GAME OVER text if necessary
            if use_tetris.get_game_over() {
                text.draw(&"GAME OVER", use_cache, &c.draw_state,
                    transform.transform, gl);
                transform = transform.trans(0f64, LINE_HEIGHT);

                text.draw(&"Press 'N' for a new game", use_cache, &c.draw_state,
                    transform.transform, gl);
                transform = transform.trans(0f64, LINE_HEIGHT);

                text.draw(&"Use arrow keys to move and rotate", use_cache, &c.draw_state,
                    transform.transform, gl);
                transform = transform.trans(0f64, LINE_HEIGHT);

                text.draw(&"Press spacebar to drop", use_cache, &c.draw_state,
                    transform.transform, gl);
                transform = transform.trans(0f64, LINE_HEIGHT);

                text.draw(&"Press 'L' to start at level 10", use_cache, &c.draw_state,
                    transform.transform, gl);
                // uncomment if drawing additional text in the status area
                //transform = transform.trans(0f64, LINE_HEIGHT);
            }

            // draw a white border around the game board
            let rect_border = graphics::Rectangle::new_border(WHITE, 1.5);
            rect_border.draw([
                LEFT_MARGIN,
                TOP_MARGIN,
                (CELL_SIZE * COL_COUNT as f64) + 1f64,
                (CELL_SIZE * ROW_COUNT as f64) + 1f64,
            ], &c.draw_state, c.transform, gl);

            // render each cell in the game board
            for col in 0..COL_COUNT as i32 {
                for row in 0..ROW_COUNT as i32 {
                    let cell = use_tetris.get_grid_cell(col, row);
                    if cell.cell_type != GridCellType::Void {
                        let (x, y) = (col as f64 * CELL_SIZE, row as f64 * CELL_SIZE);
                        let square = graphics::rectangle::square(0.0f64, 0.0f64, CELL_SIZE);
                        let color = match cell.cell_type {
                            GridCellType::Shape => get_shape_color(cell.shape_index),
                            GridCellType::Fixed => get_shape_color(cell.shape_index),
                            GridCellType::Ghost => DARK_GRAY,
                            _ => {
                                assert!(false);
                                BLACK
                            }
                        };
                        let transform = c.transform.trans(LEFT_MARGIN, TOP_MARGIN).trans(x, y);
                        graphics::rectangle(color, square, transform, gl);
                        let tetromino_border = graphics::Rectangle::new_border(DARK_GRAY, 1.0);
                        tetromino_border.draw([0f64, 0f64, CELL_SIZE, CELL_SIZE], &c.draw_state, transform, gl);
                    }
                }
            }
        });
    }

    fn update(&mut self, args: &UpdateArgs) {
        if self.tetris.get_game_over() {
            self.elapsed_time = 0.0;
        } else {
            // Here we increment the time elapsed between update()'s
            self.elapsed_time += args.dt;
            // if the elapsed time is now greater than the time allotted between ticks, then invoke tetris.tick()
            if self.elapsed_time > self.tetris.get_tick_time() as f64 {
                self.elapsed_time = 0.0;
                self.tetris.tick();
                self.should_redraw = true;
            }
        }
    }

    fn handle_input(&mut self, i: Input) {
        let prev_should_redraw = self.should_redraw;
        self.should_redraw = true;
        match i {
            Input::Press(Keyboard(Key::Left)) => {
                let col: i32 = self.tetris.get_col();
                self.tetris.set_col(col - 1);
            },

            Input::Press(Keyboard(Key::Right)) => {
                let col: i32 = self.tetris.get_col();
                self.tetris.set_col(col + 1);
            },

            Input::Press(Keyboard(Key::Up)) => {
                self.tetris.rotate(true);
            },

            Input::Press(Keyboard(Key::Down)) => {
                let row: i32 = self.tetris.get_row() + 1;
                self.tetris.set_row(row);
            },

            Input::Press(Keyboard(Key::Space)) => {
                let mut row: i32 = self.tetris.get_row() + 1;
                while self.tetris.set_row(row) {
                    row += 1;
                }
                // hard drop immediately spawns next shape
                self.tetris.tick();
            },

            Input::Press(Keyboard(Key::N)) => {
                self.tetris.start_game();
            },

            Input::Press(Keyboard(Key::L)) => {
                self.tetris.set_starting_level(10);
            },

            _ => {
                self.should_redraw = prev_should_redraw;
            }
        }
    }
}

fn main() {
    start_app();
}

fn start_app() {
    let opengl = OpenGL::_3_2;

    let window = Glutin_Window::new(
        opengl,
        WindowSettings::new("Piston Tetris", [1024, 768])
                       .exit_on_esc(true)
                       .vsync(true)
                       .samples(1)
    );

    let font_path = Path::new("FiraMono-Bold.ttf");

    let mut app = App {
        gl: GlGraphics::new(opengl),
        tetris: Tetris::new(),
        elapsed_time: 0.0,
        cache: GlyphCache::new(font_path).unwrap(),
        should_redraw: true,
    };

    for e in window.events().max_fps(30).ups(30) {
        match e {
            Event::Input(i) => {
                app.handle_input(i);
            }

            Event::Render(args) if app.should_redraw => {
                app.render(&args);
            }

            Event::Update(args) => {
                app.update(&args);
            }

            _ => {}
        }
    }
}<|endoftext|>


<commit_before>extern crate env_logger;
extern crate getopts;
extern crate hyper;
extern crate libotaplus;

use getopts::Options;
use hyper::Url;
use std::env;
use std::process::exit;

use libotaplus::{config, read_interpret};
use libotaplus::config::Config;
use libotaplus::read_interpret::ReplEnv;
use libotaplus::ota_plus::{Client as OtaClient};
use libotaplus::auth_plus::{Client as AuthClient};
use libotaplus::package_manager::{PackageManager, Dpkg};
use libotaplus::error::Error;

fn main() {

    env_logger::init().unwrap();

    let config_file = env::var("OTA_PLUS_CLIENT_CFG")
        .unwrap_or("/opt/ats/ota/etc/ota.toml".to_string());

    let config = config::load_config(&config_file)
        .unwrap_or_else(|err| {
            println!("{} (continuing with the default config)", err);
            return Config::default();
        });

    do_stuff(handle_flags(config));

}

fn do_stuff(config: Config) {

    fn post_installed_packages<M>(client: OtaClient, manager: M) -> Result<(), Error>
        where M: PackageManager {
            manager.installed_packages().and_then(|pkgs| client.post_packages(pkgs))
        }

    fn build_ota_client(config: Config) -> Result<OtaClient, Error> {
        AuthClient::new(config.auth.clone()).authenticate().map(|token| {
            OtaClient::new(token, config.ota.clone())
        })
    }

    let pkg_manager = Dpkg::new();
    let pkg_manager_clone = pkg_manager.clone();

    let _ = build_ota_client(config.clone()).and_then(|client| {
        post_installed_packages(client, pkg_manager)
    }).map(|_| {
        print!("Installed packages were posted successfully.");
    }).map_err(|e| {
        print!("{}", e);
    });

    if config.test.looping {
        read_interpret::read_interpret_loop(ReplEnv::new(pkg_manager_clone));
    }
}

fn handle_flags(config: Config) -> Config {

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

    let args: Vec<String> = env::args().collect();
    let program = args[0].clone();

    let mut opts = Options::new();
    opts.optflag("h", "help",
                 "print this help menu");
    opts.optopt("", "auth-server",
                "change the auth server url", "URL");
    opts.optopt("", "auth-client-id",
                "change auth client id", "ID");
    opts.optopt("", "auth-secret",
                "change auth secret", "SECRET");
    opts.optopt("", "ota-server",
                "change ota server url", "URL");
    opts.optopt("", "ota-vin",
                "change ota vin", "VIN");
    opts.optflag("", "test-looping",
                 "enable read-interpret test loop");

    let matches = opts.parse(&args[1..])
        .unwrap_or_else(|err| panic!(err.to_string()));

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

    let mut config = config;

    if let Some(s) = matches.opt_str("auth-server") {
        match Url::parse(&s) {
            Ok(url)  => config.auth.server = url,
            Err(err) => panic!("invalid auth-server url: {}", err)
        }
    }

    if let Some(client_id) = matches.opt_str("auth-client-id") {
        config.auth.client_id = client_id;
    }

    if let Some(secret) = matches.opt_str("auth-secret") {
        config.auth.secret = secret;
    }

    if let Some(s) = matches.opt_str("ota-server") {
        match Url::parse(&s) {
            Ok(url)  => config.ota.server = url,
            Err(err) => panic!("invalid ota-server url: {}", err)
        }
    }

    if let Some(vin) = matches.opt_str("ota-vin") {
        config.ota.vin = vin;
    }

    if matches.opt_present("test-looping") {
        config.test.looping = true;
    }

    return config
}
<commit_msg>Add unit tests of the binary.<commit_after>extern crate env_logger;
extern crate getopts;
extern crate hyper;
extern crate libotaplus;

use getopts::Options;
use hyper::Url;
use std::env;
use std::process::exit;

use libotaplus::{config, read_interpret};
use libotaplus::config::Config;
use libotaplus::read_interpret::ReplEnv;
use libotaplus::ota_plus::{Client as OtaClient};
use libotaplus::auth_plus::{Client as AuthClient};
use libotaplus::package_manager::{PackageManager, Dpkg};
use libotaplus::error::Error;

fn main() {

    env_logger::init().unwrap();

    let config_file = env::var("OTA_PLUS_CLIENT_CFG")
        .unwrap_or("/opt/ats/ota/etc/ota.toml".to_string());

    let config = config::load_config(&config_file)
        .unwrap_or_else(|err| {
            println!("{} (continuing with the default config)", err);
            return Config::default();
        });

    do_stuff(handle_flags(config));

}

fn do_stuff(config: Config) {

    fn post_installed_packages<M>(client: OtaClient, manager: M) -> Result<(), Error>
        where M: PackageManager {
            manager.installed_packages().and_then(|pkgs| client.post_packages(pkgs))
        }

    fn build_ota_client(config: Config) -> Result<OtaClient, Error> {
        AuthClient::new(config.auth.clone()).authenticate().map(|token| {
            OtaClient::new(token, config.ota.clone())
        })
    }

    let pkg_manager = Dpkg::new();
    let pkg_manager_clone = pkg_manager.clone();

    let _ = build_ota_client(config.clone()).and_then(|client| {
        post_installed_packages(client, pkg_manager)
    }).map(|_| {
        print!("Installed packages were posted successfully.");
    }).map_err(|e| {
        print!("{}", e);
    });

    if config.test.looping {
        read_interpret::read_interpret_loop(ReplEnv::new(pkg_manager_clone));
    }
}

fn handle_flags(config: Config) -> Config {

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

    let args: Vec<String> = env::args().collect();
    let program = args[0].clone();

    let mut opts = Options::new();
    opts.optflag("h", "help",
                 "print this help menu");
    opts.optopt("", "auth-server",
                "change the auth server url", "URL");
    opts.optopt("", "auth-client-id",
                "change auth client id", "ID");
    opts.optopt("", "auth-secret",
                "change auth secret", "SECRET");
    opts.optopt("", "ota-server",
                "change ota server url", "URL");
    opts.optopt("", "ota-vin",
                "change ota vin", "VIN");
    opts.optflag("", "test-looping",
                 "enable read-interpret test loop");

    let matches = opts.parse(&args[1..])
        .unwrap_or_else(|err| panic!(err.to_string()));

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

    let mut config = config;

    if let Some(s) = matches.opt_str("auth-server") {
        match Url::parse(&s) {
            Ok(url)  => config.auth.server = url,
            Err(err) => panic!("invalid auth-server url: {}", err)
        }
    }

    if let Some(client_id) = matches.opt_str("auth-client-id") {
        config.auth.client_id = client_id;
    }

    if let Some(secret) = matches.opt_str("auth-secret") {
        config.auth.secret = secret;
    }

    if let Some(s) = matches.opt_str("ota-server") {
        match Url::parse(&s) {
            Ok(url)  => config.ota.server = url,
            Err(err) => panic!("invalid ota-server url: {}", err)
        }
    }

    if let Some(vin) = matches.opt_str("ota-vin") {
        config.ota.vin = vin;
    }

    if matches.opt_present("test-looping") {
        config.test.looping = true;
    }

    return config
}

#[cfg(test)]
mod tests {

    use std::ffi::OsStr;
    use std::process::Command;

    fn client<S: AsRef<OsStr>>(args: &[S]) -> String {
        let output = Command::new("target/debug/ota_plus_client")
            .args(args)
            .output()
            .unwrap_or_else(|e| { panic!("failed to execute child: {}", e) });

        return String::from_utf8(output.stdout).unwrap()
    }

    #[test]
    fn help() {

        assert_eq!(client(&["-h"]),
r#"Usage: target/debug/ota_plus_client [options]

Options:
    -h, --help          print this help menu
        --auth-server URL
                        change the auth server url
        --auth-client-id ID
                        change auth client id
        --auth-secret SECRET
                        change auth secret
        --ota-server URL
                        change ota server url
        --ota-vin VIN   change ota vin
        --test-looping  enable read-interpret test loop
"#);

    }

}
<|endoftext|>