<commit_before>#[macro_use]
extern crate nom;
extern crate xml;

use std::io;
use std::fs::File;

mod parser;

use parser::parse;

#[derive(Debug, PartialEq)]
pub enum TestResult {
    Ok,
    Ignored,
    Failed,
}
#[derive(Debug, PartialEq)]
pub struct Failure<'a>(&'a str, &'a str, &'a str, &'a str);
#[derive(Debug, PartialEq)]
pub struct Test<'a>(&'a str, TestResult);
#[derive(Debug, PartialEq)]
pub struct TestModule<'a>(TestResult, Vec<Test<'a>>, Vec<Failure<'a>>, u32, u32, u32, u32);

fn parse_data<'a, T>(reader: &mut T) -> Vec<u8>
    where T: io::Read + 'a
{
    let mut buffer = Vec::new();

    reader.read_to_end(&mut buffer).expect("Empty input");

    buffer
}

fn format(data: Vec<TestModule>) -> xml::Element {
    let mut output = xml::Element::new("testsuites".into(), None, vec![]);

    for module in data {
        let attr = vec![
            ("failures".into(), None, format!("{}",module.4).into()),
            ("skip".into(), None, format!("{}",module.6).into()),
            ("tests".into(), None, format!("{}",module.1.len()).into()),
        ];
        output.tag(xml::Element::new("testsuite".into(), None, attr));

        for test in module.1 {
            let basename = test.0.rfind("::").map(|i| test.0[1+i..].into()).unwrap_or(test.0);
            let classname = test.0.rfind("::").map(|i| test.0[..i-1].replace("::", ".")).unwrap_or("::".into());

            let attr = vec![
                       ("name".into(), None, basename.into()),
                       ("classname".into(), None, classname.into()),
            ];

            let test_xml = output.tag(xml::Element::new("testcase".into(), None, attr));

            if test.1 == TestResult::Ignored {
                test_xml.tag(xml::Element::new("skipped".into(), None, vec![]));
            } else if test.1 == TestResult::Failed {
                for failure in &module.2 {
                    if failure.0 == test.0 {
                        test_xml.tag(xml::Element::new("failure".into(),
                                                   None,
                                                   vec![
                                    ("message".into(), None, failure.2.into()),
                                    ]))
                            .cdata(failure.3.into());
                        test_xml.tag(xml::Element::new("system-out".into(), None, vec![]))
                            .text(failure.1.into());

                    }
                }
            }
        }
    }

    output
}
///
/// # Example
/// ```
/// assert!(true);
/// ```
fn main() {
    let filename: Option<&str> = None;
    let stdin = io::stdin();

    let string = if let Some(filename) = filename {
        if let Ok(mut file) = File::open(filename) {
            parse_data(&mut file)
        } else {
            parse_data(&mut stdin.lock())
        }
    } else {
        parse_data(&mut stdin.lock())
    };

    let data = parse(&string);

    if let Ok(data) = data {
        let output = format(data);
        println!("<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n{}", output);
    } else {
        println!("Something went wrong{:#?}", data);
    }
}

#[cfg(test)]
mod tests {

    #[test]
    fn test_ok() {
        println!("Oh noes!!");
        assert!(true);
    }
    #[test]
    #[ignore]
    fn test_failing2() {
        println!("Again!!");
        assert_eq!("no", "yes");
    }

    //    #[test]
    //    fn test_failing() {
    //        println!("Oh noes!!");
    //        assert!(false);
    //    }
    //    #[test]
    //    fn test_failing2() {
    //        println!("Again!!");
    //        assert_eq!("no", "yes");
    //    }
}
<commit_msg>Fix off by one errors<commit_after>#[macro_use]
extern crate nom;
extern crate xml;

use std::io;
use std::fs::File;

mod parser;

use parser::parse;

#[derive(Debug, PartialEq)]
pub enum TestResult {
    Ok,
    Ignored,
    Failed,
}
#[derive(Debug, PartialEq)]
pub struct Failure<'a>(&'a str, &'a str, &'a str, &'a str);
#[derive(Debug, PartialEq)]
pub struct Test<'a>(&'a str, TestResult);
#[derive(Debug, PartialEq)]
pub struct TestModule<'a>(TestResult, Vec<Test<'a>>, Vec<Failure<'a>>, u32, u32, u32, u32);

fn parse_data<'a, T>(reader: &mut T) -> Vec<u8>
    where T: io::Read + 'a
{
    let mut buffer = Vec::new();

    reader.read_to_end(&mut buffer).expect("Empty input");

    buffer
}

fn format(data: Vec<TestModule>) -> xml::Element {
    let mut output = xml::Element::new("testsuites".into(), None, vec![]);

    for module in data {
        let attr = vec![
            ("failures".into(), None, format!("{}",module.4).into()),
            ("skip".into(), None, format!("{}",module.6).into()),
            ("tests".into(), None, format!("{}",module.1.len()).into()),
        ];
        output.tag(xml::Element::new("testsuite".into(), None, attr));

        for test in module.1 {
            let (basename, classname) = test.0
                .rfind("::")
                .map(|i| (test.0[2 + i..].into(), test.0[..i].replace("::", ".")))
                .unwrap_or((test.0, "::".into()));

            let attr = vec![
                       ("name".into(), None, basename.into()),
                       ("classname".into(), None, classname.into()),
            ];

            let test_xml = output.tag(xml::Element::new("testcase".into(), None, attr));

            if test.1 == TestResult::Ignored {
                test_xml.tag(xml::Element::new("skipped".into(), None, vec![]));
            } else if test.1 == TestResult::Failed {
                for failure in &module.2 {
                    if failure.0 == test.0 {
                        test_xml.tag(xml::Element::new("failure".into(),
                                                   None,
                                                   vec![
                                    ("message".into(), None, failure.2.into()),
                                    ]))
                            .cdata(failure.3.into());
                        test_xml.tag(xml::Element::new("system-out".into(), None, vec![]))
                            .text(failure.1.into());

                    }
                }
            }
        }
    }

    output
}
///
/// # Example
/// ```
/// assert!(true);
/// ```
fn main() {
    let filename: Option<&str> = None;
    let stdin = io::stdin();

    let string = if let Some(filename) = filename {
        if let Ok(mut file) = File::open(filename) {
            parse_data(&mut file)
        } else {
            parse_data(&mut stdin.lock())
        }
    } else {
        parse_data(&mut stdin.lock())
    };

    let data = parse(&string);

    if let Ok(data) = data {
        let output = format(data);
        println!("<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n{}", output);
    } else {
        println!("Something went wrong{:#?}", data);
    }
}

#[cfg(test)]
mod tests {

    #[test]
    fn test_ok() {
        println!("Oh noes!!");
        assert!(true);
    }
    #[test]
    #[ignore]
    fn test_failing2() {
        println!("Again!!");
        assert_eq!("no", "yes");
    }

    //    #[test]
    //    fn test_failing() {
    //        println!("Oh noes!!");
    //        assert!(false);
    //    }
    //    #[test]
    //    fn test_failing2() {
    //        println!("Again!!");
    //        assert_eq!("no", "yes");
    //    }
}
<|endoftext|>


<commit_before>#![feature(collections)]
#![feature(unicode)]

//modules

mod config;
mod word;

//extern crates

extern crate rand;
extern crate rustc_serialize;
extern crate regex;

//use

use config::*;
use word::*;
use std::io::prelude::*;
//use rustc_serialize::*;    //commented out as it is only used to emit test configs
use std::fs::File;
use rand::Rng;
use rand::distributions::{Weighted, WeightedChoice, IndependentSample};

//static variables

static CONFIG_FILE_NAME: &'static str = "json_sample_config.json";

//functions

fn main() {
    let config: WordGeneratorConfig = load_config(&CONFIG_FILE_NAME);

    //comment other code and uncomment these to emit a new test config
    //let mut file = File::create(&CONFIG_FILE_NAME).unwrap();

    /*match file.write(json::encode(&config).unwrap().as_bytes()) {
        Ok(_) => (),
        Err(err) => panic!("Error writing test config: {}", err),
    }*/

    let mut first_syllable_list : Vec<Weighted<String>> = Vec::new();
    let mut last_syllable_list : Vec<Weighted<String>> = Vec::new();
    let mut normal_syllable_list : Vec<Weighted<String>> = Vec::new();

    //generate weighted lists of syllable configurations in each syllable position

    for syllable in config.syllables {
        let syllable_weighted : Weighted<String> = Weighted{
            weight: syllable.weight as u32,
            item: syllable.string.clone()
        };
        //if the syllable is eligible for all positions
        if !(syllable.only_first_syllable || syllable.only_last_syllable) {
            normal_syllable_list.push(syllable_weighted.clone());
            first_syllable_list.push(syllable_weighted.clone());
            last_syllable_list.push(syllable_weighted.clone());
        }
        //these need to be separate ifs, as marking only first + only last syllable means it can be used for either
        if syllable.only_first_syllable {
            first_syllable_list.push(syllable_weighted.clone());
        }
        if syllable.only_last_syllable {
            last_syllable_list.push(syllable_weighted.clone());
        }

    }

    let mut grapheme_groups : Vec<(String, Vec<Weighted<String>>)> = Vec::new();

    //convert list of graphemes in config into lists of Weighted
    for group in config.graphemes {
        let mut graphemes_converted : Vec<Weighted<String>> = Vec::new();

        graphemes_converted.extend(
            group.graphemes.iter().map(
                |g: &Grapheme| Weighted{weight: g.weight as u32, item: g.string.clone() }
                )
            );
        grapheme_groups.push((group.name.clone(), graphemes_converted));
    }

    let word_factory : WordFactory = WordFactory {
        first_syllable_list : first_syllable_list,
        normal_syllable_list : normal_syllable_list,
        last_syllable_list : last_syllable_list,
        graphemes : grapheme_groups,
        settings : config.settings.clone(),
        rewrites : config.rewrites.clone(),
        rejects : config.rejects.clone(),
    };

    let mut file = File::create(&config.output_settings.output_file).unwrap();

    for _ in 0..config.output_settings.word_count {

        //generate a string of syllables
        // - parse config list of syllables into 3 lists, one for first syllable, one for last, and one for rest

        //apply syllable level rewrites and rejects
        //generate graphemes for each syllable
        //apply grapheme level rewrites and rejects
        //write to file
        let mut word : Word = Word {
                syllables : String::new(),
                graphemes : String::new(),
                syllable_rewrite_history : Vec::new(),
                grapheme_rewrite_history : Vec::new(),
                syllable_rejects : Vec::new(),
                grapheme_rejects : Vec::new()
            };

        word_factory.generate_syllables(&mut word);
        word_factory.rewrite_syllables(&mut word);
        word_factory.mark_syllable_rejects(&mut word);

        word_factory.generate_graphemes(&mut word);
        word_factory.rewrite_graphemes(&mut word);
        word_factory.mark_grapheme_rejects(&mut word);

        match file.write(get_word_syllables(&word).as_bytes()) {
                Err(error) => panic!("error {} writing to file", error),
                Ok(_) => (),
        };
        match file.write("\n".as_bytes()) {
                Err(error) => panic!("error {} writing to file", error),
                Ok(_) => (),
        };
    }
}

