<commit_before>#![feature(core)]
#![feature(path)]

#![feature(plugin)]
#![plugin(regex_macros)]
extern crate regex;
extern crate git2;
extern crate "rustc-serialize" as rustc_serialize;
extern crate docopt;

use git2::{Repository, Branch, BranchType, DiffLine,
    Commit, Diff, DiffFormat, DiffDelta, DiffHunk, Error, Oid};
use docopt::Docopt;
use std::old_io as io;
use std::collections::HashMap;
use std::old_io::BufferedReader;
use std::old_io::File;
use std::str;
use regex::Regex;

// Write the Docopt usage string.
static USAGE: &'static str = "
Usage: transit <repo> [<old> <new>]

If no commits are given, transit will revwalk from latest to oldest.
";

#[derive(RustcDecodable, Debug)]
struct Args {
    arg_repo: String,
    arg_old: Option<String>,
    arg_new: Option<String>,
}

fn main() {
    // Parse the args above or die.
    let args: Args = Docopt::new(USAGE)
        .and_then(|d| d.decode())
        .unwrap_or_else(|e| e.exit());
    // Pull up the revwalk.
    let path = Path::new(args.arg_repo);
    let repo = Repository::discover(&path)
        .ok().expect("Unable to find repo.");
    // If we can destructures the two optional args into real things.
    if let (Some(old_string), Some(new_string)) = (args.arg_old, args.arg_new) {
        // Compare a specific commit pair.
        // Fist, get the commits. (Error checked)
        let old = Oid::from_str(&old_string[]).and_then(|oid| repo.find_commit(oid));
        let new = Oid::from_str(&new_string[]).and_then(|oid| repo.find_commit(oid));
        if old.is_ok() && new.is_ok() {
            let output = find_moves(&repo, &old.unwrap(), &new.unwrap()).unwrap();
            make_output(output);
        } else {
            panic!("Commit ids were not valid.");
        }
    } else {
        // Revwalk.
        let mut revwalk = repo.revwalk()
            .ok().expect("Unable to get revwalk.");
        // Setup some options.
        revwalk.simplify_first_parent(); // TODO: Maybe remove?
        let mut flags = git2::Sort::empty();
        flags.insert(git2::SORT_TIME);
        flags.insert(git2::SORT_TOPOLOGICAL);
        revwalk.set_sorting(flags);
        // Push HEAD to the revwalk.
        revwalk.push_head()
            .ok().expect("Unable to push HEAD.");
        // We sadly must collect here to use `.windows()`
        let history = revwalk.filter_map(|id| repo.find_commit(id).ok())
            .collect::<Vec<Commit>>();
        // Walk through each pair of commits.
        for pair in history.windows(2) {let (old, new) = (&pair[1], &pair[0]);
			let output = find_moves(&repo, old.clone(), new.clone()).unwrap();
			// mangle the vectors here to make pretty output
			make_output(output);
		}
	}
}

fn make_output(output: Vec<Output>) {
	println!("make_output:");
    println!("\toutput.len()={}", output.len());
    for i in range(0, output.len()) {
            println!("\told_commit={}",         output[i].old_commit);
            println!("\tnew_commit={}",         output[i].new_commit);
            println!("\torigin_line={}",        output[i].origin_line);
            println!("\tdestintation_line={}",  output[i].destination_line);
            println!("\tnum_lines={}",          output[i].num_lines);
            println!("\tnew_filename={}",       output[i].new_filename);
            println!("\told_filename={}",       output[i].old_filename);
    }
}

#[derive(Debug, PartialEq, Eq)]
enum FoundState {
    Added, Deleted
}

fn dump_diffline(line: &DiffLine) {
    // 'origin' is wrapped in pipes to ease displaying space characters.
    print!("line: old={:?} new={:?} offset={} |origin|=|{}|\n      content={}",
             line.old_lineno(), line.new_lineno(), line.content_offset(),
             line.origin(), str::from_utf8(line.content()).unwrap());
}

fn dump_diffdelta(delta: &DiffDelta) {
    println!("delta: nfiles={} status={:?} old_file=(id={} path_bytes={:?} path={:?} tsize={}) new_file=(id={} path_bytes={:?} path={:?} tsize={})",
            delta.nfiles(), delta.status(),
            delta.old_file().id(), delta.old_file().path_bytes(), delta.old_file().path(), delta.old_file().size(),
            delta.new_file().id(), delta.new_file().path_bytes(), delta.new_file().path(), delta.new_file().size());
}

fn dump_diffhunk(hunk: &DiffHunk) {
    println!("hunk: old_start={} old_lines={} new_start={} new_lines={} header={}",
            hunk.old_start(), hunk.old_lines(),
            hunk.new_start(), hunk.new_lines(),
            str::from_utf8(hunk.header()).unwrap());
}

fn format_key(key: String) -> String {
    let remove_whitespace = regex!(r"\s{2,}"); // 2 or more whitespaces    // TODO Removes whitespace from a string.
    let trim = regex!(r"^[\s]+|[\s]+$");
    let result = remove_whitespace.replace_all(key.as_slice(), "");
    trim.replace_all(result.as_slice(), "")
}

#[derive(Debug)]
struct Found {
    filename: Path,
    key: String,
    state: FoundState,
    start_position: u32,
    line_count: u32,
}

fn find_keys(diff: Diff) -> Vec<Found> {

    #[derive(Debug)]
    enum State {
        Other, Addition, Deletion
    }

    let mut founds: Vec<Found> = Vec::new();

    let mut state = State::Other;
    let mut added = String::new();
    let mut deleted = String::new();
    let mut old_path = Path::new("");
    let mut new_path = Path::new("");

    let mut line_count: u32 = 0;
    let mut start_position: u32 = 0;

	// Read about this function in http://alexcrichton.com/git2-rs/git2/struct.Diff.html#method.print
	// It's a bit weird, but I think it will provide the necessary information.
	diff.print(DiffFormat::Patch, |delta, maybe_hunk, line| -> bool {

        assert!(delta.nfiles() == 2, "This only works on diffs between exactly 2 files. Found {} files.", delta.nfiles());

		// Thinking:
		//  * If is not a hunk, keep going.
		//  * If it's a hunk, do regex magic.
		//  * Stick regex output into a hashmap as a hash.
		//  * Later, we will iterate through and output pased on the values.
		// Filter out all the boring context lines.
		// If we're not interested in this line just return since it will iterate to the next.
		if maybe_hunk.is_none() { return true }; // Return early.

        println!("top of loop: founds={:?}", founds);
        println!("top of loop: added={:?} deleted={:?}", added, deleted);
        println!("top of loop: line_count={:?}", line_count);

        dump_diffline(&line);
        //dump_diffdelta(&delta);
        //dump_diffhunk(&maybe_hunk.unwrap());

        old_path = delta.old_file().path().unwrap().clone();
        new_path = delta.new_file().path().unwrap().clone();

		match line.origin() {
			// Additions
			'+' | '>' => {
                println!("In additions. state={:?}", state);

                added.push_str(str::from_utf8(line.content()).unwrap());

                match state {
                    State::Deletion => {
                        founds.push(Found {
                            filename: old_path.clone(),
                            key: format_key(deleted.clone()),
                            state: FoundState::Deleted,
                            start_position: start_position,
                            line_count: line_count,
                        });
                        deleted = String::new();
                        line_count = 0;
                        start_position = line.new_lineno().unwrap();
                    },
                    State::Addition => {
                        line_count += 1;
                    },
                    State::Other => {
                        line_count = 1;
                        start_position = line.new_lineno().unwrap();
                    },
                }

                state = State::Addition;
				true
			},
			// Deletions
			'-' | '<' => {
                println!("In deletion. state={:?}", state);

                deleted.push_str(str::from_utf8(line.content()).unwrap());

                match state {
                    State::Addition => {
                        founds.push(Found {
                            filename: new_path.clone(),
                            key: format_key(added.clone()),
                            state: FoundState::Added,
                            start_position: start_position,
                            line_count: line_count,
                        });
                        added = String::new();
                        line_count = 0;
                        start_position = line.old_lineno().unwrap();
                    },
                    State::Deletion => {
                        line_count += 1;
                    },
                    State::Other => {
                        line_count = 1;
                        start_position = line.old_lineno().unwrap();
                    },
                }

                state = State::Deletion;
				true
			},
			// Other
			_         => {
                println!("in _. state={:?}", state);

                match state {
                    State::Addition => {
                        founds.push(Found {
                            filename: new_path.clone(),
                            key: format_key(added.clone()),
                            state: FoundState::Added,
                            start_position: start_position,
                            line_count: line_count,
                        });
                        added = String::new();
                    },
                    State::Deletion => {
                        founds.push(Found {
                            filename: old_path.clone(),
                            key: format_key(deleted.clone()),
                            state: FoundState::Deleted,
                            start_position: start_position,
                            line_count: line_count,
                        });
                        deleted = String::new();
                    },
                    _ => (),
                }

                state = State::Other;
                true
            }
		}
	});

    // Grab last one.
    match state {
        State::Addition => {
            if added.len() > 0 {
                founds.push(Found {
                    filename: new_path,
                    key: format_key(added.clone()),
                    state: FoundState::Added,
                    start_position: start_position,
                    line_count: line_count,
                });
            }
        },
        State::Deletion => {
            if deleted.len() > 0 {
                founds.push(Found {
                    filename: old_path,
                    key: format_key(deleted.clone()),
                    state: FoundState::Deleted,
                    start_position: start_position,
                    line_count: line_count,
                });
            }
        },
        _ => (),
    }

    return founds;
}

fn path_to_string(path: Path) -> String {
    String::from_utf8(path.into_vec()).unwrap()
}

fn find_moves(repo: &Repository, old: &Commit, new: &Commit) -> Result<Vec<Output>, Error> {

    println!("\nFIND MOVES---------------------");

	let old_tree = try!(old.tree());
	let new_tree = try!(new.tree());
	// Build up a diff of the two trees.
	let diff = try!(Diff::tree_to_tree(repo, Some(&old_tree), Some(&new_tree), None));

    let founds: Vec<Found> = find_keys(diff);

    println!("FOUNDS={:?}", founds);

    let mut moves: Vec<Output> = Vec::new();

    let mut map: HashMap<String, Found> = HashMap::new();

    for f in founds {
        if f.key.len() == 0 { continue; }

        if map.contains_key(&f.key) {
            let q = map.get(&f.key).unwrap();
            if q.line_count == f.line_count {

                assert!(f.state != q.state, "One state must be an addition and the other state must be a deletion.");

                let output: Output;

                match f.state {
                    FoundState::Added => {
                        output = Output {
                            old_commit: old.id(),
                            new_commit: new.id(),
                            old_filename: path_to_string(q.filename.clone()),
                            new_filename: path_to_string(f.filename.clone()),
                            origin_line: q.start_position,
                            destination_line: f.start_position,
                            num_lines: f.line_count,
                        };
                    },
                    FoundState::Deleted => {
                        output = Output {
                            old_commit: old.id(),
                            new_commit: new.id(),
                            old_filename: path_to_string(f.filename.clone()),
                            new_filename: path_to_string(q.filename.clone()),
                            origin_line: f.start_position,
                            destination_line: q.start_position,
                            num_lines: f.line_count,
                        };
                    },
                }

                moves.push(output);
            }
        } else {
            map.insert(f.key.clone(), f);
        }
    }

    return Ok(moves);
}

#[derive(Debug)]
struct Output {
    old_commit: Oid,
    new_commit: Oid,
    old_filename: String,
    new_filename: String,
    origin_line: u32,
    destination_line: u32,
    num_lines: u32,
}
<commit_msg>Remove or silence debugging output.<commit_after>#![feature(core)]
#![feature(path)]

#![feature(plugin)]
#![plugin(regex_macros)]
extern crate regex;
extern crate git2;
extern crate "rustc-serialize" as rustc_serialize;
extern crate docopt;

use git2::{Repository, Branch, BranchType, DiffLine,
    Commit, Diff, DiffFormat, DiffDelta, DiffHunk, Error, Oid};
