<commit_before>#![allow(unstable)]
#![feature(plugin)]
extern crate sodiumoxide;
extern crate libc;
extern crate serialize;
extern crate unicode;
extern crate regex;
#[plugin] #[no_link]
extern crate regex_macros;

use reader::*;
use controls::*;
use constants::*;
use script::*;
use builtins::*;
use input::*;

use input::InputValue::*;

mod constants;
mod util;
mod termios;
mod signal;
mod controls;
mod input;
mod reader;
mod script;
mod builtins;
mod command;

fn run_command(args:Vec<WashArgs>, env:&mut WashEnv) -> Result<WashArgs, String> {
    let out = try!(run_function("run".to_string(), args, env));
    let outv = out.flatten_vec();
    if out.is_empty() {
        return Err("Command failed".to_string());
    } else if outv.len() < 2 {
        return Err(format!("Command failed: {}", out.flatten()));
    } else if outv != vec!["status", "0"] {
        return Err(format!("Command failed with {} {}", outv[0], outv[1]));
    } else {
        return Ok(WashArgs::Empty);
    }
}

fn run_function(name:String, args:Vec<WashArgs>, env:&mut WashEnv) -> Result<WashArgs, String> {
    if env.hasf(&name) {
        return Ok(env.runf(&name, &WashArgs::Long(args)));
    } else {
        return Err("Function not found".to_string());
    }
}

fn run_line(line:InputValue, env:&mut WashEnv) -> Result<WashArgs, String> {
    match line {
        Function(n, a) => {
            return run_function(n, try!(input_to_vec(a, env)), env);
        },
        Long(a) => {
            // run as command
            return run_command(try!(input_to_vec(a, env)), env);
        },
        Short(ref s) if VAR_PATH_REGEX.is_match(s.as_slice()) => {
            let out = try!(input_to_args(Short(s.clone()), env));
            return Ok(WashArgs::Flat(format!("{}\n", out.flatten_with_inner("\n", "="))));
        },
        Short(ref s) if VAR_REGEX.is_match(s.as_slice()) => {
            let out = try!(input_to_args(Short(s.clone()), env));
            return Ok(WashArgs::Flat(format!("{}\n", out.flatten())));
        },
        Short(s) | Literal(s) => {
            // run command without args
            return run_command(vec![WashArgs::Flat(s)], env);
        },
        _ => {
            // do nothing
            return Ok(WashArgs::Empty);
        }
    }
}

fn input_to_vec(input:Vec<InputValue>, env:&mut WashEnv) -> Result<Vec<WashArgs>, String> {
    let mut args = vec![];
    for item in input.iter() {
        match try!(input_to_args(item.clone(), env)) {
            WashArgs::Empty => {/* do nothing */},
            v => args.push(v)
        }
    }
    return Ok(args);
}

fn input_to_args(input:InputValue, env:&mut WashEnv) -> Result<WashArgs, String> {
    match input {
        Function(n, a) => {
            return run_function(n, try!(input_to_vec(a, env)),
                                env);
        },
        Long(a) => {
            let mut args = vec![];
            for item in a.iter() {
                match try!(input_to_args(item.clone(), env)) {
                    WashArgs::Empty => {/* do nothing */},
                    v => args.push(v)
                }
            }
            return Ok(WashArgs::Long(args));
        },
        // the special cases with regex make for more informative errors
        Short(ref s) if VAR_PATH_REGEX.is_match(s.as_slice()) => {
            let caps = VAR_PATH_REGEX.captures(s.as_slice()).unwrap();
            let path = caps.at(1).unwrap().to_string();
            let name = caps.at(2).unwrap().to_string();
            if name.is_empty() {
                if path.is_empty() {
                    return match env.getall() {
                        WashArgs::Empty => Err(format!("Path not found: {}", path)),
                        v => Ok(v)
                    }
                } else {
                    return match env.getallp(&path) {
                        WashArgs::Empty => Err(format!("Path not found: {}", path)),
                        v => Ok(v)
                    }
                }
            } else {
                return match env.getvp(&name, &path) {
                    WashArgs::Empty => Err(format!("Variable not found: {}:{}", path, name)),
                    v => Ok(v)
                }
            }
        },
        Short(ref s) if VAR_REGEX.is_match(s.as_slice()) => {
            let caps = VAR_REGEX.captures(s.as_slice()).unwrap();
            let name = caps.at(1).unwrap().to_string();
            return match env.getv(&name) {
                WashArgs::Empty => Err(format!("Variable not found: {}", name)),
                v => Ok(v)
            }
        },
        Short(s) | Literal(s) => return Ok(WashArgs::Flat(s)),
        Split(_) => return Ok(WashArgs::Empty)
    }
}

// public so no warnings when we run tests
pub fn main() {
    let mut controls = &mut Controls::new();
    let mut reader = LineReader::new();
    let mut env = WashEnv::new();
    load_builtins(&mut env);
    env.update_terminal();
    loop {
        controls.flush();
        match reader.read_line() {
            None => {
                if reader.eof {
                    break;
                } else if !reader.line.is_empty() {
                    controls.outc(BEL);
                    reader.restart();
                } else {
                    controls.outc(NL);
                    reader.clear();
                }
            },
            Some(line) => {
                controls.outc(NL);
                match run_line(line, &mut env) {
                    Err(e) => controls.errf(format_args!("{}\n", e)),
                    Ok(v) => {
                        controls.outs(v.flatten().as_slice());
                    }
                }
                reader.clear();
            }
        }
    }
    controls.outs("\nExiting\n");
    controls.flush();
    env.restore_terminal();
}
<commit_msg>Get rid of unnecessary Controls object<commit_after>#![allow(unstable)]
#![feature(plugin)]
extern crate sodiumoxide;
extern crate libc;
extern crate serialize;
extern crate unicode;
extern crate regex;
#[plugin] #[no_link]
extern crate regex_macros;

use reader::*;
use constants::*;
use script::*;
use builtins::*;
use input::*;

use input::InputValue::*;

mod constants;
mod util;
mod termios;
mod signal;
mod controls;
mod input;
mod reader;
mod script;
mod builtins;
mod command;

fn run_command(args:Vec<WashArgs>, env:&mut WashEnv) -> Result<WashArgs, String> {
    let out = try!(run_function("run".to_string(), args, env));
    let outv = out.flatten_vec();
    if out.is_empty() {
        return Err("Command failed".to_string());
    } else if outv.len() < 2 {
        return Err(format!("Command failed: {}", out.flatten()));
    } else if outv != vec!["status", "0"] {
        return Err(format!("Command failed with {} {}", outv[0], outv[1]));
    } else {
        return Ok(WashArgs::Empty);
    }
}

fn run_function(name:String, args:Vec<WashArgs>, env:&mut WashEnv) -> Result<WashArgs, String> {
    if env.hasf(&name) {
        return Ok(env.runf(&name, &WashArgs::Long(args)));
    } else {
        return Err("Function not found".to_string());
    }
}

fn run_line(line:InputValue, env:&mut WashEnv) -> Result<WashArgs, String> {
    match line {
        Function(n, a) => {
            return run_function(n, try!(input_to_vec(a, env)), env);
        },
        Long(a) => {
            // run as command
            return run_command(try!(input_to_vec(a, env)), env);
        },
        Short(ref s) if VAR_PATH_REGEX.is_match(s.as_slice()) => {
            let out = try!(input_to_args(Short(s.clone()), env));
            return Ok(WashArgs::Flat(format!("{}\n", out.flatten_with_inner("\n", "="))));
        },
        Short(ref s) if VAR_REGEX.is_match(s.as_slice()) => {
            let out = try!(input_to_args(Short(s.clone()), env));
            return Ok(WashArgs::Flat(format!("{}\n", out.flatten())));
        },
        Short(s) | Literal(s) => {
            // run command without args
            return run_command(vec![WashArgs::Flat(s)], env);
        },
        _ => {
            // do nothing
            return Ok(WashArgs::Empty);
        }
    }
}

fn input_to_vec(input:Vec<InputValue>, env:&mut WashEnv) -> Result<Vec<WashArgs>, String> {
    let mut args = vec![];
    for item in input.iter() {
        match try!(input_to_args(item.clone(), env)) {
            WashArgs::Empty => {/* do nothing */},
            v => args.push(v)
        }
    }
    return Ok(args);
}

fn input_to_args(input:InputValue, env:&mut WashEnv) -> Result<WashArgs, String> {
    match input {
        Function(n, a) => {
            return run_function(n, try!(input_to_vec(a, env)),
                                env);
        },
        Long(a) => {
            let mut args = vec![];
            for item in a.iter() {
                match try!(input_to_args(item.clone(), env)) {
                    WashArgs::Empty => {/* do nothing */},
                    v => args.push(v)
                }
            }
            return Ok(WashArgs::Long(args));
        },
        // the special cases with regex make for more informative errors
        Short(ref s) if VAR_PATH_REGEX.is_match(s.as_slice()) => {
            let caps = VAR_PATH_REGEX.captures(s.as_slice()).unwrap();
            let path = caps.at(1).unwrap().to_string();
            let name = caps.at(2).unwrap().to_string();
            if name.is_empty() {
                if path.is_empty() {
                    return match env.getall() {
                        WashArgs::Empty => Err(format!("Path not found: {}", path)),
                        v => Ok(v)
                    }
                } else {
                    return match env.getallp(&path) {
                        WashArgs::Empty => Err(format!("Path not found: {}", path)),
                        v => Ok(v)
                    }
                }
            } else {
                return match env.getvp(&name, &path) {
                    WashArgs::Empty => Err(format!("Variable not found: {}:{}", path, name)),
                    v => Ok(v)
                }
            }
        },
        Short(ref s) if VAR_REGEX.is_match(s.as_slice()) => {
            let caps = VAR_REGEX.captures(s.as_slice()).unwrap();
            let name = caps.at(1).unwrap().to_string();
            return match env.getv(&name) {
                WashArgs::Empty => Err(format!("Variable not found: {}", name)),
                v => Ok(v)
            }
        },
        Short(s) | Literal(s) => return Ok(WashArgs::Flat(s)),
        Split(_) => return Ok(WashArgs::Empty)
    }
}

// public so no warnings when we run tests
pub fn main() {
    let mut reader = LineReader::new();
    let mut env = WashEnv::new();
    load_builtins(&mut env);
    env.update_terminal();
    loop {
        env.flush();
        match reader.read_line() {
            None => {
                if reader.eof {
                    break;
                } else if !reader.line.is_empty() {
                    env.outc(BEL);
                    reader.restart();
                } else {
                    env.outc(NL);
                    reader.clear();
                }
            },
            Some(line) => {
                env.outc(NL);
                match run_line(line, &mut env) {
                    Err(e) => env.errf(format_args!("{}\n", e)),
                    Ok(v) => {
                        env.outs(v.flatten().as_slice());
                    }
                }
                reader.clear();
            }
        }
    }
    env.outs("\nExiting\n");
    env.flush();
    env.restore_terminal();
}
<|endoftext|>


<commit_before>#![feature(macro_rules)]

//! Implementation of a Micro Transport Protocol library,
//! as well as a small client and server.
//!
//! http://www.bittorrent.org/beps/bep_0029.html

extern crate utp;
use std::io::net::ip::{Ipv4Addr, SocketAddr};

fn usage() {
    println!("Usage: torresmo [-s|-c] <address> <port>");
}