fn make_word() -> String {
    let vowels : Vec<Weighted<&str>> = vec![
                                        Weighted {weight: 3, item:"i"},
                                        Weighted {weight: 3, item:"e"},
                                        Weighted {weight: 3, item:"é"}]; //, 'a']; //removed leading 'a's as dictated

    let leading_vowel_chance : f32 = 0.25;
    let syllable_decay_mult : f32 = 0.5;

    let mut current_chance_for_syllable : f32 = 0.75;

    let mut rng = rand::thread_rng();
    let mut word : String = String::new();

    //decide if we'll have a leading vowel
    if rng.gen::<f32>() < leading_vowel_chance {
        word.push_str(&get_random_phoneme(&vowels));
    }
    word.push_str(&get_random_syllable()); //minimum 1 normal syllable

    let mut syllable_loop_iter = rng.gen_iter::<f32>();

    loop {
        let result = syllable_loop_iter.next();
        match result {
            Some(x) => {
                if x < current_chance_for_syllable {
                    word.push_str(&get_random_syllable());
                    current_chance_for_syllable *= syllable_decay_mult;
                } else {
                    break
                }
            }
            None => { break }
        }
    }

    word
}

fn get_random_syllable() -> String {
    let consonants : Vec<Weighted<&str>> = vec![
                                        Weighted {weight: 6, item:"p"},
                                        Weighted {weight: 6, item:"m"},
                                        Weighted {weight: 6, item:"n"},
                                        Weighted {weight: 1, item:"ń"},
                                        Weighted {weight: 6, item:"s"},
                                        Weighted {weight: 1, item:"ś"},
                                        Weighted {weight: 6, item:"t"},
                                        Weighted {weight: 1, item:"d"},
                                        Weighted {weight: 4, item:"r"},
                                        Weighted {weight: 2, item:"ts"},
                                        Weighted {weight: 1, item:"tś"},
                                        Weighted {weight: 2, item:"ps"},
                                        Weighted {weight: 1, item:"pś"},
                                        Weighted {weight: 2, item:"mn"}];

    let vowels : Vec<Weighted<&str>> = vec![
                                        Weighted {weight: 3, item:"i"},
                                        Weighted {weight: 3, item:"e"},
                                        Weighted {weight: 3, item:"é"},
                                        Weighted {weight: 3, item:"a"},
                                        Weighted {weight: 1, item:"ié"},
                                        Weighted {weight: 1, item:"ea"}];

    let mut syllable : String = String::new();

    syllable.push_str(&get_random_phoneme(&consonants));
    syllable.push_str(&get_random_phoneme(&vowels));

    syllable
}

fn get_random_phoneme(values : &Vec<Weighted<&str>>) -> String {

    let mut local_values : Vec<Weighted<&str>> = values.clone();

    let phoneme_selector : WeightedChoice<&str> = WeightedChoice::new(&mut local_values);
    let mut rng = rand::thread_rng();

    String::from_str(phoneme_selector.ind_sample(&mut rng))
}
<commit_msg>removed extraneous code and comments in main.rs<commit_after>#![feature(collections)]
#![feature(unicode)]

//modules

mod config;
mod word;

//extern crates

extern crate rand;
extern crate rustc_serialize;
extern crate regex;

//use

use config::*;
use word::*;
use std::io::prelude::*;
//use rustc_serialize::*;    //commented out as it is only used to emit test configs
use std::fs::File;
use rand::distributions::Weighted;

//static variables

static CONFIG_FILE_NAME: &'static str = "json_sample_config.json";

//functions

fn main() {
    let config: WordGeneratorConfig = load_config(&CONFIG_FILE_NAME);

    //comment other code and uncomment these to emit a new test config
    //let mut file = File::create(&CONFIG_FILE_NAME).unwrap();

    /*match file.write(json::encode(&config).unwrap().as_bytes()) {
        Ok(_) => (),
        Err(err) => panic!("Error writing test config: {}", err),
    }*/

    let mut first_syllable_list : Vec<Weighted<String>> = Vec::new();
    let mut last_syllable_list : Vec<Weighted<String>> = Vec::new();
    let mut normal_syllable_list : Vec<Weighted<String>> = Vec::new();

    //generate weighted lists of syllable configurations in each syllable position

    for syllable in config.syllables {
        let syllable_weighted : Weighted<String> = Weighted{
            weight: syllable.weight as u32,
            item: syllable.string.clone()
        };
        //if the syllable is eligible for all positions
        if !(syllable.only_first_syllable || syllable.only_last_syllable) {
            normal_syllable_list.push(syllable_weighted.clone());
            first_syllable_list.push(syllable_weighted.clone());
            last_syllable_list.push(syllable_weighted.clone());
        }
        //these need to be separate ifs, as marking only first + only last syllable means it can be used for either
        if syllable.only_first_syllable {
            first_syllable_list.push(syllable_weighted.clone());
        }
        if syllable.only_last_syllable {
            last_syllable_list.push(syllable_weighted.clone());
        }

    }

    let mut grapheme_groups : Vec<(String, Vec<Weighted<String>>)> = Vec::new();

    //convert list of graphemes in config into lists of Weighted
    for group in config.graphemes {
        let mut graphemes_converted : Vec<Weighted<String>> = Vec::new();

        graphemes_converted.extend(
            group.graphemes.iter().map(
                |g: &Grapheme| Weighted{weight: g.weight as u32, item: g.string.clone() }
                )
            );
        grapheme_groups.push((group.name.clone(), graphemes_converted));
    }

    let word_factory : WordFactory = WordFactory {
        first_syllable_list : first_syllable_list,
        normal_syllable_list : normal_syllable_list,
        last_syllable_list : last_syllable_list,
        graphemes : grapheme_groups,
        settings : config.settings.clone(),
        rewrites : config.rewrites.clone(),
        rejects : config.rejects.clone(),
    };

    let mut file = File::create(&config.output_settings.output_file).unwrap();

    for _ in 0..config.output_settings.word_count {

        //generate a string of syllables
        // - parse config list of syllables into 3 lists, one for first syllable, one for last, and one for rest

        //apply syllable level rewrites and rejects
        //generate graphemes for each syllable
        //apply grapheme level rewrites and rejects
        //write to file
        let mut word : Word = Word {
                syllables : String::new(),
                graphemes : String::new(),
                syllable_rewrite_history : Vec::new(),
                grapheme_rewrite_history : Vec::new(),
                syllable_rejects : Vec::new(),
                grapheme_rejects : Vec::new()
            };

        word_factory.generate_syllables(&mut word);
        word_factory.rewrite_syllables(&mut word);
        word_factory.mark_syllable_rejects(&mut word);

        word_factory.generate_graphemes(&mut word);
        word_factory.rewrite_graphemes(&mut word);
        word_factory.mark_grapheme_rejects(&mut word);

        match file.write(get_word_graphemes(&word).as_bytes()) {
                Err(error) => panic!("error {} writing to file", error),
                Ok(_) => (),
        };
        match file.write("\n".as_bytes()) {
                Err(error) => panic!("error {} writing to file", error),
                Ok(_) => (),
        };
    }
}
<|endoftext|>


<commit_before>
fn main() {
    println!("hello");
}
<commit_msg>http request test<commit_after>extern crate hyper;

use hyper::client::Client;
use std::io::Read;

fn main() {
    let client = Client::new();

    let mut res = client.get("http://finance.naver.com/item/main.nhn?code=063760").send().unwrap();

    let mut bin_buff = Vec::new();

    res.read_to_end(&mut bin_buff).unwrap();

    println!("{:?}", bin_buff);
}
<|endoftext|>


<commit_before>use bison::*;
use std::env;
use std::fs::File;
use std::io;
use std::io::Read;

mod bison;
mod yacc;

