<commit_before>mod words;

use std::env;

fn matches(pat: &String, line: &str) -> bool {
    fn check<P, L>(mut pc: P, lc: L) -> bool where P: Iterator<Item=char>, L: Iterator<Item=char> {
        let mut c = pc.next();
        for outer in lc {
            match c {
                Some(ch) => {
                    if outer == ch {
                        c = pc.next();
                    }
                    else if words::consonant(outer) {
                        return false;
                    }
                },

                None => {
                    return true;
                }
            }
        }

        false
    }

    check(pat.chars(), line.chars()) || check(pat.chars().rev(), line.chars())
}

fn usage(args: Vec<String>) -> ! {
    println!("Usage: {} <consonants>", args[0]);
    std::process::exit(2);
}

fn main() {
    let args: Vec<String> = env::args().collect();
    if args.len() != 2 {
        usage(args);
    }
    if args[1].chars().any(|c| {!words::consonant(c)}) {
        usage(args);
    }

    let words = words::WORDS.lines().map(|line| {
        line.to_lowercase()
    }).filter(|line| {
        matches(&args[1], line)
    });

    let mut found = false;
    for word in words {
        println!("{}", word);
        found = true;
    }
    if !found {
        println!("No matches found.");
    }
}
<commit_msg>Reverse both pattern and word when checking backwards.<commit_after>mod words;

use std::env;

fn matches(pat: &String, line: &str) -> bool {
    fn check<P, L>(mut pc: P, lc: L) -> bool where P: Iterator<Item=char>, L: Iterator<Item=char> {
        let mut c = pc.next();
        for outer in lc {
            match c {
                Some(ch) => {
                    if outer == ch {
                        c = pc.next();
                    }
                    else if words::consonant(outer) {
                        return false;
                    }
                },

                None => {
                    return true;
                }
            }
        }

        false
    }

    check(pat.chars(), line.chars()) || check(pat.chars().rev(), line.chars().rev())
}

fn usage(args: Vec<String>) -> ! {
    println!("Usage: {} <consonants>", args[0]);
    std::process::exit(2);
}

fn main() {
    let args: Vec<String> = env::args().collect();
    if args.len() != 2 {
        usage(args);
    }
    if args[1].chars().any(|c| {!words::consonant(c)}) {
        usage(args);
    }

    let words = words::WORDS.lines().map(|line| {
        line.to_lowercase()
    }).filter(|line| {
        matches(&args[1], line)
    });

    let mut found = false;
    for word in words {
        println!("{}", word);
        found = true;
    }
    if !found {
        println!("No matches found.");
    }
}
<|endoftext|>


<commit_before>#![crate_name = "limonite"]
#![crate_type = "bin"]
#![allow(dead_code)]

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

use std::io::{BufReader, Read};
use std::fs::File;
use std::path::Path;
use docopt::Docopt;
use syntax::lexer::Lexer;
use syntax::parser::Parser;
use codegen::codegen::codegen; // REVIEW: better codegen name convention + class?

pub mod syntax;
pub mod codegen;

static USAGE: &'static str = "\
Usage: limonite <file>
       limonite (-s | --stdin)
       limonite (-v | --version)

Options:
    -h, --help      Display this message
    -s, --stdin     Read input from stdin
    -v, --version   Displays current version
";

#[derive(RustcDecodable)]
struct Args {
    pub arg_file: String,
    pub flag_stdin: bool,
    pub flag_version: bool
}

fn main() {
    env_logger::init().unwrap();

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

    // TODO: Compile the version in from the .toml
    if args.flag_version {
        let version = env!("CARGO_PKG_VERSION");

        return println!("limonite {}", version);
    }

    let input_string = if !args.flag_stdin {
        let ref file_name = &args.arg_file;
        let path = Path::new(file_name);
        let file = match File::open(&path) {
            Ok(f)  => f,
            Err(e) => panic!("Failed to open file: {}", e)
        };

        let mut input_string = String::new();
        if let Err(e) = BufReader::new(file).read_to_string(&mut input_string) {
            panic!("Failed to read file: {}", e);
        }

        input_string
    } else {
        let mut input_string = String::new();
        if let Err(e) = std::io::stdin().read_to_string(&mut input_string) {
            panic!("Failed to read file: {}", e);
        }

        input_string
    };

    // Tokanize the input
    let lexer = Lexer::new(&input_string);

    // Parse & Build an AST
    let mut parser = Parser::new(lexer);

    let ast_root = match parser.parse() {
        Some(ast) => ast,
        None => return,
    };

    // TODO: Semantic Analysis

    // Run Code Gen
    unsafe {
        codegen("module1", ast_root, true);
    }
}
<commit_msg>Abstracted reading from stdio/bufreader<commit_after>#![crate_name = "limonite"]
#![crate_type = "bin"]
#![allow(dead_code)]

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

use std::io::{BufReader, Read};
use std::fs::File;
use std::path::Path;
use docopt::Docopt;
use syntax::lexer::Lexer;
use syntax::parser::Parser;
use codegen::codegen::codegen; // REVIEW: better codegen name convention + class?

pub mod syntax;
pub mod codegen;

static USAGE: &'static str = "\
Usage: limonite <file>
       limonite (-s | --stdin)
       limonite (-v | --version)

Options:
    -h, --help      Display this message
    -s, --stdin     Read input from stdin
    -v, --version   Displays current version
";

#[derive(RustcDecodable)]
struct Args {
    pub arg_file: String,
    pub flag_stdin: bool,
    pub flag_version: bool
}

fn main() {
    env_logger::init().unwrap();

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

    if args.flag_version {
        let version = env!("CARGO_PKG_VERSION");

        return println!("limonite {}", version);
    }

    let input_string = if !args.flag_stdin {
        let ref file_name = &args.arg_file;
        let path = Path::new(file_name);
        let file = match File::open(&path) {
            Ok(f)  => f,
            Err(e) => panic!("Failed to open file: {}", e)
        };

        readable_to_string(BufReader::new(file))
    } else {
        readable_to_string(std::io::stdin())
    };

    // Tokanize the input
    let lexer = Lexer::new(&input_string);

    // Parse & Build an AST
    let mut parser = Parser::new(lexer);

    let ast_root = match parser.parse() {
        Some(ast) => ast,
        None => return,
    };

    // TODO: Semantic Analysis

    // Run Code Gen
    unsafe {
        codegen("module1", ast_root, true);
    }
}

fn readable_to_string<R: Read>(mut readable: R) -> String {
    let mut input_string = String::new();

    if let Err(e) = readable.read_to_string(&mut input_string) {
        panic!("Failed to read: {}", e);
    }

    input_string
}
<|endoftext|>


<commit_before>extern crate libc;

use libc::funcs::posix88::unistd;
use std::c_str;
use std::cmp;
use std::os;
use std::ptr;
use std::rand::Rng;

fn main() {
    let version = "0.1.0";
    match parse_args(os::args().as_slice().tail()) {
        Err(Usage) => {
            os::set_exit_status(1);
            print_usage(version);
        }
        Err(Help) =>
            print_usage(version),
        Err(Version) =>
            print_version(version),
        Ok(opts) => {
            if whack(&opts) {
                os::set_exit_status(1);
            } else {
                opts.exe.map_or((), |exe| {
                    execvp_easy(exe.name, exe.args)
                });
            }
        }
    }
}

type ArgParse<T> = Result<T, Exit>;

#[deriving(Show)]
struct Options<'a> {
    chance: int,
    exe: Option<Exe<'a>>,
}

#[deriving(Show)]
struct Exe<'a> {
    name: &'a str,
    args: &'a[String],
}

#[deriving(Show)]
enum Exit {
    Usage,
    Help,
    Version,
}

fn parse_args(args: &[String]) -> ArgParse<Options> {
    args.uncons().map_or(Err(Usage), |(s, args)| {
        match s.as_slice() {
            "--help"    | "-h" => Err(Help),
            "--version" | "-v" => Err(Version),
            "--chance"  | "-c" => {
                args.uncons().map_or(Err(Usage), |(s, args)| {
                    from_str(s.as_slice()).map_or(Err(Usage), |val| {
                        args.skip("--").uncons().map_or(
                            Ok(Options {
                                chance: val,
                                exe: None
                            }), |(exe, args)| {
                                Ok(Options {
                                    chance: val,
                                    exe: Some(Exe {
                                        name: exe.as_slice(),
                                        args: args,
                                    })
                                })
                            })
                        })
                    })
                }
            _ => Err(Usage),
        }
    })
}

trait Uncons<'a, A> { fn uncons(&self) -> Option<(&'a A, &'a [A])>; }
trait Skip<'a, A, B> { fn skip(&self, x: A) -> &'a [B]; }

impl<'a, A> Uncons<'a, A> for &'a [A] {
    fn uncons(&self) -> Option<(&'a A, &'a [A])> {
        self.head().map(|x| (x, self.tail()))
    }
}

impl<'a > Skip<'a, &'a str, String> for &'a [String] {
    fn skip(&self, x: &'a str) -> &'a [String] {
        self.uncons().map_or(*self, |(y, ys)| { if x == y.as_slice() { ys } else { *self } })
    }
}

fn whack(opts: &Options) -> bool {
    std::rand::task_rng().gen_range(0, 100) > cmp::min(cmp::max(opts.chance, 0), 100)
}

fn execvp_easy(name: &str, args: &[String]) {
    let c_name: c_str::CString = name.to_c_str();
    let c_args: Vec<c_str::CString> = args.iter().map(|tmp| tmp.to_c_str()).collect();
    with_argv(&c_name, c_args.as_slice(), proc(c_argv) -> () unsafe {
        unistd::execvp(*c_argv, c_argv);
        panic!("executing {}: {}", name, os::last_os_error());
    });
}

fn with_argv<T>(prog: &c_str::CString, args: &[c_str::CString], f: proc(*mut*const libc::c_char) -> T) -> T {
    let mut ptrs: Vec<*const libc::c_char> = Vec::with_capacity(args.len() + 1);

    ptrs.push(prog.as_ptr());
    ptrs.extend(args.iter().map(|tmp| tmp.as_ptr()));
    ptrs.push(ptr::null());

    f(ptrs.as_mut_ptr())
}

fn print_usage(version: &str) {
    print_version(version);
    println!("\n\
        Usage: whacky (-c PERCENTAGE|--chance PERCENTAGE) [[--] COMMAND]\n\
          whacky, yet another randomly failing program\n\
        \n\
        Available options:\n\
          -h,--help           show this help text\n\
          -c,--chance         set success chance");
}

fn print_version(version: &str) {
    println!("whacky {}", version);
}
<commit_msg>Simplify a call to execvp()<commit_after>extern crate libc;

use libc::funcs::posix88::unistd;
use std::c_str;
use std::cmp;
use std::os;
use std::ptr;
use std::rand::Rng;

fn main() {
    let version = "0.1.0";
    match parse_args(os::args().as_slice().tail()) {
        Err(Usage) => {
            os::set_exit_status(1);
            print_usage(version);
        }
        Err(Help) =>
            print_usage(version),
        Err(Version) =>
            print_version(version),
        Ok(opts) => {
            if whack(&opts) {
                os::set_exit_status(1);
            } else {
                opts.exe.map_or((), |exe| {
                    execvp(exe.name, exe.args)
                });
            }
        }
    }
}

type ArgParse<T> = Result<T, Exit>;

#[deriving(Show)]
struct Options<'a> {
    chance: int,
    exe: Option<Exe<'a>>,
}

#[deriving(Show)]
struct Exe<'a> {
    name: &'a str,
    args: &'a[String],
}