fn main() {
    use utp::{UtpStream, UtpSocket};
    use std::from_str::FromStr;

    // Defaults
    static BUF_SIZE: uint = 4096;
    let mut addr = SocketAddr { ip: Ipv4Addr(127,0,0,1), port: 8080 };

    let args = std::os::args();

    if args.len() == 4 {
        addr = SocketAddr {
            ip:   FromStr::from_str(args.get(2).as_slice()).unwrap(),
            port: FromStr::from_str(args.get(3).as_slice()).unwrap(),
        };
    }

    match args.get(1).as_slice() {
        "-s" => {
            let mut buf = [0, ..BUF_SIZE];
            let mut sock = UtpSocket::bind(addr).unwrap();
            println!("Serving on {}", addr);

            loop {
                match sock.recvfrom(buf) {
                    Ok((read, _src)) => {
                        spawn(proc() {
                            let buf = buf.slice(0, read);
                            let path = Path::new("output.txt");
                            let mut file = match std::io::File::open_mode(&path, std::io::Open, std::io::ReadWrite) {
                                Ok(f) => f,
                                Err(e) => fail!("file error: {}", e),
                            };
                            match file.write(buf) {
                                Ok(_) => {}
                                Err(e) => fail!("error writing to file: {}", e),
                            };
                        })
                    }
                    Err(e) => fail!("{}", e),
                }
            }
        }
        "-c" => {
            let mut stream = UtpStream::connect(addr);

            let buf = [0xF, ..BUF_SIZE];
            match stream.write(buf) {
                Ok(_) => {},
                Err(e) => fail!("{}", e),
            }

            let mut buf = [0u8, ..BUF_SIZE];
            match stream.read(buf) {
                Ok(n) => println!("{}", Vec::from_slice(buf.slice(0, n))),
                Err(e) => println!("{}", e),
            }

            match stream.close() {
                Ok(_) => {},
                Err(e) => fail!("{}", e),
            }
            drop(stream);
        }
        _ => usage(),
    }
}
<commit_msg>Massively simplify server.<commit_after>#![feature(macro_rules)]

//! Implementation of a Micro Transport Protocol library,
//! as well as a small client and server.
//!
//! http://www.bittorrent.org/beps/bep_0029.html

extern crate utp;
use std::io::net::ip::{Ipv4Addr, SocketAddr};

fn usage() {
    println!("Usage: torresmo [-s|-c] <address> <port>");
}

fn main() {
    use utp::{UtpStream, UtpSocket};
    use std::from_str::FromStr;

    // Defaults
    static BUF_SIZE: uint = 4096;
    let mut addr = SocketAddr { ip: Ipv4Addr(127,0,0,1), port: 8080 };

    let args = std::os::args();

    if args.len() == 4 {
        addr = SocketAddr {
            ip:   FromStr::from_str(args.get(2).as_slice()).unwrap(),
            port: FromStr::from_str(args.get(3).as_slice()).unwrap(),
        };
    }

    match args.get(1).as_slice() {
        "-s" => {
            let mut buf = [0, ..BUF_SIZE];
            let mut sock = UtpSocket::bind(addr).unwrap();
            println!("Serving on {}", addr);

            loop {
                match sock.recvfrom(buf) {
                    Ok((_read, _src)) => {}
                    Err(e) => fail!("{}", e),
                }
            }
        }
        "-c" => {
            let mut stream = UtpStream::connect(addr);

            let buf = [0xF, ..BUF_SIZE];
            match stream.write(buf) {
                Ok(_) => {},
                Err(e) => fail!("{}", e),
            }

            let mut buf = [0u8, ..BUF_SIZE];
            match stream.read(buf) {
                Ok(n) => println!("{}", Vec::from_slice(buf.slice(0, n))),
                Err(e) => println!("{}", e),
            }

            match stream.close() {
                Ok(_) => {},
                Err(e) => fail!("{}", e),
            }
            drop(stream);
        }
        _ => usage(),
    }
}
<|endoftext|>


<commit_before>#[macro_use]
extern crate error_chain;
#[macro_use]
extern crate stderr;
extern crate chan;
extern crate clap;
extern crate filetime;
extern crate glob;

#[macro_use] mod errors;
mod compression;
mod lists;
mod structs;

use clap::{App, Arg};
use errors::*;
use lists::*;
use structs::*;
use std::path::{Path, PathBuf};
use std::sync::Arc;

quick_main!(run);

fn run() -> Result<()> {
    let matches = App::new("static-compress")
        .version("0.1")
        .about("Create statically-compresed copies of matching files")
        .author("NeoSmart Technologies")
        .arg(Arg::with_name("compressor")
            .short("c")
            .long("compressor")
            .value_name("[brotli|gzip|zopfli]")
            .help("The compressor to use (default: gzip)")
            .takes_value(true))
        .arg(Arg::with_name("threads")
            .short("j")
            .long("threads")
            .value_name("COUNT")
            .help("The number of simultaneous compressions (default: 1)")
            .takes_value(true))
        .arg(Arg::with_name("filters")
            .value_name("FILTER")
            .multiple(true)
            .required(true))
        .arg(Arg::with_name("ext")
            .short("e")
            .value_name("EXT")
            .long("extension")
            .help("The extension to use for compressed files (default: gz or br)"))
        /*.arg(Arg::with_name("excludes")
            .short("x")
            .value_name("FILTER")
            .long("exclude")
            .multiple(true)
            .help("Exclude files matching this glob expression"))*/
        .get_matches();

    fn get_parameter<'a, T>(matches: &clap::ArgMatches, name: &str, default_value: T) -> Result<T>
        where T: std::str::FromStr
    {
        match matches.value_of(name) {
            Some(v) => {
                Ok(v.parse().map_err(|_| ErrorKind::InvalidParameterValue(name.to_owned()))?)
            }
            None => Ok(default_value),
        }
    }

    let compressor = get_parameter(&matches, "compressor", CompressionAlgorithm::GZip)?;
    let temp = Parameters {
        extension: matches.value_of("ext")
            .unwrap_or(compressor.extension())
            .trim_matches(|c: char| c.is_whitespace() || c.is_control() || c == '.')
            .to_owned(),
        compressor: compressor,
        include_filters: match matches.values_of("filters") {
            Some(values) => Ok(values.map(|s| s.to_owned()).collect()),
            None => Err(ErrorKind::InvalidUsage),
        }?,
        threads: get_parameter(&matches, "threads", 1)?,
    };

    /*let exclude_filters = match matches.values_of("exclude") {
        Some(values)=> values.map(|s| s.to_owned()).collect(),
        None => Vec::<String>::new(),
    };*/

    let parameters = Arc::<Parameters>::new(temp);
    let (send_queue, wait_group) = start_workers(&parameters);

    //convert filters to paths and deal out conversion jobs
    dispatch_jobs(send_queue, &parameters.include_filters/*, exclude_filters*/)?;

    //wait for all jobs to finish
    wait_group.wait();

    Ok(())
}

type ThreadParam = std::path::PathBuf;

fn start_workers<'a>(params: &Arc<Parameters>) -> (chan::Sender<ThreadParam>, chan::WaitGroup) {
    let (tx, rx) = chan::sync::<ThreadParam>(params.threads);
    let wg = chan::WaitGroup::new();

    for _ in 0..params.threads {
        let local_params = params.clone();
        let local_rx = rx.clone();
        let local_wg = wg.clone();
        wg.add(1);
        std::thread::spawn(move || {
            worker_thread(local_params, local_rx);
            local_wg.done();
        });
    }

    (tx, wg)
}

fn dispatch_jobs(send_queue: chan::Sender<ThreadParam>, filters: &Vec<String>/*, exclude_filters: Vec<String>*/) -> Result<()> {
    for filter in filters {
        //by default, rs-glob treats "**" as a directive to match only directories
        //we can either rewrite "**" as "**/*" or recurse into directories below
        let new_filter = (&*filter).replace("**", "**/*");
        for entry in glob::glob(&new_filter).map_err(|_| ErrorKind::InvalidIncludeFilter)? {
            match entry {
                Ok(path) => {
                    if is_blacklisted(&path)? {
                        //this path has been excluded
                        continue;
                    }
                    //make sure this is a file, not a folder
                    match std::fs::metadata(&path) {
                        Ok(metadata) => {
                            if metadata.is_file() {
                                send_queue.send(path);
                            }
                            continue; //skip otherwise
                        }
                        Err(e) => errstln!("{}: {}", path.to_string_lossy(), e),
                    }
                }
                Err(e) => errstln!("{}", e),
            };
        }
    }
    Ok(())
}

fn worker_thread(params: Arc<Parameters>, rx: chan::Receiver<ThreadParam>) {
    loop {
        let src = match rx.recv() {
            Some(task) => task,
            None => return, //no more tasks
        };

        //in a nested function so we can handle errors centrally
        fn compress_single(src: &ThreadParam, params: &Parameters) -> Result<()> {
            let dst_path = format!("{}.{}",
                                   src.to_str().ok_or(ErrorKind::InvalidCharactersInPath)?,
                                   params.extension);
            let dst = Path::new(&dst_path);

            //again, in a scope for error handling
            || -> Result<()> {
                    println!("{}", src.to_string_lossy());
                    let src_metadata = std::fs::metadata(src)?;

                    //don't compress files that are already compressed that haven't changed
                    if let Ok(dst_metadata) = std::fs::metadata(dst) {
                        //the destination already exists
                        match src_metadata.modified()? == dst_metadata.modified()? {
                            true => return Ok(()), //no need to recompress
                            false => std::fs::remove_file(dst)?, //throw if we can't
                        };
                    }
                    params.compressor.compress(src.as_path(), dst)?;
                    let src_modified = filetime::FileTime::from_last_modification_time(&src_metadata);
                    filetime::set_file_times(dst, filetime::FileTime::zero(), src_modified).unwrap_or_default();

                    Ok(())
                }()
                .map_err(|e| {
                    //try deleting the invalid destination file, but don't care if we can't
                    std::fs::remove_file(dst).unwrap_or_default();
                    e //return the same error
                })
        }

        if let Err(e) = compress_single(&src, &params) {
            errstln!("Error compressing {}: {}", src.to_string_lossy(), e);
        }
    }
}

fn str_search(sorted: &[&str], search_term: &str, case_sensitive: bool) -> std::result::Result<usize, usize> {
    let term = match case_sensitive {
        true => search_term.to_owned(),
        false => search_term.to_lowercase(),
    };

    sorted.binary_search_by(|probe| probe.cmp(&&*term))
}

fn is_blacklisted(path: &PathBuf) -> Result<bool> {
    let r = match path.extension() {
        Some(x) => {
            let ext = x.to_str().ok_or(ErrorKind::InvalidCharactersInPath)?;
            str_search(COMP_EXTS, &ext, false).is_ok()
        },
        None => false,
    };

    return Ok(r);
}

<commit_msg>Skip .paths by default<commit_after>#[macro_use]
extern crate error_chain;
#[macro_use]
extern crate stderr;
extern crate chan;
extern crate clap;
extern crate filetime;
extern crate glob;

#[macro_use] mod errors;
mod compression;
mod lists;
mod structs;

use clap::{App, Arg};
use errors::*;
use lists::*;
use structs::*;
use std::path::{Path, PathBuf};
use std::sync::Arc;

quick_main!(run);

fn run() -> Result<()> {
    let matches = App::new("static-compress")
        .version("0.1")
        .about("Create statically-compresed copies of matching files")
        .author("NeoSmart Technologies")
        .arg(Arg::with_name("compressor")
            .short("c")
            .long("compressor")
            .value_name("[brotli|gzip|zopfli]")
            .help("The compressor to use (default: gzip)")
            .takes_value(true))
        .arg(Arg::with_name("threads")
            .short("j")
            .long("threads")
            .value_name("COUNT")
            .help("The number of simultaneous compressions (default: 1)")
            .takes_value(true))
        .arg(Arg::with_name("filters")
            .value_name("FILTER")
            .multiple(true)
            .required(true))
        .arg(Arg::with_name("ext")
            .short("e")
            .value_name("EXT")
            .long("extension")
            .help("The extension to use for compressed files (default: gz or br)"))
        /*.arg(Arg::with_name("excludes")
            .short("x")
            .value_name("FILTER")
            .long("exclude")
            .multiple(true)
            .help("Exclude files matching this glob expression"))*/
        .get_matches();

    fn get_parameter<'a, T>(matches: &clap::ArgMatches, name: &str, default_value: T) -> Result<T>
        where T: std::str::FromStr
    {
        match matches.value_of(name) {
            Some(v) => {
                Ok(v.parse().map_err(|_| ErrorKind::InvalidParameterValue(name.to_owned()))?)
            }
            None => Ok(default_value),
        }
    }

    let compressor = get_parameter(&matches, "compressor", CompressionAlgorithm::GZip)?;
    let temp = Parameters {
        extension: matches.value_of("ext")
            .unwrap_or(compressor.extension())
            .trim_matches(|c: char| c.is_whitespace() || c.is_control() || c == '.')
            .to_owned(),
        compressor: compressor,
        include_filters: match matches.values_of("filters") {
            Some(values) => Ok(values.map(|s| s.to_owned()).collect()),
            None => Err(ErrorKind::InvalidUsage),
        }?,
        threads: get_parameter(&matches, "threads", 1)?,
    };

    /*let exclude_filters = match matches.values_of("exclude") {
        Some(values)=> values.map(|s| s.to_owned()).collect(),
        None => Vec::<String>::new(),
    };*/

    let parameters = Arc::<Parameters>::new(temp);
    let (send_queue, wait_group) = start_workers(&parameters);

    //convert filters to paths and deal out conversion jobs
    dispatch_jobs(send_queue, &parameters.include_filters/*, exclude_filters*/)?;

    //wait for all jobs to finish
    wait_group.wait();

    Ok(())
}