use docopt::Docopt;
use std::old_io as io;
use std::collections::HashMap;
use std::old_io::BufferedReader;
use std::old_io::File;
use std::str;
use regex::Regex;

// Write the Docopt usage string.
static USAGE: &'static str = "
Usage: transit <repo> [<old> <new>]

If no commits are given, transit will revwalk from latest to oldest.
";

#[derive(RustcDecodable, Debug)]
struct Args {
    arg_repo: String,
    arg_old: Option<String>,
    arg_new: Option<String>,
}

fn main() {
    // Parse the args above or die.
    let args: Args = Docopt::new(USAGE)
        .and_then(|d| d.decode())
        .unwrap_or_else(|e| e.exit());
    // Pull up the revwalk.
    let path = Path::new(args.arg_repo);
    let repo = Repository::discover(&path)
        .ok().expect("Unable to find repo.");
    // If we can destructures the two optional args into real things.
    if let (Some(old_string), Some(new_string)) = (args.arg_old, args.arg_new) {
        // Compare a specific commit pair.
        // Fist, get the commits. (Error checked)
        let old = Oid::from_str(&old_string[]).and_then(|oid| repo.find_commit(oid));
        let new = Oid::from_str(&new_string[]).and_then(|oid| repo.find_commit(oid));
        if old.is_ok() && new.is_ok() {
            let output = find_moves(&repo, &old.unwrap(), &new.unwrap()).unwrap();
            make_output(output);
        } else {
            panic!("Commit ids were not valid.");
        }
    } else {
        // Revwalk.
        let mut revwalk = repo.revwalk()
            .ok().expect("Unable to get revwalk.");
        // Setup some options.
        revwalk.simplify_first_parent(); // TODO: Maybe remove?
        let mut flags = git2::Sort::empty();
        flags.insert(git2::SORT_TIME);
        flags.insert(git2::SORT_TOPOLOGICAL);
        revwalk.set_sorting(flags);
        // Push HEAD to the revwalk.
        revwalk.push_head()
            .ok().expect("Unable to push HEAD.");
        // We sadly must collect here to use `.windows()`
        let history = revwalk.filter_map(|id| repo.find_commit(id).ok())
            .collect::<Vec<Commit>>();
        // Walk through each pair of commits.
        for pair in history.windows(2) {let (old, new) = (&pair[1], &pair[0]);
			let output = find_moves(&repo, old.clone(), new.clone()).unwrap();
			// mangle the vectors here to make pretty output
			make_output(output);
		}
	}
}

fn make_output(output: Vec<Output>) {
	println!("make_output:");
    println!("\toutput.len()={}", output.len());
    for i in range(0, output.len()) {
            println!("\told_commit={}",         output[i].old_commit);
            println!("\tnew_commit={}",         output[i].new_commit);
            println!("\torigin_line={}",        output[i].origin_line);
            println!("\tdestintation_line={}",  output[i].destination_line);
            println!("\tnum_lines={}",          output[i].num_lines);
            println!("\tnew_filename={}",       output[i].new_filename);
            println!("\told_filename={}",       output[i].old_filename);
    }
}

#[derive(Debug, PartialEq, Eq)]
enum FoundState {
    Added, Deleted
}

fn dump_diffline(line: &DiffLine) {
    // 'origin' is wrapped in pipes to ease displaying space characters.
    print!("line: old={:?} new={:?} offset={} |origin|=|{}|\n      content={}",
             line.old_lineno(), line.new_lineno(), line.content_offset(),
             line.origin(), str::from_utf8(line.content()).unwrap());
}

fn dump_diffdelta(delta: &DiffDelta) {
    println!("delta: nfiles={} status={:?} old_file=(id={} path_bytes={:?} path={:?} tsize={}) new_file=(id={} path_bytes={:?} path={:?} tsize={})",
            delta.nfiles(), delta.status(),
            delta.old_file().id(), delta.old_file().path_bytes(), delta.old_file().path(), delta.old_file().size(),
            delta.new_file().id(), delta.new_file().path_bytes(), delta.new_file().path(), delta.new_file().size());
}

fn dump_diffhunk(hunk: &DiffHunk) {
    println!("hunk: old_start={} old_lines={} new_start={} new_lines={} header={}",
            hunk.old_start(), hunk.old_lines(),
            hunk.new_start(), hunk.new_lines(),
            str::from_utf8(hunk.header()).unwrap());
}

fn format_key(key: String) -> String {
    let remove_whitespace = regex!(r"\s{2,}"); // 2 or more whitespaces    // TODO Removes whitespace from a string.
    let trim = regex!(r"^[\s]+|[\s]+$");
    let result = remove_whitespace.replace_all(key.as_slice(), "");
    trim.replace_all(result.as_slice(), "")
}

#[derive(Debug)]
struct Found {
    filename: Path,
    key: String,
    state: FoundState,
    start_position: u32,
    line_count: u32,
}

fn find_keys(diff: Diff) -> Vec<Found> {

    #[derive(Debug)]
    enum State {
        Other, Addition, Deletion
    }

    let mut founds: Vec<Found> = Vec::new();

    let mut state = State::Other;
    let mut added = String::new();
    let mut deleted = String::new();
    let mut old_path = Path::new("");
    let mut new_path = Path::new("");

    let mut line_count: u32 = 0;
    let mut start_position: u32 = 0;

	// Read about this function in http://alexcrichton.com/git2-rs/git2/struct.Diff.html#method.print
	// It's a bit weird, but I think it will provide the necessary information.
	diff.print(DiffFormat::Patch, |delta, maybe_hunk, line| -> bool {

        assert!(delta.nfiles() == 2, "This only works on diffs between exactly 2 files. Found {} files.", delta.nfiles());

		// Thinking:
		//  * If is not a hunk, keep going.
		//  * If it's a hunk, do regex magic.
		//  * Stick regex output into a hashmap as a hash.
		//  * Later, we will iterate through and output pased on the values.
		// Filter out all the boring context lines.
		// If we're not interested in this line just return since it will iterate to the next.
		if maybe_hunk.is_none() { return true }; // Return early.

        //dump_diffline(&line);
        //dump_diffdelta(&delta);
        //dump_diffhunk(&maybe_hunk.unwrap());

        old_path = delta.old_file().path().unwrap().clone();
        new_path = delta.new_file().path().unwrap().clone();

		match line.origin() {
			// Additions
			'+' | '>' => {
                added.push_str(str::from_utf8(line.content()).unwrap());

                match state {
                    State::Deletion => {
                        founds.push(Found {
                            filename: old_path.clone(),
                            key: format_key(deleted.clone()),
                            state: FoundState::Deleted,
                            start_position: start_position,
                            line_count: line_count,
                        });
                        deleted = String::new();
                        line_count = 0;
                        start_position = line.new_lineno().unwrap();
                    },
                    State::Addition => {
                        line_count += 1;
                    },
                    State::Other => {
                        line_count = 1;
                        start_position = line.new_lineno().unwrap();
                    },
                }

                state = State::Addition;
				true
			},
			// Deletions
			'-' | '<' => {
                deleted.push_str(str::from_utf8(line.content()).unwrap());

                match state {
                    State::Addition => {
                        founds.push(Found {
                            filename: new_path.clone(),
                            key: format_key(added.clone()),
                            state: FoundState::Added,
                            start_position: start_position,
                            line_count: line_count,
                        });
                        added = String::new();
                        line_count = 0;
                        start_position = line.old_lineno().unwrap();
                    },
                    State::Deletion => {
                        line_count += 1;
                    },
                    State::Other => {
                        line_count = 1;
                        start_position = line.old_lineno().unwrap();
                    },
                }

                state = State::Deletion;
				true
			},
			// Other
			_         => {
                match state {
                    State::Addition => {
                        founds.push(Found {
                            filename: new_path.clone(),
                            key: format_key(added.clone()),
                            state: FoundState::Added,
                            start_position: start_position,
                            line_count: line_count,
                        });
                        added = String::new();
                    },
                    State::Deletion => {
                        founds.push(Found {
                            filename: old_path.clone(),
                            key: format_key(deleted.clone()),
                            state: FoundState::Deleted,
                            start_position: start_position,
                            line_count: line_count,
                        });
                        deleted = String::new();
                    },
                    _ => (),
                }

                state = State::Other;
                true
            }
		}
	});

    // Grab last one.
    match state {
        State::Addition => {
            if added.len() > 0 {
                founds.push(Found {
                    filename: new_path,
                    key: format_key(added.clone()),
                    state: FoundState::Added,
                    start_position: start_position,
                    line_count: line_count,
                });
            }
        },
        State::Deletion => {
            if deleted.len() > 0 {
                founds.push(Found {
                    filename: old_path,
                    key: format_key(deleted.clone()),
                    state: FoundState::Deleted,
                    start_position: start_position,
                    line_count: line_count,
                });
            }
        },
        _ => (),
    }

    return founds;
}

fn path_to_string(path: Path) -> String {
    String::from_utf8(path.into_vec()).unwrap()
}

fn find_moves(repo: &Repository, old: &Commit, new: &Commit) -> Result<Vec<Output>, Error> {
	let old_tree = try!(old.tree());
	let new_tree = try!(new.tree());
	// Build up a diff of the two trees.
	let diff = try!(Diff::tree_to_tree(repo, Some(&old_tree), Some(&new_tree), None));

    let founds: Vec<Found> = find_keys(diff);

    let mut moves: Vec<Output> = Vec::new();
    let mut map: HashMap<String, Found> = HashMap::new();

    for f in founds {
        if f.key.len() == 0 { continue; }

        if map.contains_key(&f.key) {
            let q = map.get(&f.key).unwrap();
            if q.line_count == f.line_count {

                assert!(f.state != q.state, "One state must be an addition and the other state must be a deletion.");

                let output: Output;

                match f.state {
                    FoundState::Added => {
                        output = Output {
                            old_commit: old.id(),
                            new_commit: new.id(),
                            old_filename: path_to_string(q.filename.clone()),
                            new_filename: path_to_string(f.filename.clone()),
                            origin_line: q.start_position,
                            destination_line: f.start_position,
                            num_lines: f.line_count,
                        };
                    },
                    FoundState::Deleted => {
                        output = Output {
                            old_commit: old.id(),
                            new_commit: new.id(),
                            old_filename: path_to_string(f.filename.clone()),
                            new_filename: path_to_string(q.filename.clone()),
                            origin_line: f.start_position,
                            destination_line: q.start_position,
                            num_lines: f.line_count,
                        };
                    },
                }

                moves.push(output);
            }
        } else {
            map.insert(f.key.clone(), f);
        }
    }

    return Ok(moves);
}

#[derive(Debug)]
struct Output {
    old_commit: Oid,
    new_commit: Oid,
    old_filename: String,
    new_filename: String,
    origin_line: u32,
    destination_line: u32,
    num_lines: u32,
}
<|endoftext|>


<commit_before>#![recursion_limit = "128"]

extern crate ape;
extern crate app_dirs;
extern crate core;
#[macro_use]
extern crate diesel;
#[macro_use]
extern crate diesel_codegen;
#[macro_use]
extern crate error_chain;
extern crate getopts;
extern crate hyper;
extern crate id3;
extern crate image;
extern crate iron;
extern crate lewton;
extern crate metaflac;
extern crate mount;
extern crate params;
extern crate rand;
extern crate reqwest;
extern crate regex;
extern crate ring;
extern crate router;
extern crate secure_session;
extern crate serde;
#[macro_use]
extern crate serde_derive;
extern crate serde_json;
extern crate staticfile;
extern crate toml;
extern crate typemap;
extern crate url;
#[macro_use]
extern crate log;
extern crate simplelog;

#[cfg(windows)]
extern crate uuid;
#[cfg(windows)]
extern crate winapi;
#[cfg(windows)]
extern crate kernel32;
#[cfg(windows)]
extern crate shell32;
#[cfg(windows)]
extern crate user32;

#[cfg(unix)]
extern crate unix_daemonize;