#[deriving(Show)]
enum Exit {
    Usage,
    Help,
    Version,
}

fn parse_args(args: &[String]) -> ArgParse<Options> {
    args.uncons().map_or(Err(Usage), |(s, args)| {
        match s.as_slice() {
            "--help"    | "-h" => Err(Help),
            "--version" | "-v" => Err(Version),
            "--chance"  | "-c" => {
                args.uncons().map_or(Err(Usage), |(s, args)| {
                    from_str(s.as_slice()).map_or(Err(Usage), |val| {
                        args.skip("--").uncons().map_or(
                            Ok(Options {
                                chance: val,
                                exe: None
                            }), |(exe, args)| {
                                Ok(Options {
                                    chance: val,
                                    exe: Some(Exe {
                                        name: exe.as_slice(),
                                        args: args,
                                    })
                                })
                            })
                        })
                    })
                }
            _ => Err(Usage),
        }
    })
}

trait Uncons<'a, A> { fn uncons(&self) -> Option<(&'a A, &'a [A])>; }
trait Skip<'a, A, B> { fn skip(&self, x: A) -> &'a [B]; }

impl<'a, A> Uncons<'a, A> for &'a [A] {
    fn uncons(&self) -> Option<(&'a A, &'a [A])> {
        self.head().map(|x| (x, self.tail()))
    }
}

impl<'a > Skip<'a, &'a str, String> for &'a [String] {
    fn skip(&self, x: &'a str) -> &'a [String] {
        self.uncons().map_or(*self, |(y, ys)| { if x == y.as_slice() { ys } else { *self } })
    }
}

fn whack(opts: &Options) -> bool {
    std::rand::task_rng().gen_range(0, 100) > cmp::min(cmp::max(opts.chance, 0), 100)
}

fn execvp(name: &str, args: &[String]) {
    let c_name: c_str::CString = name.to_c_str();
    let c_args: Vec<c_str::CString> = args.iter().map(|tmp| tmp.to_c_str()).collect();

    let mut xs: Vec<*const libc::c_char> = Vec::with_capacity(args.len() + 2);

    xs.push(c_name.as_ptr());
    xs.extend(c_args.iter().map(|tmp| tmp.as_ptr()));
    xs.push(ptr::null());

    let c_arg0 = xs[0];
    let c_argv = xs.as_mut_ptr();

    unsafe {
        unistd::execvp(c_arg0, c_argv);
    };

    panic!("execvp(3) failed with: {}", os::last_os_error());
}

fn print_usage(version: &str) {
    print_version(version);
    println!("\n\
        Usage: whacky (-c PERCENTAGE|--chance PERCENTAGE) [[--] COMMAND]\n\
          whacky, yet another randomly failing program\n\
        \n\
        Available options:\n\
          -h,--help           show this help text\n\
          -c,--chance         set success chance");
}

fn print_version(version: &str) {
    println!("whacky {}", version);
}
<|endoftext|>


<commit_before>extern crate cargo_update;
extern crate tabwriter;

use std::process::{Command, exit};
use std::io::{Write, stdout};
use tabwriter::TabWriter;

fn main() {
    let result = actual_main().err().unwrap_or(0);
    exit(result);
}

fn actual_main() -> Result<(), i32> {
    let opts = cargo_update::Options::parse();

    let mut packages = cargo_update::ops::installed_main_repo_packages(&opts.cargo_dir.1);

    if !opts.to_update.is_empty() {
        packages = cargo_update::ops::intersect_packages(packages, &opts.to_update);
    }

    {
        // Searching for "" will just update the registry
        let search_res = Command::new("cargo").arg("search").arg("").status().unwrap();
        if !search_res.success() {
            try!(Err(search_res.code().unwrap_or(-1)));
        }
        println!("");
    }

    let registry = cargo_update::ops::get_index_path(&opts.cargo_dir.1);

    for package in &mut packages {
        package.pull_version(&registry);
    }

    {
        let mut out = TabWriter::new(stdout());
        writeln!(out, "Package\tInstalled\tLatest\tNeeds update").unwrap();
        for package in &packages {
            writeln!(out,
                     "{}\tv{}\tv{}\t{}",
                     package.name,
                     package.version,
                     package.newest_version.as_ref().unwrap(),
                     if package.version < *package.newest_version.as_ref().unwrap() {
                         "Yes"
                     } else {
                         "No"
                     })
                .unwrap();
        }
        writeln!(out, "").unwrap();
        out.flush().unwrap();
    }

    if opts.update {
        packages = packages.into_iter().filter(|pkg| pkg.version < *pkg.newest_version.as_ref().unwrap()).collect();

        if !packages.is_empty() {
            for package in &packages {
                println!("Updating {}", package.name);

                let install_res = Command::new("cargo").arg("install").arg("-f").arg(&package.name).status().unwrap();
                if !install_res.success() {
                    try!(Err(install_res.code().unwrap_or(-1)));
                }

                println!("");
            }
        } else {
            println!("No packages need updating.");
        }
    }

    Ok(())
}
<commit_msg>Support self-updates by just renaming the current executable<commit_after>extern crate cargo_update;
extern crate tabwriter;

use std::process::{Command, exit};
use std::io::{Write, stdout};
use tabwriter::TabWriter;
use std::env;
use std::fs;

fn main() {
    let result = actual_main().err().unwrap_or(0);
    exit(result);
}

fn actual_main() -> Result<(), i32> {
    let opts = cargo_update::Options::parse();

    let mut packages = cargo_update::ops::installed_main_repo_packages(&opts.cargo_dir.1);

    if !opts.to_update.is_empty() {
        packages = cargo_update::ops::intersect_packages(packages, &opts.to_update);
    }

    {
        // Searching for "" will just update the registry
        let search_res = Command::new("cargo").arg("search").arg("").status().unwrap();
        if !search_res.success() {
            try!(Err(search_res.code().unwrap_or(-1)));
        }
        println!("");
    }

    let registry = cargo_update::ops::get_index_path(&opts.cargo_dir.1);

    for package in &mut packages {
        package.pull_version(&registry);
    }

    {
        let mut out = TabWriter::new(stdout());
        writeln!(out, "Package\tInstalled\tLatest\tNeeds update").unwrap();
        for package in &packages {
            writeln!(out,
                     "{}\tv{}\tv{}\t{}",
                     package.name,
                     package.version,
                     package.newest_version.as_ref().unwrap(),
                     if package.version < *package.newest_version.as_ref().unwrap() {
                         "Yes"
                     } else {
                         "No"
                     })
                .unwrap();
        }
        writeln!(out, "").unwrap();
        out.flush().unwrap();
    }

    if opts.update {
        packages = packages.into_iter().filter(|pkg| pkg.version < *pkg.newest_version.as_ref().unwrap()).collect();

        if !packages.is_empty() {
            for package in &packages {
                println!("Updating {}", package.name);

                if cfg!(target_os = "windows") && package.name == "cargo-update" {
                    let cur_exe = env::current_exe().unwrap();
                    let mut new_exe = cur_exe.clone();
                    new_exe.set_extension(format!("exe-v{}", package.version));
                    fs::rename(cur_exe, new_exe).unwrap();
                }

                let install_res = Command::new("cargo").arg("install").arg("-f").arg(&package.name).status().unwrap();
                if !install_res.success() {
                    try!(Err(install_res.code().unwrap_or(-1)));
                }

                println!("");
            }
        } else {
            println!("No packages need updating.");
        }
    }

    Ok(())
}
<|endoftext|>


<commit_before>use std::boxed::Box;
use std::collections::HashMap;
extern crate time;

#[derive(Debug)]
struct SearchTree<T> {
    left: Option<Box<SearchTree<T>>>,
    right: Option<Box<SearchTree<T>>>,
    key: T,
}

impl<T> SearchTree<T> where T: std::fmt::Debug + std::cmp::Eq + std::cmp::PartialOrd + std::clone::Clone {
    /// 中序遍历节点,只是打印
    fn inorder(&self) {
        if let Some(ref tree) = self.left {
            tree.inorder();
        }
        println!("self.key = {:#?}", self.key);
        if let Some(ref tree) = self.right {
            tree.inorder();
        }
    }

    /// 查找节点
    fn search(&self, key: T ) -> Option<T> {
        if self.key == key {
            return Some(self.key.clone());
        }

        if key < self.key {
            match self.left {
                Some(ref tree) => tree.search(key),
                None => None
            }
        } else {
            match self.right {
                Some(ref tree) => tree.search(key),
                None => None
            }
        }
    }

    /// 取出最小节点的 key
    fn minimum(&self) -> T {
        match self.left {
            Some(ref tree) => tree.minimum(),
            None => self.key.clone()
        }
    }

    /// 取出最大节点的 key
    fn maximum(&self) -> T {
        match self.right {
            Some(ref tree) => tree.maximum(),
            None => self.key.clone()
        }
    }
//    fn insert(&mut self, val: T) {
//        let mut node;
//        if val <= self.key {
//            node = self.left;
//        } else {
//            node = self.right;
//        }
//
//        loop {
//            match node {
//                Some(n) => {
//                    if val <= n.key {
//                        node = n.left;
//                    } else {
//                        node = n.right;
//                    }
//                },
//                None => break,
//            }
//        }
//
//    }
    /// 插入一个节点
//    fn insert(&mut self, val: T) {
//        if self.key >= val {
//            if let Some(ref mut left) = self.left {
//                left.insert(val);
//            } else {
//                self.left = Some(Box::new(SearchTree {
//                    left: None,
//                    right: None,
//                    key: val,
//
//                }));
//            }
//        } else {
//            if let Some(ref mut right) = self.right {
//                right.insert(val);
//            } else {
//                self.right = Some(Box::new(SearchTree {
//                    left: None,
//                    right: None,
//                    key: val,
//
//                }));
//            }
//        }
//    }