type ThreadParam = std::path::PathBuf;

fn start_workers<'a>(params: &Arc<Parameters>) -> (chan::Sender<ThreadParam>, chan::WaitGroup) {
    let (tx, rx) = chan::sync::<ThreadParam>(params.threads);
    let wg = chan::WaitGroup::new();

    for _ in 0..params.threads {
        let local_params = params.clone();
        let local_rx = rx.clone();
        let local_wg = wg.clone();
        wg.add(1);
        std::thread::spawn(move || {
            worker_thread(local_params, local_rx);
            local_wg.done();
        });
    }

    (tx, wg)
}

fn dispatch_jobs(send_queue: chan::Sender<ThreadParam>, filters: &Vec<String>/*, exclude_filters: Vec<String>*/) -> Result<()> {
    let mut match_options = glob::MatchOptions::new();
    match_options.require_literal_leading_dot = true;

    for filter in filters {
        //by default, rs-glob treats "**" as a directive to match only directories
        //we can either rewrite "**" as "**/*" or recurse into directories below
        let new_filter = (&*filter).replace("**", "**/*");
        for entry in glob::glob_with(&new_filter, &match_options).map_err(|_| ErrorKind::InvalidIncludeFilter)? {
            match entry {
                Ok(path) => {
                    if is_blacklisted(&path)? {
                        //this path has been excluded
                        continue;
                    }
                    //make sure this is a file, not a folder
                    match std::fs::metadata(&path) {
                        Ok(metadata) => {
                            if metadata.is_file() {
                                send_queue.send(path);
                            }
                            continue; //skip otherwise
                        }
                        Err(e) => errstln!("{}: {}", path.to_string_lossy(), e),
                    }
                }
                Err(e) => errstln!("{}", e),
            };
        }
    }
    Ok(())
}

fn worker_thread(params: Arc<Parameters>, rx: chan::Receiver<ThreadParam>) {
    loop {
        let src = match rx.recv() {
            Some(task) => task,
            None => return, //no more tasks
        };

        //in a nested function so we can handle errors centrally
        fn compress_single(src: &ThreadParam, params: &Parameters) -> Result<()> {
            let dst_path = format!("{}.{}",
                                   src.to_str().ok_or(ErrorKind::InvalidCharactersInPath)?,
                                   params.extension);
            let dst = Path::new(&dst_path);

            //again, in a scope for error handling
            || -> Result<()> {
                    println!("{}", src.to_string_lossy());
                    let src_metadata = std::fs::metadata(src)?;

                    //don't compress files that are already compressed that haven't changed
                    if let Ok(dst_metadata) = std::fs::metadata(dst) {
                        //the destination already exists
                        match src_metadata.modified()? == dst_metadata.modified()? {
                            true => return Ok(()), //no need to recompress
                            false => std::fs::remove_file(dst)?, //throw if we can't
                        };
                    }
                    params.compressor.compress(src.as_path(), dst)?;
                    let src_modified = filetime::FileTime::from_last_modification_time(&src_metadata);
                    filetime::set_file_times(dst, filetime::FileTime::zero(), src_modified).unwrap_or_default();

                    Ok(())
                }()
                .map_err(|e| {
                    //try deleting the invalid destination file, but don't care if we can't
                    std::fs::remove_file(dst).unwrap_or_default();
                    e //return the same error
                })
        }

        if let Err(e) = compress_single(&src, &params) {
            errstln!("Error compressing {}: {}", src.to_string_lossy(), e);
        }
    }
}

fn str_search(sorted: &[&str], search_term: &str, case_sensitive: bool) -> std::result::Result<usize, usize> {
    let term = match case_sensitive {
        true => search_term.to_owned(),
        false => search_term.to_lowercase(),
    };

    sorted.binary_search_by(|probe| probe.cmp(&&*term))
}

fn is_blacklisted(path: &PathBuf) -> Result<bool> {
    //after some careful consideration, ignoring directories and files that start with a literal
    //dot. We might add a feature to bypass this in the future.
    if path.as_path().to_string_lossy().contains("/.") || path.as_path().to_string_lossy().starts_with(".") {
        //errstln!("Skipping path with leading literal .: {}", path.display());
        return Ok(true);
    }

    let r = match path.extension() {
        Some(x) => {
            let ext = x.to_str().ok_or(ErrorKind::InvalidCharactersInPath)?;
            str_search(COMP_EXTS, &ext, false).is_ok()
        },
        None => false,
    };

    return Ok(r);
}

<|endoftext|>


<commit_before>#![feature(macro_rules)]
#![feature(phase)]
#[phase(plugin, link)] extern crate log;

extern crate syntax;
extern crate time;
extern crate debug;
extern crate collections;

#[cfg(not(test))]
use racer::Match;
#[cfg(not(test))]
use racer::util::getline;
#[cfg(not(test))]
use racer::nameres::{do_file_search, do_external_search};
#[cfg(not(test))]
use std::io::File;
#[cfg(not(test))]
use std::io::BufferedReader;
#[cfg(not(test))]
use std::str;
#[cfg(not(test))]
use racer::scopes;

pub mod racer;

#[cfg(not(test))]
fn match_fn(m:Match) {
    let (linenum, charnum) = scopes::point_to_coords2(&m.filepath, m.point).unwrap();
    if m.matchstr.as_slice() == "" {
        fail!("MATCHSTR is empty - waddup?");
    }
    println!("MATCH {},{},{},{}", m.matchstr,
                                    linenum.to_string(),
                                    charnum.to_string(),
                                    m.filepath.as_str().unwrap());
}

#[cfg(not(test))]
fn complete() {
    let args = std::os::args();
    match std::uint::parse_bytes(std::os::args().as_slice()[2].as_bytes(), 10) {
        Some(linenum) => {
            // input: linenum, colnum, fname
            let charnum = std::uint::parse_bytes(std::os::args().as_slice()[3].as_bytes(), 10).unwrap();
            let fname = args.as_slice()[4].as_slice();
            let fpath = Path::new(fname);
            let filetxt = BufferedReader::new(File::open(&fpath)).read_to_end().unwrap();
            // print the start-end of the identifier being matched
            let src = str::from_utf8(filetxt.as_slice()).unwrap();
            let line = getline(&fpath, linenum);
            let (start, pos) = racer::util::expand_ident(line.as_slice(), charnum);
            println!("PREFIX {},{},{}", start, pos, line.as_slice().slice(start, pos));

            let point = scopes::coords_to_point(src, linenum, charnum);
            for m in racer::complete_from_file(src, &fpath, point) {
                match_fn(m);
            }
        }
        None => {
            // input: a command line string passed in
            let arg = args.as_slice()[2].as_slice();
            let mut it = arg.split_str("::");
            let p : Vec<&str> = it.collect();

            do_file_search(p.as_slice()[0], &Path::new("."), &mut |m| {
                if p.len() == 1 {
                    match_fn(m);
                } else {
                    do_external_search(p.slice_from(1), &m.filepath, m.point, racer::StartsWith, racer::BothNamespaces, &mut |m| match_fn(m));
                }
            });

        }
    }
}

#[cfg(not(test))]
fn prefix() {
    let args_ = std::os::args();
    let args = args_.as_slice();
    let linenum = std::uint::parse_bytes(args[2].as_bytes(), 10).unwrap();
    let charnum = std::uint::parse_bytes(args[3].as_bytes(), 10).unwrap();
    let fname = args[4].as_slice();

    // print the start, end, and the identifier prefix being matched
    let path = Path::new(fname);
    let line = getline(&path, linenum);
    let (start, pos) = racer::util::expand_ident(line.as_slice(), charnum);
    println!("PREFIX {},{},{}", start, pos, line.as_slice().slice(start, pos));
}

#[cfg(not(test))]
fn find_definition() {
    let args_ = std::os::args();
    let args = args_.as_slice();
    let linenum = std::uint::parse_bytes(args[2].as_bytes(), 10).unwrap();
    let charnum = std::uint::parse_bytes(args[3].as_bytes(), 10).unwrap();
    let fname = args[4].as_slice();
    let fpath = Path::new(fname);
    let filetxt = BufferedReader::new(File::open(&fpath)).read_to_end().unwrap();
    let src = str::from_utf8(filetxt.as_slice()).unwrap();
    let pos = scopes::coords_to_point(src, linenum, charnum);

    racer::find_definition(src, &fpath, pos).map(match_fn);
}

#[cfg(not(test))]
fn print_usage() {
    let program = std::os::args().as_slice()[0].clone();
    println!("usage: {} complete linenum charnum fname", program);
    println!("or:    {} find-definition linenum charnum fname", program);
    println!("or:    {} complete fullyqualifiedname   (e.g. std::io::)",program);
    println!("or:    {} prefix linenum charnum fname",program);
}

#[cfg(not(test))]
fn main() {
    if std::os::getenv("RUST_SRC_PATH").is_none() {
        println!("RUST_SRC_PATH environment variable must be set");
        std::os::set_exit_status(1);
        return;
    }

    let args_ = std::os::args();
    let args = args_.as_slice();

    if args.len() == 1 {
        print_usage();
        std::os::set_exit_status(1);
        return;
    }

    let command = args[1].as_slice();
    match command.as_slice() {
        "prefix" => prefix(),
        "complete" => complete(),
        "find-definition" => find_definition(),
        "help" => print_usage(),
        _ => {
            println!("Sorry, I didn't understand command {}", command );
            print_usage();
            std::os::set_exit_status(1);
            return;
        }
    }
}
<commit_msg>fix up main.rs to use iterator<commit_after>#![feature(macro_rules)]
#![feature(phase)]
#[phase(plugin, link)] extern crate log;

extern crate syntax;
extern crate time;
extern crate debug;
extern crate collections;

#[cfg(not(test))]
use racer::Match;
#[cfg(not(test))]
use racer::util::getline;
#[cfg(not(test))]
use racer::nameres::{do_file_search, do_external_search};
#[cfg(not(test))]
use std::io::File;
#[cfg(not(test))]
use std::io::BufferedReader;
#[cfg(not(test))]
use std::str;
#[cfg(not(test))]
use racer::scopes;

pub mod racer;

#[cfg(not(test))]
fn match_fn(m:Match) {
    let (linenum, charnum) = scopes::point_to_coords2(&m.filepath, m.point).unwrap();
    if m.matchstr.as_slice() == "" {
        fail!("MATCHSTR is empty - waddup?");
    }
    println!("MATCH {},{},{},{}", m.matchstr,
                                    linenum.to_string(),
                                    charnum.to_string(),
                                    m.filepath.as_str().unwrap());
}