#[cfg(unix)]
use unix_daemonize::{daemonize_redirect, ChdirMode};
#[cfg(unix)]
use std::fs::File;
#[cfg(unix)]
use std::io::prelude::*;

use core::ops::Deref;
use errors::*;
use getopts::Options;
use iron::prelude::*;
use mount::Mount;
use staticfile::Static;
use std::path::Path;
use std::sync::{Arc, Mutex};
use std::sync::mpsc::channel;
use simplelog::{Config, TermLogger, LogLevelFilter};

mod api;
mod config;
mod db;
mod ddns;
mod errors;
mod index;
mod metadata;
mod playlist;
mod ui;
mod user;
mod utils;
mod serve;
mod thumbnails;
mod vfs;

fn main() {
	if let Err(ref e) = run() {
		println!("Error: {}", e);

		for e in e.iter().skip(1) {
			println!("caused by: {}", e);
		}
		if let Some(backtrace) = e.backtrace() {
			println!("backtrace: {:?}", backtrace);
		}
		::std::process::exit(1);
	}
}

#[cfg(unix)]
fn daemonize(options: &getopts::Matches) -> Result<()> {
	if options.opt_present("f") {
		return Ok(());
	}
	let mut log_file = utils::get_data_root()?;
	log_file.push("polaris.log");
	let pid = match daemonize_redirect(Some(&log_file), Some(&log_file), ChdirMode::NoChdir) {
		Ok(p) => p,
		Err(_) => bail!(ErrorKind::DaemonError),
	};
	let mut pid_path = utils::get_data_root()?;
	pid_path.push("polaris.pid");
	let mut file = File::create(pid_path)?;
	file.write_all(pid.to_string().as_bytes())?;
	Ok(())
}

fn run() -> Result<()> {

	// Parse CLI options
	let args: Vec<String> = std::env::args().collect();
	let mut options = Options::new();
	options.optopt("c", "config", "set the configuration file", "FILE");
	options.optopt("p", "port", "set polaris to run on a custom port", "PORT");
	options.optopt("d", "database", "set the path to index database", "FILE");
	options.optopt("w", "web", "set the path to web client files", "DIRECTORY");
	options.optopt("l",
	               "log",
	               "set the log level to a value between 0 (off) and 3 (debug)",
	               "LEVEL");

	#[cfg(unix)]
	options.optflag("f",
	                "foreground",
	                "run polaris in the foreground instead of daemonizing");

	options.optflag("h", "help", "print this help menu");

	let matches = options.parse(&args[1..])?;

	if matches.opt_present("h") {
		let program = args[0].clone();
		let brief = format!("Usage: {} [options]", program);
		print!("{}", options.usage(&brief));
		return Ok(());
	}

	let log_level = match matches.opt_str("l").as_ref().map(String::as_ref) {
		Some("0") => LogLevelFilter::Off,
		Some("1") => LogLevelFilter::Error,
		Some("2") => LogLevelFilter::Info,
		Some("3") => LogLevelFilter::Debug,
		_ => LogLevelFilter::Info,
	};

	if let Err(e) = TermLogger::init(log_level, Config::default()) {
		bail!("Error starting logger: {}", e);
	};

	#[cfg(unix)]
	daemonize(&matches)?;

	// Init DB
	info!("Starting up database");
	let db_path = matches.opt_str("d");
	let mut default_db_path = utils::get_data_root()?;
	default_db_path.push("db.sqlite");
	let db_path = db_path
		.map(|n| Path::new(n.as_str()).to_path_buf())
		.unwrap_or(default_db_path);
	let db = Arc::new(db::DB::new(&db_path)?);

	// Parse config
	let config_file_name = matches.opt_str("c");
	let config_file_path = config_file_name.map(|p| Path::new(p.as_str()).to_path_buf());
	if let Some(path) = config_file_path {
		let config = config::parse_toml_file(&path)?;
		config::overwrite(db.deref(), &config)?;
	}
	let config = config::read(db.deref())?;

	// Init index
	let (index_sender, index_receiver) = channel();
	let index_sender = Arc::new(Mutex::new(index_sender));
	let db_ref = db.clone();
	std::thread::spawn(move || {
		                   let db = db_ref.deref();
		                   index::update_loop(db, index_receiver);
		                  });

	// Trigger auto-indexing
	let db_ref = db.clone();
	let sender_ref = index_sender.clone();
	std::thread::spawn(move || { index::self_trigger(db_ref.deref(), sender_ref); });

	// Mount API
	let prefix_url = config.prefix_url.unwrap_or("".to_string());
	let api_url = format!("{}/api", &prefix_url);
	info!("Mounting API on {}", api_url);
	let mut mount = Mount::new();
	let handler = api::get_handler(db.clone(), index_sender)?;
	mount.mount(&api_url, handler);

	// Mount static files
	let static_url = format!("/{}", &prefix_url);

	info!("Mounting static files on {}", static_url);
	let web_dir_name = matches.opt_str("w");
	let mut default_web_dir = utils::get_data_root()?;
	default_web_dir.push("web");
	let web_dir_path = web_dir_name
		.map(|n| Path::new(n.as_str()).to_path_buf())
		.unwrap_or(default_web_dir);

	mount.mount(&static_url, Static::new(web_dir_path));

	info!("Starting up server");
	let port: u16 = matches
		.opt_str("p")
		.unwrap_or("5050".to_owned())
		.parse()
		.or(Err("invalid port number"))?;

	let mut server = match Iron::new(mount).http(("0.0.0.0", port)) {
		Ok(s) => s,
		Err(e) => bail!("Error starting up server: {}", e),
	};

	// Start DDNS updates
	let db_ref = db.clone();
	std::thread::spawn(move || { ddns::run(db_ref.deref()); });

	// Run UI
	ui::run();

	info!("Shutting down server");
	if let Err(e) = server.close() {
		bail!("Error shutting down server: {}", e);
	}

	Ok(())
}
<commit_msg>Fixed startup error when terminal isn't available<commit_after>#![recursion_limit = "128"]

extern crate ape;
extern crate app_dirs;
extern crate core;
#[macro_use]
extern crate diesel;
#[macro_use]
extern crate diesel_codegen;
#[macro_use]
extern crate error_chain;
extern crate getopts;
extern crate hyper;
extern crate id3;
extern crate image;
extern crate iron;
extern crate lewton;
extern crate metaflac;
extern crate mount;
extern crate params;
extern crate rand;
extern crate reqwest;
extern crate regex;
extern crate ring;
extern crate router;
extern crate secure_session;
extern crate serde;
#[macro_use]
extern crate serde_derive;
extern crate serde_json;
extern crate staticfile;
extern crate toml;
extern crate typemap;
extern crate url;
#[macro_use]
extern crate log;
extern crate simplelog;

#[cfg(windows)]
extern crate uuid;
#[cfg(windows)]
extern crate winapi;
#[cfg(windows)]
extern crate kernel32;
#[cfg(windows)]
extern crate shell32;
#[cfg(windows)]
extern crate user32;

#[cfg(unix)]
extern crate unix_daemonize;

#[cfg(unix)]
use unix_daemonize::{daemonize_redirect, ChdirMode};
#[cfg(unix)]
use std::fs::File;
#[cfg(unix)]
use std::io::prelude::*;

use core::ops::Deref;
use errors::*;
use getopts::Options;
use iron::prelude::*;
use mount::Mount;
use staticfile::Static;
use std::path::Path;
use std::sync::{Arc, Mutex};
use std::sync::mpsc::channel;
use simplelog::{Config, TermLogger, LogLevelFilter};
#[cfg(unix)]
use simplelog::{SimpleLogger};

mod api;
mod config;
mod db;
mod ddns;
mod errors;
mod index;
mod metadata;
mod playlist;
mod ui;
mod user;
mod utils;
mod serve;
mod thumbnails;
mod vfs;

fn main() {
	if let Err(ref e) = run() {
		println!("Error: {}", e);

		for e in e.iter().skip(1) {
			println!("caused by: {}", e);
		}
		if let Some(backtrace) = e.backtrace() {
			println!("backtrace: {:?}", backtrace);
		}
		::std::process::exit(1);
	}
}

#[cfg(unix)]
fn daemonize(options: &getopts::Matches) -> Result<()> {
	if options.opt_present("f") {
		return Ok(());
	}
	let mut log_file = utils::get_data_root()?;
	log_file.push("polaris.log");
	let pid = match daemonize_redirect(Some(&log_file), Some(&log_file), ChdirMode::NoChdir) {
		Ok(p) => p,
		Err(_) => bail!(ErrorKind::DaemonError),
	};
	let mut pid_path = utils::get_data_root()?;
	pid_path.push("polaris.pid");
	let mut file = File::create(pid_path)?;
	file.write_all(pid.to_string().as_bytes())?;
	Ok(())
}

#[cfg(unix)]
fn init_log(log_level: LogLevelFilter, options: &getopts::Matches) -> Result<()> {
	if options.opt_present("f") {
		if let Err(e) = TermLogger::init(log_level, Config::default()) {
			bail!("Error starting terminal logger: {}", e);
		};
	}
	else
	{
		if let Err(e) = SimpleLogger::init(log_level, Config::default()) {
			bail!("Error starting simple logger: {}", e);
		}
	}
	Ok(())
}

#[cfg(windows)]
fn init_log(log_level: LogLevelFilter, _: &getopts::Matches) -> Result<()> {
	if let Err(e) = TermLogger::init(log_level, Config::default()) {
		bail!("Error starting terminal logger: {}", e);
	};
	Ok(())
}

fn run() -> Result<()> {

	// Parse CLI options
	let args: Vec<String> = std::env::args().collect();
	let mut options = Options::new();
	options.optopt("c", "config", "set the configuration file", "FILE");
	options.optopt("p", "port", "set polaris to run on a custom port", "PORT");
	options.optopt("d", "database", "set the path to index database", "FILE");
	options.optopt("w", "web", "set the path to web client files", "DIRECTORY");
	options.optopt("l",
	               "log",
	               "set the log level to a value between 0 (off) and 3 (debug)",
	               "LEVEL");

	#[cfg(unix)]
	options.optflag("f",
	                "foreground",
	                "run polaris in the foreground instead of daemonizing");

	options.optflag("h", "help", "print this help menu");

	let matches = options.parse(&args[1..])?;

	if matches.opt_present("h") {
		let program = args[0].clone();
		let brief = format!("Usage: {} [options]", program);
		print!("{}", options.usage(&brief));
		return Ok(());
	}

	let log_level = match matches.opt_str("l").as_ref().map(String::as_ref) {
		Some("0") => LogLevelFilter::Off,
		Some("1") => LogLevelFilter::Error,
		Some("2") => LogLevelFilter::Info,
		Some("3") => LogLevelFilter::Debug,
		_ => LogLevelFilter::Info,
	};

	init_log(log_level, &matches)?;

	#[cfg(unix)]
	daemonize(&matches)?;

	// Init DB
	info!("Starting up database");
	let db_path = matches.opt_str("d");
	let mut default_db_path = utils::get_data_root()?;
	default_db_path.push("db.sqlite");
	let db_path = db_path
		.map(|n| Path::new(n.as_str()).to_path_buf())
		.unwrap_or(default_db_path);
	let db = Arc::new(db::DB::new(&db_path)?);

	// Parse config
	let config_file_name = matches.opt_str("c");
	let config_file_path = config_file_name.map(|p| Path::new(p.as_str()).to_path_buf());
	if let Some(path) = config_file_path {
		let config = config::parse_toml_file(&path)?;
		config::overwrite(db.deref(), &config)?;
	}
	let config = config::read(db.deref())?;

	// Init index
	let (index_sender, index_receiver) = channel();
	let index_sender = Arc::new(Mutex::new(index_sender));
	let db_ref = db.clone();
	std::thread::spawn(move || {
		                   let db = db_ref.deref();
		                   index::update_loop(db, index_receiver);
		                  });

	// Trigger auto-indexing
	let db_ref = db.clone();
	let sender_ref = index_sender.clone();
	std::thread::spawn(move || { index::self_trigger(db_ref.deref(), sender_ref); });

	// Mount API
	let prefix_url = config.prefix_url.unwrap_or("".to_string());
	let api_url = format!("{}/api", &prefix_url);
	info!("Mounting API on {}", api_url);
	let mut mount = Mount::new();
	let handler = api::get_handler(db.clone(), index_sender)?;
	mount.mount(&api_url, handler);

	// Mount static files
	let static_url = format!("/{}", &prefix_url);

	info!("Mounting static files on {}", static_url);
	let web_dir_name = matches.opt_str("w");
	let mut default_web_dir = utils::get_data_root()?;
	default_web_dir.push("web");
	let web_dir_path = web_dir_name
		.map(|n| Path::new(n.as_str()).to_path_buf())
		.unwrap_or(default_web_dir);

	mount.mount(&static_url, Static::new(web_dir_path));

	info!("Starting up server");
	let port: u16 = matches
		.opt_str("p")
		.unwrap_or("5050".to_owned())
		.parse()
		.or(Err("invalid port number"))?;

	let mut server = match Iron::new(mount).http(("0.0.0.0", port)) {
		Ok(s) => s,
		Err(e) => bail!("Error starting up server: {}", e),
	};

	// Start DDNS updates
	let db_ref = db.clone();
	std::thread::spawn(move || { ddns::run(db_ref.deref()); });

	// Run UI
	ui::run();

	info!("Shutting down server");
	if let Err(e) = server.close() {
		bail!("Error shutting down server: {}", e);
	}

	Ok(())
}
<|endoftext|>