    /// 删除一个节点
    fn delete(&mut self, key: T) {

    }

}
use std::mem::size_of;

//fn main() {

//    let mut v = Vec::new();
//    for i in 0..330000 {
//        v.push(SearchTree {
//            left: None,
//            right: None,
//            key: 100,
//        });
//    }

//
//    let mut root = SearchTree {
//        left: None,
//        right: None,
//        key: 330001,
//    };
////    let mut hash_map = HashMap::new();
//    for i in 0..330000 {
//        root.insert(i);
//    }
//    println!("insert end");
//    let mut start = timestamp();
//    let result = hash_map.keys().filter(|&&x| (x >= 1000000 - 1)).collect::<Vec<_>>();
//    let mut end = timestamp();
//    println!("end - start = {:#?}", end - start);
//
//    start = timestamp();
//    let max = root.maximum();
//    end = timestamp();
//    println!("end - start = {:#?}", end - start);
//    println!("max = {:#?}", max);
//}

//fn timestamp() -> f64 {
//    let timespec = time::get_time();
//    // 1459440009.113178
//    let mills: f64 = timespec.sec as f64 + (timespec.nsec as f64 / 1000.0 / 1000.0 / 1000.0 );
//    mills
//
//}
//
//use std::ptr;
//
//struct RawLink<T> {
//    p: *mut T,
//}
//
//fn none<T>() -> RawLink<T> {
//    RawLink { p: ptr::null_mut() }
//}
//
//fn some<T>(n: &mut T) -> RawLink<T> {
//    RawLink { p: n as *mut T }
//}
//
//struct Node<T> {
//    next: Option<Box<Node<T>>>,
//    prev: Option<Box<Node<T>>>,
//    val:  T,
//}
//
//struct List<T> {
//    list_head: Option<Node<T>>,
//    list_tail: Option<Node<T>>,
//}
//
//impl<T> List<T> {
//    fn push_front_node(&mut self, mut new_head: Node<T>) {
//        match self.list_head {
//            None => {
//                self.list_tail = Some(Box::new(new_head));
//                new_head.prev = None;
//                self.list_head = Some(Box::new(new_head));
//            },
//            Some(ref mut head) => {
//
//            }
//        }
//    }
//}

fn main() {

}

<commit_msg>write a vec<commit_after>fn main() {

}<|endoftext|>


<commit_before>#![allow(unused)]

extern crate websocket;
extern crate futures;
extern crate tokio_core;
#[macro_use]
extern crate tokio_io;
extern crate tokio_stdin_stdout;

#[cfg(unix)]
extern crate tokio_file_unix;
#[cfg(unix)]
extern crate tokio_signal;

use std::thread;
use std::io::stdin;
use tokio_core::reactor::Core;
use futures::future::Future;
use futures::sink::Sink;
use futures::stream::Stream;
use futures::sync::mpsc;
use websocket::result::WebSocketError;
use websocket::{ClientBuilder, OwnedMessage};
use tokio_io::{AsyncRead,AsyncWrite};
use std::io::{Read,Write};
use std::io::Result as IoResult;

use std::rc::Rc;
use std::cell::RefCell;

use websocket::stream::async::Stream as WsStream;
use futures::Async::{Ready, NotReady};

use tokio_io::io::copy;

use tokio_io::codec::FramedRead;
use std::fs::File;

#[cfg(unix)]
use tokio_file_unix::{File as UnixFile, StdFile};
#[cfg(unix)]
use std::os::unix::io::FromRawFd;

type Result<T> = std::result::Result<T, Box<std::error::Error>>;

type WaitingForImplTraitFeature0 = tokio_io::codec::Framed<websocket::async::TcpStream, websocket::async::MessageCodec<websocket::OwnedMessage>>;
type WaitingForImplTraitFeature2 = futures::stream::SplitSink<WaitingForImplTraitFeature0>;
type WsSource = futures::stream::SplitStream<WaitingForImplTraitFeature0>;
type MultiProducerWsSink = Rc<RefCell<WaitingForImplTraitFeature2>>;

fn wouldblock<T>() -> std::io::Result<T> {
    Err(std::io::Error::new(std::io::ErrorKind::WouldBlock, ""))
}
fn brokenpipe<T>() -> std::io::Result<T> {
    Err(std::io::Error::new(std::io::ErrorKind::BrokenPipe, ""))
}
fn io_other_error<E : std::error::Error + Send + Sync + 'static>(e:E) -> std::io::Error {
    std::io::Error::new(std::io::ErrorKind::Other,e)
}

mod my_copy;

struct WsReadWrapper {
    s: WsSource,
    pingreply : MultiProducerWsSink,
    debt: Option<Vec<u8>>,
}

impl AsyncRead for WsReadWrapper {

}

impl WsReadWrapper {
    fn process_message(&mut self, buf: &mut [u8], buf_in: &[u8]) -> std::result::Result<usize, std::io::Error> {
        let l = buf_in.len().min(buf.len());
        buf[..l].copy_from_slice(&buf_in[..l]);

        if l < buf_in.len() {
            self.debt = Some(buf_in[l..].to_vec());
        }

        Ok(l)
    }
}

impl Read for WsReadWrapper {
    fn read(&mut self, buf: &mut [u8]) -> std::result::Result<usize, std::io::Error> {
        if let Some(debt) = self.debt.take() {
            return self.process_message(buf, debt.as_slice())
        }
        match self.s.poll().map_err(io_other_error)? {
            Ready(Some(OwnedMessage::Close(_))) => {
                brokenpipe()
            },
            Ready(None) => {
                brokenpipe()
            }
            Ready(Some(OwnedMessage::Ping(x))) => {
                let om = OwnedMessage::Pong(x);
                let mut sink = self.pingreply.borrow_mut();
                let mut proceed = false;
                // I'm not sure this is safe enough, RefCell-wise and Futures-wise
                // And pings and their replies are not tested yet
                match sink.start_send(om).map_err(io_other_error)? {
                    futures::AsyncSink::NotReady(_) => {
                        // drop the ping
                    },
                    futures::AsyncSink::Ready => {
                        proceed = true;
                    }
                }
                if proceed {
                    let _ = sink.poll_complete().map_err(io_other_error)?;
                }

                Ok(0)
            }
            Ready(Some(OwnedMessage::Pong(_))) => {
                Ok(0)
            }
            Ready(Some(OwnedMessage::Text(x))) => {
                self.process_message(buf, x.as_str().as_bytes())
            }
            Ready(Some(OwnedMessage::Binary(x))) => {
                self.process_message(buf, x.as_slice())
            }
            NotReady => {
                wouldblock()
            }
        }
    }
}

struct WsWriteWrapper(MultiProducerWsSink);

impl AsyncWrite for WsWriteWrapper {
    fn shutdown(&mut self) -> futures::Poll<(),std::io::Error> {
        // TODO: check this
        Ok(Ready(()))
    }
}

impl Write for WsWriteWrapper {
    fn write(&mut self, buf: &[u8]) -> IoResult<usize> {
        let om = OwnedMessage::Binary(buf.to_vec());
        match self.0.borrow_mut().start_send(om).map_err(io_other_error)? {
            futures::AsyncSink::NotReady(_) => {
                wouldblock()
            },
            futures::AsyncSink::Ready => {
                Ok(buf.len())
            }
        }
    }
    fn flush(&mut self) -> IoResult<()> {
        match self.0.borrow_mut().poll_complete().map_err(io_other_error)? {
            NotReady => {
                wouldblock()
            },
            Ready(()) => {
                Ok(())
            }
        }
    }

}

fn run() -> Result<()> {
    let peeraddr = std::env::args().nth(1).ok_or("no arg")?;

    println!("Connecting to {}", peeraddr);
    let mut core = Core::new()?;
    let handle = core.handle();

    let si;
    let so;

    #[cfg(any(not(unix),feature="no_unix_stdio"))]
    {
        si = tokio_stdin_stdout::stdin(0);
        so = tokio_stdin_stdout::stdout(0);
    }

    #[cfg(all(unix,not(feature="no_unix_stdio")))]
    {
        let stdin  = UnixFile::new_nb(std::io::stdin())?;
        let stdout = UnixFile::new_nb(std::io::stdout())?;

        si = stdin.into_reader(&handle)?;
        so = stdout.into_io(&handle)?;

        let ctrl_c = tokio_signal::ctrl_c(&handle).flatten_stream();
        let prog = ctrl_c.for_each(|()| {
            UnixFile::raw_new(std::io::stdin()).set_nonblocking(false);
            UnixFile::raw_new(std::io::stdout()).set_nonblocking(false);
            ::std::process::exit(0);
            Ok(())
        });
        handle.spawn(prog.map_err(|_|()));
    }

    let runner = ClientBuilder::new(peeraddr.as_ref())?
        .add_protocol("rust-websocket")
        .async_connect_insecure(&core.handle())
        .and_then(|(duplex, _)| {
            let (sink, stream) = duplex.split();
            let mpsink = Rc::new(RefCell::new(sink));

            let ws_str = WsReadWrapper {
                s: stream,
                pingreply: mpsink.clone(),
                debt: None,
            };
            let ws_sin = WsWriteWrapper(mpsink);

            handle.spawn(my_copy::copy(si, ws_sin).map(|_|()).map_err(|_|()));
            my_copy::copy(ws_str, so).map_err(|e| WebSocketError::IoError(e))
        });
    core.run(runner)?;
    Ok(())
}

fn main() {
    let r = run();

    #[cfg(all(unix,not(feature="no_unix_stdio")))]
    {
        UnixFile::raw_new(std::io::stdin()).set_nonblocking(false);
        UnixFile::raw_new(std::io::stdout()).set_nonblocking(false);
    }

    if let Err(e) = r {
        eprintln!("websocat: {}", e);
        ::std::process::exit(1);
    }
}
<commit_msg>Drop that println<commit_after>#![allow(unused)]

extern crate websocket;
extern crate futures;
extern crate tokio_core;
#[macro_use]
extern crate tokio_io;
extern crate tokio_stdin_stdout;

#[cfg(unix)]
extern crate tokio_file_unix;
#[cfg(unix)]
extern crate tokio_signal;

use std::thread;
use std::io::stdin;
use tokio_core::reactor::Core;
use futures::future::Future;
use futures::sink::Sink;
use futures::stream::Stream;
use futures::sync::mpsc;
use websocket::result::WebSocketError;
use websocket::{ClientBuilder, OwnedMessage};
use tokio_io::{AsyncRead,AsyncWrite};
use std::io::{Read,Write};
use std::io::Result as IoResult;

use std::rc::Rc;
use std::cell::RefCell;

use websocket::stream::async::Stream as WsStream;
use futures::Async::{Ready, NotReady};

use tokio_io::io::copy;

use tokio_io::codec::FramedRead;
use std::fs::File;

#[cfg(unix)]
use tokio_file_unix::{File as UnixFile, StdFile};
#[cfg(unix)]
use std::os::unix::io::FromRawFd;

type Result<T> = std::result::Result<T, Box<std::error::Error>>;

type WaitingForImplTraitFeature0 = tokio_io::codec::Framed<websocket::async::TcpStream, websocket::async::MessageCodec<websocket::OwnedMessage>>;
type WaitingForImplTraitFeature2 = futures::stream::SplitSink<WaitingForImplTraitFeature0>;
type WsSource = futures::stream::SplitStream<WaitingForImplTraitFeature0>;
type MultiProducerWsSink = Rc<RefCell<WaitingForImplTraitFeature2>>;

fn wouldblock<T>() -> std::io::Result<T> {
    Err(std::io::Error::new(std::io::ErrorKind::WouldBlock, ""))
}
fn brokenpipe<T>() -> std::io::Result<T> {
    Err(std::io::Error::new(std::io::ErrorKind::BrokenPipe, ""))
}
fn io_other_error<E : std::error::Error + Send + Sync + 'static>(e:E) -> std::io::Error {
    std::io::Error::new(std::io::ErrorKind::Other,e)
}

mod my_copy;

struct WsReadWrapper {
    s: WsSource,
    pingreply : MultiProducerWsSink,
    debt: Option<Vec<u8>>,
}

impl AsyncRead for WsReadWrapper {

}

impl WsReadWrapper {
    fn process_message(&mut self, buf: &mut [u8], buf_in: &[u8]) -> std::result::Result<usize, std::io::Error> {
        let l = buf_in.len().min(buf.len());
        buf[..l].copy_from_slice(&buf_in[..l]);

        if l < buf_in.len() {
            self.debt = Some(buf_in[l..].to_vec());
        }

        Ok(l)
    }
}

impl Read for WsReadWrapper {
    fn read(&mut self, buf: &mut [u8]) -> std::result::Result<usize, std::io::Error> {
        if let Some(debt) = self.debt.take() {
            return self.process_message(buf, debt.as_slice())
        }
        match self.s.poll().map_err(io_other_error)? {
            Ready(Some(OwnedMessage::Close(_))) => {
                brokenpipe()
            },
            Ready(None) => {
                brokenpipe()
            }
            Ready(Some(OwnedMessage::Ping(x))) => {
                let om = OwnedMessage::Pong(x);
                let mut sink = self.pingreply.borrow_mut();
                let mut proceed = false;
                // I'm not sure this is safe enough, RefCell-wise and Futures-wise
                // And pings and their replies are not tested yet
                match sink.start_send(om).map_err(io_other_error)? {
                    futures::AsyncSink::NotReady(_) => {
                        // drop the ping
                    },
                    futures::AsyncSink::Ready => {
                        proceed = true;
                    }
                }
                if proceed {
                    let _ = sink.poll_complete().map_err(io_other_error)?;
                }

                Ok(0)
            }
            Ready(Some(OwnedMessage::Pong(_))) => {
                Ok(0)
            }
            Ready(Some(OwnedMessage::Text(x))) => {
                self.process_message(buf, x.as_str().as_bytes())
            }
            Ready(Some(OwnedMessage::Binary(x))) => {
                self.process_message(buf, x.as_slice())
            }
            NotReady => {
                wouldblock()
            }
        }
    }
}