#[cfg(not(test))]
fn complete() {
    let args = std::os::args();
    match std::uint::parse_bytes(std::os::args().as_slice()[2].as_bytes(), 10) {
        Some(linenum) => {
            // input: linenum, colnum, fname
            let charnum = std::uint::parse_bytes(std::os::args().as_slice()[3].as_bytes(), 10).unwrap();
            let fname = args.as_slice()[4].as_slice();
            let fpath = Path::new(fname);
            let filetxt = BufferedReader::new(File::open(&fpath)).read_to_end().unwrap();
            // print the start-end of the identifier being matched
            let src = str::from_utf8(filetxt.as_slice()).unwrap();
            let line = getline(&fpath, linenum);
            let (start, pos) = racer::util::expand_ident(line.as_slice(), charnum);
            println!("PREFIX {},{},{}", start, pos, line.as_slice().slice(start, pos));

            let point = scopes::coords_to_point(src, linenum, charnum);
            for m in racer::complete_from_file(src, &fpath, point) {
                match_fn(m);
            }
        }
        None => {
            // input: a command line string passed in
            let arg = args.as_slice()[2].as_slice();
            let mut it = arg.split_str("::");
            let p : Vec<&str> = it.collect();

            for m in do_file_search(p.as_slice()[0], &Path::new(".")) {
                if p.len() == 1 {
                    match_fn(m);
                } else {
                    for m in do_external_search(p.slice_from(1), &m.filepath, m.point, racer::StartsWith, racer::BothNamespaces) {
                        match_fn(m);
                    }
                }
            }
        }
    }
}

#[cfg(not(test))]
fn prefix() {
    let args_ = std::os::args();
    let args = args_.as_slice();
    let linenum = std::uint::parse_bytes(args[2].as_bytes(), 10).unwrap();
    let charnum = std::uint::parse_bytes(args[3].as_bytes(), 10).unwrap();
    let fname = args[4].as_slice();

    // print the start, end, and the identifier prefix being matched
    let path = Path::new(fname);
    let line = getline(&path, linenum);
    let (start, pos) = racer::util::expand_ident(line.as_slice(), charnum);
    println!("PREFIX {},{},{}", start, pos, line.as_slice().slice(start, pos));
}

#[cfg(not(test))]
fn find_definition() {
    let args_ = std::os::args();
    let args = args_.as_slice();
    let linenum = std::uint::parse_bytes(args[2].as_bytes(), 10).unwrap();
    let charnum = std::uint::parse_bytes(args[3].as_bytes(), 10).unwrap();
    let fname = args[4].as_slice();
    let fpath = Path::new(fname);
    let filetxt = BufferedReader::new(File::open(&fpath)).read_to_end().unwrap();
    let src = str::from_utf8(filetxt.as_slice()).unwrap();
    let pos = scopes::coords_to_point(src, linenum, charnum);

    racer::find_definition(src, &fpath, pos).map(match_fn);
}

#[cfg(not(test))]
fn print_usage() {
    let program = std::os::args().as_slice()[0].clone();
    println!("usage: {} complete linenum charnum fname", program);
    println!("or:    {} find-definition linenum charnum fname", program);
    println!("or:    {} complete fullyqualifiedname   (e.g. std::io::)",program);
    println!("or:    {} prefix linenum charnum fname",program);
}

#[cfg(not(test))]
fn main() {
    if std::os::getenv("RUST_SRC_PATH").is_none() {
        println!("RUST_SRC_PATH environment variable must be set");
        std::os::set_exit_status(1);
        return;
    }

    let args_ = std::os::args();
    let args = args_.as_slice();

    if args.len() == 1 {
        print_usage();
        std::os::set_exit_status(1);
        return;
    }

    let command = args[1].as_slice();
    match command.as_slice() {
        "prefix" => prefix(),
        "complete" => complete(),
        "find-definition" => find_definition(),
        "help" => print_usage(),
        _ => {
            println!("Sorry, I didn't understand command {}", command );
            print_usage();
            std::os::set_exit_status(1);
            return;
        }
    }
}
<|endoftext|>


<commit_before>extern crate rudit;
extern crate termion;

use std::io::{Write, stdout};
use termion::raw::IntoRawMode;
use termion::event::Key;
use termion::input::TermRead;
use rudit::gapbuffer::GapBuffer;

fn main() {
    let mut buffer = GapBuffer::new(30);
    let mut stdout = stdout().into_raw_mode().unwrap();
    let mut index = 0;
    let mut cx: u16 = 1;
    let mut cy: u16 = 1;
    write!(stdout,
           "{}{}",
           termion::clear::All,
           termion::cursor::Goto(cx, cy))
        .unwrap();
    stdout.flush().unwrap();
    'main: loop {

        write!(stdout, "{}", termion::clear::All).unwrap();
        stdout.flush().unwrap();

        draw_lines(&mut stdout);
        draw_cursor(&mut stdout, cx, cy);

        for c in std::io::stdin().keys() {
            match c.unwrap() {
                Key::Char('\n') => {
                    buffer.insert(index, '\n');
                    cx = 1;
                    cy += 1;
                }
                Key::Char(c) => {
                    buffer.insert(index, c);
                    index += 1;
                    cx += 1;
                }
                Key::Left => {
                    if cx > 0 {
                        cx -= 1
                    }
                }
                Key::Right => {
                    if cx as usize <= buffer.len() {
                        cx += 1
                    }
                }
                Key::Esc => break,
                _ => (),
            }
            continue 'main;
        }
        write!(stdout, "{}", termion::clear::All).unwrap();
        stdout.flush().unwrap();
        break;
    }
}
fn draw_lines(stdout: &mut termion::raw::RawTerminal<std::io::Stdout>) {
    // TODO
    // implement real drawing of buffer lines and line numbers
    for i in 0..5 {
        write!(stdout,
               "{}{}",
               termion::cursor::Goto(0, i + 1),
               (i + 1).to_string())
            .unwrap();
    }
    stdout.flush().unwrap();
}

fn draw_cursor(stdout: &mut termion::raw::RawTerminal<std::io::Stdout>, cx: u16, cy: u16) {
    write!(stdout, "{}", termion::cursor::Goto(cx, cy)).unwrap();
    stdout.flush().unwrap();
}
<commit_msg>line drawing working<commit_after>extern crate rudit;
extern crate termion;

use std::io::{Write, stdout};
use termion::raw::IntoRawMode;
use termion::event::Key;
use termion::input::TermRead;
use termion::cursor::Goto;
use rudit::gapbuffer::GapBuffer;

fn main() {
    let mut buffer = GapBuffer::new(30);
    let mut stdout = stdout().into_raw_mode().unwrap();
    let mut index = 0;
    let mut cx: u16 = 3;
    let mut cy: u16 = 1;
    write!(stdout,
           "{}{}",
           termion::clear::All,
           termion::cursor::Goto(cx, cy))
            .unwrap();
    stdout.flush().unwrap();
    'main: loop {

        write!(stdout, "{}", termion::clear::CurrentLine).unwrap();

        draw_lines(&mut stdout, &buffer.buffer);
        draw_cursor(&mut stdout, cx, cy);

        stdout.flush().unwrap();

        for c in std::io::stdin().keys() {
            match c.unwrap() {
                Key::Char('\n') => {
                    buffer.insert(index, '\n');
                    cx = 3;
                    cy += 1;
                    index += 1;
                }
                Key::Char(c) => {
                    buffer.insert(index, c);
                    index += 1;
                    cx += 1;
                }
                Key::Left => {
                    if cx > 0 {
                        cx -= 1;
                        index -= 1;
                    }
                }
                Key::Right => {
                    if cx as usize <= buffer.len() {
                        cx += 1;
                        index += 1;
                    }
                }
                Key::Esc => break,
                _ => (),
            }
            continue 'main;
        }
        write!(stdout, "{}", termion::clear::All).unwrap();
        stdout.flush().unwrap();
        break;
    }
}
fn draw_lines(stdout: &mut termion::raw::RawTerminal<std::io::Stdout>, buffer: &Vec<char>) {
    let s: String = buffer.iter().collect();
    for (index, i) in s.split('\n').enumerate() {
        write!(stdout,
               "{}{}{}{}",
               Goto(0, (index + 1) as u16),
               index,
               Goto(3, (index + 1) as u16),
               i)
                .unwrap();
    }
}

fn draw_cursor(stdout: &mut termion::raw::RawTerminal<std::io::Stdout>, cx: u16, cy: u16) {
    write!(stdout, "{}", termion::cursor::Goto(cx, cy)).unwrap();
}
<|endoftext|>


<commit_before>use std::io::{BufReader, BufWriter};
use std::io::prelude::*;
use std::net::{TcpListener, TcpStream};
use std::thread;

fn main() {

    let listener = TcpListener::bind("127.0.0.1:8080").unwrap();

    fn handle_client(stream: TcpStream) {
        let writer_stream = stream.try_clone().unwrap();
        let reader = BufReader::new(stream);
        let mut writer = BufWriter::new(writer_stream);

        for line in reader.lines() {
            let in_str = line.unwrap();
            println!("{}", in_str);
            writer.write_fmt(format_args!("receive: {}\n", in_str.trim()));
        }

        // let mut in_str = String::new();
        // let read_size = buffer.read_line(&mut in_str).unwrap();
        // println!("{}", in_str);

        // buffer.write_fmt(format_args!("receive: {}\nsize: {}\n", in_str.trim(), read_size));
    }

    // accept connections and process them, spawning a new thread for each one
    for stream in listener.incoming() {
        match stream {
            Ok(stream) => {
                thread::spawn( move || {
                    // connection succeeded
                    handle_client(stream)
                });
            }
            Err(e) => { println!("{}", e); }
        }
    }

    // close the socket server
    drop(listener);

    println!("Hello, world!");
}

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

    #[test]
    fn it_works() {
        assert_eq!(2, 2);
    }
}<commit_msg>a rust's tcp server demo<commit_after>use std::io::{BufReader, BufWriter};
use std::io::prelude::*;
use std::net::{TcpListener, TcpStream};
use std::sync::Arc;
use std::thread;

fn main() {
    run_server(handle_client);
}

fn run_server<F>(handle_client: F)
    // handle_client needs to be shared between threads.
    // F's trait constraint is required.
    where F: 'static + Fn(TcpStream) + Send + Sync {

    let handle_client_arc = Arc::new(handle_client);

    match TcpListener::bind("127.0.0.1:8080") {
        Ok(listener) => {
            // accept connections and process them, spawning a new thread for each one
            for stream in listener.incoming() {
                match stream {
                    Ok(stream) => {
                        let handle_client_clone = handle_client_arc.clone();
                        thread::spawn( move || {
                            // connection succeeded
                            handle_client_clone(stream);
                        });
                    }
                    Err(e) => { println!("{}", e); }
                }
            }

            // close the socket server
            drop(listener);

            println!("Exit!");
        }
        Err(e) => {
            println!("{}", e);
        }
    }
}

fn handle_client(stream: TcpStream) {
    // A TcpStream is unable to create BufReader and BufWriter at the same time.
    // So a cloned TcpStream is needed
    match stream.try_clone() {
        Ok(stream_clone) => {
            let mut writer = BufWriter::new(stream_clone);
            let reader = BufReader::new(stream);
            // a simple protocal for string message with line breaks
            for line in reader.lines() {
                // error handling in chained Results
                // see std::result::Result and std::io::Result
                if let Err(e) = line
                    // line is Result<String>. The String value is used to call closure
                    .and_then(|in_str| writer
                        .write_fmt(format_args!("receive: {}\n", in_str.trim()))
                    )
                    .and_then(|()| writer.flush()) {
                        println!("{}", e);
                }
            }
            println!("one connection is closed");
        }
        Err(e) => {
            println!("Opening connection is failed. {}", e);
        }
    }
}

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

    #[test]
    fn it_works() {
        assert_eq!(2, 2);
    }
}<|endoftext|>


<commit_before>#[macro_use]
extern crate clap;
extern crate meval;
extern crate itertools;

use std::io::{self, BufRead};
use std::io::BufReader;
use std::path::Path;
use std::fs::File;
use itertools::Itertools;

#[cfg(feature = "yaml")]
fn main()
{
    use clap::App;

    let yml = load_yaml!("cli.yaml");
    let m = App::from_yaml(yml).get_matches();

    match m.subcommand_name()
    {
        Some("generate") => generate(m),
        Some("lookup") => lookup(m),
        None => println!("show help here. TODO: me!"),
           _ => println!("Some other subcommand was used"),
    }
}