<commit_before>#[macro_use]
mod util;

use crate::util::DisplayName;
use clang::{self, Clang, Entity, EntityKind, Index, SourceError, Type};

fn main() -> Result<(), SourceError> {
    let clang = Clang::new().unwrap();
    let index = Index::new(&clang, false, true);

    let file = index
        .parser("examples/example.cc")
        .skip_function_bodies(true)
        .arguments(&[
            "-std=c++17",
            "-isysroot",
            "/Library/Developer/CommandLineTools/SDKs/MacOSX.sdk",
        ])
        .parse()?;

    let mut visitor = Visitor::new();
    visitor.visit_children(file.get_entity());

    Ok(())
}

struct Visitor<'cpp> {
    namespace: String,
    current_ty: Option<Type<'cpp>>,
    indent: usize,
}

impl<'cpp> Visitor<'cpp> {
    fn new() -> Visitor<'cpp> {
        Visitor {
            namespace: String::new(),
            current_ty: None,
            indent: 0,
        }
    }

    fn visit_children(&mut self, ent: Entity<'cpp>) {
        let entities = ent.get_children().into_iter();
        for ent in entities {
            use EntityKind::*;
            match ent.get_kind() {
                Namespace => self.handle_namespace(ent),
                StructDecl | ClassDecl => self.handle_struct(ent),
                FieldDecl => self.handle_field(ent),
                Method => self.handle_method(ent),
                TypedefDecl => self.handle_typedef(ent),
                ClassTemplate => self.handle_class_template(ent),
                _ => (),
            }
        }
    }

    fn handle_namespace(&mut self, ns: Entity<'cpp>) {
        let full = format!("{}::{}", self.namespace, ns.display_name());
        let orig = std::mem::replace(&mut self.namespace, full);
        self.visit_children(ns);
        self.namespace = orig;
    }

    fn handle_struct(&mut self, st: Entity<'cpp>) {
        let ty = st.get_type().unwrap();
        print_indent!(self, "struct {}::{}", self.namespace, st.display_name());
        match ty.get_sizeof() {
            Ok(size) => println!(" ({} bytes)", size),
            Err(e) => println!(" ({})", e),
        }
        self.indent += 1;
        self.visit_with_ty(Some(ty), st);
        self.indent -= 1;
    }

    fn handle_field(&mut self, field: Entity<'cpp>) {
        match field.get_name() {
            Some(name) => {
                print_indent!(self, "{}", field.display_name());
                if let Some(ty) = field.get_type() {
                    print!(": {}", ty.display_name());
                }
                if let Some(struct_ty) = self.current_ty {
                    match struct_ty.get_offsetof(&name) {
                        Ok(offset) => print!(" (offset {} bits)", offset),
                        Err(e) => print!(" ({})", e),
                    }
                }
                println!();
            }
            None => {
                println!("field: {}", field.display_name());
            }
        }
    }

    fn handle_method(&mut self, meth: Entity<'cpp>) {
        print_indent!(self, "{}", meth.display_name());
        if let Some(ty) = meth.get_result_type() {
            print!(" -> {}", ty.display_name());
        }
        println!();
    }

    fn handle_typedef(&mut self, td: Entity<'cpp>) {
        println_indent!(
            self,
            "typedef {} = {}",
            td.display_name(),
            td.get_type().unwrap().display_name()
        );
    }

    fn handle_class_template(&mut self, t: Entity<'cpp>) {
        println_indent!(self, "template {}", t.display_name());
        self.indent += 1;
        self.visit_with_ty(None, t);
        self.indent -= 1;
    }

    fn visit_with_ty(&mut self, ty: Option<Type<'cpp>>, ent: Entity<'cpp>) {
        let orig = std::mem::replace(&mut self.current_ty, ty);
        self.visit_children(ent);
        self.current_ty = orig;
    }
}
<commit_msg>Add BindGen to hold binding state<commit_after>#[macro_use]
mod util;

use crate::util::DisplayName;
use clang::{self, Clang, Entity, EntityKind, Index, SourceError, Type};
use std::collections::HashSet;

fn main() -> Result<(), SourceError> {
    let clang = Clang::new().unwrap();
    BindGen::new(&clang)
        // TODO how do I remove this magic __1?
        .add_item("::std::__1::vector")
        .parse("examples/example.cc")?;
    Ok(())
}

struct BindGen<'cl> {
    index: Index<'cl>,
    items: HashSet<String>,
}

impl<'cl> BindGen<'cl> {
    fn new(clang: &'cl Clang) -> Self {
        let index = Index::new(&clang, false, true);
        BindGen {
            index,
            items: HashSet::new(),
        }
    }

    fn add_item(&mut self, item: &str) -> &mut Self {
        self.items.insert(item.to_string());
        self
    }

    fn parse(&mut self, filename: &str) -> Result<&mut Self, SourceError> {
        {
            let file = self
                .index
                .parser(filename)
                .skip_function_bodies(true)
                .arguments(&[
                    "-std=c++17",
                    "-isysroot",
                    "/Library/Developer/CommandLineTools/SDKs/MacOSX.sdk",
                ])
                .parse()?;
            let mut visitor = Visitor::new(&self);
            visitor.visit_children(file.get_entity());
        }
        Ok(self)
    }

    // Called by Visitor when we hit an entity in self.items.
    fn lower(&self, ent: Entity<'cl>) {
        println!("lowering {:?}", ent);
    }
}

struct Visitor<'cpp> {
    bindgen: &'cpp BindGen<'cpp>,
    namespace: String,
    current_ty: Option<Type<'cpp>>,
    indent: usize,
}

impl<'cpp> Visitor<'cpp> {
    fn new(bindgen: &'cpp BindGen<'cpp>) -> Visitor<'cpp> {
        Visitor {
            bindgen,
            namespace: String::new(),
            current_ty: None,
            indent: 0,
        }
    }

    fn visit_children(&mut self, ent: Entity<'cpp>) {
        let entities = ent.get_children().into_iter();
        for ent in entities {
            use EntityKind::*;
            match ent.get_kind() {
                Namespace => self.handle_namespace(ent),
                StructDecl | ClassDecl => self.handle_struct(ent),
                FieldDecl => self.handle_field(ent),
                Method => self.handle_method(ent),
                TypedefDecl => self.handle_typedef(ent),
                ClassTemplate => self.handle_class_template(ent),
                _ => (),
            }
        }
    }

    fn handle_namespace(&mut self, ns: Entity<'cpp>) {
        let full = format!("{}::{}", self.namespace, ns.display_name());
        let orig = std::mem::replace(&mut self.namespace, full);
        self.visit_children(ns);
        self.namespace = orig;
    }

    fn handle_struct(&mut self, st: Entity<'cpp>) {
        print_indent!(self, "struct {}::{}", self.namespace, st.display_name());
        let ty = st.get_type().unwrap();
        match ty.get_sizeof() {
            Ok(size) => println!(" ({} bytes)", size),
            Err(e) => println!(" ({})", e),
        }

        self.maybe_bindgen(st);

        self.indent += 1;
        self.visit_with_ty(Some(ty), st);
        self.indent -= 1;
    }

    fn handle_field(&mut self, field: Entity<'cpp>) {
        match field.get_name() {
            Some(name) => {
                print_indent!(self, "{}", field.display_name());
                if let Some(ty) = field.get_type() {
                    print!(": {}", ty.display_name());
                }
                if let Some(struct_ty) = self.current_ty {
                    match struct_ty.get_offsetof(&name) {
                        Ok(offset) => print!(" (offset {} bits)", offset),
                        Err(e) => print!(" ({})", e),
                    }
                }
                println!();
            }
            None => {
                println!("field: {}", field.display_name());
            }
        }
    }

    fn handle_method(&mut self, meth: Entity<'cpp>) {
        print_indent!(self, "{}", meth.display_name());
        if let Some(ty) = meth.get_result_type() {
            print!(" -> {}", ty.display_name());
        }
        println!();
        self.maybe_bindgen(meth);
    }

    fn handle_typedef(&mut self, td: Entity<'cpp>) {
        println_indent!(
            self,
            "typedef {} = {}",
            td.display_name(),
            td.get_type().unwrap().display_name()
        );
    }

    fn handle_class_template(&mut self, t: Entity<'cpp>) {
        println_indent!(self, "template {}::{}", self.namespace, t.display_name());
        let name = format!(
            "{}::{}",
            self.namespace,
            t.get_name().unwrap_or("?".to_string())
        );
        println_indent!(self, "  => {}", name);

        self.maybe_bindgen(t);

        self.indent += 1;
        self.visit_with_ty(None, t);
        self.indent -= 1;
    }

    fn maybe_bindgen(&self, ent: Entity<'cpp>) {
        if let Some(name) = ent.get_name() {
            let name = format!("{}::{}", self.namespace, name);
            if self.bindgen.items.contains(&name) {
                self.bindgen.lower(ent);
            }
        }
    }

    fn visit_with_ty(&mut self, ty: Option<Type<'cpp>>, ent: Entity<'cpp>) {
        let orig = std::mem::replace(&mut self.current_ty, ty);
        self.visit_children(ent);
        self.current_ty = orig;
    }
}
<|endoftext|>


<commit_before>extern crate piston_window;
extern crate find_folder;
extern crate gfx_device_gl;
extern crate gfx_graphics;
extern crate gfx;
extern crate vecmath;
extern crate image as im;
extern crate time;
extern crate rand;

use piston_window::*;
use time::{Duration, PreciseTime};

mod player;
mod io;
mod level;
mod inventory;
mod item;
mod actor;
mod field;
mod interactable;
mod coord;
mod enums;
mod camera;
mod bot;

use camera::Cam;
use player::{Player, LastKey};
use bot::Bot;
use io::render_tile;
use io::tileset::{TILE_HEIGHT, TILE_WIDTH, Tileset};
use level::Level;
use actor::Actor;
use interactable::Interactable;
use io::sprite::Sprite;

//EINGABEN
const TWO_PLAYER: bool = true;
const SPRITE_P_1: &'static str = "warrior2.png";
const SPRITE_P_2: &'static str = "paladin.png";
const CAMERA_BUF_X: u64 = 4;
const CAMERA_BUF_Y: u64 = 4;

const WIDTH: i64 = 586;
const HEIGHT: i64 = 586;

const RED: [f32; 4] = [1.0, 0.0, 0.0, 1.0];
const BLACK: [f32; 4] = [0.0, 0.0, 0.0, 1.0];

pub struct App {
    player_one: Player,
    player_two: Option<Player>,
    bots: Vec<Bot>,
    cam: Cam,
}