struct WsWriteWrapper(MultiProducerWsSink);

impl AsyncWrite for WsWriteWrapper {
    fn shutdown(&mut self) -> futures::Poll<(),std::io::Error> {
        // TODO: check this
        Ok(Ready(()))
    }
}

impl Write for WsWriteWrapper {
    fn write(&mut self, buf: &[u8]) -> IoResult<usize> {
        let om = OwnedMessage::Binary(buf.to_vec());
        match self.0.borrow_mut().start_send(om).map_err(io_other_error)? {
            futures::AsyncSink::NotReady(_) => {
                wouldblock()
            },
            futures::AsyncSink::Ready => {
                Ok(buf.len())
            }
        }
    }
    fn flush(&mut self) -> IoResult<()> {
        match self.0.borrow_mut().poll_complete().map_err(io_other_error)? {
            NotReady => {
                wouldblock()
            },
            Ready(()) => {
                Ok(())
            }
        }
    }

}

fn run() -> Result<()> {
    let peeraddr = std::env::args().nth(1).ok_or("no arg")?;

    //println!("Connecting to {}", peeraddr);
    let mut core = Core::new()?;
    let handle = core.handle();

    let si;
    let so;

    #[cfg(any(not(unix),feature="no_unix_stdio"))]
    {
        si = tokio_stdin_stdout::stdin(0);
        so = tokio_stdin_stdout::stdout(0);
    }

    #[cfg(all(unix,not(feature="no_unix_stdio")))]
    {
        let stdin  = UnixFile::new_nb(std::io::stdin())?;
        let stdout = UnixFile::new_nb(std::io::stdout())?;

        si = stdin.into_reader(&handle)?;
        so = stdout.into_io(&handle)?;

        let ctrl_c = tokio_signal::ctrl_c(&handle).flatten_stream();
        let prog = ctrl_c.for_each(|()| {
            UnixFile::raw_new(std::io::stdin()).set_nonblocking(false);
            UnixFile::raw_new(std::io::stdout()).set_nonblocking(false);
            ::std::process::exit(0);
            Ok(())
        });
        handle.spawn(prog.map_err(|_|()));
    }

    let runner = ClientBuilder::new(peeraddr.as_ref())?
        .add_protocol("rust-websocket")
        .async_connect_insecure(&core.handle())
        .and_then(|(duplex, _)| {
            let (sink, stream) = duplex.split();
            let mpsink = Rc::new(RefCell::new(sink));

            let ws_str = WsReadWrapper {
                s: stream,
                pingreply: mpsink.clone(),
                debt: None,
            };
            let ws_sin = WsWriteWrapper(mpsink);

            handle.spawn(my_copy::copy(si, ws_sin).map(|_|()).map_err(|_|()));
            my_copy::copy(ws_str, so).map_err(|e| WebSocketError::IoError(e))
        });
    core.run(runner)?;
    Ok(())
}

fn main() {
    let r = run();

    #[cfg(all(unix,not(feature="no_unix_stdio")))]
    {
        UnixFile::raw_new(std::io::stdin()).set_nonblocking(false);
        UnixFile::raw_new(std::io::stdout()).set_nonblocking(false);
    }

    if let Err(e) = r {
        eprintln!("websocat: {}", e);
        ::std::process::exit(1);
    }
}
<|endoftext|>


<commit_before>#[macro_use]
extern crate glium;
extern crate cgmath;
extern crate rand;

mod vertex;
mod camera;
mod planet;
mod triangle;
mod renderable;
mod ocean;

fn main() {
    use glium::{DisplayBuild, Surface};
    use vertex::{VertexPosition, Normal};
    use camera::Camera;
    use cgmath::Vector3;
    use planet::Planet;
    use ocean::Ocean;

    let display = glium::glutin::WindowBuilder::new().with_depth_buffer(24).build_glium().unwrap();
    let target = display.draw();
    let (width, height) = target.get_dimensions();
    target.finish().unwrap();

    let mut cam: Camera = Camera::new(Vector3::new(0.0, -5.0, 0.0),
                                      width as f32 / height as f32,
                                      5.);
    let mut planet: Planet<VertexPosition, Normal> = Planet::new(&display, 4);
    let mut ocean: Ocean<VertexPosition, Normal> = Ocean::new(&display, 4, 1.09);

    let mut vertical_position: f32 = 0.;
    let mut horisontal_angle: f32 = 0.;

    let light = [-1.0, 0.4, 0.9f32];

    let mut time = 0.0;

    loop {
        let mut target = display.draw();

        target.clear_color_and_depth((0.0, 0.0, 0.0, 1.0), 1.0);

        let params = glium::DrawParameters {
            depth: glium::Depth {
                test: glium::draw_parameters::DepthTest::IfLess,
                write: true,
                ..Default::default()
            },
            ..Default::default()
        };

        time += 0.05;
        ocean.draw(&mut target, &params, cam.view, cam.projection, light, time);
        planet.draw(&mut target, &params, cam.view, cam.projection, light);

        target.finish().unwrap();

        let mut cam_pos = cam.get_position();
        for ev in display.poll_events() {
            match ev {
                glium::glutin::Event::KeyboardInput(_, _, Some(glium::glutin::VirtualKeyCode::Escape)) |
                glium::glutin::Event::Closed => return,

                glium::glutin::Event::KeyboardInput(_,
                                                    _,
                                                    Some(glium::glutin::VirtualKeyCode::Up)) => {
                    vertical_position += 0.1
                }
                glium::glutin::Event::KeyboardInput(_,
                                                    _,
                                                    Some(glium::glutin::VirtualKeyCode::Down)) => {
                    vertical_position -= 0.1
                }

                glium::glutin::Event::KeyboardInput(_,
                                                    _,
                                                    Some(glium::glutin::VirtualKeyCode::Right)) => {
                    horisontal_angle += 0.1
                }
                glium::glutin::Event::KeyboardInput(_,
                                                    _,
                                                    Some(glium::glutin::VirtualKeyCode::Left)) => {
                    horisontal_angle -= 0.1
                }

                glium::glutin::Event::KeyboardInput(_,
                                                    _,
                                                    Some(glium::glutin::VirtualKeyCode::Space)) => {
                    planet = Planet::new(&display, 4);
                    ocean = Ocean::new(&display, 4, 1.09);
                }

                _ => (),
            }
        }

        if vertical_position < -1. {
            vertical_position = -1.;
        } else if vertical_position > 1. {
            vertical_position = 1.;
        }

        cam_pos += Vector3::new(f32::cos(horisontal_angle),
                                f32::sin(horisontal_angle),
                                vertical_position);
        cam.set_position(cam_pos);
    }
}
<commit_msg>Use enum variants for shorter match<commit_after>#[macro_use]
extern crate glium;
extern crate cgmath;
extern crate rand;

mod vertex;
mod camera;
mod planet;
mod triangle;
mod renderable;
mod ocean;

fn main() {
    use glium::{DisplayBuild, Surface};
    use vertex::{VertexPosition, Normal};
    use camera::Camera;
    use cgmath::Vector3;
    use planet::Planet;
    use ocean::Ocean;

    let display = glium::glutin::WindowBuilder::new().with_depth_buffer(24).build_glium().unwrap();
    let target = display.draw();
    let (width, height) = target.get_dimensions();
    target.finish().unwrap();

    let mut cam: Camera = Camera::new(Vector3::new(0.0, -5.0, 0.0),
                                      width as f32 / height as f32,
                                      5.);
    let mut planet: Planet<VertexPosition, Normal> = Planet::new(&display, 4);
    let mut ocean: Ocean<VertexPosition, Normal> = Ocean::new(&display, 4, 1.09);

    let mut vertical_position: f32 = 0.;
    let mut horisontal_angle: f32 = 0.;

    let light = [-1.0, 0.4, 0.9f32];

    let mut time = 0.0;

    loop {
        let mut target = display.draw();

        target.clear_color_and_depth((0.0, 0.0, 0.0, 1.0), 1.0);

        let params = glium::DrawParameters {
            depth: glium::Depth {
                test: glium::draw_parameters::DepthTest::IfLess,
                write: true,
                ..Default::default()
            },
            ..Default::default()
        };

        time += 0.05;
        ocean.draw(&mut target, &params, cam.view, cam.projection, light, time);
        planet.draw(&mut target, &params, cam.view, cam.projection, light);

        target.finish().unwrap();

        let mut cam_pos = cam.get_position();

        for ev in display.poll_events() {
            use glium::glutin::Event::*;
            use glium::glutin::VirtualKeyCode::*;

            match ev {
                KeyboardInput(_, _, Some(Escape)) |
                Closed => return,
                KeyboardInput(_, _, Some(Up)) => {
                    vertical_position += 0.1
                }
                KeyboardInput(_, _, Some(Down)) => {
                    vertical_position -= 0.1
                }
                KeyboardInput(_, _, Some(Right)) => {
                    horisontal_angle += 0.1
                }
                KeyboardInput(_, _, Some(Left)) => {
                    horisontal_angle -= 0.1
                }
                KeyboardInput(_, _, Some(Space)) => {
                    planet = Planet::new(&display, 4);
                    ocean = Ocean::new(&display, 4, 1.09);
                }
                _ => (),
            }
        }

        if vertical_position < -1. {
            vertical_position = -1.;
        } else if vertical_position > 1. {
            vertical_position = 1.;
        }

        cam_pos += Vector3::new(f32::cos(horisontal_angle),
                                f32::sin(horisontal_angle),
                                vertical_position);
        cam.set_position(cam_pos);
    }
}
<|endoftext|>


<commit_before>extern crate ftp;
extern crate regex;
extern crate openssl;

use std::env;
use std::fs;
use std::fs::File;
use std::io::prelude::*;
use ftp::FtpStream;
// use openssl::ssl::*;

struct DownloadableFile {
    client_dir: String,
    server_dir: String,
    filename: String,
    clientfile_namescheme: String,
}

struct DownRequest {
    host: String,
    user: String,
    pass: String,
    remote_files: Vec<DownloadableFile>,
}

/// Makes a directory specified
fn mk_dir(d: &str) -> std::io::Result<()> {
    try!(fs::create_dir_all(d));
    Ok(())
}