#[cfg(feature = "yaml")]
fn generate(m_opts: clap::ArgMatches)
{
    if let Some(ref m_opts) = m_opts.subcommand_matches("generate")
    {
        let lib = m_opts.value_of("lib").unwrap();
        let gb_ratios = m_opts.value_of("gb_ratios").unwrap();
        let m :f64 = m_opts.value_of("gear_m").unwrap().parse::<f64>().unwrap();  // TODO dafuq?
        let n :f64 = m_opts.value_of("gear_n").unwrap().parse::<f64>().unwrap();  // TODO same
        let pitch :f64 = m_opts.value_of("pitch").unwrap().parse::<f64>().unwrap(); // TODO and me
        let out = m_opts.value_of("out").unwrap();

        let gears :Vec<i32> = gears_from_file(lib);
        let ratios :Vec<f64> = ratios_from_file(gb_ratios);

/*
        println!("lib: {:?}", lib);
        println!("gb_ratios: {:?}", gb_ratios);
        println!("m: {:?}", m);
        println!("n: {:?}", n);
        println!("out: {:?}", out);
        println!("pitch: {:?}", pitch);
        println!("gears: {:?}", gears);
        println!("ratios: {:?}", ratios);
*/

        for combos in gears.clone().into_iter().combinations(2)
        {
            // println!("{:?}", combos);

            let a = combos[0] as f64;
            let b = combos[1] as f64;

            // generate a list with 2 gears
            // a/b
            // b/a
            for r in ratios.clone().into_iter()
            {
                print_ab(m, n, a, b, r, pitch, (m/n) * ( a/b ) * r * pitch );
                print_ab(m, n, b, a, r, pitch, (m/n) * ( b/a ) * r * pitch );
            }
        }

        for combos in gears.clone().into_iter().combinations(4)
        {
            //println!("{:?}", combos);

            let a = combos[0] as f64;
            let b = combos[1] as f64;
            let c = combos[3] as f64;
            let d = combos[2] as f64;

            // generate a list with 4 gears
            // 2 on top = 4C2 = 6 sub-combinations:
            // ac / bd
            // ab / cd
            // ad / bc
            // bc / ad
            // bd / ac
            // cd / ab
            for r in ratios.clone().into_iter()
            {
                print_abcd(m, n, a, c, b, d, r, pitch, (m/n) * ( (a*c) / (b*d)) * r * pitch );
                print_abcd(m, n, a, b, c, d, r, pitch, (m/n) * ( (a*b) / (c*d)) * r * pitch );
                print_abcd(m, n, a, d, b, c, r, pitch, (m/n) * ( (a*d) / (b*c)) * r * pitch );
                print_abcd(m, n, b, c, a, d, r, pitch, (m/n) * ( (b*c) / (a*d)) * r * pitch );
                print_abcd(m, n, b, d, a, c, r, pitch, (m/n) * ( (b*d) / (a*c)) * r * pitch );
                print_abcd(m, n, c, d, a, b, r, pitch, (m/n) * ( (c*d) / (a*b)) * r * pitch );
            }
        }
    }
}

fn print_ab(m: f64, n: f64, a: f64, b: f64, r: f64, pitch: f64, ans: f64)
{
    println!("({:03}/{:03}) * ({:03} / {:03}) * {:2.5} * {:?} = {:2.5}", m, n, a, b, r, pitch, ans );
}

fn print_abcd(m: f64, n: f64, a: f64, b: f64, c: f64, d: f64, r: f64, pitch: f64, ans: f64)
{
    println!("({:03}/{:03}) * [({:03} * {:03}) / ({:03} * {:03})] * {:2.5} * {:?} = {:2.5}", m, n, a, c, b, d, r, pitch, ans );
}

fn lookup(m: clap::ArgMatches)
{
    if let Some(ref m) = m.subcommand_matches("generate")
    {
        let db = m.value_of("db").unwrap();
        let pitch = m.value_of("pitch").unwrap();
        for line in lines_from_file(db).unwrap()
        {
            let line = match line
            {
                Ok(line) => line,
                Err(err) => panic!("failed to read line: {}", err)
            };
            assert_eq!(line.trim(), pitch);
        }
    }
}

fn gears_from_file<P>(filename: P) -> Vec<i32>
where
    P: AsRef<Path>,
{
    let file = File::open(filename).expect("No such file.");
    let gears = BufReader::new(file);
    gears.lines()
        .map(|l| l.expect("could not parse line"))
        .map(|l| l.parse::<i32>().unwrap())
        .collect()
}

fn ratios_from_file<P>(filename: P) -> Vec<f64>
where
    P: AsRef<Path>,
{
    use meval::eval_str;
    let file = File::open(filename).expect("No such file.");
    let ratios = BufReader::new(file);
    ratios.lines()
        .map(|l| l.expect("could not parse line"))
        .map(|l| match eval_str(l)
        {
            Ok(v) => v,
            Err(e) => panic!("{:?}", e)
        })
        //.map(|l| l.parse::<f64>().unwrap())
        .collect()
}

// https://stackoverflow.com/a/30801708
// returns BufReader s of strings
fn lines_from_file<P>(filename: P) -> Result<io::Lines<io::BufReader<File>>, io::Error>
where
    P: AsRef<Path>,
{
    let file = try!(File::open(filename));
    Ok(io::BufReader::new(file).lines())
}

#[cfg(not(feature = "yaml"))]
fn main() {
    // As stated above, if clap is not compiled with the YAML feature, it is disabled.
    println!("YAML feature is disabled.");
    println!("Pass --features yaml to cargo when trying this example.");
}
<commit_msg>write outputs to file rather that STDOUT<commit_after>#[macro_use]
extern crate clap;
extern crate meval;
extern crate itertools;

use std::io::{self, BufRead};
use std::io::prelude::*;
use std::io::BufReader;
use std::io::BufWriter;
use std::path::Path;
use std::fs::File;
use itertools::Itertools;

#[cfg(feature = "yaml")]
fn main()
{
    use clap::App;

    let yml = load_yaml!("cli.yaml");
    let m = App::from_yaml(yml).get_matches();

    match m.subcommand_name()
    {
        Some("generate") => generate(m),
        Some("lookup") => lookup(m),
        None => println!("show help here. TODO: me!"),
           _ => println!("Some other subcommand was used"),
    }
}

#[cfg(feature = "yaml")]
fn generate(m_opts: clap::ArgMatches)
{
    if let Some(ref m_opts) = m_opts.subcommand_matches("generate")
    {
        let lib = m_opts.value_of("lib").unwrap();
        let gb_ratios = m_opts.value_of("gb_ratios").unwrap();
        let m: f64 = m_opts.value_of("gear_m").unwrap().parse::<f64>().unwrap();  // TODO dafuq?
        let n: f64 = m_opts.value_of("gear_n").unwrap().parse::<f64>().unwrap();  // TODO same
        let pitch: f64 = m_opts.value_of("pitch").unwrap().parse::<f64>().unwrap(); // TODO and me

        // file output (w/buffering)
        let out_str = m_opts.value_of("out").unwrap();
        let mut out_file = match File::create(Path::new(out_str))
        {
            Ok(out_file) => out_file,
            Err(e) => panic!("Couldn't open output file: {:?}", e),
        };
        let mut out = BufWriter::new(&out_file);

        let gears: Vec<i32> = gears_from_file(lib);
        let ratios: Vec<f64> = ratios_from_file(gb_ratios);

        let mnp: f64 = (m/n)*pitch;

        // iterate every ab combination
        for combos in gears.clone().into_iter().combinations(2)
        {
            let a = combos[0] as f64;
            let b = combos[1] as f64;

            // generate a list with 2 gears
            // a/b
            // b/a
            for r in &ratios
            {
                let mut ans = (mnp * (a/b) * r);
                out.write_fmt(format_args!("({:03}/{:03}) * ({:03} / {:03}) * {:2.5} * {:?} = {:2.5}mm ({:2.5} TPI)\n", m, n, a, b, r, pitch, ans, 25.4/ans ));
                ans = (mnp * (b/a) * r);
                out.write_fmt(format_args!("({:03}/{:03}) * ({:03} / {:03}) * {:2.5} * {:?} = {:2.5}mm ({:2.5} TPI)\n", m, n, a, b, r, pitch, ans, 25.4/ans ));
            }
        }

        // iterate every abcd combination
        for combos in gears.clone().into_iter().combinations(4)
        {
            let a = combos[0] as f64;
            let b = combos[1] as f64;
            let c = combos[3] as f64;
            let d = combos[2] as f64;

            // generate a list with 4 gears
            // 2 on top = 4C2 = 6 sub-combinations:
            // ac / bd
            // ab / cd
            // ad / bc
            // bc / ad
            // bd / ac
            // cd / ab
            for r in &ratios
            {
                let mut ans;
                ans = (mnp * ((a*c)/(b*d)) * r);
                out.write_fmt(format_args!("({:03}/{:03}) * [({:03} * {:03}) / ({:03} * {:03})] * {:2.5} * {:?} = {:2.5}mm ({:2.5} TPI)\n", m, n, a, c, b, d, r, pitch, ans, 25.4/ans) );
                ans = (mnp * ((a*b)/(c*d)) * r);
                out.write_fmt(format_args!("({:03}/{:03}) * [({:03} * {:03}) / ({:03} * {:03})] * {:2.5} * {:?} = {:2.5}mm ({:2.5} TPI)\n", m, n, a, b, c, d, r, pitch, ans, 25.4/ans) );
                ans = (mnp * ((a*d)/(b*c)) * r);
                out.write_fmt(format_args!("({:03}/{:03}) * [({:03} * {:03}) / ({:03} * {:03})] * {:2.5} * {:?} = {:2.5}mm ({:2.5} TPI)\n", m, n, a, d, b, c, r, pitch, ans, 25.4/ans) );
                ans = (mnp * ((b*c)/(a*d)) * r);
                out.write_fmt(format_args!("({:03}/{:03}) * [({:03} * {:03}) / ({:03} * {:03})] * {:2.5} * {:?} = {:2.5}mm ({:2.5} TPI)\n", m, n, b, c, a, d, r, pitch, ans, 25.4/ans) );
                ans = (mnp * ((b*d)/(a*c)) * r);
                out.write_fmt(format_args!("({:03}/{:03}) * [({:03} * {:03}) / ({:03} * {:03})] * {:2.5} * {:?} = {:2.5}mm ({:2.5} TPI)\n", m, n, b, d, a, c, r, pitch, ans, 25.4/ans) );
                ans = (mnp * ((c*d)/(a*b)) * r);
                out.write_fmt(format_args!("({:03}/{:03}) * [({:03} * {:03}) / ({:03} * {:03})] * {:2.5} * {:?} = {:2.5}mm ({:2.5} TPI)\n", m, n, c, d, a, b, r, pitch, ans, 25.4/ans) );
                /*
                print_abcd(&m, &n, &a, &c, &b, &d, &r, &pitch, mnp * ( (a*c) / (b*d)) * r );
                print_abcd(&m, &n, &a, &b, &c, &d, &r, &pitch, mnp * ( (a*b) / (c*d)) * r );
                print_abcd(&m, &n, &a, &d, &b, &c, &r, &pitch, mnp * ( (a*d) / (b*c)) * r );
                print_abcd(&m, &n, &b, &c, &a, &d, &r, &pitch, mnp * ( (b*c) / (a*d)) * r );
                print_abcd(&m, &n, &b, &d, &a, &c, &r, &pitch, mnp * ( (b*d) / (a*c)) * r );
                print_abcd(&m, &n, &c, &d, &a, &b, &r, &pitch, mnp * ( (c*d) / (a*b)) * r );
                */
            }
        }
    }
}

//fn print_abcd(m: &f64, n: &f64, a: &f64, b: &f64, c: &f64, d: &f64, r: &f64, pitch: &f64, ans: f64)
//{
    //println!("({:03}/{:03}) * [({:03} * {:03}) / ({:03} * {:03})] * {:2.5} * {:?} = {:2.5}", m, n, a, c, b, d, r, pitch, ans );
//}