impl App {
    fn new(two_player: bool) -> Self {
        App {
            // 0,0 Dummy-Value
            player_one: Player::new(0, 0),
            player_two: if two_player {
                // 0,0 Dummy-Value
                Some(Player::new(0, 0))
            } else {
                None
            },
            bots: vec![Bot::new(2, 2), Bot::new(2, 2), Bot::new(2, 2), Bot::new(2, 2), Bot::new(2, 2)],
            cam: Cam::new(CAMERA_BUF_X, CAMERA_BUF_Y),
        }
    }

    fn on_draw(&mut self,
               mut w: &mut PistonWindow,
               e: &Event,
               tileset: &Tileset,
               level: &mut Level,
               state: usize) {
        let range = self.cam.get_range();

        w.draw_2d(e, |c, gl| {
            let player_one = &self.player_one.sprite;
            let player_two = &self.player_two;

            // Clear the screen.
            clear(BLACK, gl);

            let center_lv = c.transform.trans(0.0, 0.0);

            //render_level(&tileset, gl, center_lv, &mut level);
            for (h, j) in (range.x_min..range.x_max).enumerate() {
                for (w, i) in (range.y_min..range.y_max).enumerate() {
                    let tile = match tileset.get_texture(level.get_data()[i as usize][j as usize].get_id()) {
                    Some(x) => x,
                    None => panic!("No texture found."),
                    };
                    // DEBUG
                    //println!("{} {}", i, j);
                    render_tile(&tile, gl, center_lv,  h as u32 * TILE_HEIGHT,
                            w as u32 * TILE_WIDTH,
                            w as u32,
                            h as u32);
                }
            }
            if let Some(ref p1) = *player_one {
                let center_p1 = c.transform.trans(((self.player_one.coord.get_x() - range.x_min )* 65) as f64,
                                              ((self.player_one.coord.get_y() - range.y_min)* 65) as f64);

                p1.render(gl, center_p1, state as u64);
            }

            if let Some(ref p2) = *player_two {
                if let Some (ref x) =p2.sprite {

                let center_p2 = c.transform.trans(((p2.coord.get_x() - range.x_min) * 65) as f64,

                                              ((p2.coord.get_y() - range.y_min )* 65) as f64);
                 x.render(gl, center_p2, state as u64);
                 }

            }

            for b in &mut self.bots {

                if let Some(ref br) = b.sprite {
                    if b.coord.get_x() >= range.x_min &&  b.coord.get_x() < range.x_max &&
                        b.coord.get_y() >= range.y_min && b.coord.get_y() < range.y_max {

                        let center_b1 = c.transform.trans(((b.coord.get_x() - range.x_min )* 65) as f64,
                                                          ((b.coord.get_y() - range.y_min)* 65) as f64);
                        br.render(gl, center_b1, state as u64);
                    }
                }

            }
        });
    }

    fn on_update(&mut self, args: &UpdateArgs, state: usize) {
        let coord1 = self.player_one.coord.clone();
        let mut coord2 = coord1.clone();

        if let Some(ref p2) = self.player_two {
            coord2 = p2.coord.clone();
        }

        let range = self.cam.get_range_update();

        self.player_one.on_update(args, range);
        if let Some(ref mut x) = self.player_two {

            x.on_update(args, range);
        }

        for b in &mut self.bots {
            b.on_update(args, range, state);
        }

        self.cam.calc_coordinates(coord1, coord2);

    }

    fn on_input(&mut self, inp: Button, pressed: bool) {

        match inp {
            Button::Keyboard(Key::Up) => {
                if pressed {
                    self.player_one.last = LastKey::Up;
                }
                self.player_one.pressed = pressed;
            }
            Button::Keyboard(Key::Down) => {
                if pressed {
                    self.player_one.last = LastKey::Down;
                }
                self.player_one.pressed = pressed;
            }
            Button::Keyboard(Key::Left) => {
                if pressed {
                    self.player_one.last = LastKey::Left;
                }
                self.player_one.pressed = pressed;
            }
            Button::Keyboard(Key::Right) => {
                if pressed {
                    self.player_one.last = LastKey::Right;
                }
                self.player_one.pressed = pressed;
            }
            Button::Keyboard(Key::W) => {
                if let Some(ref mut x) = self.player_two {
                    if pressed {
                        x.last = LastKey::Up;
                    }
                    x.pressed = pressed;
                }
            }
            Button::Keyboard(Key::S) => {
                if let Some(ref mut x) = self.player_two {
                    if pressed {
                        x.last = LastKey::Down;
                    }
                    x.pressed = pressed;
                }
            }
            Button::Keyboard(Key::A) => {
                if let Some(ref mut x) = self.player_two {
                    if pressed {
                        x.last = LastKey::Left;
                    }
                    x.pressed = pressed;
                }
            }
            Button::Keyboard(Key::D) => {
                if let Some(ref mut x) = self.player_two {
                    if pressed {
                        x.last = LastKey::Right;
                    }
                    x.pressed = pressed;
                }
            }
            Button::Keyboard(Key::Space) => {
                if pressed {
                    println!("Space!!!");
                }
            }
            _ => {}

        }
    }
}

fn main() {
    let mut window: PistonWindow = WindowSettings::new("chicken_fight_3000_ultimate_tournament",
                                                       [WIDTH as u32, HEIGHT as u32])
        .exit_on_esc(true)
        .fullscreen(false)
        .resizable(false)
        .build()
        .unwrap();

    // Create a new game and run it.

    let mut app = App::new(TWO_PLAYER);

    let mut events = window.events();

    let tiles = match find_folder::Search::Kids(1).for_folder("tiles") {
        Ok(res) => res.join("tileset-pokemon_dawn.png"),
        Err(_) => panic!("Folder 'tiles' not found!"),
    };

    let file_path = match tiles.to_str() {
        Some(res) => res,
        None => panic!("Tileset not found!"),
    };

    let folder_level = match find_folder::Search::Kids(0).for_folder("src") {
        Ok(res) => res.join("level1.lvl"),
        Err(_) => panic!("Folder 'src' not found!"),
    };

    let level_path = match folder_level.to_str() {
        Some(res) => res,
        None => panic!("Level not found!"),
    };

    let tileset = io::read_tileset(file_path, &mut window);

    let mut level = io::read_level(level_path);

    let mut start = PreciseTime::now();

    app.cam.set_borders((level.get_x() as u64, level.get_y()as u64));
    app.player_one.set_borders((level.get_x() as u64, level.get_y()as u64));

    for b in &mut app.bots {
        b.set_borders((level.get_x() as u64, level.get_y()as u64));
    }

    app.player_one.set_sprite(Sprite::fill_sprite("knight.png",2,1,64,64,&mut window));
    if let Some(ref mut p2) = app.player_two {
        p2.set_borders((level.get_x() as u64, level.get_y() as u64));
        p2.set_sprite(Sprite::fill_sprite("paladin.png", 2, 1, 64, 64, &mut window));
    }

    for b in &mut app.bots {
        b.set_sprite(Sprite::fill_sprite("chicken_pink.png",2,1,64,64,&mut window));
    }

    while let Some(e) = events.next(&mut window) {
        let now = start.to(PreciseTime::now()).num_milliseconds();
        if now > 1000 {
            start = PreciseTime::now();
        }
        let state = if now <= 500 { 0 } else { 1 };

        if let Some(_) = e.render_args() {
            app.on_draw(&mut window, &e, &tileset, &mut level, state);
        }
        if let Some(i) = e.release_args() {
            app.on_input(i, false);
        }
        if let Some(i) = e.press_args() {
            app.on_input(i, true);
        }

        if let Some(u) = e.update_args() {
            app.on_update(&u, state);
        }

    }

}
<commit_msg>Add more chicken<commit_after>extern crate piston_window;
extern crate find_folder;
extern crate gfx_device_gl;
extern crate gfx_graphics;
extern crate gfx;
extern crate vecmath;
extern crate image as im;
extern crate time;
extern crate rand;

use piston_window::*;
use time::{Duration, PreciseTime};

mod player;
mod io;
mod level;
mod inventory;
mod item;
mod actor;
mod field;
mod interactable;
mod coord;
mod enums;
mod camera;
mod bot;

use camera::Cam;
use player::{Player, LastKey};
use bot::Bot;
use io::render_tile;
use io::tileset::{TILE_HEIGHT, TILE_WIDTH, Tileset};
use level::Level;
use actor::Actor;
use interactable::Interactable;
use io::sprite::Sprite;

//EINGABEN
const TWO_PLAYER: bool = true;
const SPRITE_P_1: &'static str = "warrior2.png";
const SPRITE_P_2: &'static str = "paladin.png";
const CAMERA_BUF_X: u64 = 4;
const CAMERA_BUF_Y: u64 = 4;

const WIDTH: i64 = 586;
const HEIGHT: i64 = 586;

const RED: [f32; 4] = [1.0, 0.0, 0.0, 1.0];
const BLACK: [f32; 4] = [0.0, 0.0, 0.0, 1.0];

pub struct App {
    player_one: Player,
    player_two: Option<Player>,
    bots: Vec<Bot>,
    cam: Cam,
}

impl App {
    fn new(two_player: bool) -> Self {
        App {
            // 0,0 Dummy-Value
            player_one: Player::new(0, 0),
            player_two: if two_player {
                // 0,0 Dummy-Value
                Some(Player::new(0, 0))
            } else {
                None
            },
            bots: vec![Bot::new(2, 2), Bot::new(2, 2), Bot::new(2, 2), Bot::new(2, 2), Bot::new(2, 2), Bot::new(2, 2), Bot::new(2, 2), Bot::new(2, 2), Bot::new(2, 2), Bot::new(2, 2), Bot::new(2, 2), Bot::new(2, 2), Bot::new(2, 2), Bot::new(2, 2), Bot::new(2, 2), Bot::new(2, 2), Bot::new(2, 2), Bot::new(2, 2), Bot::new(2, 2), Bot::new(2, 2), Bot::new(2, 2), Bot::new(2, 2), Bot::new(2, 2), Bot::new(2, 2), Bot::new(2, 2), Bot::new(2, 2), Bot::new(2, 2), Bot::new(2, 2), Bot::new(2, 2), Bot::new(2, 2), Bot::new(2, 2), Bot::new(2, 2), Bot::new(2, 2), Bot::new(2, 2), Bot::new(2, 2), Bot::new(2, 2), Bot::new(2, 2), Bot::new(2, 2), Bot::new(2, 2), Bot::new(2, 2), Bot::new(2, 2), Bot::new(2, 2), Bot::new(2, 2), Bot::new(2, 2), Bot::new(2, 2), Bot::new(2, 2), Bot::new(2, 2), Bot::new(2, 2), Bot::new(2, 2), Bot::new(2, 2), Bot::new(2, 2), Bot::new(2, 2), Bot::new(2, 2), Bot::new(2, 2), Bot::new(2, 2), Bot::new(2, 2)],
            cam: Cam::new(CAMERA_BUF_X, CAMERA_BUF_Y),
        }
    }