/// Breaks down the config given a String of the config file's contents
fn break_conf(b: &mut String) -> Option<DownRequest> {

    /// Find line and get the data from it, if there isn't data to get, None is returned
    fn break_line(input: &mut String, line: &str) -> Option<String> {
        if input.contains(line) {
            let loca = input.find(line).unwrap().checked_add(line.len()).unwrap();
            let y = &input[loca..];

            let locb = y.find(";").unwrap();
            Some(y[..locb].trim().to_string())
        } else {
            None
        }
    }
    // Make sure we won't get an unexpected None
    if b.contains("host:") && b.contains("user:") && b.contains("password:") &&
       b.contains("remoteFiles:") {

        /// Breaks down the remoteFile: line specificly since it's kinda special in layout
        fn break_remotefile(input: &mut String) -> Option<Vec<DownloadableFile>> {

            let start =
                input.find("remoteFiles:").unwrap().checked_add("remoteFiles:".len()).unwrap();
            let inp = &input[start..];
            let tinp = &inp[..inp.rfind(";").unwrap().checked_sub(";".len()).unwrap()];
            // let ttinp = &tinp[..tinp.rfind("]").unwrap().checked_sub("]".len()).unwrap()];

            let why = &tinp[tinp.find("[").unwrap().checked_add("[".len()).unwrap()..];
            let files: Vec<&str> = why.split(',').collect();
            let mut f: Vec<DownloadableFile> = Vec::new();

            println!("There are {} entries from this config to download",
                     files.len());

            for file in files {

                if file.contains("remoteDir:") && file.contains("localDir:") &&
                   file.contains("name:") {
                    let a: &mut String = &mut file.to_string();
                    f.push(DownloadableFile {
                        client_dir: break_line(a, "localDir:").unwrap(),
                        server_dir: break_line(a, "remoteDir:").unwrap(),
                        filename: break_line(a, "name:").unwrap(),
                        clientfile_namescheme: break_line(a, "nameToSaveAs:")
                            .unwrap_or(break_line(a, "name:").unwrap()),
                    });
                } else {}

            }

            if f.len() > 0 {
                Some(f)
            } else {
                println!("No files found to download or check on in this config. Check your \
                          config.");
                None
            }

        }

        let temp = DownRequest {
            host: break_line(b, "host:").unwrap(),
            user: break_line(b, "user:").unwrap(),
            pass: break_line(b, "password:").unwrap(),
            remote_files: break_remotefile(b).unwrap(),
        };

        Some(temp)
    } else {
        // If we would there's no point
        None
    }

}

/// Loads all configs into the folder
fn load_configs() -> std::io::Result<Vec<DownRequest>> {

    if mk_dir("./configs").is_ok() {
        println!("Made the dir needed");
    } // make directory

    let config_dir = fs::read_dir("./configs/").unwrap(); //read all files in dir, and expand them
    let mut but_two_m8 = fs::read_dir("./configs/").unwrap();
    let mut numb_in_folder: u8 = 0;
    let mut configs = Vec::new();

    for f in config_dir {
        // for all files f in the directory open them to file, and save the contained string

        numb_in_folder += 1;
        let name = but_two_m8.next();
        let mut file = try!(File::open(try!(f).path()));
        let mut buff = String::new();

        try!(file.read_to_string(&mut buff));
        let temcon = break_conf(&mut buff); // send buff off to be broken down

        if temcon.is_some() {
            // Check to make sure we didn't get nothing.
            configs.push(temcon.unwrap());
            println!("Config \"{}\" loaded successfully!",
                     name.unwrap().unwrap().file_name().to_str().unwrap());
        } else {
            println!("Config \"{}\" couldn't be loaded.",
                     name.unwrap().unwrap().file_name().to_str().unwrap());
        }

    }
    println!("There were {} configs to load!", numb_in_folder);
    Ok(configs)
}

/// Downloads files from a DownRequest
fn download_from_site(c: DownRequest, dr: bool) -> std::io::Result<()> {
    // TODO ftps support
    let host: String;
    let port: u16;
    if c.host.contains(":") {
        let sp: Vec<&str> = c.host.split(':').collect();
        host = sp[0].trim().to_string();
        port = sp[1].trim().parse().unwrap();

    } else {
        host = c.host;
        port = 21
    }

    println!("Downloading files from \"{}:{}\"", host, port);

    let mut fstream = FtpStream::connect((host.as_str(), port)).unwrap();

    if fstream.login(&c.user.as_str(), &c.pass.as_str()).is_ok() {

        println!("Connected to server, and logged in successfully");

        for f in c.remote_files {
            /// prints the print_progress from a usize from 0 - 100
            fn print_progress(per_done: usize) {
                let outa = per_done.checked_mul(4).unwrap().checked_div(10).unwrap();
                let mut t = 0;
                let mut pbar: String = "[".to_string();
                while t < 40 {
                    if outa < t {
                        pbar.push_str(" ")
                    } else {
                        pbar.push_str("=")
                    }

                    t = t + 1;
                }
                pbar.push_str("]");

                print!("\r{} : {}%", pbar, per_done);
            }

            let mut to_download: Vec<String> = Vec::new();
            let mut cl_names: Vec<String>;
            let _cd = fstream.cwd(&f.server_dir.as_str());

            if f.filename.contains("(*)") {
                let all_in_dir: Vec<String> = fstream.nlst(None).unwrap();
                let spieces_to_check: Vec<&str> = f.filename.split("(*)").collect();
                let cpieces_to_check: Vec<&str> = f.clientfile_namescheme.split("(*)").collect();

                for sf in all_in_dir {

                    let mut check_match = true;

                    while check_match {
                        for p in &spieces_to_check {
                            if !sf.contains(p) {
                                check_match = false;
                            }
                        }
                        break;
                    }
                    if check_match {
                        to_download.push(sf);
                    }
                }

                if f.filename.contains(f.clientfile_namescheme.as_str()) &&
                   f.filename.len() == f.clientfile_namescheme.len() {
                    cl_names = to_download.clone();
                } else {
                    cl_names = Vec::new();

                    if spieces_to_check.len() == cpieces_to_check.len() {
                        for n in &to_download {

                            let mut inv_pieces: Vec<&str> = Vec::new();
                            let mut cfn: String = "".to_string();
                            inv_pieces.push(n.as_str());
                            for piece in &spieces_to_check {
                                let mut temp: Vec<&str> = Vec::new();
                                for a in inv_pieces {
                                    if a.contains(piece) {
                                        let t: Vec<&str> = a.split(piece).collect();
                                        for tt in t {
                                            temp.push(tt);
                                        }
                                    } else {
                                        temp.push(a);
                                    }
                                }
                                inv_pieces = temp;
                            }

                            for x in 0..inv_pieces.len() {
                                if x > 0 {
                                    cfn.push_str(cpieces_to_check[x - 1])
                                }
                                cfn.push_str(inv_pieces[x]);
                            }

                            cl_names.push(cfn);
                        }
                    } else {
                        println!("Can't download files. The client and server name must have the \
                                  same number of (*)!");
                    }
                }

                println!("{} files matching \"{}\"", &to_download.len(), &f.filename);

            } else {
                cl_names = Vec::new();
                cl_names.push(f.clientfile_namescheme);
                to_download.push(f.filename);
            }

            for fz in 0..cl_names.len() {
                let dir = &f.client_dir.as_str().clone();
                let _md = mk_dir(dir); // Make Client dir

                /// Checks to see if the file is downloaded
                /// Takes a local file with it's path and the remote filee's byte size in usize
                fn is_downloaded(fileandpath: &String, rsz: &usize) -> Option<bool> {
                    let mdata = fs::metadata(fileandpath);
                    if mdata.is_ok() {

                        let lsz = mdata.unwrap().len() as usize;
                        if &lsz == rsz { Some(true) } else { Some(false) }
                    } else {
                        None
                    }
                }
                if dr == false {
                    let rsize = fstream.size(&to_download[fz].as_str()).unwrap();

                    let mut fnm = "".to_string();
                    fnm.push_str(dir);
                    fnm.push_str("/");
                    fnm.push_str(&cl_names[fz].as_str());

                    println!("Downloading \"{}\"", to_download[fz]);

                    if !is_downloaded(&fnm, &rsize.unwrap()).unwrap_or(false) {

                        // Make local file
                        let _tt = fstream.transfer_type(::ftp::types::FileType::Binary);

                        let _result = fstream.retr(&to_download[fz].as_str(), |stream| {
                            let mut buf = [0; 4096];
                            let mut flnm = "".to_string();
                            flnm.push_str(dir);
                            flnm.push_str("/");
                            flnm.push_str(&cl_names[fz].as_str());

                            let mut file = File::create(flnm).unwrap();
                            let mut lsize: usize = 0;

                            loop {
                                match stream.read(&mut buf) {
                                    Ok(0) => break,
                                    Ok(n) => {
                                        file.write_all(&buf[0..n]).unwrap();
                                        lsize += n;
                                    }
                                    Err(_err) => break,
                                };
                                print_progress(((lsize.checked_mul(100).unwrap())
                                    .checked_div(rsize.unwrap())
                                    .unwrap()));
                            }
                            print!("\r\n");
                            Ok(())
                        });
                    } else {
                        println!("File is already downloaded");
                    }
                } else {
                    println!("Would be downloading {} and saving as {}",
                             &to_download[fz],
                             &cl_names[fz]);
                }
            }
        }

        let _f = fstream.quit();

        Ok(())
    } else {
        let _f = fstream.quit();
        println!("User login credentals were incorrect");
        Ok(())
    }
}

fn main() {

    let mut _should_ls = false;
    let mut dry_run = false;

    for ar in env::args() {
        if ar.contains("-dr") {
            dry_run = true;
        }
        println!("Arg {}", ar);
    }

    // TODO ls command

    println!("\r Loading configs...");

    let configs = load_configs().unwrap();

    for con in configs {
        let _d = download_from_site(con, dry_run);
    }
}
<commit_msg>more args<commit_after>extern crate ftp;
extern crate regex;
extern crate openssl;

use std::env;
use std::fs;
use std::fs::File;
use std::io::prelude::*;
use std::fs::OpenOptions;
use std::io::BufWriter;
use ftp::FtpStream;
// use openssl::ssl::*;

struct DownloadableFile {
    client_dir: String,
    server_dir: String,
    filename: String,
    clientfile_namescheme: String,
}

struct DownRequest {
    host: String,
    user: String,
    pass: String,
    remote_files: Vec<DownloadableFile>,
}

/// Makes a directory specified
fn mk_dir(d: &str) -> std::io::Result<()> {
    try!(fs::create_dir_all(d));
    Ok(())
}

/// Breaks down the config given a String of the config file's contents
fn break_conf(b: &mut String) -> Option<DownRequest> {

    /// Find line and get the data from it, if there isn't data to get, None is returned
    fn break_line(input: &mut String, line: &str) -> Option<String> {
        if input.contains(line) {
            let loca = input.find(line).unwrap().checked_add(line.len()).unwrap();
            let y = &input[loca..];

            let locb = y.find(";").unwrap();
            Some(y[..locb].trim().to_string())
        } else {
            None
        }
    }
    // Make sure we won't get an unexpected None
    if b.contains("host:") && b.contains("user:") && b.contains("password:") &&
       b.contains("remoteFiles:") {

        /// Breaks down the remoteFile: line specificly since it's kinda special in layout
        fn break_remotefile(input: &mut String) -> Option<Vec<DownloadableFile>> {

            let start =
                input.find("remoteFiles:").unwrap().checked_add("remoteFiles:".len()).unwrap();
            let inp = &input[start..];
            let tinp = &inp[..inp.rfind(";").unwrap().checked_sub(";".len()).unwrap()];
            // let ttinp = &tinp[..tinp.rfind("]").unwrap().checked_sub("]".len()).unwrap()];

            let why = &tinp[tinp.find("[").unwrap().checked_add("[".len()).unwrap()..];
            let files: Vec<&str> = why.split(',').collect();
            let mut f: Vec<DownloadableFile> = Vec::new();

            println!("There are {} entries from this config to download",
                     files.len());

            for file in files {

                if file.contains("remoteDir:") && file.contains("localDir:") &&
                   file.contains("name:") {
                    let a: &mut String = &mut file.to_string();
                    f.push(DownloadableFile {
                        client_dir: break_line(a, "localDir:").unwrap(),
                        server_dir: break_line(a, "remoteDir:").unwrap(),
                        filename: break_line(a, "name:").unwrap(),
                        clientfile_namescheme: break_line(a, "nameToSaveAs:")
                            .unwrap_or(break_line(a, "name:").unwrap()),
                    });
                } else {}

            }

            if f.len() > 0 {
                Some(f)
            } else {
                println!("No files found to download or check on in this config. Check your \
                          config.");
                None
            }

        }

        let temp = DownRequest {
            host: break_line(b, "host:").unwrap(),
            user: break_line(b, "user:").unwrap(),
            pass: break_line(b, "password:").unwrap(),
            remote_files: break_remotefile(b).unwrap(),
        };

        Some(temp)
    } else {
        // If we would there's no point
        None
    }

}