fn lookup(m: clap::ArgMatches)
{
    if let Some(ref m) = m.subcommand_matches("generate")
    {
        let db = m.value_of("db").unwrap();
        let pitch = m.value_of("pitch").unwrap();
        for line in lines_from_file(db).unwrap()
        {
            let line = match line
            {
                Ok(line) => line,
                Err(err) => panic!("failed to read line: {}", err)
            };
            assert_eq!(line.trim(), pitch);
        }
    }
}

fn gears_from_file<P>(filename: P) -> Vec<i32>
where
    P: AsRef<Path>,
{
    let file = File::open(filename).expect("No such file.");
    let gears = BufReader::new(file);
    gears.lines()
        .map(|l| l.expect("could not parse line"))
        .map(|l| l.parse::<i32>().unwrap())
        .collect()
}

fn ratios_from_file<P>(filename: P) -> Vec<f64>
where
    P: AsRef<Path>,
{
    use meval::eval_str;
    let file = File::open(filename).expect("No such file.");
    let ratios = BufReader::new(file);
    ratios.lines()
        .map(|l| l.expect("could not parse line"))
        .map(|l| match eval_str(l)
        {
            Ok(v) => v,
            Err(e) => panic!("{:?}", e)
        })
        //.map(|l| l.parse::<f64>().unwrap())
        .collect()
}

// https://stackoverflow.com/a/30801708
// returns BufReader s of strings
fn lines_from_file<P>(filename: P) -> Result<io::Lines<io::BufReader<File>>, io::Error>
where
    P: AsRef<Path>,
{
    let file = try!(File::open(filename));
    Ok(io::BufReader::new(file).lines())
}

#[cfg(not(feature = "yaml"))]
fn main() {
    // As stated above, if clap is not compiled with the YAML feature, it is disabled.
    println!("YAML feature is disabled.");
    println!("Pass --features yaml to cargo when trying this example.");
}
<|endoftext|>


<commit_before>use std::io::Read;
use std::collections::HashMap;
use std::str::Split;

struct Cli<'a> {
    commands: HashMap<&'a str, Cli<'a>>,
    exec: Option<Box<Fn()>>,
    complete_cb: Option<Box<Fn()>>
}

impl<'a> Cli<'a>{

    fn new(callback: Option<Box<Fn()>>) -> Cli<'a> {
        Cli {
            commands: HashMap::new(),
            exec: callback,
            complete_cb: None,
        }
    }

    fn register(&mut self, command: Vec<&'a str>, callback: Fn()) {
        let mut it = command.iter();
        self._register(it, callback);
    }

    fn _register(&mut self, mut it: std::slice::Iter<&'a str>, callback: Fn()) {
        if let Some(portion) = it.next() {
            if !self.commands.contains_key(portion) {
                self.commands.insert(portion, Cli::new(Some(Box::new(callback))));
            }

            self.commands.get_mut(portion).unwrap()._register(it, callback);
        }
    }

    fn suggest(&mut self, command: &str) -> Vec<&str> {
        let mut portions = command.trim().split(" ");
        let mut suggestions = self._suggest(&mut portions);
        if let Some(ref cb) = self.complete_cb {
            cb();
            println!("got callback");
        }
        suggestions
    }

    fn _suggest(&self, portions: &mut std::str::Split<&str>) -> Vec<&str> {
        let mut ret = Vec::with_capacity(self.commands.len());

        if let Some(portion) = portions.next() {
            if !portion.is_empty() {
                if let Some(cmd) = self.commands.get(portion) {
                    ret = cmd._suggest(portions);
                }
            } else {
                for key in self.commands.keys() {
                    ret.push(*key);
                }
            }
        } else {
            for key in self.commands.keys() {
                ret.push(*key);
            }
        }

        ret
    }
}

fn foo(args: Vec<&str>) {

}

fn main() {
    let mut cli = Cli::new(Box::new(foo));

    cli.register(vec!["show", "stuff"], foo);
    cli.register(vec!["show", "other"], foo);
    cli.register(vec!["list", "other", "cool"], foo);
    cli.register(vec!["list", "other", "uncool"], foo);

    loop {
        let mut line = String::new();
        std::io::stdin().read_line(&mut line).unwrap();

        println!("got: {:?}", cli.suggest(&line));
    }
}
<commit_msg>registering sth<commit_after>use std::io::Read;
use std::collections::HashMap;
use std::str::Split;

pub struct Command<'a> {
    command: &'a str,
    exec: Box<Fn(Vec<&str>)>,
    complete: Option<Box<Fn(Vec<&str>)>>
}

impl<'a> Command<'a> {
    fn new<T: Fn(Vec<&str>) + 'static, U: Fn(Vec<&str>) + 'static>(cmd: &'a str, exec_handler: T, complete_handler: Option<U>) -> Command {
        let mut obj = Command {
            command: cmd,
            exec: Box::new(exec_handler),
            complete: None
        };

        if let Some(cb) = complete_handler {
            obj.complete = Some(Box::new(cb));
        }

        obj
    }
}

pub struct Cli<'a> {
    commands: HashMap<&'a str, Command<'a>>
}

impl<'a> Cli<'a>{

    fn new() -> Cli<'a> {
        Cli {
            commands: HashMap::new()
        }
    }

    fn register<T: Fn(Vec<&str>) + 'static>(&mut self, cmd: &'a str, exec: T) -> Result<(), Command> {

        let tmp = Command {
            command: cmd,
            exec: Box::new(exec),
            complete: None
        };

        match self.commands.insert(cmd, tmp) {
            Some(existing) => Err(existing),
            None => Ok(())
        }
    }

    fn complete(&self, argv: &str) -> Vec<&str> {
        Vec::new()
    }

    fn exec(&self, cmd: &str) {
        if let Some(command) = self.commands.get(cmd) {
            //TODO: figure out why I can't do that in one line
            let ref x = command.exec;
            x(vec!["blah"]);
        }
    }
}

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

    #[test]
    fn testRegister() {
        let mut cli = Cli::new();
        let mut called = false;

        cli.register("my first command", | args | { println!("called"); } );
        cli.exec("my first command");

        assert!(called == true)
    }
}

    //fn new(callback: Option<Box<Fn()>>) -> Cli<'a> {
        //Cli {
            //commands: HashMap::new(),
            //exec: callback,
            //complete_cb: None,
        //}
    //}

    //fn register<T: Fn() + 'static>(&mut self, command: Vec<&'a str>, callback: T) {
        //let mut it = command.iter();
        //self._register(it, callback);
    //}

    //fn _register<T: Fn() + 'static>(&mut self, mut it: std::slice::Iter<&'a str>, callback: T) {
        //if let Some(portion) = it.next() {
            //if !self.commands.contains_key(portion) {
                //self.commands.insert(portion, Cli::new(Some(Box::new(callback))));
            //}

            //self.commands.get_mut(portion).unwrap()._register(it, callback);
        //}
    //}

    //fn suggest(&mut self, command: &str) -> Vec<&str> {
        //let mut portions = command.trim().split(" ");
        //let mut suggestions = self._suggest(&mut portions);
        //if let Some(ref cb) = self.complete_cb {
            //cb();
            //println!("got callback");
        //}
        //suggestions
    //}

    //fn _suggest(&self, portions: &mut std::str::Split<&str>) -> Vec<&str> {
        //let mut ret = Vec::with_capacity(self.commands.len());

        //if let Some(portion) = portions.next() {
            //if !portion.is_empty() {
                //if let Some(cmd) = self.commands.get(portion) {
                    //ret = cmd._suggest(portions);
                //}
            //} else {
                //for key in self.commands.keys() {
                    //ret.push(*key);
                //}
            //}
        //} else {
            //for key in self.commands.keys() {
                //ret.push(*key);
            //}
        //}

        //ret
    //}
//}

//fn foo() {

//}

fn main() {
    //let mut cli = Cli::new(Some(Box::new(foo)));

    //cli.register(vec!["show", "stuff"], foo);
    //cli.register(vec!["show", "other"], foo);
    //cli.register(vec!["list", "other", "cool"], foo);
    //cli.register(vec!["list", "other", "uncool"], foo);

    //loop {
        //let mut line = String::new();
        //std::io::stdin().read_line(&mut line).unwrap();

        //println!("got: {:?}", cli.suggest(&line));
    //}
}
<|endoftext|>


<commit_before>#![feature(globs, macro_rules, phase)]

extern crate debug;
extern crate piston;
extern crate sdl2;
extern crate sdl2_game_window;
extern crate gfx;
#[phase(plugin)]
extern crate gfx_macros;
extern crate image;
extern crate libc;
extern crate cgmath;
extern crate time;

use sdl2_game_window::GameWindowSDL2 as Window;
use piston::input;
use piston::cam;
use piston::{
    AssetStore,
    GameIterator,
    GameIteratorSettings,
    GameWindow,
    GameWindowSettings,
    Input,
    Render,
    Update,
};

use array::*;
use texture::Texture;

pub mod array;
pub mod cube;
pub mod fps_counter;
pub mod shader;
pub mod texture;
pub mod vecmath;

fn main() {
    let mut window = Window::new(
        piston::shader_version::opengl::OpenGL_3_3,
        GameWindowSettings {
            title: "Hematite".to_string(),
            size: [854, 480],
            fullscreen: false,
            exit_on_esc: true,
        }
    );
    let (mut device, frame) = window.gfx();

    let asset_store = AssetStore::from_folder("../assets");

    // Load texture.
    let texture = asset_store.path("texture.png").unwrap();
    let texture = Texture::from_path(&texture, &mut device).unwrap();

    let game_iter_settings = GameIteratorSettings {
        updates_per_second: 120,
        max_frames_per_second: 10000,
    };

    let mut renderer = shader::Renderer::new(device, frame, texture.tex);

    renderer.set_projection(cam::CameraPerspective {
        fov: 70.0,
        near_clip: 0.1,
        far_clip: 1000.0,
        aspect_ratio: {
            let (w, h) = window.get_size();
            (w as f32) / (h as f32)
        }
    }.projection());

    let mut first_person_settings = cam::FirstPersonSettings::default();
    first_person_settings.speed_horizontal = 8.0;
    first_person_settings.speed_vertical = 4.0;
    let mut first_person = cam::FirstPerson::new(
        0.5, 0.5, 4.0,
        first_person_settings
    );

    // Disable V-Sync.
    sdl2::video::gl_set_swap_interval(0);

    let mut fps_counter = fps_counter::FPSCounter::new();

    let mut capture_cursor = false;
    println!("Press C to capture mouse");
    let mut extrapolate_time = false;
    println!("Press X to extrapolate time");

    let buffer = {
        let mut tri = vec![];
        for face in cube::FaceIterator::new() {
            let xyz = face.vertices([0.0, 0.0, 0.0], [1.0, 1.0, 1.0]);
            let [u0, v1, u1, v0] = [0.0, 0.75, 0.25, 1.0];
            let uv = [
                [u1, v0],
                [u0, v0],
                [u0, v1],
                [u1, v1]
            ];
            let v = [
                (xyz[0], uv[0], [1.0, 0.0, 0.0]),
                (xyz[1], uv[1], [0.0, 1.0, 0.0]),
                (xyz[2], uv[2], [0.0, 0.0, 1.0]),
                (xyz[3], uv[3], [1.0, 0.0, 1.0])
            ].map(|(xyz, uv, rgb)| shader::Vertex { xyz: xyz, uv: uv, rgb: rgb });

            // Split the clockwise quad into two clockwise triangles.
            tri.push_all([v[0], v[1], v[2]]);
            tri.push_all([v[2], v[3], v[0]]);
        }
        renderer.create_buffer(tri.as_slice())
    };

    let mut events = GameIterator::new(&mut window, &game_iter_settings);
    for e in events {
        match e {
            Render(_args) => {
                renderer.set_view(first_person.camera(
                        _args.ext_dt * if extrapolate_time { 0.0 } else { 1.0 }
                    ).orthogonal());
                renderer.reset();
                renderer.render(buffer);
                renderer.end_frame();

                let fps = fps_counter.update();
                let title = format!("Hematite @ {}FPS", fps);
                events.game_window.window.set_title(title.as_slice());
            }
            Input(input::KeyPress { key: input::keyboard::C }) => {
                println!("Turned cursor capture {}",
                    if capture_cursor { "off" } else { "on" });
                capture_cursor = !capture_cursor;

                events.game_window.capture_cursor(capture_cursor);
            },
            Input(input::KeyPress { key: input::keyboard::X }) => {
                println!("Turned extrapolated time {}",
                    if extrapolate_time { "off" } else { "on" });
                extrapolate_time = !extrapolate_time;
            },
            Input(input::MouseRelativeMove { .. }) => {
                if !capture_cursor {
                    // Don't send the mouse event to the FPS controller.
                    continue;
                }
            }
            _ => {}
        }

        // Camera controller.
        match e {
            Input(ref args) => first_person.input(args),
            Update(piston::UpdateArgs { dt, .. }) => first_person.update(dt),
            _ => {}
        }
    }
}
<commit_msg>Use Z to toggle update camera on render<commit_after>#![feature(globs, macro_rules, phase)]