    fn on_draw(&mut self,
               mut w: &mut PistonWindow,
               e: &Event,
               tileset: &Tileset,
               level: &mut Level,
               state: usize) {
        let range = self.cam.get_range();

        w.draw_2d(e, |c, gl| {
            let player_one = &self.player_one.sprite;
            let player_two = &self.player_two;

            // Clear the screen.
            clear(BLACK, gl);

            let center_lv = c.transform.trans(0.0, 0.0);

            //render_level(&tileset, gl, center_lv, &mut level);
            for (h, j) in (range.x_min..range.x_max).enumerate() {
                for (w, i) in (range.y_min..range.y_max).enumerate() {
                    let tile = match tileset.get_texture(level.get_data()[i as usize][j as usize].get_id()) {
                    Some(x) => x,
                    None => panic!("No texture found."),
                    };
                    // DEBUG
                    //println!("{} {}", i, j);
                    render_tile(&tile, gl, center_lv,  h as u32 * TILE_HEIGHT,
                            w as u32 * TILE_WIDTH,
                            w as u32,
                            h as u32);
                }
            }
            if let Some(ref p1) = *player_one {
                let center_p1 = c.transform.trans(((self.player_one.coord.get_x() - range.x_min )* 65) as f64,
                                              ((self.player_one.coord.get_y() - range.y_min)* 65) as f64);

                p1.render(gl, center_p1, state as u64);
            }

            if let Some(ref p2) = *player_two {
                if let Some (ref x) =p2.sprite {

                let center_p2 = c.transform.trans(((p2.coord.get_x() - range.x_min) * 65) as f64,

                                              ((p2.coord.get_y() - range.y_min )* 65) as f64);
                 x.render(gl, center_p2, state as u64);
                 }

            }

            for b in &mut self.bots {

                if let Some(ref br) = b.sprite {
                    if b.coord.get_x() >= range.x_min &&  b.coord.get_x() < range.x_max &&
                        b.coord.get_y() >= range.y_min && b.coord.get_y() < range.y_max {

                        let center_b1 = c.transform.trans(((b.coord.get_x() - range.x_min )* 65) as f64,
                                                          ((b.coord.get_y() - range.y_min)* 65) as f64);
                        br.render(gl, center_b1, state as u64);
                    }
                }

            }
        });
    }

    fn on_update(&mut self, args: &UpdateArgs, state: usize) {
        let coord1 = self.player_one.coord.clone();
        let mut coord2 = coord1.clone();

        if let Some(ref p2) = self.player_two {
            coord2 = p2.coord.clone();
        }

        let range = self.cam.get_range_update();

        self.player_one.on_update(args, range);
        if let Some(ref mut x) = self.player_two {

            x.on_update(args, range);
        }

        for b in &mut self.bots {
            b.on_update(args, range, state);
        }

        self.cam.calc_coordinates(coord1, coord2);

    }

    fn on_input(&mut self, inp: Button, pressed: bool) {

        match inp {
            Button::Keyboard(Key::Up) => {
                if pressed {
                    self.player_one.last = LastKey::Up;
                }
                self.player_one.pressed = pressed;
            }
            Button::Keyboard(Key::Down) => {
                if pressed {
                    self.player_one.last = LastKey::Down;
                }
                self.player_one.pressed = pressed;
            }
            Button::Keyboard(Key::Left) => {
                if pressed {
                    self.player_one.last = LastKey::Left;
                }
                self.player_one.pressed = pressed;
            }
            Button::Keyboard(Key::Right) => {
                if pressed {
                    self.player_one.last = LastKey::Right;
                }
                self.player_one.pressed = pressed;
            }
            Button::Keyboard(Key::W) => {
                if let Some(ref mut x) = self.player_two {
                    if pressed {
                        x.last = LastKey::Up;
                    }
                    x.pressed = pressed;
                }
            }
            Button::Keyboard(Key::S) => {
                if let Some(ref mut x) = self.player_two {
                    if pressed {
                        x.last = LastKey::Down;
                    }
                    x.pressed = pressed;
                }
            }
            Button::Keyboard(Key::A) => {
                if let Some(ref mut x) = self.player_two {
                    if pressed {
                        x.last = LastKey::Left;
                    }
                    x.pressed = pressed;
                }
            }
            Button::Keyboard(Key::D) => {
                if let Some(ref mut x) = self.player_two {
                    if pressed {
                        x.last = LastKey::Right;
                    }
                    x.pressed = pressed;
                }
            }
            Button::Keyboard(Key::Space) => {
                if pressed {
                    println!("Space!!!");
                }
            }
            _ => {}

        }
    }
}

fn main() {
    let mut window: PistonWindow = WindowSettings::new("chicken_fight_3000_ultimate_tournament",
                                                       [WIDTH as u32, HEIGHT as u32])
        .exit_on_esc(true)
        .fullscreen(false)
        .resizable(false)
        .build()
        .unwrap();

    // Create a new game and run it.

    let mut app = App::new(TWO_PLAYER);

    let mut events = window.events();

    let tiles = match find_folder::Search::Kids(1).for_folder("tiles") {
        Ok(res) => res.join("tileset-pokemon_dawn.png"),
        Err(_) => panic!("Folder 'tiles' not found!"),
    };

    let file_path = match tiles.to_str() {
        Some(res) => res,
        None => panic!("Tileset not found!"),
    };

    let folder_level = match find_folder::Search::Kids(0).for_folder("src") {
        Ok(res) => res.join("level1.lvl"),
        Err(_) => panic!("Folder 'src' not found!"),
    };

    let level_path = match folder_level.to_str() {
        Some(res) => res,
        None => panic!("Level not found!"),
    };

    let tileset = io::read_tileset(file_path, &mut window);

    let mut level = io::read_level(level_path);

    let mut start = PreciseTime::now();

    app.cam.set_borders((level.get_x() as u64, level.get_y()as u64));
    app.player_one.set_borders((level.get_x() as u64, level.get_y()as u64));

    app.player_one.set_sprite(Sprite::fill_sprite("knight.png",2,1,64,64,&mut window));
    if let Some(ref mut p2) = app.player_two {
        p2.set_borders((level.get_x() as u64, level.get_y() as u64));
        p2.set_sprite(Sprite::fill_sprite("paladin.png", 2, 1, 64, 64, &mut window));
    }
    let mut i = 0;
    for b in &mut app.bots {
        let file = if i %3 == 0 {"chicken_pink.png"} else if i% 3 == 1 {"chicken_brown.png"} else {"chicken_white.png"};
        b.set_sprite(Sprite::fill_sprite(file,2,1,64,64,&mut window));
        b.set_borders((level.get_x() as u64, level.get_y()as u64));
        i = i +1;
    }

    while let Some(e) = events.next(&mut window) {
        let now = start.to(PreciseTime::now()).num_milliseconds();
        if now > 1000 {
            start = PreciseTime::now();
        }
        let state = if now <= 500 { 0 } else { 1 };

        if let Some(_) = e.render_args() {
            app.on_draw(&mut window, &e, &tileset, &mut level, state);
        }
        if let Some(i) = e.release_args() {
            app.on_input(i, false);
        }
        if let Some(i) = e.press_args() {
            app.on_input(i, true);
        }

        if let Some(u) = e.update_args() {
            app.on_update(&u, state);
        }

    }

}
<|endoftext|>


<commit_before>// Implements http://rosettacode.org/wiki/Menu

use std::io;

// Print the menu followed by the prompt
fn print_both(menu: [&str, ..4], prompt: &str) {

    // Iterate through array and print index, period, menu item
    for i in range(0, 4u) { // Hard coded number 4 here
        println!("{}. {}", i, menu[i]);
    }

    // Print the prompt
    println!("{}", prompt);

}

// Grab the next line of input
fn next_input() -> int {

    // Convert it to a possible int
    let mut stdin = io::stdin();
    let line: io::IoResult<String> = stdin.read_line();
    let string: String = line.unwrap();
    let trimmed: &str = string.as_slice().trim();
    let possible: Option<int> = from_str(trimmed);

    // If possible num is between 0 and 3, return it.
    // Otherwise return -1 <= I don't think this is good practice
    match possible {
        None => return -1,
        Some(possible) => match possible {
            0...3 => return possible,
            _=> return -1
        }
    }
}

// Couldn't figure out how to make select return an element of menu
// Got a 'missing lifetime specifier' error when trying to return &str
fn select(menu: [&str, ..4], prompt: &str) -> String {

    // Check if menu is empty
    if menu.len() == 0 {
        return "".to_string()
    }

    // Loop until user inputs a valid menu index
    loop {

        print_both(menu, prompt);

        let menu_index: int = next_input();

        match menu_index{
            0...3 => return menu[menu_index as uint].to_string(),
            _=> print_both(menu, prompt),
        }
    }
}

#[cfg(not(test))]
fn main() {
    let items = ["fee fie", "huff and puff", "mirror mirror", "tick tock"];
    let prompt = "Choose one.";
    println!("{}", select(items, prompt));
}

// Need to add tests but having trouble simulating std io<commit_msg>implement changes from comments by aochagavia<commit_after>// Implements http://rosettacode.org/wiki/Menu

use std::io;

// Print the menu followed by the prompt
fn print_both(menu: &[&str], prompt: &str) {

    // Iterate through array and print index, period, and menu item
    for (i, item) in menu.iter().enumerate() {
        println!("{}. {}", i, item);
    }

    // Print the prompt
    println!("{}", prompt);
}

// Grab the next line of input
fn next_input() -> Option<uint> {

    let line = io::stdin().read_line().unwrap();
    let input: Option<uint> = line.trim().parse();
    return input;
}

fn select<'a>(menu: &'a [&str], prompt: &str) -> &'a str {

    // Check if menu is empty
    if menu.len() == 0 {
        return "";
    }

    // Loop until user inputs a valid menu index
    loop {

        print_both(menu, prompt);

        let input = next_input();

        let num = match input {
            Some(num) => num,
            None      => continue
        };

        if let 0...3 = num {
            return menu[num];
        }
    }
}

#[cfg(not(test))]
fn main() {

    let prompt = "Choose one.";
    let items = ["fee fie", "huff and puff", "mirror mirror", "tick tock"];
    let menu = items.slice(0,4);

    println!("{}", select(menu, prompt));
}

#[test]
fn test_empty_menu() {
    let prompt = "Choose one.";
    let items = ["fee fie", "huff and puff", "mirror mirror", "tick tock"];
    let menu = items.slice(0,0);
    assert_eq!(select(menu, prompt), "");
}

// Need to add more tests but having trouble simulating std input
<|endoftext|>


<commit_before>// Copyright 2018 Syn Developers
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.

//! This module contains some simple tests where we can write strings which we

extern crate syn;

macro_rules! should_parse {
    ($name:ident, { $($in:tt)* }) => {
        #[test]
        fn $name() {
            // Make sure we can parse the file!
            syn::parse_file(stringify!($($in)*)).unwrap();
        }
    }
}

should_parse!(generic_associated_type, {
    impl Foo {
        type Item = &'a i32;
        fn foo<'a>(&'a self) -> Self::Item<'a> {}
    }
});

should_parse!(const_generics_use, {
    type X = Foo<5>;
    type Y = Foo<"foo">;
    type Z = Foo<X>;
    type W = Foo<{ X + 10 }>;
});

should_parse!(trailing_plus_type, {
    type A = Box<Foo>;
    type A = Box<Foo + 'a>;
    type A = Box<'a + Foo>;
});

should_parse!(generic_associated_type_where, {
    trait Foo {
        type Item;
        fn foo<T>(&self, t: T) -> Self::Item<T>;
    }
});
<commit_msg>Remove incomplete test explanation<commit_after>// Copyright 2018 Syn Developers
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.

extern crate syn;

macro_rules! should_parse {
    ($name:ident, { $($in:tt)* }) => {
        #[test]
        fn $name() {
            // Make sure we can parse the file!
            syn::parse_file(stringify!($($in)*)).unwrap();
        }
    }
}

should_parse!(generic_associated_type, {
    impl Foo {
        type Item = &'a i32;
        fn foo<'a>(&'a self) -> Self::Item<'a> {}
    }
});

should_parse!(const_generics_use, {
    type X = Foo<5>;
    type Y = Foo<"foo">;
    type Z = Foo<X>;
    type W = Foo<{ X + 10 }>;
});

should_parse!(trailing_plus_type, {
    type A = Box<Foo>;
    type A = Box<Foo + 'a>;
    type A = Box<'a + Foo>;
});

should_parse!(generic_associated_type_where, {
    trait Foo {
        type Item;
        fn foo<T>(&self, t: T) -> Self::Item<T>;
    }
});
<|endoftext|>


<commit_before>extern crate rosc;

use rosc::{encoder, decoder, errors};
use rosc::errors::OscError;
use rosc::types::{Result, OscMessage, OscPacket};