/// Loads all configs into the folder
fn load_configs() -> std::io::Result<Vec<DownRequest>> {

    if mk_dir("./configs").is_ok() {
        println!("Made the dir needed");
    } // make directory

    let config_dir = fs::read_dir("./configs/").unwrap(); //read all files in dir, and expand them
    let mut but_two_m8 = fs::read_dir("./configs/").unwrap();
    let mut numb_in_folder: u8 = 0;
    let mut configs = Vec::new();

    for f in config_dir {
        // for all files f in the directory open them to file, and save the contained string

        numb_in_folder += 1;
        let name = but_two_m8.next();
        let mut file = try!(File::open(try!(f).path()));
        let mut buff = String::new();

        try!(file.read_to_string(&mut buff));
        let temcon = break_conf(&mut buff); // send buff off to be broken down

        if temcon.is_some() {
            // Check to make sure we didn't get nothing.
            configs.push(temcon.unwrap());
            println!("Config \"{}\" loaded successfully!",
                     name.unwrap().unwrap().file_name().to_str().unwrap());
        } else {
            println!("Config \"{}\" couldn't be loaded.",
                     name.unwrap().unwrap().file_name().to_str().unwrap());
        }

    }
    println!("There were {} configs to load!", numb_in_folder);
    Ok(configs)
}

/// Downloads files from a DownRequest
fn download_from_site(c: DownRequest, dr: bool) -> std::io::Result<()> {
    // TODO ftps support
    let host: String;
    let port: u16;
    if c.host.contains(":") {
        let sp: Vec<&str> = c.host.split(':').collect();
        host = sp[0].trim().to_string();
        port = sp[1].trim().parse().unwrap();

    } else {
        host = c.host;
        port = 21
    }

    println!("Downloading files from \"{}:{}\"", host, port);

    let mut fstream = FtpStream::connect((host.as_str(), port)).unwrap();

    if fstream.login(&c.user.as_str(), &c.pass.as_str()).is_ok() {

        println!("Connected to server, and logged in successfully");

        for f in c.remote_files {
            /// prints the print_progress from a usize from 0 - 100
            fn print_progress(per_done: usize) {
                let outa = per_done.checked_mul(4).unwrap().checked_div(10).unwrap();
                let mut t = 0;
                let mut pbar: String = "[".to_string();
                while t < 40 {
                    if outa < t {
                        pbar.push_str(" ")
                    } else {
                        pbar.push_str("=")
                    }

                    t = t + 1;
                }
                pbar.push_str("]");

                print!("\r{} : {}%", pbar, per_done);
            }

            let mut to_download: Vec<String> = Vec::new();
            let mut cl_names: Vec<String>;
            let _cd = fstream.cwd(&f.server_dir.as_str());

            if f.filename.contains("(*)") {
                let all_in_dir: Vec<String> = fstream.nlst(None).unwrap();
                let spieces_to_check: Vec<&str> = f.filename.split("(*)").collect();
                let cpieces_to_check: Vec<&str> = f.clientfile_namescheme.split("(*)").collect();

                for sf in all_in_dir {

                    let mut check_match = true;

                    while check_match {
                        for p in &spieces_to_check {
                            if !sf.contains(p) {
                                check_match = false;
                            }
                        }
                        break;
                    }
                    if check_match {
                        to_download.push(sf);
                    }
                }

                if f.filename.contains(f.clientfile_namescheme.as_str()) &&
                   f.filename.len() == f.clientfile_namescheme.len() {
                    cl_names = to_download.clone();
                } else {
                    cl_names = Vec::new();

                    if spieces_to_check.len() == cpieces_to_check.len() {
                        for n in &to_download {

                            let mut inv_pieces: Vec<&str> = Vec::new();
                            let mut cfn: String = "".to_string();
                            inv_pieces.push(n.as_str());
                            for piece in &spieces_to_check {
                                let mut temp: Vec<&str> = Vec::new();
                                for a in inv_pieces {
                                    if a.contains(piece) {
                                        let t: Vec<&str> = a.split(piece).collect();
                                        for tt in t {
                                            temp.push(tt);
                                        }
                                    } else {
                                        temp.push(a);
                                    }
                                }
                                inv_pieces = temp;
                            }

                            for x in 0..inv_pieces.len() {
                                if x > 0 {
                                    cfn.push_str(cpieces_to_check[x - 1])
                                }
                                cfn.push_str(inv_pieces[x]);
                            }

                            cl_names.push(cfn);
                        }
                    } else {
                        println!("Can't download files. The client and server name must have the \
                                  same number of (*)!");
                    }
                }

                println!("{} files matching \"{}\"", &to_download.len(), &f.filename);

            } else {
                cl_names = Vec::new();
                cl_names.push(f.clientfile_namescheme);
                to_download.push(f.filename);
            }

            for fz in 0..cl_names.len() {
                let dir = &f.client_dir.as_str().clone();
                let _md = mk_dir(dir); // Make Client dir

                /// Checks to see if the file is downloaded
                /// Takes a local file with it's path and the remote filee's byte size in usize
                fn is_downloaded(fileandpath: &String, rsz: &usize) -> Option<bool> {
                    let mdata = fs::metadata(fileandpath);
                    if mdata.is_ok() {

                        let lsz = mdata.unwrap().len() as usize;
                        if &lsz == rsz { Some(true) } else { Some(false) }
                    } else {
                        None
                    }
                }
                if dr == false {
                    let rsize = fstream.size(&to_download[fz].as_str()).unwrap();

                    let mut fnm = "".to_string();
                    fnm.push_str(dir);
                    fnm.push_str("/");
                    fnm.push_str(&cl_names[fz].as_str());

                    println!("Downloading \"{}\"", to_download[fz]);

                    if !is_downloaded(&fnm, &rsize.unwrap()).unwrap_or(false) {

                        // Make local file
                        let _tt = fstream.transfer_type(::ftp::types::FileType::Binary);

                        let _result = fstream.retr(&to_download[fz].as_str(), |stream| {
                            let mut buf = [0; 4096];
                            let mut flnm = "".to_string();
                            flnm.push_str(dir);
                            flnm.push_str("/");
                            flnm.push_str(&cl_names[fz].as_str());

                            let mut file = File::create(flnm).unwrap();
                            let mut lsize: usize = 0;

                            loop {
                                match stream.read(&mut buf) {
                                    Ok(0) => break,
                                    Ok(n) => {
                                        file.write_all(&buf[0..n]).unwrap();
                                        lsize += n;
                                    }
                                    Err(_err) => break,
                                };
                                print_progress(((lsize.checked_mul(100).unwrap())
                                    .checked_div(rsize.unwrap())
                                    .unwrap()));
                            }
                            print!("\r\n");
                            Ok(())
                        });
                    } else {
                        println!("File is already downloaded");
                    }
                } else {
                    println!("Would be downloading {} and saving as {}",
                             &to_download[fz],
                             &cl_names[fz]);
                }
            }
        }

        let _f = fstream.quit();

        Ok(())
    } else {
        let _f = fstream.quit();
        println!("User login credentals were incorrect");
        Ok(())
    }
}

// Adds a file to downlaod to a config
fn add_to_file(mut file: Vec<String>) -> std::io::Result<()> {
    // TODO Catch errors and check inputs
    if file.len() == 4 {
        let g = file[3].clone();
        file.push(g);
    }
    let mut name = "./configs/".to_string();
    let t = file[0].clone();
    name.push_str(t.as_str());
    let mut b = "".to_string();
    let mut _a = File::open(&name).unwrap();
    let __ = _a.read_to_string(&mut b);
    let mut _f = OpenOptions::new().write(true).truncate(true).open(name).unwrap();
    let mut _w = BufWriter::new(_f);
    let _s1: &str;
    let _s2: &str;

    let (_s1, _s2) = b.split_at(b.rfind("}").unwrap().checked_add("}".len()).unwrap());

    println!("Writing to config");

    let _ =
        _w.write_all(format!("{},\r\n{{\r\n  remoteDir: {};\r\n  localDir: {};\r\n  name: \
                              {};\r\n  nameToSaveAs: {};\r\n}}{}",
                             _s1,
                             file[1],
                             file[2],
                             file[3],
                             file[4],
                             _s2)
            .as_bytes());
    Ok(())
}

fn main() {

    let mut _should_ls = false;
    let mut dry_run = false;
    let mut should_add = false;
    let mut add_to_config: Vec<String> = Vec::new();
    let ag: Vec<String> = env::args().collect();

    for x in 0..ag.len() {
        if ag[x].contains("-dr") {
            dry_run = true;
        }
        if ag[x].contains("-af") {
            if (x + 4) < ag.len() {
                should_add = true;
                add_to_config.push(ag[x + 1].clone());
                add_to_config.push(ag[x + 2].clone());
                add_to_config.push(ag[x + 3].clone());
                add_to_config.push(ag[x + 4].clone());
                if x + 5 < ag.len() {
                    add_to_config.push(ag[x + 5].clone());
                }
            } else {
                println!("Config name, client and server directory, and server filename must be \
                          supplied");
            }
        }
    }

    if should_add {
        let _ = add_to_file(add_to_config);
    }

    // TODO ls command
    println!("\rLoading configs...");

    let configs = load_configs().unwrap();

    for con in configs {
        let _d = download_from_site(con, dry_run);
    }
}
<|endoftext|>


<commit_before>pub extern crate rusty_sword;
use rusty_sword::*;