extern crate debug;
extern crate piston;
extern crate sdl2;
extern crate sdl2_game_window;
extern crate gfx;
#[phase(plugin)]
extern crate gfx_macros;
extern crate image;
extern crate libc;
extern crate cgmath;
extern crate time;

use sdl2_game_window::GameWindowSDL2 as Window;
use piston::input;
use piston::cam;
use piston::{
    AssetStore,
    GameIterator,
    GameIteratorSettings,
    GameWindow,
    GameWindowSettings,
    Input,
    Render,
    Update,
};

use array::*;
use texture::Texture;

pub mod array;
pub mod cube;
pub mod fps_counter;
pub mod shader;
pub mod texture;
pub mod vecmath;

fn main() {
    let mut window = Window::new(
        piston::shader_version::opengl::OpenGL_3_3,
        GameWindowSettings {
            title: "Hematite".to_string(),
            size: [854, 480],
            fullscreen: false,
            exit_on_esc: true,
        }
    );
    let (mut device, frame) = window.gfx();

    let asset_store = AssetStore::from_folder("../assets");

    // Load texture.
    let texture = asset_store.path("texture.png").unwrap();
    let texture = Texture::from_path(&texture, &mut device).unwrap();

    let game_iter_settings = GameIteratorSettings {
        updates_per_second: 120,
        max_frames_per_second: 10000,
    };

    let mut renderer = shader::Renderer::new(device, frame, texture.tex);

    renderer.set_projection(cam::CameraPerspective {
        fov: 70.0,
        near_clip: 0.1,
        far_clip: 1000.0,
        aspect_ratio: {
            let (w, h) = window.get_size();
            (w as f32) / (h as f32)
        }
    }.projection());

    let mut first_person_settings = cam::FirstPersonSettings::default();
    first_person_settings.speed_horizontal = 8.0;
    first_person_settings.speed_vertical = 4.0;
    let mut first_person = cam::FirstPerson::new(
        0.5, 0.5, 4.0,
        first_person_settings
    );

    // Disable V-Sync.
    sdl2::video::gl_set_swap_interval(0);

    let mut fps_counter = fps_counter::FPSCounter::new();

    let mut capture_cursor = false;
    println!("Press C to capture mouse");
    let mut extrapolate_time = false;
    println!("Press X to extrapolate time");
    let mut update_cam_render = false;
    println!("Press Z to update first person camera when rendering");

    let buffer = {
        let mut tri = vec![];
        for face in cube::FaceIterator::new() {
            let xyz = face.vertices([0.0, 0.0, 0.0], [1.0, 1.0, 1.0]);
            let [u0, v1, u1, v0] = [0.0, 0.75, 0.25, 1.0];
            let uv = [
                [u1, v0],
                [u0, v0],
                [u0, v1],
                [u1, v1]
            ];
            let v = [
                (xyz[0], uv[0], [1.0, 0.0, 0.0]),
                (xyz[1], uv[1], [0.0, 1.0, 0.0]),
                (xyz[2], uv[2], [0.0, 0.0, 1.0]),
                (xyz[3], uv[3], [1.0, 0.0, 1.0])
            ].map(|(xyz, uv, rgb)| shader::Vertex { xyz: xyz, uv: uv, rgb: rgb });

            // Split the clockwise quad into two clockwise triangles.
            tri.push_all([v[0], v[1], v[2]]);
            tri.push_all([v[2], v[3], v[0]]);
        }
        renderer.create_buffer(tri.as_slice())
    };

    let mut last_render = time::precise_time_ns();
    let mut events = GameIterator::new(&mut window, &game_iter_settings);
    for e in events {
        match e {
            Render(_args) => {
                if update_cam_render {
                    let now = time::precise_time_ns();
                    let dt = (now - last_render) as f64 / 1_000_000_000.0f64;
                    first_person.update(dt);
                    last_render = now;
                }

                renderer.set_view(first_person.camera(
                        _args.ext_dt * if extrapolate_time { 0.0 } else { 1.0 }
                    ).orthogonal());
                renderer.reset();
                renderer.render(buffer);
                renderer.end_frame();

                let fps = fps_counter.update();
                let title = format!("Hematite @ {}FPS", fps);
                events.game_window.window.set_title(title.as_slice());
            }
            Input(input::KeyPress { key: input::keyboard::C }) => {
                println!("Turned cursor capture {}",
                    if capture_cursor { "off" } else { "on" });
                capture_cursor = !capture_cursor;

                events.game_window.capture_cursor(capture_cursor);
            },
            Input(input::KeyPress { key: input::keyboard::X }) => {
                println!("Turned extrapolated time {}",
                    if extrapolate_time { "off" } else { "on" });
                extrapolate_time = !extrapolate_time;
            },
            Input(input::KeyPress { key: input::keyboard::Z }) => {
                println!("Turned update camera on render {}",
                    if update_cam_render { "off" } else { "on" });
                update_cam_render = !update_cam_render;
            },
            Input(input::MouseRelativeMove { .. }) => {
                if !capture_cursor {
                    // Don't send the mouse event to the FPS controller.
                    continue;
                }
            }
            _ => {}
        }

        // Camera controller.
        match e {
            Input(ref args) => first_person.input(args),
            Update(piston::UpdateArgs { dt, .. }) =>
                if !update_cam_render { first_person.update(dt) },
            _ => {}
        }
    }
}
<|endoftext|>


<commit_before>#![feature(custom_derive)]
#[macro_use] extern crate clap;

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

#[allow(unused_imports, unused_variables, dead_code)]

use std::fs::File;
use clap::App;
mod todo;
mod list;
mod storage;

fn main() {
    let yml = load_yaml!("cli.yml");
    let m = App::from_yaml(yml).version(crate_version!()).author(crate_authors!()).get_matches();
    }

fn test() {
    let mut li = list::TodoList::new("kek");
    let tdo1 = todo::Todo::new(0, "Bla");
    let tdo2 = todo::Todo::new(1, "Bla1");

    li.list.push(tdo1.clone());
    li.list.push(tdo2);

    let mut f = File::create("foo.json").unwrap();

    let _ = serde_json::to_writer_pretty(&mut f, &li);

    println!("{:?}", serde_json::to_string_pretty(&li).unwrap());

    // deserialisation

    // let mut inpf = File::open("foo.json").unwrap();
    // let mut serialized = String::new();
    //
    // let _ = inpf.read_to_string(&mut serialized);
    //
    // if let Ok(j) = todo::Todo::from_json(&bla) {
    //     println!("{:?}", j);
    // }
}
<commit_msg>cleaning up<commit_after>#![feature(custom_derive)]
#[macro_use]
extern crate clap;

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

#[allow(unused_imports)]

use std::fs::File;
use std::io::Read;
use serde_json::Value;
use clap::App;
mod todo;
mod list;
mod storage;

#[allow(unused_variables)]
fn main() {
    let yml = load_yaml!("cli.yml");
    let m = App::from_yaml(yml).version(crate_version!()).author(crate_authors!()).get_matches();
    test();
}

#[allow(dead_code)]
fn test() {
    let mut li = list::TodoList::new("kek");
    let tdo1 = todo::Todo::new(0, "Bla");
    let tdo2 = todo::Todo::new(1, "Bla1");

    li.list.push(tdo1.clone());
    li.list.push(tdo2);

    let mut f = File::create("foo.json").unwrap();

    let _ = serde_json::to_writer_pretty(&mut f, &li);

    println!("{:?}", serde_json::to_string_pretty(&li).unwrap());

    // deserialisation

    let mut s = String::new();
    let _ = File::open("foo.json").unwrap().read_to_string(&mut s).unwrap();
    let json: Value = serde_json::from_str(&s).unwrap();
    println!("{:?}", serde_json::to_string_pretty(&json).unwrap());
}
<|endoftext|>


<commit_before>extern crate chrono;
extern crate iron;
extern crate persistent;
extern crate r2d2;
extern crate r2d2_sqlite;
extern crate router;
extern crate rusqlite;
extern crate sha2;

use chrono::*;

use iron::prelude::*;
use iron::Url;
use iron::modifiers::Redirect;
use iron::status::Status;
use iron::typemap::Key;

use persistent::Read;

use r2d2::Pool;

use r2d2_sqlite::SqliteConnectionManager;

use router::Router;

use rusqlite::Connection;

use sha2::digest::Digest;
use sha2::sha2::Sha256;

use std::env;

const HOST: &'static str = "https://yaus.pw/";

pub type SqlitePool = Pool<SqliteConnectionManager>;

pub struct YausDb;
impl Key for YausDb {
    type Value = SqlitePool;
}

// A simple macro to return early if the URL can't parse.
macro_rules! try_url {
    ($url:expr) => {
        match Url::parse($url) {
            Ok(_) => { },
            Err(_) => {
                return Ok(Response::with((Status::BadRequest, "Malformed URL")));
            }
        }
    }
}

fn create_shortened_url(db: &Connection, long_url: &str) -> IronResult<Response> {
    let mut hash = Sha256::new();
    hash.input_str(long_url);
    let locator = hash.result_str();

    let timestamp = Local::now().to_rfc3339();
    db.execute("INSERT INTO urls VALUES (NULL, ?1, ?2, ?3)",
        &[&timestamp, &long_url, &&locator[0..7]]).unwrap();

    Ok(Response::with((Status::Created, [HOST, &locator[0..7]].join(""))))
}

/// Given a long URL, see if it already exists in the table, else create an entry and return
/// it.
///
/// A 200 means that a shortened URL already exists and has been returned. A 201
/// response means that a new shortened URL has been created.
fn check_or_shorten_url(db: &Connection, long_url: &str) -> IronResult<Response> {
    let mut stmt = db.prepare("SELECT locator FROM urls WHERE url = (?)").unwrap();
    let mut row = stmt.query_map::<String, _>(&[&long_url], |r| r.get(0)).unwrap();

    if let Some(l) = row.next() {
        return Ok(Response::with((Status::Ok, [HOST, &l.unwrap()].join(""))));
    }
    create_shortened_url(db, long_url)
}

/// The handler to shorten a URL.
fn shorten_handler(req: &mut Request) -> IronResult<Response> {
    match req.url.query.clone() {
        None => { Ok(Response::with((Status::BadRequest, "URL missing in query"))) },
        Some(ref s) => {
            let long: Vec<&str> = s.split("url=").collect();
            if long.len() == 2 {
                try_url!(long[1]);
                let pool = req.get::<Read<YausDb>>().unwrap().clone();
                let db = pool.get().unwrap();
                check_or_shorten_url(&db, long[1])
            } else {
                Ok(Response::with((Status::BadRequest, "Malformed query string")))
            }
        }
    }
}

/// The handler that redirects to the long URL.
fn redirect_handler(req: &mut Request) -> IronResult<Response> {
    let locator = req.url.path[0].clone();
    let pool = req.get::<Read<YausDb>>().unwrap().clone();
    let db = pool.get().unwrap();
    let mut stmt = db.prepare("SELECT url FROM urls WHERE locator = (?)").unwrap();
    let mut row = stmt.query_map::<String, _>(&[&locator], |r| r.get(0)).unwrap();

    if let Some(u) = row.next() {
        let long_url = Url::parse(&u.unwrap()).unwrap();
        Ok(Response::with((Status::MovedPermanently, Redirect(long_url))))
    } else {
        Ok(Response::with((Status::NotFound, "Not found")))
    }
}