#[test]
fn test_encode_message_wo_args() {
    let msg = OscMessage {
        addr: "/some/addr".to_string(),
        args: None,
    };

    let enc_msg = encoder::encode_message(&msg).unwrap();
    match decoder::decode(&enc_msg).unwrap() {
        OscPacket::Message(dec_msg) => assert_eq!("/some/addr", dec_msg.addr),
        _ => panic!("Expected OSC message!")
    }
}
<commit_msg>Check agains `addr` field of source `msg`<commit_after>extern crate rosc;

use rosc::{encoder, decoder, errors};
use rosc::errors::OscError;
use rosc::types::{Result, OscMessage, OscPacket};

#[test]
fn test_encode_message_wo_args() {
    let msg = OscMessage {
        addr: "/some/addr".to_string(),
        args: None,
    };

    let enc_msg = encoder::encode_message(&msg).unwrap();
    match decoder::decode(&enc_msg).unwrap() {
        OscPacket::Message(dec_msg) => assert_eq!(msg.addr, dec_msg.addr),
        _ => panic!("Expected OSC message!"),
    }
}
<|endoftext|>


<commit_before>#[macro_use]
extern crate nom;

use nom::{IResult, digit, alpha};

named!(without_complete<&[u8], (&[u8], Option<&[u8]>)>,
       do_parse!(
           first: digit >>
               second: opt!(alpha) >>
               (first, second)
       ));

named!(with_complete<&[u8], (&[u8], Option<&[u8]>)>,
       do_parse!(
           first: digit >>
               second: opt!(complete!(alpha)) >>
               (first, second)
       ));

#[test]
fn without_complete_should_parse_digit_alpha() {
    assert_eq!(without_complete(&b"1a"[..]), IResult::Done(&b""[..], (&b"1"[..], Option::Some(&b"a"[..]))));
    assert_eq!(without_complete(&b"12a"[..]), IResult::Done(&b""[..], (&b"12"[..], Option::Some(&b"a"[..]))));
    assert_eq!(without_complete(&b"1ab"[..]), IResult::Done(&b""[..], (&b"1"[..], Option::Some(&b"ab"[..]))));
    assert_eq!(without_complete(&b"12ab"[..]), IResult::Done(&b""[..], (&b"12"[..], Option::Some(&b"ab"[..]))));
}

#[ignore]
#[test]
fn without_complete_should_parse_digit_TEST_SHOULD_BE_IGNORED() {
    assert_eq!(without_complete(&b"1"[..]), IResult::Done(&b""[..], (&b"1"[..], Option::None)));
    assert_eq!(without_complete(&b"12"[..]), IResult::Done(&b""[..], (&b"12"[..], Option::None)));
}

#[test]
fn with_complete_should_parse_digit_alpha() {
    assert_eq!(with_complete(&b"1a"[..]), IResult::Done(&b""[..], (&b"1"[..], Option::Some(&b"a"[..]))));
    assert_eq!(with_complete(&b"12a"[..]), IResult::Done(&b""[..], (&b"12"[..], Option::Some(&b"a"[..]))));
    assert_eq!(with_complete(&b"1ab"[..]), IResult::Done(&b""[..], (&b"1"[..], Option::Some(&b"ab"[..]))));
    assert_eq!(with_complete(&b"12ab"[..]), IResult::Done(&b""[..], (&b"12"[..], Option::Some(&b"ab"[..]))));
}

#[test]
fn with_complete_should_parse_digit() {
    assert_eq!(with_complete(&b"1"[..]), IResult::Done(&b""[..], (&b"1"[..], Option::None)));
    assert_eq!(with_complete(&b"12"[..]), IResult::Done(&b""[..], (&b"12"[..], Option::None)));
}
<commit_msg>Allow non snake case for ignored test in nom opt test<commit_after>#[macro_use]
extern crate nom;

use nom::{IResult, digit, alpha};

named!(without_complete<&[u8], (&[u8], Option<&[u8]>)>,
       do_parse!(
           first: digit >>
               second: opt!(alpha) >>
               (first, second)
       ));

named!(with_complete<&[u8], (&[u8], Option<&[u8]>)>,
       do_parse!(
           first: digit >>
               second: opt!(complete!(alpha)) >>
               (first, second)
       ));

#[test]
fn without_complete_should_parse_digit_alpha() {
    assert_eq!(without_complete(&b"1a"[..]), IResult::Done(&b""[..], (&b"1"[..], Option::Some(&b"a"[..]))));
    assert_eq!(without_complete(&b"12a"[..]), IResult::Done(&b""[..], (&b"12"[..], Option::Some(&b"a"[..]))));
    assert_eq!(without_complete(&b"1ab"[..]), IResult::Done(&b""[..], (&b"1"[..], Option::Some(&b"ab"[..]))));
    assert_eq!(without_complete(&b"12ab"[..]), IResult::Done(&b""[..], (&b"12"[..], Option::Some(&b"ab"[..]))));
}

#[ignore]
#[allow(non_snake_case)]
#[test]
fn without_complete_should_parse_digit_TEST_SHOULD_BE_IGNORED() {
    assert_eq!(without_complete(&b"1"[..]), IResult::Done(&b""[..], (&b"1"[..], Option::None)));
    assert_eq!(without_complete(&b"12"[..]), IResult::Done(&b""[..], (&b"12"[..], Option::None)));
}

#[test]
fn with_complete_should_parse_digit_alpha() {
    assert_eq!(with_complete(&b"1a"[..]), IResult::Done(&b""[..], (&b"1"[..], Option::Some(&b"a"[..]))));
    assert_eq!(with_complete(&b"12a"[..]), IResult::Done(&b""[..], (&b"12"[..], Option::Some(&b"a"[..]))));
    assert_eq!(with_complete(&b"1ab"[..]), IResult::Done(&b""[..], (&b"1"[..], Option::Some(&b"ab"[..]))));
    assert_eq!(with_complete(&b"12ab"[..]), IResult::Done(&b""[..], (&b"12"[..], Option::Some(&b"ab"[..]))));
}

#[test]
fn with_complete_should_parse_digit() {
    assert_eq!(with_complete(&b"1"[..]), IResult::Done(&b""[..], (&b"1"[..], Option::None)));
    assert_eq!(with_complete(&b"12"[..]), IResult::Done(&b""[..], (&b"12"[..], Option::None)));
}
<|endoftext|>


<commit_before>#[macro_use]
extern crate failure;
extern crate hyper;
extern crate serialize;

use failure::Error;
use hyper::client::Client;
use hyper::header::ContentType;
use std::time;

use serialize::Serialize;

fn mean(u: &[f32]) -> f32 {
    let n = u.len() as f32;
    u.iter().fold(0f32, |a, b| a + b) / n
}

fn squared_deviation(u: &[f32], mu: f32) -> f32 {
    u.iter().fold(0f32, |a, b| a + (b - mu).powi(2))
}

fn t_statistic(n: f32, (mu_u, sd_u): (f32, f32), (mu_v, sd_v): (f32, f32)) -> f32 {
    let m = n;
    let var = (sd_u + sd_v) / (n + m - 2f32);
    (n * m / (n + m)).sqrt() * (mu_u - mu_v) / var.sqrt()
}

fn try_signature(mac: &[u8]) -> Result<bool, Error> {
    let client = Client::new();
    let mime = "application/json".parse().unwrap();
    let body = format!("{{\"file\":\"4.txt\", \"signature\":\"{}\"}}", mac.to_hex());

    let request = client
        .post("http://localhost:3000")
        .header(ContentType(mime))
        .body(&body);

    let response = request.send()?;

    Ok(response.status == hyper::status::StatusCode::Ok)
}

fn perform_measurement(mac: &[u8], n: u32) -> Result<(f32, f32), Error> {
    let measurements = (0..n)
        .map(|_| {
            let now = time::Instant::now();
            try_signature(mac)?;
            let elapsed_time = now.elapsed();
            let elapsed_micros = (elapsed_time.as_secs() as f32) * 1_000_000.0
                + (elapsed_time.subsec_nanos() as f32) / 1_000.0;
            Ok(elapsed_micros)
        })
    .collect::<Result<Vec<f32>, Error>>()?;

    let mu = mean(&measurements);
    let sd = squared_deviation(&measurements, mu);
    Ok((mu, sd))
}

pub fn run() -> Result<(), Error> {
    let mut mac = vec![0; 20];

    // Number of measurements to perform per signature
    let n = 3;

    for i in 0..mac.len() {
        let mut u_max = 0;
        let mut stat_max = (0f32, 0f32);
        for u in 0..=255 {
            mac[i] = u;
            let stat = perform_measurement(&mac, n)?;

            // Two-sample t-test to test whether the mean in stat is bigger than the mean in
            // stat_max.
            let t = t_statistic(n as f32, stat_max, stat);
            if t < -2f32 {
                u_max = u;
                stat_max = stat;
            }
        }
        mac[i] = u_max;
        println!("{}", u_max);
    }

    if !try_signature(&mac)? {
        bail!("Failed to determine mac");
    }

    Ok(())
}
<commit_msg>Remove leftover debug output<commit_after>#[macro_use]
extern crate failure;
extern crate hyper;
extern crate serialize;

use failure::Error;
use hyper::client::Client;
use hyper::header::ContentType;
use std::time;

use serialize::Serialize;

fn mean(u: &[f32]) -> f32 {
    let n = u.len() as f32;
    u.iter().fold(0f32, |a, b| a + b) / n
}

fn squared_deviation(u: &[f32], mu: f32) -> f32 {
    u.iter().fold(0f32, |a, b| a + (b - mu).powi(2))
}

fn t_statistic(n: f32, (mu_u, sd_u): (f32, f32), (mu_v, sd_v): (f32, f32)) -> f32 {
    let m = n;
    let var = (sd_u + sd_v) / (n + m - 2f32);
    (n * m / (n + m)).sqrt() * (mu_u - mu_v) / var.sqrt()
}

fn try_signature(mac: &[u8]) -> Result<bool, Error> {
    let client = Client::new();
    let mime = "application/json".parse().unwrap();
    let body = format!("{{\"file\":\"4.txt\", \"signature\":\"{}\"}}", mac.to_hex());

    let request = client
        .post("http://localhost:3000")
        .header(ContentType(mime))
        .body(&body);

    let response = request.send()?;

    Ok(response.status == hyper::status::StatusCode::Ok)
}

fn perform_measurement(mac: &[u8], n: u32) -> Result<(f32, f32), Error> {
    let measurements = (0..n)
        .map(|_| {
            let now = time::Instant::now();
            try_signature(mac)?;
            let elapsed_time = now.elapsed();
            let elapsed_micros = (elapsed_time.as_secs() as f32) * 1_000_000.0
                + (elapsed_time.subsec_nanos() as f32) / 1_000.0;
            Ok(elapsed_micros)
        })
    .collect::<Result<Vec<f32>, Error>>()?;

    let mu = mean(&measurements);
    let sd = squared_deviation(&measurements, mu);
    Ok((mu, sd))
}

pub fn run() -> Result<(), Error> {
    let mut mac = vec![0; 20];

    // Number of measurements to perform per signature
    let n = 3;

    for i in 0..mac.len() {
        let mut u_max = 0;
        let mut stat_max = (0f32, 0f32);
        for u in 0..=255 {
            mac[i] = u;
            let stat = perform_measurement(&mac, n)?;

            // Two-sample t-test to test whether the mean in stat is bigger than the mean in
            // stat_max.
            let t = t_statistic(n as f32, stat_max, stat);
            if t < -2f32 {
                u_max = u;
                stat_max = stat;
            }
        }
        mac[i] = u_max;
    }

    if !try_signature(&mac)? {
        bail!("Failed to determine mac");
    }

    Ok(())
}
<|endoftext|>


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

use docopt::Docopt;
use flac::{Stream, StreamProducer, StreamReader};
use flac::metadata::{self, Picture, SeekPoint, VorbisComment};

use std::env;
use std::io::{self, Write};
use std::fs::File;

const USAGE: &'static str = "
Usage: metadata streaminfo [options] <filename>
       metadata comments [options] <filename>
       metadata seektable <filename>
       metadata picture [options] <filename>
       metadata --help