fn main() {
    // To avoid lock contention for this group of objects, we'll follow the rule:
    // - You must have a lock on floor before trying to lock anything else
    // - You must unlock all other locks before (or when) floor gets unlocked
    let floor        = Arc::new(Mutex::new(Floor::new(60, 30)));
    let player       = Arc::new(Mutex::new(Player::new(Coord::new(30, 15))));
    let dirty_coords = Arc::new(Mutex::new(Vec::<Coord>::new()));
    let monsters     = Arc::new(Mutex::new(Vec::<Monster>::new()));

    // To avoid lock contention, we'll follow the rule:
    // - stop should be locked only when no other objects are locked
    let stop = Arc::new(Mutex::new(false));

    // Render Thread
    let render_thread = {
        let stop = stop.clone();
        let floor = floor.clone();
        let player = player.clone();
        let dirty_coords = dirty_coords.clone();
        let monsters = monsters.clone();
        spawn(move || { render_loop(stop, floor, player, dirty_coords, monsters) } )
    };

    // Sound Thread
    let (sound_tx, sound_rx) = mpsc::channel::<&str>();
    let sound_thread = {
        let stop = stop.clone();
        spawn(move || { sound_loop(stop, sound_rx) } )
    };

    // Game Loop
    let mut quit = false;
    let mut astdin = async_stdin();
    let mut rng = rand::thread_rng();
    let mut spawn_timer = Timer::from_millis(1000);
    let mut last_instant = Instant::now();
    loop {
        sleep(Duration::from_millis(10));
        if quit {
            sleep(Duration::from_millis(50));
            *stop.lock().unwrap() = true;
        }
        {
            if *stop.lock().unwrap() {
                break;
            }
        }
        // Lock floor first!
        let floor = floor.lock().unwrap();
        let mut player = player.lock().unwrap();
        let mut dirty_coords = dirty_coords.lock().unwrap();
        let mut monsters = monsters.lock().unwrap();

        let current_instant = Instant::now();
        let delta = current_instant - last_instant;

        // Player moves?
        let mut player_moved = false;
        let mut bytebuf : [u8; 1] = [0];
        while let Ok(amount) = astdin.read(&mut bytebuf) {
            if amount == 1 {
                match bytebuf[0] {
                    27|b'q' => {
                        quit = true;
                    },
                    _ => {
                        if let Some(direction) = byte_to_direction(bytebuf[0]) {
                            player_moved = player.travel(direction, &floor, &mut dirty_coords);
                        }
                    },
                }
            } else {
                break;
            }
        }

        // Update monster timers
        for monster in monsters.iter_mut() {
            monster.move_timer.update(delta);
        }

        // Monsters move?
        if !player_moved {
            for monster in monsters.iter_mut() {
                monster.try_travel(player.coord, &mut dirty_coords);
            }
        }

        // Did a monster die?
        let num_monsters = monsters.len();
        monsters.retain(|monster| monster.coord != player.sword_coord);
        let num_killed = num_monsters - monsters.len();
        if num_killed > 0 {
            player.score += num_killed as u64;
            sound_tx.send("monster_dies").unwrap();
        }

        // Spawn a new monster!
        spawn_timer.update(delta);
        if spawn_timer.ready {
            spawn_timer = Timer::from_millis(sample(&mut rng, 1000..5000, 1)[0]);
            let to_coord = Coord::new(
                sample(&mut rng, 1..59, 1)[0],
                sample(&mut rng, 1..29, 1)[0],
            );
            if to_coord != player.coord {
                monsters.push(Monster::new(to_coord, &mut rng));
                sound_tx.send("monster_spawns").unwrap();
            }
        }

        // Did the player die?
        if monsters.iter().any(|monster| monster.coord == player.coord) {
            quit = true;
            sound_tx.send("player_dies").unwrap();
        }

        last_instant = current_instant;
    }

    // Wait for other threads to stop before exiting
    render_thread.join().unwrap();
    println!("Thanks for playing!");
    sound_thread.join().unwrap();
}

<commit_msg>Simpler breaking out of the game loop.<commit_after>pub extern crate rusty_sword;
use rusty_sword::*;

fn main() {
    // To avoid lock contention for this group of objects, we'll follow the rule:
    // - You must have a lock on floor before trying to lock anything else
    // - You must unlock all other locks before (or when) floor gets unlocked
    let floor        = Arc::new(Mutex::new(Floor::new(60, 30)));
    let player       = Arc::new(Mutex::new(Player::new(Coord::new(30, 15))));
    let dirty_coords = Arc::new(Mutex::new(Vec::<Coord>::new()));
    let monsters     = Arc::new(Mutex::new(Vec::<Monster>::new()));

    // To avoid lock contention, we'll follow the rule:
    // - stop should be locked only when no other objects are locked
    let stop = Arc::new(Mutex::new(false));

    // Render Thread
    let render_thread = {
        let stop = stop.clone();
        let floor = floor.clone();
        let player = player.clone();
        let dirty_coords = dirty_coords.clone();
        let monsters = monsters.clone();
        spawn(move || { render_loop(stop, floor, player, dirty_coords, monsters) } )
    };

    // Sound Thread
    let (sound_tx, sound_rx) = mpsc::channel::<&str>();
    let sound_thread = {
        let stop = stop.clone();
        spawn(move || { sound_loop(stop, sound_rx) } )
    };

    // Game Loop
    let mut quit = false;
    let mut astdin = async_stdin();
    let mut rng = rand::thread_rng();
    let mut spawn_timer = Timer::from_millis(1000);
    let mut last_instant = Instant::now();
    loop {
        sleep(Duration::from_millis(10));
        if quit {
            sleep(Duration::from_millis(50));
            *stop.lock().unwrap() = true;
            break;
        }
        // Lock floor first!
        let floor = floor.lock().unwrap();
        let mut player = player.lock().unwrap();
        let mut dirty_coords = dirty_coords.lock().unwrap();
        let mut monsters = monsters.lock().unwrap();

        let current_instant = Instant::now();
        let delta = current_instant - last_instant;

        // Player moves?
        let mut player_moved = false;
        let mut bytebuf : [u8; 1] = [0];
        while let Ok(amount) = astdin.read(&mut bytebuf) {
            if amount == 1 {
                match bytebuf[0] {
                    27|b'q' => {
                        quit = true;
                    },
                    _ => {
                        if let Some(direction) = byte_to_direction(bytebuf[0]) {
                            player_moved = player.travel(direction, &floor, &mut dirty_coords);
                        }
                    },
                }
            } else {
                break;
            }
        }

        // Update monster timers
        for monster in monsters.iter_mut() {
            monster.move_timer.update(delta);
        }

        // Monsters move?
        if !player_moved {
            for monster in monsters.iter_mut() {
                monster.try_travel(player.coord, &mut dirty_coords);
            }
        }

        // Did a monster die?
        let num_monsters = monsters.len();
        monsters.retain(|monster| monster.coord != player.sword_coord);
        let num_killed = num_monsters - monsters.len();
        if num_killed > 0 {
            player.score += num_killed as u64;
            sound_tx.send("monster_dies").unwrap();
        }

        // Spawn a new monster!
        spawn_timer.update(delta);
        if spawn_timer.ready {
            spawn_timer = Timer::from_millis(sample(&mut rng, 1000..5000, 1)[0]);
            let to_coord = Coord::new(
                sample(&mut rng, 1..59, 1)[0],
                sample(&mut rng, 1..29, 1)[0],
            );
            if to_coord != player.coord {
                monsters.push(Monster::new(to_coord, &mut rng));
                sound_tx.send("monster_spawns").unwrap();
            }
        }

        // Did the player die?
        if monsters.iter().any(|monster| monster.coord == player.coord) {
            quit = true;
            sound_tx.send("player_dies").unwrap();
        }

        last_instant = current_instant;
    }

    // Wait for other threads to stop before exiting
    render_thread.join().unwrap();
    println!("Thanks for playing!");
    sound_thread.join().unwrap();
}

<|endoftext|>


<commit_before>#![feature(libc)]
extern crate libc;
use std::ffi;

extern crate rustwlc;

use rustwlc::types;
use rustwlc::types::*;
use rustwlc::handle::{WlcView, WlcOutput};
use rustwlc::interface::*;
use rustwlc::input::{pointer, keyboard};

/*
struct CompositorAction {
    view: WlcView,
    grab: Point,
    edges: u32
}

static mut compositor: CompositorAction = CompositorAction {
    view: WlcView(0),
    grab: Point{ x: 0, y: 0},
    edges: 0
};
*/
fn main() {
    let interface: WlcInterface = WlcInterface {
        output: OutputInterface {
            created: Some(output_created),
            destroyed: Some(output_destroyed),
            focus: Some(output_focus),
            resolution: Some(output_resolution),

            render: OutputRenderInterface {
                pre: Some(output_render_pre),
                post: Some(output_render_post)
            }
        },
        view: ViewInterface {
            created: Some(view_created),
            destroyed: Some(view_destroyed),
            focus: Some(view_focus),
            move_to_output: Some(view_move_to_output),
            request: RequestInterface {
                geometry: Some(view_request_geometry),
                state: Some(view_request_state),
                move_: Some(view_request_move),
                resize: Some(view_request_resize),
                render: ViewRenderInterface {
                    pre: Some(view_request_render_pre),
                    post: Some(view_request_render_post)
                }
            }
        },
        keyboard: KeyboardInterface {
            key: Some(keyboard_key)
        },
        pointer: PointerInterface {
            button: Some(pointer_button),
            scroll: Some(pointer_scroll),
            motion: Some(pointer_motion)
        },
        touch: TouchInterface {
            touch: Some(touch_touch)
        },
        compositor: CompositorInterface {
            ready: Some(compositor_ready)
        },
        input: InputInterface {
            created: Some(input_created),
            destroyed: Some(input_destroyed)
        }
    };

    if !rustwlc::init(interface) {
        panic!("Unable to initialize wlc!");
    }
    rustwlc::run_wlc();
}

// Important rendering functions copied from wlc/example/example.c

fn start_interactive_action(view: WlcView, origin: Point) -> bool {
    true
}

fn stop_interactive_action() {

}

fn start_interactive_move(view: WlcView, origin: Point) {

}

fn start_interactive_resize(view: WlcView, edges: u32, origin: Point) {

}

fn get_topmost_view(output: WlcOutput, offset: Size) {

}

/// From example.c:
/// very simple layout function
/// you probably don't want to layout certain type of windows in wm
fn render_output(output: WlcOutput) {
    use std::cmp;
    let resolution = output.get_resolution();
    let views = output.get_views();
    println!("Rendering {} views for {} (resolution = {:?})", views.len(), output.get_name(), resolution);

    if views.len() == 0 { println!("Didn't find any views to render :/"); }

    for view in views {
        println!("Setting {:?}", view);
        println!("\tIts type: {}", view.get_type());
        println!("\tIts output: {}", view.get_output().get_name());
        println!("\tIts geometry: {:?}", view.get_geometry());
        println!("\tIts state: {}", view.get_state());
        println!("\tIts parent: {:?}", view.get_parent());
        println!("\tIts title: {}", view.get_title());
        // get_class doesn't work but maybe it's not supposed to
        //println!("\tIts class: {}", view.get_class());
        view.set_geometry(0,
                          &Geometry {
                              size: Size {
                                  w: 0 as u32,
                                  h: 0 as u32
                              },
                              origin: Point {
                                  x: resolution.w as i32,
                                  y: resolution.h as i32
                              }
                          });
        println!("Attempted to set geometry, got {:?}", view.get_geometry());
    }

    /*
    let mut toggle = false;
    let mut y = 0u32;
//    use std::cmp;

    let w: u32 = resolution.w as u32 / 2u32;
    let h: u32 = resolution.h as u32 / cmp::max((1u32 + views.len() as u32) / 2u32, 1);

    for view in views {
        let g = Geometry {
            size: Size {
                w: if toggle { w } else { 0 },
                h: y
            },
            origin: Point {
                x: if !toggle { resolution.w as i32 } else { w as i32 },
                y: h as i32
            }
        };
        view.set_geometry(0, g);
        toggle = !toggle;
        y = y + if !toggle { h } else { 0 };
    }*/
}

// Hook up basic callbacks

extern fn output_created(output: WlcOutput) -> bool {
    println!("output_created: {:?}: {}", output, output.get_name());
    return true;
}

extern fn output_destroyed(output: WlcOutput) {
    println!("output_destroyed");
}

extern fn output_focus(output: WlcOutput, focused: bool) {
    println!("output_focus: {}", focused);
}

extern fn output_resolution(output: WlcOutput,
                            old_size_ptr: &Size, new_size_ptr: &Size) {
    println!("output_resolution: {:?} from  {:?} to {:?}",
             output, *old_size_ptr, *new_size_ptr);
}

extern fn output_render_pre(output: WlcOutput) {
    //println!("output_render_pre");
}

extern fn output_render_post(output: WlcOutput) {
    //println!("output_render_post");
}