fn main() {
    let input = env::args().skip(1).next().unwrap();
    let yacctext = read_file(&input).unwrap();
    let yacc = yacc::parse_Yacc(&yacctext).unwrap();

    println!("grammar;");

    let start_symbol = yacc.declarations.iter()
                                        .filter_map(|decl| match *decl {
                                            BisonDecl::Start(ident) => Some(ident),
                                            _ => None,
                                        })
                                        .next();

    let mut all_chars = vec![];

    for rule in &yacc.rules {
        let is_pub = start_symbol == Some(rule.nonterminal);
        println!("{}{}: () = {{", if is_pub {"pub "} else {""}, rule.nonterminal.text);

        for alternative in &rule.alternatives {
            let mut string = String::from("  ");
            for symbol in &alternative.symbols {
                match *symbol {
                    Symbol::Ident(ref i) => string.push_str(i.text),
                    Symbol::Character(i) => {
                        let ch = i.chars().skip(1).next().unwrap();
                        string.push('"');
                        string.push(ch);
                        string.push('"');
                        all_chars.push(ch);
                    }
                }
                string.push_str(" ");
            }
            if alternative.symbols.is_empty() {
                string.push_str("() ");
            }
            string.push_str("=> (),");
            println!("{}", string);
        }

        println!("}};");
    }

    all_chars.sort();
    all_chars.dedup();

    println!("extern {{");
    println!("  enum &'input str {{");
    let mut c = 0;
    for &ch in &all_chars {
        println!(r#"    "{}" => Token{},"#, ch, c);
        c += 1;
    }
    for declaration in &yacc.declarations {
        match *declaration {
            BisonDecl::Token(i) => {
                println!(r#"    {} => Token{},"#, i.text, c);
                c += 1;
            }
            BisonDecl::Start(_) => { }
        }
    }
    println!("  }}");
    println!("}}");
}

fn read_file(name: &str) -> io::Result<String> {
    let mut string = String::new();
    let mut f = try!(File::open(name));
    try!(f.read_to_string(&mut string));
    Ok(string)
}
<commit_msg>indent better, handle zero args<commit_after>use bison::*;
use std::env;
use std::fs::File;
use std::io;
use std::io::Read;
use std::process;

mod bison;
mod yacc;

fn main() {
    if env::args().len() == 0 {
        println!("Usage: yaccrpop [file.y]");
        process::exit(1);
    }

    let input = env::args().skip(1).next().unwrap();
    let yacctext = read_file(&input).unwrap();
    let yacc = yacc::parse_Yacc(&yacctext).unwrap();

    println!("grammar;");

    let start_symbol = yacc.declarations.iter()
                                        .filter_map(|decl| match *decl {
                                            BisonDecl::Start(ident) => Some(ident),
                                            _ => None,
                                        })
                                        .next();

    let mut all_chars = vec![];

    for rule in &yacc.rules {
        let is_pub = start_symbol == Some(rule.nonterminal);
        println!("");
        println!("{}{}: () = {{", if is_pub {"pub "} else {""}, rule.nonterminal.text);

        for alternative in &rule.alternatives {
            let mut string = String::from("    ");
            for (index, symbol) in alternative.symbols.iter().enumerate() {
                if index > 0 {
                    string.push_str(" ");
                }
                match *symbol {
                    Symbol::Ident(ref i) => string.push_str(i.text),
                    Symbol::Character(i) => {
                        let ch = i.chars().skip(1).next().unwrap();
                        string.push('"');
                        string.push(ch);
                        string.push('"');
                        all_chars.push(ch);
                    }
                }
            }
            if alternative.symbols.is_empty() {
                string.push_str("() ");
            }
            string.push_str(",");
            println!("{}", string);
        }

        println!("}};");
    }

    all_chars.sort();
    all_chars.dedup();

    println!("extern {{");
    println!("  enum &'input str {{");
    let mut c = 0;
    for &ch in &all_chars {
        println!(r#"    "{}" => Token{},"#, ch, c);
        c += 1;
    }
    for declaration in &yacc.declarations {
        match *declaration {
            BisonDecl::Token(i) => {
                println!(r#"    {} => Token{},"#, i.text, c);
                c += 1;
            }
            BisonDecl::Start(_) => { }
        }
    }
    println!("  }}");
    println!("}}");
}

fn read_file(name: &str) -> io::Result<String> {
    let mut string = String::new();
    let mut f = try!(File::open(name));
    try!(f.read_to_string(&mut string));
    Ok(string)
}
<|endoftext|>


<commit_before>extern crate reqwest;
extern crate select;
use std::io::Read;
use select::document::Document;
use select::predicate::{Name, Class};

fn scrape_crix_local() {
    // This function by Abiel Parra (https://github.com/Heeled-Jim)

    // http://crix.hu-berlin.de/

    let document = Document::from(include_str!("../html/crix.html"));

    println!("Top 25 Cryptomonedas");
    for node in document.find(Class("currencies")).take(25) {
      let moneda = node.find(Class("currency-name")).next().unwrap();
      let precio = node.find(Class("price")).next().unwrap().text();
      println!(" Moneda: {} Precio: ${}", moneda.text(), precio);
    }
}

fn scrape_coinmarketcap_remote() {
    // https://coinmarketcap.com/
    let mut response = reqwest::get("https://coinmarketcap.com/").unwrap();
    assert!(response.status().is_success());

    let mut body = String::new();
    response.read_to_string(&mut body).expect("Read failed");

    let document = Document::from(body.as_str());
    for node in document.find(Name("tbody"))
        .next()
        .unwrap()
        .find(Name("tr"))
        .take(3)
    {
        let coin_name = node.find(Class("currency-name")).next().unwrap().text();
        let coin_price = node.find(Class("price")).next().unwrap().text();
        println!("{}:   {}", coin_name.trim(), coin_price.trim());
    }

}

fn main() {
    // Uncomment the function you want to use.

    // scrape_crix_local();
    // scrape_coinmarketcap_remote();

}<commit_msg>Update main.rs<commit_after>extern crate reqwest;
extern crate select;
use std::io::Read;
use select::document::Document;
use select::predicate::{Name, Class};

fn scrape_crix_local() {
    // This function is for local webscraping
    // http://crix.hu-berlin.de/

    let document = Document::from(include_str!("../html/crix.html"));

    println!("Top 25 Cryptomonedas");
    for node in document.find(Class("currencies")).take(25) {
      let moneda = node.find(Class("currency-name")).next().unwrap();
      let precio = node.find(Class("price")).next().unwrap().text();
      println!(" Moneda: {} Precio: ${}", moneda.text(), precio);
    }
}

fn scrape_coinmarketcap_remote() {
    // This function is for remote webscraping
    // https://coinmarketcap.com/

    let mut response = reqwest::get("https://coinmarketcap.com/").unwrap();
    assert!(response.status().is_success());

    let mut body = String::new();
    response.read_to_string(&mut body).expect("Read failed");

    let document = Document::from(body.as_str());
    for node in document.find(Name("tbody"))
        .next()
        .unwrap()
        .find(Name("tr"))
        .take(3)
    {
        let coin_name = node.find(Class("currency-name")).next().unwrap().text();
        let coin_price = node.find(Class("price")).next().unwrap().text();
        println!("{}:   {}", coin_name.trim(), coin_price.trim());
    }

}

fn main() {
    // Uncomment the function you want to use.

    // scrape_crix_local();
    // scrape_coinmarketcap_remote();

}
<|endoftext|>


<commit_before>extern crate app_dirs;
#[macro_use]
extern crate clap;
extern crate num_cpus;
extern crate term_painter;
extern crate threadpool;

extern crate gitlib;
extern crate util;

use std::env;
use std::fs;
use std::path::{Path, PathBuf};
use std::sync::mpsc::channel;

use app_dirs::{AppInfo, AppDataType};
use term_painter::Color::{BrightRed, BrightCyan, BrightGreen, BrightMagenta, BrightYellow};
use term_painter::ToStyle;
use threadpool::ThreadPool;

use gitlib::{FileStatus, GitError, GitRepo};
use util::{GitRepositories, Manifest};

mod cli;

#[derive(Debug)]
enum RunOption {
    Checkout(String),
    Manifest(ManifestOption),
    Reset,
    Status,
}

#[derive(Debug)]
enum ManifestOption {
    Clean,
    Preview,
    Update,
}

fn main() {
    let working_dir = env::current_dir().expect("Could not get working directory");
    let matches = cli::build_cli().get_matches();

    let option = match matches.subcommand_name() {
        Some(cli::CMD_CHECKOUT) => {
            let branch_match = matches.subcommand_matches(cli::CMD_CHECKOUT).unwrap();
            let branch = value_t!(branch_match, cli::BRANCH, String).unwrap();
            RunOption::Checkout(branch)
        }
        Some(cli::CMD_MANIFEST) => {
            let matches = matches.subcommand_matches(cli::CMD_MANIFEST).unwrap();

            match matches.subcommand_name() {
                Some(cli::CMD_CLEAN) => RunOption::Manifest(ManifestOption::Clean),
                Some(cli::CMD_UPDATE) => RunOption::Manifest(ManifestOption::Update),
                _ => RunOption::Manifest(ManifestOption::Preview),
            }
        }
        Some(cli::CMD_COMPLETIONS) => {
            if let Some(ref matches) = matches.subcommand_matches(cli::CMD_COMPLETIONS) {
                let shell = value_t!(matches, cli::SHELL, clap::Shell).unwrap();
                cli::build_cli().gen_completions_to(cli::APP_NAME, shell, &mut std::io::stdout());
            }

            return;
        }
        Some(cli::CMD_RESET) => RunOption::Reset,

        // By default, just show status.
        _ => RunOption::Status,
    };

    process(option, &working_dir);
}

fn process(option: RunOption, path: &Path) {
    let manifest_path = build_manifest_path();
    let mut manifest = Manifest::open(&manifest_path, &path);

    if let RunOption::Manifest(ref m) = option {
        let repos = GitRepositories::new(path);

        match *m {
            ManifestOption::Clean => manifest_clean(&manifest_path),
            ManifestOption::Preview => manifest_preview(repos),
            ManifestOption::Update => manifest_update(repos, &mut manifest),
        }
        return;
    }

    let repos = match manifest.is_empty() {
        true => GitRepositories::new(path),
        false => GitRepositories::from_manifest(&manifest),
    };

    let func = match option {
        /*RunOption::Checkout(ref branch) => {
            move |repo| {
                checkout(repo, branch).unwrap_or_else(|_| println!("Error on checkout"));
            }
        }*/
        RunOption::Reset => reset,
        RunOption::Status => status,
        _ => panic!("Unhandled run option"),
    };

    let thread_count = num_cpus::get();
    let pool = ThreadPool::new(thread_count);
    let (tx, rx) = channel();
    let mut repo_count = 0;

    for repo in repos {
        let tx = tx.clone();

        pool.execute(move || {
            if let Err(e) = func(&repo) {
                println!("Error in execution for {:?}: {:?}", repo.path(), e);
            }

            tx.send(1).expect("Could not signal main thread");
        });

        repo_count += 1;
    }

    let completed = rx.iter().take(repo_count).sum::<usize>();

    assert_eq!(completed, repo_count);
}

fn build_manifest_path() -> PathBuf {
    const APP_INFO: AppInfo = AppInfo {
        name: "git-plz",
        author: "devnought",
    };

    let root = app_dirs::get_app_root(AppDataType::UserCache, &APP_INFO).expect("Could not locate app settings directory");
    let mut path = PathBuf::from(root);
    path.push("manifest.json");

    path
}

/*fn checkout(repo: &GitRepo, branch: &str) -> Result<(), GitError> {
    repo.checkout(branch)?;

    println!("{}", repo.path().to_str().unwrap());
    //println!("    {}", BrightCyan.paint(branch));

    Ok(())
}*/

fn manifest_update(repos: GitRepositories, manifest: &mut Manifest) {
    manifest.add_repositories(repos);

    println!("{:#?}", &manifest);
}

fn manifest_preview(repos: GitRepositories) {
    for repo in repos {
        println!("{}", repo.path().to_str().unwrap());
    }
}

fn manifest_clean(manifest_path: &Path) {
    println!("Attempting to delete: {:?}", manifest_path);

    if manifest_path.exists() {
        fs::remove_file(manifest_path).unwrap()
    }
}

fn reset(repo: &GitRepo) -> Result<(), GitError> {
    let head = repo.reset()?;
    let branch = BrightCyan.paint(head.name().unwrap());
    let l_brace = BrightYellow.paint("[");
    let r_brace = BrightYellow.paint("]");

    println!("{}  {}{}{}",
             repo.path().to_str().unwrap(),
             l_brace,
             branch,
             r_brace);

    Ok(())
}

fn status(repo: &GitRepo) -> Result<(), GitError> {
    let statuses = repo.statuses()?;

    if statuses.len() == 0 {
        return Ok(());
    }

    println!("{}",
             repo.path()
                 .to_str()
                 .expect("Could not unwrap repo path"));

    for entry in statuses.iter() {
        let (pre, colour) = match entry.status() {
            FileStatus::Deleted => ("    Deleted", BrightRed),
            FileStatus::Modified => ("   Modified", BrightCyan),
            FileStatus::New => ("        New", BrightGreen),
            FileStatus::Renamed => ("    Renamed", BrightCyan),
            FileStatus::Typechanged => ("Typechanged", BrightCyan),
            FileStatus::Unknown => ("    Unknown", BrightMagenta),
        };

        println!("  {} {}",
                 colour.paint(pre),
                 entry.path().expect("Could not unwrap entry path"));
    }

    Ok(())
}<commit_msg>Added back in functionality<commit_after>extern crate app_dirs;
#[macro_use]
extern crate clap;
extern crate num_cpus;
extern crate term_painter;
extern crate threadpool;

extern crate gitlib;
extern crate util;

use std::env;
use std::fs;
use std::path::{Path, PathBuf};
use std::sync::mpsc::channel;

use app_dirs::{AppInfo, AppDataType};
use term_painter::Color::{BrightRed, BrightCyan, BrightGreen, BrightMagenta, BrightYellow};
use term_painter::ToStyle;
use threadpool::ThreadPool;

use gitlib::{FileStatus, GitError, GitRepo};
use util::{GitRepositories, Manifest};

mod cli;

#[derive(Debug, Clone)]
enum RunOption {
    Checkout(String),
    Manifest(ManifestOption),
    Reset,
    Status,
}

#[derive(Debug, Clone)]
enum ManifestOption {
    Clean,
    Preview,
    Update,
}

fn main() {
    let working_dir = env::current_dir().expect("Could not get working directory");
    let matches = cli::build_cli().get_matches();

    let option = match matches.subcommand_name() {
        Some(cli::CMD_CHECKOUT) => {
            let branch_match = matches.subcommand_matches(cli::CMD_CHECKOUT).unwrap();
            let branch = value_t!(branch_match, cli::BRANCH, String).unwrap();
            RunOption::Checkout(branch)
        }
        Some(cli::CMD_MANIFEST) => {
            let matches = matches.subcommand_matches(cli::CMD_MANIFEST).unwrap();

            match matches.subcommand_name() {
                Some(cli::CMD_CLEAN) => RunOption::Manifest(ManifestOption::Clean),
                Some(cli::CMD_UPDATE) => RunOption::Manifest(ManifestOption::Update),
                _ => RunOption::Manifest(ManifestOption::Preview),
            }
        }
        Some(cli::CMD_COMPLETIONS) => {
            if let Some(ref matches) = matches.subcommand_matches(cli::CMD_COMPLETIONS) {
                let shell = value_t!(matches, cli::SHELL, clap::Shell).unwrap();
                cli::build_cli().gen_completions_to(cli::APP_NAME, shell, &mut std::io::stdout());
            }

            return;
        }
        Some(cli::CMD_RESET) => RunOption::Reset,

        // By default, just show status.
        _ => RunOption::Status,
    };

    process(option, &working_dir);
}

fn process(option: RunOption, path: &Path) {
    let manifest_path = build_manifest_path();
    let mut manifest = Manifest::open(&manifest_path, &path);

    if let RunOption::Manifest(ref m) = option {
        let repos = GitRepositories::new(path);

        match *m {
            ManifestOption::Clean => manifest_clean(&manifest_path),
            ManifestOption::Preview => manifest_preview(repos),
            ManifestOption::Update => manifest_update(repos, &mut manifest),
        }
        return;
    }

    let repos = match manifest.is_empty() {
        true => GitRepositories::new(path),
        false => GitRepositories::from_manifest(&manifest),
    };

    let thread_count = num_cpus::get();
    let pool = ThreadPool::new(thread_count);
    let (tx, rx) = channel();
    let mut repo_count = 0;

    for repo in repos {
        let tx = tx.clone();
        let option = option.clone();

        pool.execute(move || {
            let result = match option {
                RunOption::Checkout(ref branch) => checkout(&repo, branch),
                RunOption::Reset => reset(&repo),
                RunOption::Status => status(&repo),
                _ => {
                    tx.send(1).expect("Could not signal main thread");
                    panic!("Unhandled run option");
                }
            };

            if let Err(e) = result {
                println!("Error in process: {:?}", e);
            }

            tx.send(1).expect("Could not signal main thread");
        });

        repo_count += 1;
    }

    let completed = rx.iter().take(repo_count).sum::<usize>();

    assert_eq!(completed, repo_count);
}

fn build_manifest_path() -> PathBuf {
    const APP_INFO: AppInfo = AppInfo {
        name: "git-plz",
        author: "devnought",
    };

    let root = app_dirs::get_app_root(AppDataType::UserCache, &APP_INFO).expect("Could not locate app settings directory");
    let mut path = PathBuf::from(root);
    path.push("manifest.json");

    path
}

fn checkout(repo: &GitRepo, branch: &str) -> Result<(), GitError> {
    repo.checkout(branch)?;

    println!("{}",
             repo.path()
                 .to_str()
                 .expect("Could not unwrap repo path"));
    println!("    {}", BrightCyan.paint(branch));

    Ok(())
}

fn manifest_update(repos: GitRepositories, manifest: &mut Manifest) {
    manifest.add_repositories(repos);

    println!("{:#?}", &manifest);
}

fn manifest_preview(repos: GitRepositories) {
    for repo in repos {
        println!("{}", repo.path().to_str().unwrap());
    }
}

fn manifest_clean(manifest_path: &Path) {
    println!("Attempting to delete: {:?}", manifest_path);

    if manifest_path.exists() {
        fs::remove_file(manifest_path).unwrap()
    }
}

fn reset(repo: &GitRepo) -> Result<(), GitError> {
    let head = repo.reset()?;
    let branch = BrightCyan.paint(head.name().expect("Error unwrapping head name"));
    let l_brace = BrightYellow.paint("[");
    let r_brace = BrightYellow.paint("]");

    println!("{}  {}{}{}",
             repo.path()
                 .to_str()
                 .expect("Error unwrapping repo path"),
             l_brace,
             branch,
             r_brace);

    Ok(())
}

fn status(repo: &GitRepo) -> Result<(), GitError> {
    let statuses = repo.statuses()?;

    if statuses.len() == 0 {
        return Ok(());
    }

    println!("{}",
             repo.path()
                 .to_str()
                 .expect("Could not unwrap repo path"));

    for entry in statuses.iter() {
        let (pre, colour) = match entry.status() {
            FileStatus::Deleted => ("    Deleted", BrightRed),
            FileStatus::Modified => ("   Modified", BrightCyan),
            FileStatus::New => ("        New", BrightGreen),
            FileStatus::Renamed => ("    Renamed", BrightCyan),
            FileStatus::Typechanged => ("Typechanged", BrightCyan),
            FileStatus::Unknown => ("    Unknown", BrightMagenta),
        };

        println!("  {} {}",
                 colour.paint(pre),
                 entry.path().expect("Could not unwrap entry path"));
    }

    Ok(())
}<|endoftext|>


<commit_before>#[macro_use]
extern crate glium;

extern crate cgmath;
extern crate rand;
extern crate num;
extern crate time;

mod world;
mod draw;

use world::terrain::Terrain;
use draw::shaders::ShaderManager;
use draw::display_object::{Drawable,Frame};
use cgmath::{Matrix4};

fn main() {
	use glium::{DisplayBuild, Surface};
	// can not do multisampling due to glutin bug with_multisampling(16)
	let display = glium::glutin::WindowBuilder::new().with_vsync().with_depth_buffer(24).build_glium().unwrap();

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

	// view frustum
	let display_size = display.get_window().unwrap().get_inner_size_pixels().unwrap();
	let mut perspective_matrix:Matrix4<f32> = cgmath::perspective(cgmath::deg(45.0),display_size.0 as f32/display_size.1 as f32,0.0001,100.0);

	// setup the shaders
	let mut shader_manager = ShaderManager::new(&display);

	// create terrain
	let terrain = Terrain::new(&display,&mut shader_manager,5);

    // listen for events produced in the window and wait to be received
    let mut t:u64 = time::precise_time_ns();
    let mut x:f32 = 0.0;
    let mut y:f32 = 0.0;
    let mut z:f32 = 0.0;
    loop {
    	let nt = time::precise_time_ns();
    	let dt = nt - t;
    	t = nt;

    	// update position
    	//z += (dt as f32/16000000 as f32) / 5 as f32;

    	// get reference to the frame
    	let mut target = display.draw();

    	// clear the background
    	target.clear_color_and_depth((0.0, 0.0, 0.0, 1.0),1.0);

    	// draw the terrain
    	let mvp_matrix = perspective_matrix;
    	//let mut mvp_matrix = Into::<[[f32; 4]; 4]>::into(perspective_matrix);
    	terrain.draw(&mut target,&params,&mvp_matrix);

    	// finish drawing and destroy frame object
    	target.finish().unwrap();

    	// render loop
	    for ev in display.poll_events(){
	    	match ev {
	    		glium::glutin::Event::Closed => return,
	    		glium::glutin::Event::Resized(width, height) => {
	    			// update the perspective_matrix
	    			perspective_matrix = cgmath::perspective(cgmath::deg(45.0),width as f32/height as f32,0.0001,100.0);
	    		},
	    		_ => ()
	    	}
	    }
    }
}<commit_msg>Perspective projection is working<commit_after>#[macro_use]
extern crate glium;

extern crate cgmath;
extern crate rand;
extern crate num;
extern crate time;

mod world;
mod draw;

use world::terrain::Terrain;
use draw::shaders::ShaderManager;
use draw::display_object::{Drawable,Frame};
use cgmath::{Matrix4,Point3,Vector3};

fn main() {
	use glium::{DisplayBuild, Surface};
	// can not do multisampling due to glutin bug with_multisampling(16)
	let display = glium::glutin::WindowBuilder::new().with_vsync().with_depth_buffer(24).build_glium().unwrap();

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

	// perspective_matrix
	let display_size = display.get_window().unwrap().get_inner_size_pixels().unwrap();
	let mut perspective_matrix:Matrix4<f32> = cgmath::perspective(cgmath::deg(45.0),display_size.0 as f32/display_size.1 as f32,0.0001,100.0);

	// view matrix
	let mut camera_position:Point3<f32> = Point3::new(0.0, 2.0, 2.0);
	let mut camera_target:Point3<f32> = Point3::new(0.0, 0.0, 0.0);
	let mut camera_up:Vector3<f32> = Vector3::unit_y();
	let mut view_matrix:Matrix4<f32> = cgmath::Matrix4::look_at(camera_position, camera_target, camera_up);

	// setup the shaders
	let mut shader_manager = ShaderManager::new(&display);

	// create terrain
	let terrain = Terrain::new(&display,&mut shader_manager,5);

    // listen for events produced in the window and wait to be received
    let mut t:u64 = time::precise_time_ns();
    loop {
    	let nt = time::precise_time_ns();
    	let dt = nt - t;
    	t = nt;

    	// update position
    	camera_position.y += (dt as f32/16000000 as f32) / 5 as f32;
    	camera_position.z += (dt as f32/16000000 as f32) / 5 as f32;
    	view_matrix = cgmath::Matrix4::look_at(camera_position, camera_target, camera_up);
    	//z += (dt as f32/16000000 as f32) / 5 as f32;

    	// get reference to the frame
    	let mut target = display.draw();

    	// clear the background
    	target.clear_color_and_depth((0.0, 0.0, 0.0, 1.0),1.0);

    	// draw the terrain
    	let mvp_matrix = perspective_matrix * view_matrix;
    	terrain.draw(&mut target,&params,&mvp_matrix);

    	// finish drawing and destroy frame object
    	target.finish().unwrap();

    	// render loop
	    for ev in display.poll_events(){
	    	match ev {
	    		glium::glutin::Event::Closed => return,
	    		glium::glutin::Event::Resized(width, height) => {
	    			// update the perspective_matrix
	    			perspective_matrix = cgmath::perspective(cgmath::deg(45.0),width as f32/height as f32,0.0001,100.0);
	    		},
	    		_ => ()
	    	}
	    }
    }
}<|endoftext|>


<commit_before>#[macro_use]
extern crate log;
extern crate env_logger;

use std::io::prelude::*;
use std::io;
use std::fs::File;
use std::collections::HashMap;
use std::string::String;
use std::vec::Vec;
use std::path::Path;
use std::net::{TcpListener, TcpStream};
use std::thread;
use std::fs;
use std::sync::{Arc, Mutex};
use std::env;
use std::env::Args;

/// The different run modes for REM
enum Mode {
    NONE,
    CLIENT,
    SERVER,
}

/// Simple error structure to be used when errors occur during a cache operation
#[derive(Debug)]
struct CacheError {
    reason: String,
}

impl CacheError {
    pub fn with_reason(reason: String) -> CacheError {
        return CacheError { reason: reason };
    }
}

/// A structure to store a series of cache operations and a value
/// Cache operations are represented by a single character
struct CacheOperation {
    commands: Vec<char>,
    value: String,
}

impl CacheOperation {
    /// Creates a new CacheOperation instance from an input string
    /// Stores the commands and corresponding value
    /// Write Example: ```W$abc:def```
    /// The resulting command would be W with a value of abc:def
    fn new_from_string(cache_op_str: &String) -> CacheOperation {
        let mut cache_op = CacheOperation {
            commands: Vec::new(),
            value: String::new(),
        };
        let mut idx = 0;
        let chars_iter = cache_op_str.chars();
        // Read the string until $ is found
        for c in chars_iter {
            idx += 1;
            if c == '$' {
                // Set the value to everything after $
                cache_op.value = String::from(&cache_op_str[idx..]);
                break;
            }
            // Add a new command for each iteration where $ hasn't been found yet
            cache_op.commands.push(c);
        }
        return cache_op;
    }
}

/// Cache object -- Simple wrapper around a map
struct Cache {
    map_internal: HashMap<String, Vec<u8>>,
}

impl Cache {
    fn new() -> Cache {
        return Cache { map_internal: HashMap::new() };
    }

    /// Writes the provided value to the cache using the provided key
    ///
    /// The value will be written to the in memory store and the file store
    ///
    /// The _cache directory will be created if it does not exist
    ///
    /// If a value for the provided key already exists it will be overwritten
    fn cache_item(&mut self, key: String, val: Vec<u8>) -> Result<(), CacheError> {
        debug!("Writing to cache: key={:?} val={:?}", key, val);
        fs::create_dir("_cache");
        let mut f: File = File::create(format!("_cache/{}", key)).unwrap();
        f.write(&val.as_slice());
        f.flush();
        self.map_internal.insert(key, val);
        return Ok(());
    }

    /// Reads a value from the cache
    ///
    /// If the key is found in the in memory map then the corresponding value is returned
    ///
    /// If the key cannot be found in the map then an attempt will be made to load the value
    /// from the file corresponding with the key
    fn read_item(&self, key: String) -> Option<Box<Vec<u8>>> {
        let mut res: Option<Box<Vec<u8>>>;
        if self.map_internal.contains_key(&key) {
            let res_opt = self.map_internal.get(&key);
            match res_opt {
                Some(vec_ref) => res = Some(Box::new(vec_ref.clone())),
                None => res = None,
            }
        } else {
            let mut buf: Vec<u8> = Vec::new();
            let f_res = match File::open(format!("_cache/{}", key)) {
                Err(why) => res = None,
                Ok(mut file) => {
                    file.read_to_end(&mut buf);
                    res = Some(Box::new(buf));
                }
            };
        }
        return res;
    }

    /// Delete's an item from the cache
    ///
    /// If the key is found in the in memory map then that entry will be removed
    ///
    /// The file corresponding to the key will also be deleted
    fn delete_item(&mut self, key: String) -> Result<(), CacheError> {
        if self.map_internal.contains_key(&key) {
            self.map_internal.remove(&key);
        }
        let path = format!("_cache/{}", key);
        if Path::new(&path).exists() {
            match fs::remove_file(path) {
                Ok(x) => x,
                Err(e) => {
                    return Err(CacheError::with_reason(format!("Failed to delete file for key: \
                                                                {}",
                                                               key)))
                }
            }
        }
        return Ok(());
    }
}

/// Parses a TCP input stream and extracts the data
/// Allocates a 64 byte buffer which is used to read the input info from the stream
/// The expected format is ```{size}|{content}```
/// Ex. ```5|W$a:b```
fn string_from_stream(stream: &mut TcpStream) -> String {
    //Read in the first 54 bytes of the stram
    stream.set_nodelay(true);
    let mut buf_arr: [u8; 64] = [0; 64];
    stream.read(&mut buf_arr);
    // Parse the message size
    let mut size_str = String::new();
    let mut buf_size: usize = 0;
    for i in 0..64 {
        buf_size += 1;
        if buf_arr[i] == '|' as u8 {
            break;
        }
        size_str.push(buf_arr[i as usize] as char);
    }

    // Convert the size string to a usize so it can be used to drain the buffer
    let upper_idx: usize = size_str.parse::<i32>().unwrap() as usize;
    let mut buf_temp: Vec<u8> = buf_arr.to_vec();
    // Create a new buffer using the parsed indicies
    let buf: Vec<u8> = buf_temp.drain(buf_size..upper_idx + buf_size).collect();

    stream.flush().unwrap();

    // Return the value as a string
    let buf_str: String = String::from_utf8(buf).unwrap();
    return buf_str;
}

fn handle_client(mut stream: &mut TcpStream,
                 cache: &Arc<Mutex<Cache>>)
                 -> Result<(), CacheError> {
    let buf_str: String = string_from_stream(stream);
    if buf_str.len() > 0 {
        let cache_op: CacheOperation = CacheOperation::new_from_string(&buf_str);

        debug!("cmds = {:?}, value = {}", cache_op.commands, cache_op.value);

        if cache_op.commands.len() > 0 {
            let prim_cmd: char = cache_op.commands[0];
            return match prim_cmd {
                'W' => write_stream_str_to_cache(cache_op.value, cache),
                'R' => read_value_from_cache(cache_op.value, cache, &mut stream),
                'D' => delete_value_from_cache(cache_op.value, cache),
                _ => Err(CacheError::with_reason(format!("Invalid cache command {:?}", prim_cmd))),
            };
        }
    } else {
        panic!("Empty cache operation");
    }
    return Ok(());
}

fn read_value_from_cache(key: String,
                         cache_mtx: &Arc<Mutex<Cache>>,
                         mut stream: &mut TcpStream)
                         -> Result<(), CacheError> {
    let cache = cache_mtx.lock().unwrap();
    let cache_opt: Option<Box<Vec<u8>>> = cache.read_item(key);
    match cache_opt {
        Some(boxed_val) => {
            let val: Vec<u8> = *boxed_val;
            debug!("Writing to stream {:?}", val);
            write_str_to_stream_with_size(&mut stream, String::from_utf8(val).unwrap());
            return Ok(());
        }
        None => {
            write_str_to_stream_with_size(&mut stream, String::from("Invalid Key"));
            return Err(CacheError::with_reason(String::from("Could not read from cache")));
        }
    }
}

fn write_stream_str_to_cache(stream_str: String,
                             cache_mtx: &Arc<Mutex<Cache>>)
                             -> Result<(), CacheError> {
    let mut key: String = String::new();
    let mut val: String = String::new();
    let mut idx = 0;
    let mut chars_iter = stream_str.chars();
    for c in chars_iter {
        idx += 1;
        if c == ':' {
            val = String::from(&stream_str[idx..]);
            break;
        }
        key.push(c);
    }
    let bytes = val.into_bytes();
    let mut cache = cache_mtx.lock().unwrap();
    return cache.cache_item(key, bytes);
}

fn delete_value_from_cache(key: String, cache_mtx: &Arc<Mutex<Cache>>) -> Result<(), CacheError> {
    let mut cache = cache_mtx.lock().unwrap();
    return cache.delete_item(key);
}

fn write_str_to_stream_with_size(stream: &mut TcpStream, value: String) {
    let sized_val = String::from(format!("{}|{}", value.len(), value));
    stream.write(String::from(sized_val).as_bytes());
    stream.flush();
}

fn launch_client(ip: String, port: String) {
    info!("Connection to {}:{}", ip, port);

    match TcpStream::connect(format!("{}:{}", ip, port).as_str()) {
        Ok(mut stream) => {
            loop {
                // Contine looping, executing any commands from the user
                let stdin = io::stdin();
                for line_res in stdin.lock().lines() {
                    let line: String = line_res.unwrap();
                    if line.starts_with("write ") {
                        client_exec_write(line, &mut stream);
                    } else if line.starts_with("read ") {
                        client_exec_read(line, &mut stream);
                    } else if line.starts_with("delete ") {
                        client_exec_delete(line, &mut stream);
                    }
                }
            }
        }
        Err(e) => {
            panic!("Failed to connect to server. Error '{}'", e);
        }
    }
}

/// Executres a write operation by parsing the client command and converting it to REM format
/// ex: write abc:def would be converted to 9|W$abc:def and sent to the REM server
fn client_exec_write(line: String, mut stream: &mut TcpStream) {
    let key_val = String::from(&line["write ".len()..line.len()]);
    let delim_idx = key_val.find(" ").unwrap();
    let key = &key_val[0..delim_idx];
    let val = &key_val[delim_idx + 1..key_val.len()];
    let sized_val = String::from(format!("W${}:{}", key, val));
    write_str_to_stream_with_size(&mut stream, sized_val);
}

/// Executres a read operation by parsing the client command and converting it to REM format
/// ex: read abc:def would be converted to 5|R$abc and sent to the REM launch_server
/// The respone from the REM server is writen to stdout
/// If stdout::flush fail a warning will be logged
fn client_exec_read(line: String, mut stream: &mut TcpStream) {
    let key = String::from(&line["read ".len()..line.len()]);
    let cmd_val = String::from(format!("R${}", key));
    write_str_to_stream_with_size(&mut stream, cmd_val);
    let val: String = string_from_stream(&mut stream);
    println!("{}", val);
    let flush_res = io::stdout().flush();
    if flush_res.is_err() {
        warn!("Failed to flush standart out. Error '{:?}'",
              flush_res.err());
    }
}

/// Executres a delete operation by parsing the client command and converting it to REM format
/// ex: delete abc would be converted to 5|D$abc and sent to the REM server
fn client_exec_delete(line: String, mut stream: &mut TcpStream) {
    let key = String::from(&line["delete ".len()..line.len()]);
    let cmd_val = String::from(format!("D${}", key));
    write_str_to_stream_with_size(&mut stream, cmd_val)
}

fn launch_server(ip: String, port: String) {

    info!("Starting on {}:{}", ip, port);

    let listener: TcpListener = TcpListener::bind(format!("{}:{}", ip, port).as_str()).unwrap();

    let cache = Arc::new(Mutex::new(Cache::new()));

    loop {
        // accept connections and process them, spawning a new thread for each one
        for stream in listener.incoming() {
            let cache: Arc<Mutex<Cache>> = cache.clone();
            match stream {
                Ok(mut stream) => {
                    thread::spawn(move || {
                        info!("Incoming connection: {:?}", stream.peer_addr());
                        io::stdout().flush().unwrap();
                        loop {
                            let client_res = handle_client(&mut stream, &cache);
                            if client_res.is_err() {
                                error!("An error occured while handling a client connection {:?}",
                                       client_res.err());
                            }
                        }
                    });
                }
                Err(e) => error!("Incoming connection failed. Error {}", e),
            }
        }
    }
}

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

    let mut args: Args = env::args();

    // Set default values for arguments
    let mut ip: String = String::from("127.0.0.1");
    let mut port: String = String::from("8080");

    let mut mode: Mode = Mode::NONE;

    loop {
        match args.next().as_ref() {
            Some(opt) => {
                match opt.as_ref() {
                    "server" => {
                        mode = Mode::SERVER;
                    }
                    "client" => {
                        mode = Mode::CLIENT;
                    }
                    "-port" => {
                        match args.next() {
                            Some(x) => port = x,
                            None => break,
                        }
                    }
                    "-ip" => {
                        match args.next() {
                            Some(x) => ip = x,
                            None => break,
                        }
                    }
                    _ => continue,
                }
            }
            None => break,
        }
    }

    match mode {
        Mode::CLIENT => launch_client(ip, port),
        Mode::SERVER => launch_server(ip, port),
        Mode::NONE => panic!("Mode must be specified"),
    }
}
<commit_msg>Starting work on proper error handling<commit_after>#[macro_use]
extern crate log;
extern crate env_logger;

use std::io::prelude::*;
use std::io;
use std::fs::File;
use std::collections::HashMap;
use std::string::String;
use std::vec::Vec;
use std::path::Path;
use std::net::{TcpListener, TcpStream};
use std::thread;
use std::fs;
use std::sync::{Arc, Mutex};
use std::env;
use std::env::Args;
use std::fmt;

const REM_00001: &'static str = "REM_00001: A run mode must be specified. One of [server, client] \
                                 expected";
const REM_00002: &'static str = "REM_00002: Unexpected argument encountered";

/// The different run modes for REM
enum Mode {
    NONE,
    CLIENT,
    SERVER,
}

/// Simple error structure to be used when errors occur during a cache operation
#[derive(Debug)]
struct RemError {
    reason: String,
    details: Option<String>,
}

impl RemError {
    pub fn with_reason(reason: String) -> RemError {
        return RemError {
            reason: reason,
            details: Option::None,
        };
    }

    pub fn with_reason_str(reason: &'static str) -> RemError {
        return RemError {
            reason: String::from(reason),
            details: Option::None,
        };
    }

    pub fn with_reason_str_and_details(reason: &'static str, details: String) -> RemError {
        return RemError {
            reason: String::from(reason),
            details: Some(details),
        };
    }

    pub fn log(self) {
        match self.details {
            None => error!("{}", self.reason),
            Some(details) => error!("{}: {}", self.reason, details),
        }
    }

    pub fn log_and_exit(self) {
        self.log();
        std::process::exit(1);
    }

    pub fn print(self) {
        match self.details {
            None => print!("{}", self.reason),
            Some(details) => print!("{}. Details: {}", self.reason, details),
        }
        match io::stdout().flush() {
            Err(why) => {
                warn!("Failed to flush standart out. Error '{:?}'", why);
            }
            _ => (),
        }
    }
}

impl fmt::Display for RemError {
    fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
        return write!(formatter, "{}", self.reason);
    }
}

/// A structure to store a series of cache operations and a value
/// Cache operations are represented by a single character
struct CacheOperation {
    commands: Vec<char>,
    value: String,
}

impl CacheOperation {
    /// Creates a new CacheOperation instance from an input string
    /// Stores the commands and corresponding value
    /// Write Example: ```W$abc:def```
    /// The resulting command would be W with a value of abc:def
    fn new_from_string(cache_op_str: &String) -> CacheOperation {
        let mut cache_op = CacheOperation {
            commands: Vec::new(),
            value: String::new(),
        };
        let mut idx = 0;
        let chars_iter = cache_op_str.chars();
        // Read the string until $ is found
        for c in chars_iter {
            idx += 1;
            if c == '$' {
                // Set the value to everything after $
                cache_op.value = String::from(&cache_op_str[idx..]);
                break;
            }
            // Add a new command for each iteration where $ hasn't been found yet
            cache_op.commands.push(c);
        }
        return cache_op;
    }
}

/// Cache object -- Simple wrapper around a map
struct Cache {
    map_internal: HashMap<String, Vec<u8>>,
}

impl Cache {
    fn new() -> Cache {
        return Cache { map_internal: HashMap::new() };
    }

    /// Writes the provided value to the cache using the provided key
    ///
    /// The value will be written to the in memory store and the file store
    ///
    /// The _cache directory will be created if it does not exist
    ///
    /// If a value for the provided key already exists it will be overwritten
    fn cache_item(&mut self, key: String, val: Vec<u8>) -> Result<(), RemError> {
        debug!("Writing to cache: key={:?} val={:?}", key, val);
        fs::create_dir("_cache");
        let mut f: File = File::create(format!("_cache/{}", key)).unwrap();
        f.write(&val.as_slice());
        f.flush();
        self.map_internal.insert(key, val);
        return Ok(());
    }

    /// Reads a value from the cache
    ///
    /// If the key is found in the in memory map then the corresponding value is returned
    ///
    /// If the key cannot be found in the map then an attempt will be made to load the value
    /// from the file corresponding with the key
    fn read_item(&self, key: String) -> Option<Box<Vec<u8>>> {
        let mut res: Option<Box<Vec<u8>>>;
        if self.map_internal.contains_key(&key) {
            let res_opt = self.map_internal.get(&key);
            match res_opt {
                Some(vec_ref) => res = Some(Box::new(vec_ref.clone())),
                None => res = None,
            }
        } else {
            let mut buf: Vec<u8> = Vec::new();
            let f_res = match File::open(format!("_cache/{}", key)) {
                Err(why) => res = None,
                Ok(mut file) => {
                    file.read_to_end(&mut buf);
                    res = Some(Box::new(buf));
                }
            };
        }
        return res;
    }

    /// Delete's an item from the cache
    ///
    /// If the key is found in the in memory map then that entry will be removed
    ///
    /// The file corresponding to the key will also be deleted
    fn delete_item(&mut self, key: String) -> Result<(), RemError> {
        if self.map_internal.contains_key(&key) {
            self.map_internal.remove(&key);
        }
        let path = format!("_cache/{}", key);
        if Path::new(&path).exists() {
            match fs::remove_file(path) {
                Ok(x) => x,
                Err(e) => {
                    return Err(RemError::with_reason(format!("Failed to delete file for key: \
                                                                {}",
                                                             key)))
                }
            }
        }
        return Ok(());
    }
}

/// Parses a TCP input stream and extracts the data
/// Allocates a 64 byte buffer which is used to read the input info from the stream
/// The expected format is ```{size}|{content}```
/// Ex. ```5|W$a:b```
fn string_from_stream(stream: &mut TcpStream) -> String {
    //Read in the first 54 bytes of the stram
    stream.set_nodelay(true);
    let mut buf_arr: [u8; 64] = [0; 64];
    stream.read(&mut buf_arr);
    // Parse the message size
    let mut size_str = String::new();
    let mut buf_size: usize = 0;
    for i in 0..64 {
        buf_size += 1;
        if buf_arr[i] == '|' as u8 {
            break;
        }
        size_str.push(buf_arr[i as usize] as char);
    }

    // Convert the size string to a usize so it can be used to drain the buffer
    let upper_idx: usize = size_str.parse::<i32>().unwrap() as usize;
    let mut buf_temp: Vec<u8> = buf_arr.to_vec();
    // Create a new buffer using the parsed indicies
    let buf: Vec<u8> = buf_temp.drain(buf_size..upper_idx + buf_size).collect();

    stream.flush().unwrap();

    // Return the value as a string
    let buf_str: String = String::from_utf8(buf).unwrap();
    return buf_str;
}

fn handle_client(mut stream: &mut TcpStream, cache: &Arc<Mutex<Cache>>) -> Result<(), RemError> {
    let buf_str: String = string_from_stream(stream);
    if buf_str.len() > 0 {
        let cache_op: CacheOperation = CacheOperation::new_from_string(&buf_str);

        debug!("cmds = {:?}, value = {}", cache_op.commands, cache_op.value);

        if cache_op.commands.len() > 0 {
            let prim_cmd: char = cache_op.commands[0];
            return match prim_cmd {
                'W' => write_stream_str_to_cache(cache_op.value, cache),
                'R' => read_value_from_cache(cache_op.value, cache, &mut stream),
                'D' => delete_value_from_cache(cache_op.value, cache),
                _ => Err(RemError::with_reason(format!("Invalid cache command {:?}", prim_cmd))),
            };
        }
    } else {
        panic!("Empty cache operation");
    }
    return Ok(());
}

fn read_value_from_cache(key: String,
                         cache_mtx: &Arc<Mutex<Cache>>,
                         mut stream: &mut TcpStream)
                         -> Result<(), RemError> {
    let cache = cache_mtx.lock().unwrap();
    let cache_opt: Option<Box<Vec<u8>>> = cache.read_item(key);
    match cache_opt {
        Some(boxed_val) => {
            let val: Vec<u8> = *boxed_val;
            debug!("Writing to stream {:?}", val);
            write_str_to_stream_with_size(&mut stream, String::from_utf8(val).unwrap());
            return Ok(());
        }
        None => {
            write_str_to_stream_with_size(&mut stream, String::from("Invalid Key"));
            return Err(RemError::with_reason(String::from("Could not read from cache")));
        }
    }
}

fn write_stream_str_to_cache(stream_str: String,
                             cache_mtx: &Arc<Mutex<Cache>>)
                             -> Result<(), RemError> {
    let mut key: String = String::new();
    let mut val: String = String::new();
    let mut idx = 0;
    let mut chars_iter = stream_str.chars();
    for c in chars_iter {
        idx += 1;
        if c == ':' {
            val = String::from(&stream_str[idx..]);
            break;
        }
        key.push(c);
    }
    let bytes = val.into_bytes();
    let mut cache = cache_mtx.lock().unwrap();
    return cache.cache_item(key, bytes);
}

fn delete_value_from_cache(key: String, cache_mtx: &Arc<Mutex<Cache>>) -> Result<(), RemError> {
    let mut cache = cache_mtx.lock().unwrap();
    return cache.delete_item(key);
}

fn write_str_to_stream_with_size(stream: &mut TcpStream, value: String) {
    let sized_val = String::from(format!("{}|{}", value.len(), value));
    stream.write(String::from(sized_val).as_bytes());
    stream.flush();
}

fn launch_client(ip: String, port: String) {
    info!("Connection to {}:{}", ip, port);

    match TcpStream::connect(format!("{}:{}", ip, port).as_str()) {
        Ok(mut stream) => {
            loop {
                // Contine looping, executing any commands from the user
                let stdin = io::stdin();
                for line_res in stdin.lock().lines() {
                    let line: String = line_res.unwrap();
                    if line.starts_with("write ") {
                        client_exec_write(line, &mut stream);
                    } else if line.starts_with("read ") {
                        client_exec_read(line, &mut stream);
                    } else if line.starts_with("delete ") {
                        client_exec_delete(line, &mut stream);
                    }
                }
            }
        }
        Err(e) => {
            panic!("Failed to connect to server. Error '{}'", e);
        }
    }
}

/// Executres a write operation by parsing the client command and converting it to REM format
/// ex: write abc:def would be converted to 9|W$abc:def and sent to the REM server
fn client_exec_write(line: String, mut stream: &mut TcpStream) {
    let key_val = String::from(&line["write ".len()..line.len()]);
    let delim_idx = key_val.find(" ").unwrap();
    let key = &key_val[0..delim_idx];
    let val = &key_val[delim_idx + 1..key_val.len()];
    let sized_val = String::from(format!("W${}:{}", key, val));
    write_str_to_stream_with_size(&mut stream, sized_val);
}

/// Executres a read operation by parsing the client command and converting it to REM format
/// ex: read abc:def would be converted to 5|R$abc and sent to the REM launch_server
/// The respone from the REM server is writen to stdout
/// If stdout::flush fail a warning will be logged
fn client_exec_read(line: String, mut stream: &mut TcpStream) {
    let key = String::from(&line["read ".len()..line.len()]);
    let cmd_val = String::from(format!("R${}", key));
    write_str_to_stream_with_size(&mut stream, cmd_val);
    let val: String = string_from_stream(&mut stream);
    println!("{}", val);
    let flush_res = io::stdout().flush();
    if flush_res.is_err() {
        warn!("Failed to flush standart out. Error '{:?}'",
              flush_res.err());
    }
}

/// Executes a delete operation by parsing the client command and converting it to REM format
/// ex: delete abc would be converted to 5|D$abc and sent to the REM server
fn client_exec_delete(line: String, mut stream: &mut TcpStream) {
    let key = String::from(&line["delete ".len()..line.len()]);
    let cmd_val = String::from(format!("D${}", key));
    write_str_to_stream_with_size(&mut stream, cmd_val)
}

fn launch_server(ip: String, port: String) {

    info!("Starting on {}:{}", ip, port);

    let listener: TcpListener = TcpListener::bind(format!("{}:{}", ip, port).as_str()).unwrap();

    let cache = Arc::new(Mutex::new(Cache::new()));

    loop {
        // accept connections and process them, spawning a new thread for each one
        for stream in listener.incoming() {
            let cache: Arc<Mutex<Cache>> = cache.clone();
            match stream {
                Ok(mut stream) => {
                    thread::spawn(move || {
                        info!("Incoming connection: {:?}", stream.peer_addr());
                        io::stdout().flush().unwrap();
                        loop {
                            let client_res = handle_client(&mut stream, &cache);
                            if client_res.is_err() {
                                error!("An error occured while handling a client connection {:?}",
                                       client_res.err());
                            }
                        }
                    });
                }
                Err(e) => error!("Incoming connection failed. Error {}", e),
            }
        }
    }
}

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

    let mut args: Args = env::args();

    // Set default values for arguments
    let mut ip: String = String::from("127.0.0.1");
    let mut port: String = String::from("8080");

    let mut mode: Mode = Mode::NONE;

    // Consume the first argument since it is just the program
    args.next();

    loop {
        match args.next().as_ref() {
            Some(opt) => {
                match opt.as_ref() {
                    "server" => {
                        mode = Mode::SERVER;
                    }
                    "client" => {
                        mode = Mode::CLIENT;
                    }
                    "-port" => {
                        match args.next() {
                            Some(x) => port = x,
                            None => break,
                        }
                    }
                    "-ip" => {
                        match args.next() {
                            Some(x) => ip = x,
                            None => break,
                        }
                    }
                    _ => {
                        RemError::with_reason_str_and_details(REM_00002,
                                                              format!("Argument {} is not a \
                                                                       valid option",
                                                                      opt))
                            .log_and_exit();
                    }
                }
            }
            None => break,
        }
    }

    match mode {
        Mode::CLIENT => launch_client(ip, port),
        Mode::SERVER => launch_server(ip, port),
        Mode::NONE => {
            RemError::with_reason_str(REM_00001).log();
        }
    }
}
<|endoftext|>


<commit_before>extern crate sdl;
extern crate rand;

use rand::distributions::{IndependentSample, Range};
use sdl::video::{SurfaceFlag, VideoFlag, Color};
use sdl::event::{Event, Key};

fn init(screen_width: isize, screen_height: isize) -> sdl::video::Surface {
    sdl::init(&[sdl::InitFlag::Video]);
    sdl::wm::set_caption("mines", "mines");

    let screen = match sdl::video::set_video_mode(screen_width, screen_height, 32,
                                                  &[SurfaceFlag::HWSurface],
                                                  &[VideoFlag::DoubleBuf]) {
        Ok(screen) => screen,
        Err(err) => panic!("failed to set video mode: {}", err)
    };
    screen
}

fn draw_square(x: i16, y: i16, w: u16, (r,g,b): (u8, u8, u8), screen: &sdl::video::Surface) {
    screen.fill_rect(Some(sdl::Rect {x: x, y: y, w: w, h: w}), Color::RGB(r, g, b));
}

fn draw_num(n: u8, x: i16, y: i16, size: u16, screen: &sdl::video::Surface) {
    let mut n = n;
    let sub = (size-1) as i16/3;
    let pack = (size as i16-sub*3)as i16/2;
    let color = if n == 1 {
        (100,100,255)
    }else if n == 2 {
        (0,255,0)
    }else if n == 3 {
        (255,0,0)
    }else if n == 4 {
        (0,0,255)
    }else if n == 5 {
        (200,50,0)
    }else if n == 6 {
        (0,255,255)
    }else if n == 7 {
        (0,0,0)
    }else {
        (150,150,150)
    };

    loop {
        if n == 0 {break;}
        else if n == 1{
            draw_square(sub+x+pack, sub+y+pack, sub as u16-1, color, screen);
            break;
        }else if n == 2{
            draw_square(x+pack, y+pack, sub as u16-1,  color, screen);
            draw_square(sub*2+x+pack, sub*2+y+pack, sub as u16-1, color, screen);
            break;
        }else if n == 3{
            draw_square(sub+x+pack, sub+y+pack, sub as u16-1, color, screen);
            n = 2;
        }else if n == 4{
            draw_square(x+pack, sub*2+y+pack, sub as u16-1, color, screen);
            draw_square(sub*2+x+pack, y+pack, sub as u16-1, color, screen);
            n = 2;
        }else if n == 5{
            draw_square(sub+x+pack, sub+y+pack, sub as u16-1, color, screen);
            n = 4;
        }else if n == 6{
            draw_square(x+pack, sub+y+pack, sub as u16-1, color, screen);
            draw_square(sub*2+x+pack, sub+y+pack, sub as u16-1, color, screen);
            n = 4;
        }else if n == 7{
            draw_square(sub+x+pack, sub+y+pack, sub as u16-1, color, screen);
            n = 6;
        }else if n == 8{
            draw_square(sub+x+pack, y+pack, sub as u16-1, color, screen);
            draw_square(sub+x+pack, sub*2+y+pack, sub as u16-1, color, screen);
            n = 6;
        }
    }
}

fn draw_field(ref field: &Vec<Vec<bool>>, length: i16, screen: &sdl::video::Surface) {
    let mut n = 0;
    for ref i in field.iter() {
        let mut m = 0;
        for ref j in i.iter() {
            draw_square(m*length+1,
                      n*length+1,
                      (length-1) as u16,
                      if **j {(0, 0, 0)} else {(255, 255, 255)},
                      screen
            );
            if !**j{
                draw_num(
                    count_field(m as usize, n as usize, field),
                    m as i16*length as i16+1,
                    n as i16*length as i16+1,
                    (length-1) as u16,
                    screen);
            }
            m += 1;
        }
        n += 1;
    }
}

fn flip_field(ref mut field: &mut Vec<Vec<bool>>, x: i16, y: i16, size: i16) {
    let i = (x/size) as usize;
    let j = (y/size) as usize;
    field[i][j] = !(field[i][j]);
}

fn random_field(r: f32, field: &mut Vec<Vec<bool>>) {
    let bt = Range::new(0.,1.);
    let mut rng = rand::thread_rng();
    field.iter().map(|x| {x.map(|y| {
        if bt.ind_sample(&mut rng) < r {
            true
        }else{
            false
        }

    })});
    let rng = rand::thread_rng();
}

fn count_field(x: usize, y: usize, field: &Vec<Vec<bool>>) -> u8 {
    let w = field[0].len();
    let h = field.len();
    let mut n = 0;
    for i in 0..3 {
        if y+i == 0 || y+i == h+1 {continue;}
        for j in 0..3 {
            if i == 1 && j == 1 {continue;}
            if x+j == 0 || x+j == w+1 {continue;}
            if field[y+i-1][x+j-1] {n += 1}
        }
    }
    n
}

fn main() {
    const WIDTH: usize = 30;
    const HEIGHT: usize = 20;
    const SIZE: usize = 35;

    let field = &mut vec![vec![false; WIDTH]; HEIGHT];

    let screen = init((SIZE*WIDTH) as isize + 1, (SIZE*HEIGHT) as isize + 1);
    loop {
        match sdl::event::poll_event() {
            Event::Quit => break,
            Event::MouseButton(_, down, mx, my) => {
                if down {
                    flip_field(field, my as i16, mx as i16, SIZE as i16);
                    println!("{}", count_field((mx/SIZE as u16) as usize, (my/SIZE as u16) as usize, field));
                }
            },
            Event::Key(k, _, _, _)
                if k == Key::Escape
                    => break,
            _ => {}
        }
        draw_field(&field, SIZE as i16, &screen);
        screen.flip();
    }

    sdl::quit();
}
<commit_msg>fully random<commit_after>extern crate sdl;
extern crate rand;

use rand::distributions::{IndependentSample, Range};
use sdl::video::{SurfaceFlag, VideoFlag, Color};
use sdl::event::{Event, Key};

fn init(screen_width: isize, screen_height: isize) -> sdl::video::Surface {
    sdl::init(&[sdl::InitFlag::Video]);
    sdl::wm::set_caption("mines", "mines");

    let screen = match sdl::video::set_video_mode(screen_width, screen_height, 32,
                                                  &[SurfaceFlag::HWSurface],
                                                  &[VideoFlag::DoubleBuf]) {
        Ok(screen) => screen,
        Err(err) => panic!("failed to set video mode: {}", err)
    };
    screen
}

fn draw_square(x: i16, y: i16, w: u16, (r,g,b): (u8, u8, u8), screen: &sdl::video::Surface) {
    screen.fill_rect(Some(sdl::Rect {x: x, y: y, w: w, h: w}), Color::RGB(r, g, b));
}

fn draw_num(n: u8, x: i16, y: i16, size: u16, screen: &sdl::video::Surface) {
    let mut n = n;
    let sub = (size-1) as i16/3;
    let pack = (size as i16-sub*3)as i16/2;
    let color = if n == 1 {
        (100,100,255)
    }else if n == 2 {
        (0,255,0)
    }else if n == 3 {
        (255,0,0)
    }else if n == 4 {
        (0,0,255)
    }else if n == 5 {
        (200,50,0)
    }else if n == 6 {
        (0,255,255)
    }else if n == 7 {
        (0,0,0)
    }else {
        (150,150,150)
    };

    loop {
        if n == 0 {break;}
        else if n == 1{
            draw_square(sub+x+pack, sub+y+pack, sub as u16-1, color, screen);
            break;
        }else if n == 2{
            draw_square(x+pack, y+pack, sub as u16-1,  color, screen);
            draw_square(sub*2+x+pack, sub*2+y+pack, sub as u16-1, color, screen);
            break;
        }else if n == 3{
            draw_square(sub+x+pack, sub+y+pack, sub as u16-1, color, screen);
            n = 2;
        }else if n == 4{
            draw_square(x+pack, sub*2+y+pack, sub as u16-1, color, screen);
            draw_square(sub*2+x+pack, y+pack, sub as u16-1, color, screen);
            n = 2;
        }else if n == 5{
            draw_square(sub+x+pack, sub+y+pack, sub as u16-1, color, screen);
            n = 4;
        }else if n == 6{
            draw_square(x+pack, sub+y+pack, sub as u16-1, color, screen);
            draw_square(sub*2+x+pack, sub+y+pack, sub as u16-1, color, screen);
            n = 4;
        }else if n == 7{
            draw_square(sub+x+pack, sub+y+pack, sub as u16-1, color, screen);
            n = 6;
        }else if n == 8{
            draw_square(sub+x+pack, y+pack, sub as u16-1, color, screen);
            draw_square(sub+x+pack, sub*2+y+pack, sub as u16-1, color, screen);
            n = 6;
        }
    }
}

fn draw_field(ref field: &Vec<Vec<bool>>, length: i16, screen: &sdl::video::Surface) {
    let mut n = 0;
    for ref i in field.iter() {
        let mut m = 0;
        for ref j in i.iter() {
            draw_square(m*length+1,
                      n*length+1,
                      (length-1) as u16,
                      if **j {(0, 0, 0)} else {(255, 255, 255)},
                      screen
            );
            if !**j{
                draw_num(
                    count_field(m as usize, n as usize, field),
                    m as i16*length as i16+1,
                    n as i16*length as i16+1,
                    (length-1) as u16,
                    screen);
            }
            m += 1;
        }
        n += 1;
    }
}

fn flip_field(ref mut field: &mut Vec<Vec<bool>>, x: i16, y: i16, size: i16) {
    let i = (x/size) as usize;
    let j = (y/size) as usize;
    field[i][j] = !(field[i][j]);
}

fn random_field(r: f32, field: &mut Vec<Vec<bool>>) {
    let bt = Range::new(0.,1.);
    let mut rng = rand::thread_rng();
    for i in 0..field.len() {
        for j in 0..field[0].len() {
            if bt.ind_sample(&mut rng) < r {
                field[i][j] = true;
            }else{
                field[i][j] = false;
            }
        }
    }
}

fn count_field(x: usize, y: usize, field: &Vec<Vec<bool>>) -> u8 {
    let w = field[0].len();
    let h = field.len();
    let mut n = 0;
    for i in 0..3 {
        if y+i == 0 || y+i == h+1 {continue;}
        for j in 0..3 {
            if i == 1 && j == 1 {continue;}
            if x+j == 0 || x+j == w+1 {continue;}
            if field[y+i-1][x+j-1] {n += 1}
        }
    }
    n
}

fn main() {
    const WIDTH: usize = 30;
    const HEIGHT: usize = 20;
    const SIZE: usize = 35;

    let field = &mut vec![vec![false; WIDTH]; HEIGHT];

    let screen = init((SIZE*WIDTH) as isize + 1, (SIZE*HEIGHT) as isize + 1);
    loop {
        match sdl::event::poll_event() {
            Event::Quit => break,
            Event::MouseButton(_, down, mx, my) => {
                if down {
                    flip_field(field, my as i16, mx as i16, SIZE as i16);
                }
            },
            Event::Key(k, down, _, _) => {
                if down {
                    if k == Key::Escape {
                        break;
                    }
                    if k == Key::R {
                        random_field(0.1, field);
                    }
                }
            }
            _ => {}
        }
        draw_field(&field, SIZE as i16, &screen);
        screen.flip();
    }

    sdl::quit();
}
<|endoftext|>


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

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

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

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

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

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

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

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

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

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

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

    let mut camera = cam::Camera::new(0.5, 0.5, 4.0);
    let mut fps_controller_settings = cam::FPSControllerSettings::default();
    fps_controller_settings.speed_horizontal = 8.0;
    fps_controller_settings.speed_vertical = 4.0;
    let mut fps_controller = cam::FPSController::new(fps_controller_settings);
    camera.set_yaw_pitch(fps_controller.yaw, fps_controller.pitch);

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

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

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

    let mut events = GameIterator::new(&mut window, &game_iter_settings);
    for e in events {
        match e {
            Render(_args) => {
                let mut tri = vec![];
                for face in cube::FaceIterator::new() {
                    let xyz = face.vertices([0.0, 0.0, 0.0], [1.0, 1.0, 1.0]);
                    let [u0, v1, u1, v0] = [0.0, 0.75, 0.25, 1.0];
                    let uv = [
                        [u1, v0],
                        [u0, v0],
                        [u0, v1],
                        [u1, v1]
                    ];
                    let v = [
                        (xyz[0], uv[0], [1.0, 0.0, 0.0]),
                        (xyz[1], uv[1], [0.0, 1.0, 0.0]),
                        (xyz[2], uv[2], [0.0, 0.0, 1.0]),
                        (xyz[3], uv[3], [1.0, 0.0, 1.0])
                    ].map(|(xyz, uv, rgb)| shader::Vertex { xyz: xyz, uv: uv, rgb: rgb });

                    // Split the clockwise quad into two clockwise triangles.
                    tri.push_all([v[0], v[1], v[2]]);
                    tri.push_all([v[2], v[3], v[0]]);
                }
                let buf = renderer.create_buffer(tri.as_slice());
                renderer.set_view(camera.orthogonal());
                renderer.reset();
                renderer.render(buf);
                renderer.end_frame();
                renderer.delete_buffer(buf);

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

                events.game_window.capture_cursor(capture_cursor);
            }
            Input(input::MouseRelativeMove { .. }) => {
                if !capture_cursor {
                    // Don't send the mouse event to the FPS controller.
                    continue;
                }
            }
            _ => {}
        }

        // Camera controller.
        match e {
            Input(ref args) => fps_controller.input(args, &mut camera),
            Update(piston::UpdateArgs { dt, .. }) => fps_controller.update(dt, &mut camera),
            _ => {}
        }
    }
}
<commit_msg>Move buffer building out of the event loop.<commit_after>#![feature(globs, macro_rules, phase)]

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

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

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

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

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

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

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

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

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

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

    let mut camera = cam::Camera::new(0.5, 0.5, 4.0);
    let mut fps_controller_settings = cam::FPSControllerSettings::default();
    fps_controller_settings.speed_horizontal = 8.0;
    fps_controller_settings.speed_vertical = 4.0;
    let mut fps_controller = cam::FPSController::new(fps_controller_settings);
    camera.set_yaw_pitch(fps_controller.yaw, fps_controller.pitch);

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

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

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

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

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

    let mut events = GameIterator::new(&mut window, &game_iter_settings);
    for e in events {
        match e {
            Render(_args) => {
                renderer.set_view(camera.orthogonal());
                renderer.reset();
                renderer.render(buffer);
                renderer.end_frame();

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

                events.game_window.capture_cursor(capture_cursor);
            }
            Input(input::MouseRelativeMove { .. }) => {
                if !capture_cursor {
                    // Don't send the mouse event to the FPS controller.
                    continue;
                }
            }
            _ => {}
        }

        // Camera controller.
        match e {
            Input(ref args) => fps_controller.input(args, &mut camera),
            Update(piston::UpdateArgs { dt, .. }) => fps_controller.update(dt, &mut camera),
            _ => {}
        }
    }
}
<|endoftext|>