Options:
  --block-size       Show both the max and min block size from StreamInfo.
  --frame-size       Show both the max and min frame size from StreamInfo.
  --sample-rate      Show the sample rate from StreamInfo.
  --channels         Show the number of channels from StreamInfo.
  --bits-per-sample  Show the size in bits for each sample from StreamInfo.
  --total-samples    Show total number of samples from StreamInfo.
  --md5              Show the MD5 signature from StreamInfo.
  --vendor           Show the vendor string from VorbisComment.
  --name=NAME        Show the comments matching the `NAME` from VorbisComment.
  --export=FILE      Export VorbisComment or Picture to file.
  --index=NUMBER     Index of the current metadata type.
  -h, --help         Show this message.
";

#[derive(Debug, RustcDecodable)]
struct Arguments {
  arg_filename: String,
  cmd_streaminfo: bool,
  cmd_comments: bool,
  cmd_seektable: bool,
  cmd_picture: bool,
  flag_block_size: bool,
  flag_frame_size: bool,
  flag_sample_rate: bool,
  flag_channels: bool,
  flag_bits_per_sample: bool,
  flag_total_samples: bool,
  flag_md5: bool,
  flag_vendor: bool,
  flag_name: Option<String>,
  flag_export: Option<String>,
  flag_index: Option<usize>,
}

macro_rules! format_print (
  ($format_str: expr, $opt_str: expr, $data: expr, $no_flag: expr) => (
    {
      println!($format_str, if $no_flag {
        $opt_str
      } else {
        ""
      }, $data);
    }
  );
);

fn print_stream_info<P>(stream: &Stream<P>, args: &Arguments)
 where P: StreamProducer {
  let info     = stream.info();
  let no_flags = (args.flag_block_size      || args.flag_frame_size    ||
                  args.flag_sample_rate     || args.flag_channels      ||
                  args.flag_bits_per_sample || args.flag_total_samples ||
                  args.flag_md5) == false;

  if no_flags || args.flag_block_size {
    println!("Minimum block size: {} samples", info.min_block_size);
    println!("Maximum block size: {} samples", info.max_block_size);
  }

  if no_flags || args.flag_frame_size {
    println!("Minimum frame size: {} bytes", info.min_frame_size);
    println!("Maximum frame size: {} bytes", info.max_frame_size);
  }

  if no_flags || args.flag_sample_rate {
    format_print!("{}{} Hz", "Sample rate: ", info.sample_rate, no_flags);
  }

  if no_flags || args.flag_channels {
    format_print!("{}{}", "Number of channels: ", info.channels, no_flags);
  }

  if no_flags || args.flag_bits_per_sample {
    format_print!("{}{}", "Bits per samples: ", info.bits_per_sample,
                                                no_flags);
  }

  if no_flags || args.flag_total_samples {
    format_print!("{}{}", "Total samples: ", info.total_samples, no_flags);
  }

  if no_flags || args.flag_md5 {
    let mut md5  = String::with_capacity(32);

    for byte in &info.md5_sum {
      let hex = format!("{:02x}", byte);

      md5.push_str(&hex);
    }

    format_print!("{}{}", "MD5 sum: ", md5, no_flags);
  }
}

fn print_vorbis_comments(vorbis_comment: &VorbisComment, args: &Arguments) {
  let no_flags  = (args.flag_vendor || args.flag_name.is_some()) == false;

  if no_flags || args.flag_vendor {
    format_print!("{}{}", "Vendor string: ", vorbis_comment.vendor_string,
                                             no_flags);
  }

  if no_flags {
    let mut index = 1;

    println!("Number of Comments: {}", vorbis_comment.comments.len());

    for (name, value) in &vorbis_comment.comments {
      println!("  {}: \"{}\" = {}", index, name, value);

      index += 1;
    }
  } else {
    if let Some(ref name) = args.flag_name {
      vorbis_comment.comments.get(name)
                             .map(|value| println!("{}", value));
    }
  }
}

fn export_vorbis_comments(vorbis_comment: &VorbisComment, filename: &str)
                          -> io::Result<()> {
  let mut file = try!(File::create(filename));

  for (name, value) in &vorbis_comment.comments {
    try!(write!(file, "{}={}\n", name, value));
  }

  Ok(())
}

fn print_seek_table(seek_points: &[SeekPoint]) {
  let mut count = 0;

  println!("Number of Seek Points: {}", seek_points.len());

  for seek_point in seek_points {
    println!("Seek Point #{}", count);
    println!("  Sample number: {}", seek_point.sample_number);
    println!("  Stream offset: {}", seek_point.stream_offset);
    println!("  Frame samples: {}", seek_point.frame_samples);
    count += 1;
  }
}

fn export_picture(picture: &Picture, filename: &str) -> io::Result<()> {
  File::create(filename).and_then(|mut file| file.write_all(&picture.data))
}

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

  let stream = StreamReader::<File>::from_file(&args.arg_filename)
                 .expect("Couldn't parse file");

  if args.cmd_streaminfo {
    print_stream_info(&stream, &args);
  }

  for meta in stream.metadata() {
    match meta.data {
      metadata::Data::VorbisComment(ref v) => {
        if args.cmd_comments {
          if let Some(ref filename) = args.flag_export {
            export_vorbis_comments(v, filename)
              .expect("couldn't write to file")
          } else {
            print_vorbis_comments(v, &args)
          }
        }
      }
      metadata::Data::SeekTable(ref s)     => {
        if args.cmd_seektable {
          print_seek_table(s);
        }
      }
      metadata::Data::Picture(ref p)       => {
        if args.cmd_picture {
          if let Some(ref filename) = args.flag_export {
            export_picture(p, filename).expect("couldn't write to file");

            break;
          }
        }
      }
      _                                    => continue,
    }
  }
}
<commit_msg>Add indexing implementation for `Picture` only<commit_after>extern crate docopt;
extern crate flac;
extern crate rustc_serialize;

use docopt::Docopt;
use flac::{Stream, StreamProducer, StreamReader};
use flac::metadata::{self, Picture, SeekPoint, VorbisComment};

use std::env;
use std::io::{self, Write};
use std::fs::File;

const USAGE: &'static str = "
Usage: metadata streaminfo [options] <filename>
       metadata comments [options] <filename>
       metadata seektable <filename>
       metadata picture [options] <filename>
       metadata --help

Options:
  --block-size       Show both the max and min block size from StreamInfo.
  --frame-size       Show both the max and min frame size from StreamInfo.
  --sample-rate      Show the sample rate from StreamInfo.
  --channels         Show the number of channels from StreamInfo.
  --bits-per-sample  Show the size in bits for each sample from StreamInfo.
  --total-samples    Show total number of samples from StreamInfo.
  --md5              Show the MD5 signature from StreamInfo.
  --vendor           Show the vendor string from VorbisComment.
  --name=NAME        Show the comments matching the `NAME` from VorbisComment.
  --export=FILE      Export VorbisComment or Picture to file.
  --index=NUMBER     Index of the current metadata type.
  -h, --help         Show this message.
";

#[derive(Debug, RustcDecodable)]
struct Arguments {
  arg_filename: String,
  cmd_streaminfo: bool,
  cmd_comments: bool,
  cmd_seektable: bool,
  cmd_picture: bool,
  flag_block_size: bool,
  flag_frame_size: bool,
  flag_sample_rate: bool,
  flag_channels: bool,
  flag_bits_per_sample: bool,
  flag_total_samples: bool,
  flag_md5: bool,
  flag_vendor: bool,
  flag_name: Option<String>,
  flag_export: Option<String>,
  flag_index: Option<usize>,
}

macro_rules! format_print (
  ($format_str: expr, $opt_str: expr, $data: expr, $no_flag: expr) => (
    {
      println!($format_str, if $no_flag {
        $opt_str
      } else {
        ""
      }, $data);
    }
  );
);

fn print_stream_info<P>(stream: &Stream<P>, args: &Arguments)
 where P: StreamProducer {
  let info     = stream.info();
  let no_flags = (args.flag_block_size      || args.flag_frame_size    ||
                  args.flag_sample_rate     || args.flag_channels      ||
                  args.flag_bits_per_sample || args.flag_total_samples ||
                  args.flag_md5) == false;

  if no_flags || args.flag_block_size {
    println!("Minimum block size: {} samples", info.min_block_size);
    println!("Maximum block size: {} samples", info.max_block_size);
  }

  if no_flags || args.flag_frame_size {
    println!("Minimum frame size: {} bytes", info.min_frame_size);
    println!("Maximum frame size: {} bytes", info.max_frame_size);
  }

  if no_flags || args.flag_sample_rate {
    format_print!("{}{} Hz", "Sample rate: ", info.sample_rate, no_flags);
  }

  if no_flags || args.flag_channels {
    format_print!("{}{}", "Number of channels: ", info.channels, no_flags);
  }

  if no_flags || args.flag_bits_per_sample {
    format_print!("{}{}", "Bits per samples: ", info.bits_per_sample,
                                                no_flags);
  }

  if no_flags || args.flag_total_samples {
    format_print!("{}{}", "Total samples: ", info.total_samples, no_flags);
  }

  if no_flags || args.flag_md5 {
    let mut md5  = String::with_capacity(32);

    for byte in &info.md5_sum {
      let hex = format!("{:02x}", byte);

      md5.push_str(&hex);
    }

    format_print!("{}{}", "MD5 sum: ", md5, no_flags);
  }
}

fn print_vorbis_comments(vorbis_comment: &VorbisComment, args: &Arguments) {
  let no_flags  = (args.flag_vendor || args.flag_name.is_some()) == false;

  if no_flags || args.flag_vendor {
    format_print!("{}{}", "Vendor string: ", vorbis_comment.vendor_string,
                                             no_flags);
  }

  if no_flags {
    let mut index = 1;

    println!("Number of Comments: {}", vorbis_comment.comments.len());

    for (name, value) in &vorbis_comment.comments {
      println!("  {}: \"{}\" = {}", index, name, value);

      index += 1;
    }
  } else {
    if let Some(ref name) = args.flag_name {
      vorbis_comment.comments.get(name)
                             .map(|value| println!("{}", value));
    }
  }
}

fn export_vorbis_comments(vorbis_comment: &VorbisComment, filename: &str)
                          -> io::Result<()> {
  let mut file = try!(File::create(filename));

  for (name, value) in &vorbis_comment.comments {
    try!(write!(file, "{}={}\n", name, value));
  }

  Ok(())
}

fn print_seek_table(seek_points: &[SeekPoint]) {
  let mut count = 0;

  println!("Number of Seek Points: {}", seek_points.len());

  for seek_point in seek_points {
    println!("Seek Point #{}", count);
    println!("  Sample number: {}", seek_point.sample_number);
    println!("  Stream offset: {}", seek_point.stream_offset);
    println!("  Frame samples: {}", seek_point.frame_samples);
    count += 1;
  }
}

fn export_picture(picture: &Picture, filename: &str) -> io::Result<()> {
  File::create(filename).and_then(|mut file| file.write_all(&picture.data))
}

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

  let mut index = 0;
  let _index    = args.flag_index.unwrap_or(0);

  let stream = StreamReader::<File>::from_file(&args.arg_filename)
                 .expect("Couldn't parse file");

  if args.cmd_streaminfo {
    print_stream_info(&stream, &args);
  }

  for meta in stream.metadata() {
    match meta.data {
      metadata::Data::VorbisComment(ref v) => {
        if args.cmd_comments {
          if let Some(ref filename) = args.flag_export {
            export_vorbis_comments(v, filename)
              .expect("couldn't write to file")
          } else {
            print_vorbis_comments(v, &args)
          }
        }
      }
      metadata::Data::SeekTable(ref s)     => {
        if args.cmd_seektable {
          print_seek_table(s);
        }
      }
      metadata::Data::Picture(ref p)       => {
        if args.cmd_picture {
          if index != _index {
            index += 1;

            continue;
          }

          if let Some(ref filename) = args.flag_export {
            export_picture(p, filename).expect("couldn't write to file");

            break;
          }
        }
      }
      _                                    => continue,
    }
  }
}
<|endoftext|>