extern fn view_created(view: WlcView) -> bool {
    println!("view_created: {:?}", view);
    let output = view.get_output();
    view.set_mask(output.get_mask());
    view.bring_to_front();
    view.focus();
    render_output(output);
    true
}

extern fn view_destroyed(view: WlcView) {
    println!("view_destroyed: {:?}", view);
    render_output(view.get_output());
}

extern fn view_focus(current: WlcView, focused: bool) {
    println!("view_focus: {:?} {}", current, focused);
    current.set_state(ViewState::Activated, focused);
}

extern fn view_move_to_output(current: WlcView, q1: WlcView, q2: WlcView) {
    println!("view_move_to_output: {:?}, {:?}, {:?}", current, q1, q2);
}

extern fn view_request_geometry(view: WlcView, geometry: &Geometry) {
    println!("view_request_geometry: {:?} wants {:?}", view, geometry);
    view.set_geometry(0, geometry);
    render_output(view.get_output());
}

extern fn view_request_state(view: WlcView, state: ViewState, handled: bool) {
    view.set_state(state, handled);
}

extern fn view_request_move(view: WlcView, dest: &Point) {
    //println!("view_request_move: to {}, start interactive mode.", *dest);
}

extern fn view_request_resize(view: WlcView, edge: ResizeEdge, location: &Point) {
    println!("view_request_resize: size {:?}, to {}, start interactive mode.",
             edge, *location);
}

extern fn view_request_render_pre(view: WlcView) {
}

extern fn view_request_render_post(view: WlcView) {
}

extern fn keyboard_key(view: WlcView, time: u32, mods_ptr: &KeyboardModifiers,
                       key: u32, state: KeyState) -> bool {
    use std::process::{Command};
    println!("keyboard_key: time {}, mods {:?}, key {:?}, state {:?}",
             time, &*mods_ptr, key, state);
    if state == KeyState::Pressed { return false; }
    if key == 67 {
        println!("Preparing to open the terminal...");
        let mut child = Command::new("/bin/weston-terminal").spawn()
            .unwrap_or_else(|e| { println!("Error spawning child: {}", e); panic!("1") });
    }
    false
}

extern fn pointer_button(view: WlcView, button: u32, mods_ptr: &KeyboardModifiers,
                         key: u32, state: ButtonState, point_ptr: &Point) -> bool {
    println!("pointer_button: pressed {} at {}", key, *point_ptr);
    if state == ButtonState::Pressed {
        view.focus();
    }
    false
}

extern fn pointer_scroll(view: WlcView, button: u32, mods_ptr: &KeyboardModifiers,
                  axis: ScrollAxis, heights: [u64; 2]) -> bool {
    println!("pointer_scroll");
    false
}

extern fn pointer_motion(view: WlcView, time: u32, point: &Point) {
    pointer::set_position(point);
}

extern fn touch_touch(view: WlcView, time: u32, mods_ptr: &KeyboardModifiers,
               touch: TouchType, key: i32, point_ptr: &Point) -> bool {
    false
}

extern fn compositor_ready() {
    println!("Preparing compositor!");
}

extern fn input_created(device: &LibinputDevice) -> bool {
    println!("input_created");
    false
}

extern fn input_destroyed(device: &LibinputDevice) {
    println!("input_destroyed");
}
<commit_msg>Removed libc library imports from way-cooler (no more foreign function calls in Way-Cooler code, so it's unneccessary)<commit_after>extern crate rustwlc;

use rustwlc::types;
use rustwlc::types::*;
use rustwlc::handle::{WlcView, WlcOutput};
use rustwlc::interface::*;
use rustwlc::input::{pointer, keyboard};

/*
struct CompositorAction {
    view: WlcView,
    grab: Point,
    edges: u32
}

static mut compositor: CompositorAction = CompositorAction {
    view: WlcView(0),
    grab: Point{ x: 0, y: 0},
    edges: 0
};
*/
fn main() {
    let interface: WlcInterface = WlcInterface {
        output: OutputInterface {
            created: Some(output_created),
            destroyed: Some(output_destroyed),
            focus: Some(output_focus),
            resolution: Some(output_resolution),

            render: OutputRenderInterface {
                pre: Some(output_render_pre),
                post: Some(output_render_post)
            }
        },
        view: ViewInterface {
            created: Some(view_created),
            destroyed: Some(view_destroyed),
            focus: Some(view_focus),
            move_to_output: Some(view_move_to_output),
            request: RequestInterface {
                geometry: Some(view_request_geometry),
                state: Some(view_request_state),
                move_: Some(view_request_move),
                resize: Some(view_request_resize),
                render: ViewRenderInterface {
                    pre: Some(view_request_render_pre),
                    post: Some(view_request_render_post)
                }
            }
        },
        keyboard: KeyboardInterface {
            key: Some(keyboard_key)
        },
        pointer: PointerInterface {
            button: Some(pointer_button),
            scroll: Some(pointer_scroll),
            motion: Some(pointer_motion)
        },
        touch: TouchInterface {
            touch: Some(touch_touch)
        },
        compositor: CompositorInterface {
            ready: Some(compositor_ready)
        },
        input: InputInterface {
            created: Some(input_created),
            destroyed: Some(input_destroyed)
        }
    };

    if !rustwlc::init(interface) {
        panic!("Unable to initialize wlc!");
    }
    rustwlc::run_wlc();
}

// Important rendering functions copied from wlc/example/example.c

fn start_interactive_action(view: WlcView, origin: Point) -> bool {
    true
}

fn stop_interactive_action() {

}

fn start_interactive_move(view: WlcView, origin: Point) {

}

fn start_interactive_resize(view: WlcView, edges: u32, origin: Point) {

}

fn get_topmost_view(output: WlcOutput, offset: Size) {

}

/// From example.c:
/// very simple layout function
/// you probably don't want to layout certain type of windows in wm
fn render_output(output: WlcOutput) {
    use std::cmp;
    let resolution = output.get_resolution();
    let views = output.get_views();
    println!("Rendering {} views for {} (resolution = {:?})", views.len(), output.get_name(), resolution);

    if views.len() == 0 { println!("Didn't find any views to render :/"); }

    for view in views {
        println!("Setting {:?}", view);
        println!("\tIts type: {}", view.get_type());
        println!("\tIts output: {}", view.get_output().get_name());
        println!("\tIts geometry: {:?}", view.get_geometry());
        println!("\tIts state: {}", view.get_state());
        println!("\tIts parent: {:?}", view.get_parent());
        println!("\tIts title: {}", view.get_title());
        // get_class doesn't work but maybe it's not supposed to
        //println!("\tIts class: {}", view.get_class());
        view.set_geometry(0,
                          &Geometry {
                              size: Size {
                                  w: 0 as u32,
                                  h: 0 as u32
                              },
                              origin: Point {
                                  x: resolution.w as i32,
                                  y: resolution.h as i32
                              }
                          });
        println!("Attempted to set geometry, got {:?}", view.get_geometry());
    }

    /*
    let mut toggle = false;
    let mut y = 0u32;
//    use std::cmp;

    let w: u32 = resolution.w as u32 / 2u32;
    let h: u32 = resolution.h as u32 / cmp::max((1u32 + views.len() as u32) / 2u32, 1);

    for view in views {
        let g = Geometry {
            size: Size {
                w: if toggle { w } else { 0 },
                h: y
            },
            origin: Point {
                x: if !toggle { resolution.w as i32 } else { w as i32 },
                y: h as i32
            }
        };
        view.set_geometry(0, g);
        toggle = !toggle;
        y = y + if !toggle { h } else { 0 };
    }*/
}

// Hook up basic callbacks

extern fn output_created(output: WlcOutput) -> bool {
    println!("output_created: {:?}: {}", output, output.get_name());
    return true;
}

extern fn output_destroyed(output: WlcOutput) {
    println!("output_destroyed");
}

extern fn output_focus(output: WlcOutput, focused: bool) {
    println!("output_focus: {}", focused);
}

extern fn output_resolution(output: WlcOutput,
                            old_size_ptr: &Size, new_size_ptr: &Size) {
    println!("output_resolution: {:?} from  {:?} to {:?}",
             output, *old_size_ptr, *new_size_ptr);
}

extern fn output_render_pre(output: WlcOutput) {
    //println!("output_render_pre");
}

extern fn output_render_post(output: WlcOutput) {
    //println!("output_render_post");
}

extern fn view_created(view: WlcView) -> bool {
    println!("view_created: {:?}", view);
    let output = view.get_output();
    view.set_mask(output.get_mask());
    view.bring_to_front();
    view.focus();
    render_output(output);
    true
}

extern fn view_destroyed(view: WlcView) {
    println!("view_destroyed: {:?}", view);
    render_output(view.get_output());
}

extern fn view_focus(current: WlcView, focused: bool) {
    println!("view_focus: {:?} {}", current, focused);
    current.set_state(ViewState::Activated, focused);
}

extern fn view_move_to_output(current: WlcView, q1: WlcView, q2: WlcView) {
    println!("view_move_to_output: {:?}, {:?}, {:?}", current, q1, q2);
}

extern fn view_request_geometry(view: WlcView, geometry: &Geometry) {
    println!("view_request_geometry: {:?} wants {:?}", view, geometry);
    view.set_geometry(0, geometry);
    render_output(view.get_output());
}

extern fn view_request_state(view: WlcView, state: ViewState, handled: bool) {
    view.set_state(state, handled);
}

extern fn view_request_move(view: WlcView, dest: &Point) {
    //println!("view_request_move: to {}, start interactive mode.", *dest);
}

extern fn view_request_resize(view: WlcView, edge: ResizeEdge, location: &Point) {
    println!("view_request_resize: size {:?}, to {}, start interactive mode.",
             edge, *location);
}

extern fn view_request_render_pre(view: WlcView) {
}

extern fn view_request_render_post(view: WlcView) {
}

extern fn keyboard_key(view: WlcView, time: u32, mods_ptr: &KeyboardModifiers,
                       key: u32, state: KeyState) -> bool {
    use std::process::{Command};
    println!("keyboard_key: time {}, mods {:?}, key {:?}, state {:?}",
             time, &*mods_ptr, key, state);
    if state == KeyState::Pressed { return false; }
    if key == 67 {
        println!("Preparing to open the terminal...");
        let mut child = Command::new("/bin/weston-terminal").spawn()
            .unwrap_or_else(|e| { println!("Error spawning child: {}", e); panic!("1") });
    }
    false
}

extern fn pointer_button(view: WlcView, button: u32, mods_ptr: &KeyboardModifiers,
                         key: u32, state: ButtonState, point_ptr: &Point) -> bool {
    println!("pointer_button: pressed {} at {}", key, *point_ptr);
    if state == ButtonState::Pressed {
        view.focus();
    }
    false
}

extern fn pointer_scroll(view: WlcView, button: u32, mods_ptr: &KeyboardModifiers,
                  axis: ScrollAxis, heights: [u64; 2]) -> bool {
    println!("pointer_scroll");
    false
}

extern fn pointer_motion(view: WlcView, time: u32, point: &Point) {
    pointer::set_position(point);
}

extern fn touch_touch(view: WlcView, time: u32, mods_ptr: &KeyboardModifiers,
               touch: TouchType, key: i32, point_ptr: &Point) -> bool {
    false
}

extern fn compositor_ready() {
    println!("Preparing compositor!");
}

extern fn input_created(device: &LibinputDevice) -> bool {
    println!("input_created");
    false
}

extern fn input_destroyed(device: &LibinputDevice) {
    println!("input_destroyed");
}
<|endoftext|>