fn index_handler(_: &mut Request) -> IronResult<Response> {
    Ok(Response::with((Status::Ok, "See https://github.com/gsquire/yaus for the API")))
}

fn main() {
    let mut router = Router::new();
    router.get("/shorten", shorten_handler);
    router.get("/:locator", redirect_handler);
    router.get("/", index_handler);

    let config = r2d2::Config::default();
    let db = env::var("SHORT_DB").unwrap();
    let manager = SqliteConnectionManager::new(&db);
    let pool = r2d2::Pool::new(config, manager).unwrap();

    let mut chain = Chain::new(router);
    chain.link_before(Read::<YausDb>::one(pool));

    Iron::new(chain).http("localhost:3000").unwrap();
}
<commit_msg>use split_at instead in case 'url=' appears in long url<commit_after>extern crate chrono;
extern crate iron;
extern crate persistent;
extern crate r2d2;
extern crate r2d2_sqlite;
extern crate router;
extern crate rusqlite;
extern crate sha2;

use chrono::*;

use iron::prelude::*;
use iron::Url;
use iron::modifiers::Redirect;
use iron::status::Status;
use iron::typemap::Key;

use persistent::Read;

use r2d2::Pool;

use r2d2_sqlite::SqliteConnectionManager;

use router::Router;

use rusqlite::Connection;

use sha2::digest::Digest;
use sha2::sha2::Sha256;

use std::env;

const HOST: &'static str = "https://yaus.pw/";

pub type SqlitePool = Pool<SqliteConnectionManager>;

pub struct YausDb;
impl Key for YausDb {
    type Value = SqlitePool;
}

// A simple macro to return early if the URL can't parse.
macro_rules! try_url {
    ($url:expr) => {
        match Url::parse($url) {
            Ok(_) => { },
            Err(_) => {
                return Ok(Response::with((Status::BadRequest, "Malformed URL")));
            }
        }
    }
}

fn create_shortened_url(db: &Connection, long_url: &str) -> IronResult<Response> {
    let mut hash = Sha256::new();
    hash.input_str(long_url);
    let locator = hash.result_str();

    let timestamp = Local::now().to_rfc3339();
    db.execute("INSERT INTO urls VALUES (NULL, ?1, ?2, ?3)",
        &[&timestamp, &long_url, &&locator[0..7]]).unwrap();

    Ok(Response::with((Status::Created, [HOST, &locator[0..7]].join(""))))
}

/// Given a long URL, see if it already exists in the table, else create an entry and return
/// it.
///
/// A 200 means that a shortened URL already exists and has been returned. A 201
/// response means that a new shortened URL has been created.
fn check_or_shorten_url(db: &Connection, long_url: &str) -> IronResult<Response> {
    let mut stmt = db.prepare("SELECT locator FROM urls WHERE url = (?)").unwrap();
    let mut row = stmt.query_map::<String, _>(&[&long_url], |r| r.get(0)).unwrap();

    if let Some(l) = row.next() {
        return Ok(Response::with((Status::Ok, [HOST, &l.unwrap()].join(""))));
    }
    create_shortened_url(db, long_url)
}

/// The handler to shorten a URL.
fn shorten_handler(req: &mut Request) -> IronResult<Response> {
    match req.url.query.clone() {
        None => { Ok(Response::with((Status::BadRequest, "URL missing in query"))) },
        Some(ref s) => {
            let (k, v) = s.split_at(4);
            if k == "url=" {
                try_url!(v);
                let pool = req.get::<Read<YausDb>>().unwrap().clone();
                let db = pool.get().unwrap();
                check_or_shorten_url(&db, v)
            } else {
                Ok(Response::with((Status::BadRequest, "Malformed query string")))
            }
        }
    }
}

/// The handler that redirects to the long URL.
fn redirect_handler(req: &mut Request) -> IronResult<Response> {
    let locator = req.url.path[0].clone();
    let pool = req.get::<Read<YausDb>>().unwrap().clone();
    let db = pool.get().unwrap();
    let mut stmt = db.prepare("SELECT url FROM urls WHERE locator = (?)").unwrap();
    let mut row = stmt.query_map::<String, _>(&[&locator], |r| r.get(0)).unwrap();

    if let Some(u) = row.next() {
        let long_url = Url::parse(&u.unwrap()).unwrap();
        Ok(Response::with((Status::MovedPermanently, Redirect(long_url))))
    } else {
        Ok(Response::with((Status::NotFound, "Not found")))
    }
}

fn index_handler(_: &mut Request) -> IronResult<Response> {
    Ok(Response::with((Status::Ok, "See https://github.com/gsquire/yaus for the API")))
}

fn main() {
    let mut router = Router::new();
    router.get("/shorten", shorten_handler);
    router.get("/:locator", redirect_handler);
    router.get("/", index_handler);

    let config = r2d2::Config::default();
    let db = env::var("SHORT_DB").unwrap();
    let manager = SqliteConnectionManager::new(&db);
    let pool = r2d2::Pool::new(config, manager).unwrap();

    let mut chain = Chain::new(router);
    chain.link_before(Read::<YausDb>::one(pool));

    Iron::new(chain).http("localhost:3000").unwrap();
}
<|endoftext|>


<commit_before>extern crate hyper;

use hyper::server::{Server, Request, Response};

fn hello(req: Request, res: Response) {
    println!("Hey, what up.");
}

fn main() {
	Server::http("localhost:3001").unwrap().handle(hello).unwrap();
}
<commit_msg>Respond with json greeting of Hey, what up.<commit_after>extern crate hyper;

use hyper::server::{Server, Request, Response};

fn hello(req: Request, res: Response) {
    res.send(b"{greeting: \"Hey, what up.\"}").unwrap();
}

fn main() {
	Server::http("localhost:3001").unwrap().handle(hello).unwrap();
}
<|endoftext|>


<commit_before>extern crate clap;
extern crate nix;
extern crate colored;

mod util;
mod stats;
mod filesystems;

use std::cmp;
use std::fs::File;
use std::io::BufReader;
use std::io::BufRead;
use std::process;
use nix::sys::statvfs::statvfs;
use colored::*;
use clap::{Arg, App};

use util::{iec, bargraph};
use stats::Stats;
use filesystems::pseudo_filesystems;

const FS_SPEC: usize = 0;
const FS_FILE: usize = 1;
const FS_VFSTYPE: usize = 2;

fn main() {
    let matches = App::new("rdf")
        .version("0.1.0")
        .author("Mike Sampson <mike@sda.io>")
        .arg(Arg::with_name("all").long("all").short("a").help(
            "Display all filesystems",
        ))
        .get_matches();

    let file = match File::open("/proc/mounts") {
        Ok(f) => f,
        Err(e) => {
            println!("Error: Could not open /proc/mounts - {}", e);
            process::exit(1);
        }
    };
    let reader = BufReader::new(&file);

    let excludes = pseudo_filesystems();

    let mut stats: Vec<Stats> = Vec::new();
    let mut max_width = 0;

    for line in reader.lines() {
        match line {
            Ok(line) => {
                let fields: Vec<&str> = line.split_whitespace().collect();
                if !matches.is_present("all") && excludes.contains(fields[FS_VFSTYPE]) {
                    continue;
                }
                let statvfs = match statvfs(fields[FS_FILE]) {
                    Ok(s) => s,
                    Err(err) => {
                        println!("Error: {}", err);
                        continue;
                    }
                };
                let size = statvfs.blocks() * statvfs.block_size();
                let avail = statvfs.blocks_available() * statvfs.block_size();
                if size == 0 && !matches.is_present("all") {
                    continue;
                }
                let s = Stats::new(fields[FS_SPEC], size, avail, fields[FS_FILE]);

                max_width = cmp::max(max_width, s.filesystem.len());
                stats.push(s);
            }
            Err(err) => println!("Error: {}", err),
        }
    }

    stats.sort();

    let headers = [
        "Filesystem",
        "Size",
        "Used",
        "Avail",
        "Use%",
        "",
        "Mounted on",
    ];
    let headers: Vec<ColoredString> = headers.iter().map(|x| x.yellow()).collect();
    println!(
        "{:width$} {:>5} {:>5} {:>5} {:>5} {:20} {}",
        headers[0],
        headers[1],
        headers[2],
        headers[3],
        headers[4],
        headers[5],
        headers[6],
        width = max_width
    );

    for stat in stats {
        let fs = if stat.is_network() {
            stat.filesystem.cyan()
        } else {
            stat.filesystem.normal()
        };
        let percent = if stat.percent.is_nan() {
            "    -".to_string()
        } else {
            format!("{:>5.1}", stat.percent)
        };
        println!(
            "{:width$} {:>5} {:>5} {:>5} {} {:20} {}",
            fs,
            iec(stat.size),
            iec(stat.used),
            iec(stat.avail),
            percent,
            bargraph(stat.percent),
            stat.mount,
            width = max_width
        );
    }

}
<commit_msg>cargo-fmt clean up<commit_after>extern crate clap;
extern crate colored;
extern crate nix;

mod filesystems;
mod stats;
mod util;

use clap::{App, Arg};
use colored::*;
use nix::sys::statvfs::statvfs;
use std::cmp;
use std::fs::File;
use std::io::BufRead;
use std::io::BufReader;
use std::process;

use filesystems::pseudo_filesystems;
use stats::Stats;
use util::{bargraph, iec};

const FS_SPEC: usize = 0;
const FS_FILE: usize = 1;
const FS_VFSTYPE: usize = 2;

fn main() {
    let matches = App::new("rdf")
        .version("0.1.0")
        .author("Mike Sampson <mike@sda.io>")
        .arg(
            Arg::with_name("all")
                .long("all")
                .short("a")
                .help("Display all filesystems"),
        )
        .get_matches();

    let file = match File::open("/proc/mounts") {
        Ok(f) => f,
        Err(e) => {
            println!("Error: Could not open /proc/mounts - {}", e);
            process::exit(1);
        }
    };
    let reader = BufReader::new(&file);

    let excludes = pseudo_filesystems();

    let mut stats: Vec<Stats> = Vec::new();
    let mut max_width = 0;

    for line in reader.lines() {
        match line {
            Ok(line) => {
                let fields: Vec<&str> = line.split_whitespace().collect();
                if !matches.is_present("all") && excludes.contains(fields[FS_VFSTYPE]) {
                    continue;
                }
                let statvfs = match statvfs(fields[FS_FILE]) {
                    Ok(s) => s,
                    Err(err) => {
                        println!("Error: {}", err);
                        continue;
                    }
                };
                let size = statvfs.blocks() * statvfs.block_size();
                let avail = statvfs.blocks_available() * statvfs.block_size();
                if size == 0 && !matches.is_present("all") {
                    continue;
                }
                let s = Stats::new(fields[FS_SPEC], size, avail, fields[FS_FILE]);

                max_width = cmp::max(max_width, s.filesystem.len());
                stats.push(s);
            }
            Err(err) => println!("Error: {}", err),
        }
    }

    stats.sort();

    let headers = [
        "Filesystem",
        "Size",
        "Used",
        "Avail",
        "Use%",
        "",
        "Mounted on",
    ];
    let headers: Vec<ColoredString> = headers.iter().map(|x| x.yellow()).collect();
    println!(
        "{:width$} {:>5} {:>5} {:>5} {:>5} {:20} {}",
        headers[0],
        headers[1],
        headers[2],
        headers[3],
        headers[4],
        headers[5],
        headers[6],
        width = max_width
    );

    for stat in stats {
        let fs = if stat.is_network() {
            stat.filesystem.cyan()
        } else {
            stat.filesystem.normal()
        };
        let percent = if stat.percent.is_nan() {
            "    -".to_string()
        } else {
            format!("{:>5.1}", stat.percent)
        };
        println!(
            "{:width$} {:>5} {:>5} {:>5} {} {:20} {}",
            fs,
            iec(stat.size),
            iec(stat.used),
            iec(stat.avail),
            percent,
            bargraph(stat.percent),
            stat.mount,
            width = max_width
        );
    }
}
<|endoftext|>