<commit_before>#![crate_name = "hashsum"]

/*
 * This file is part of the uutils coreutils package.
 *
 * (c) Arcterus <arcterus@mail.com>
 * (c) Vsevolod Velichko <torkvemada@sorokdva.net>
 * (c) Gil Cottle <gcottle@redtown.org>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

#![feature(macro_rules)]

extern crate regex;

extern crate crypto;
extern crate getopts;

use std::io::fs::File;
use std::io::stdio::stdin_raw;
use std::io::BufferedReader;
use std::io::IoError;
use std::io::EndOfFile;
use regex::Regex;
use crypto::digest::Digest;
use crypto::md5::Md5;
use crypto::sha1::Sha1;
use crypto::sha2::{Sha224, Sha256, Sha384, Sha512};

#[path = "../common/util.rs"]
mod util;

static NAME: &'static str = "hashsum";
static VERSION: &'static str = "1.0.0";

fn is_custom_binary(program: &str) -> bool {
    match program {
        "md5sum" | "sha1sum"
            | "sha224sum" | "sha256sum"
            | "sha384sum" | "sha512sum" => true,
        _ => false
    }
}

fn get_algo_opts(program: &str) -> Vec<getopts::OptGroup> {
    if is_custom_binary(program) {
        Vec::new()
    } else {
        vec!(
            getopts::optflag("", "md5", "work with MD5"),
            getopts::optflag("", "sha1", "work with SHA1"),
            getopts::optflag("", "sha224", "work with SHA224"),
            getopts::optflag("", "sha256", "work with SHA256"),
            getopts::optflag("", "sha384", "work with SHA384"),
            getopts::optflag("", "sha512", "work with SHA512")
        )
    }
}

fn detect_algo(program: &str, matches: &getopts::Matches) -> (&'static str, Box<Digest+'static>) {
    let mut alg: Option<Box<Digest>> = None;
    let mut name: &'static str = "";
    match program {
        "md5sum" => ("MD5", box Md5::new() as Box<Digest>),
        "sha1sum" => ("SHA1", box Sha1::new() as Box<Digest>),
        "sha224sum" => ("SHA224", box Sha224::new() as Box<Digest>),
        "sha256sum" => ("SHA256", box Sha256::new() as Box<Digest>),
        "sha384sum" => ("SHA384", box Sha384::new() as Box<Digest>),
        "sha512sum" => ("SHA512", box Sha512::new() as Box<Digest>),
        _ => {
            {
                let set_or_crash = |n, val| -> () {
                    if alg.is_some() { crash!(1, "You cannot combine multiple hash algorithms!") };
                    name = n;
                    alg = Some(val);
                };
                if matches.opt_present("md5") { set_or_crash("MD5", box Md5::new()) };
                if matches.opt_present("sha1") { set_or_crash("SHA1", box Sha1::new()) };
                if matches.opt_present("sha224") { set_or_crash("SHA224", box Sha224::new()) };
                if matches.opt_present("sha256") { set_or_crash("SHA256", box Sha256::new()) };
                if matches.opt_present("sha384") { set_or_crash("SHA384", box Sha384::new()) };
                if matches.opt_present("sha512") { set_or_crash("SHA512", box Sha512::new()) };
            }
            if alg.is_none() { crash!(1, "You must specify hash algorithm!") };
            (name, alg.unwrap())
        }
    }
}

pub fn uumain(args: Vec<String>) -> int {
    let program = args[0].clone();
    let binary = Path::new(program.as_slice());
    let binary_name = binary.filename_str().unwrap();

    // Default binary in Windows, text mode otherwise
    let binary_flag_default = cfg!(windows);

    let mut opts: Vec<getopts::OptGroup> = vec!(
        getopts::optflag("b", "binary", format!("read in binary mode{}", if binary_flag_default { " (default)" } else { "" }).as_slice()),
        getopts::optflag("c", "check", "read hashsums from the FILEs and check them"),
        getopts::optflag("", "tag", "create a BSD-style checksum"),
        getopts::optflag("t", "text", format!("read in text mode{}", if binary_flag_default { "" } else { " (default)" }).as_slice()),
        getopts::optflag("q", "quiet", "don't print OK for each successfully verified file"),
        getopts::optflag("s", "status", "don't output anything, status code shows success"),
        getopts::optflag("", "strict", "exit non-zero for improperly formatted checksum lines"),
        getopts::optflag("w", "warn", "warn about improperly formatted checksum lines"),
        getopts::optflag("h", "help", "display this help and exit"),
        getopts::optflag("V", "version", "output version information and exit"),
    );

    opts.extend(get_algo_opts(binary_name.as_slice()).into_iter());

    let matches = match getopts::getopts(args.tail(), opts.as_slice()) {
        Ok(m) => m,
        Err(f) => crash!(1, "{}", f)
    };

    if matches.opt_present("help") {
        usage(program.as_slice(), binary_name.as_slice(), opts.as_slice());
    } else if matches.opt_present("version") {
        version();
    } else {
        let (name, algo) = detect_algo(binary_name.as_slice(), &matches);

        let binary_flag = matches.opt_present("binary");
        let text_flag = matches.opt_present("text");
        if binary_flag && text_flag {
            crash!(1, "cannot set binary and text mode at the same time");
        }
        let binary = if binary_flag { true } else if text_flag { false } else { binary_flag_default };
        let check = matches.opt_present("check");
        let tag = matches.opt_present("tag");
        let status = matches.opt_present("status");
        let quiet = matches.opt_present("quiet") || status;
        let strict = matches.opt_present("strict");
        let warn = matches.opt_present("warn") && !status;
        let files = if matches.free.is_empty() {
            vec!("-".to_string())
        } else {
            matches.free
        };
        match hashsum(name, algo, files, binary, check, tag, status, quiet, strict, warn) {
            Ok(()) => return 0,
            Err(e) => return e
        }
    }

    0
}

fn version() {
    pipe_println!("{} v{}", NAME, VERSION);
}

fn usage(program: &str, binary_name: &str, opts: &[getopts::OptGroup]) {
    version();
    pipe_println!("");
    pipe_println!("Usage:");
    if is_custom_binary(binary_name) {
        pipe_println!("  {} [OPTION]... [FILE]...", program);
    } else {
        pipe_println!("  {} {{--md5|--sha1|--sha224|--sha256|--sha384|--sha512}} [OPTION]... [FILE]...", program);
    }
    pipe_println!("");
    pipe_print!("{}", getopts::usage("Compute and check message digests.", opts));
}

fn hashsum(algoname: &str, mut digest: Box<Digest>, files: Vec<String>, binary: bool, check: bool, tag: bool, status: bool, quiet: bool, strict: bool, warn: bool) -> Result<(), int> {
    let mut bad_format = 0u;
    let mut failed = 0u;
    let binary_marker = if binary {
        "*"
    } else {
        " "
    };
    for filename in files.iter() {
        let filename: &str = filename.as_slice();
        let mut stdin_buf;
        let mut file_buf;
        let mut file = BufferedReader::new(
            if filename == "-" {
                stdin_buf = stdin_raw();
                &mut stdin_buf as &mut Reader
            } else {
                file_buf = safe_unwrap!(File::open(&Path::new(filename)));
                &mut file_buf as &mut Reader
            }
        );
        if check {
            // Set up Regexes for line validation and parsing
            let bytes = digest.output_bits() / 4;
            let gnu_re = safe_unwrap!(
                Regex::new(
                    format!(
                        r"^(?P<digest>[a-fA-F0-9]{{{}}}) (?P<binary>[ \*])(?P<fileName>.*)",
                        bytes
                    ).as_slice()
                )
            );
            let bsd_re = safe_unwrap!(
                Regex::new(
                    format!(
                        r"^{algorithm} \((?P<fileName>.*)\) = (?P<digest>[a-fA-F0-9]{{{digest_size}}})",
                        algorithm = algoname,
                        digest_size = bytes
                    ).as_slice()
                )
            );

            let mut buffer = file;
            for (i, line) in buffer.lines().enumerate() {
                let line = safe_unwrap!(line);
                let (ck_filename, sum, binary_check): (_, Vec<Ascii>, _) = match gnu_re.captures(line.as_slice()) {
                    Some(caps) => (caps.name("fileName").unwrap(),
                                   caps.name("digest").unwrap().to_ascii().iter().map(|ch| ch.to_lowercase()).collect(),
                                   caps.name("binary").unwrap() == "*"),
                    None => match bsd_re.captures(line.as_slice()) {
                        Some(caps) => (caps.name("fileName").unwrap(),
                                       caps.name("digest").unwrap().to_ascii().iter().map(|ch| ch.to_lowercase()).collect(),
                                       true),
                        None => {
                            bad_format += 1;
                            if strict {
                                return Err(1);
                            }
                            if warn {
                                show_warning!("{}: {}: improperly formatted {} checksum line", filename, i + 1, algoname);
                            }
                            continue;
                        }
                    }
                };
                let real_sum: Vec<Ascii> = safe_unwrap!(digest_reader(&mut digest, &mut safe_unwrap!(File::open(&Path::new(ck_filename))), binary_check))
                    .as_slice().to_ascii().iter().map(|ch| ch.to_lowercase()).collect();
                if sum.as_slice() == real_sum.as_slice() {
                    if !quiet {
                        pipe_println!("{}: OK", ck_filename);
                    }
                } else {
                    if !status {
                        pipe_println!("{}: FAILED", ck_filename);
                    }
                    failed += 1;
                }
            }
        } else {
            let sum = safe_unwrap!(digest_reader(&mut digest, &mut file, binary));
            if tag {
                pipe_println!("{} ({}) = {}", algoname, filename, sum);
            } else {
                pipe_println!("{} {}{}", sum, binary_marker, filename);
            }
        }
    }
    if !status {
        if bad_format == 1 {
            show_warning!("{} line is improperly formatted", bad_format);
        } else if bad_format > 1 {
            show_warning!("{} lines are improperly formatted", bad_format);
        }
        if failed > 0 {
            show_warning!("{} computed checksum did NOT match", failed);
        }
    }

    Ok(())
}

fn digest_reader(digest: &mut Box<Digest>, reader: &mut Reader, binary: bool) -> Result<String, IoError> {
    digest.reset();

    // Digest file, do not hold too much in memory at any given moment
    let windows = cfg!(windows);
    let mut buffer = [0, ..524288];
    let mut vec = Vec::with_capacity(524288);
    let mut looking_for_newline = false;
    loop {
        match reader.read(&mut buffer) {
            Ok(0) => {},
            Ok(nread) => {
                if windows && !binary {
                    // Windows text mode returns '\n' when reading '\r\n'
                    for i in range(0, nread) {
                        if looking_for_newline {
                            if buffer[i] != ('\n' as u8) {
                                vec.push('\r' as u8);
                            }
                            if buffer[i] != ('\r' as u8) {
                                vec.push(buffer[i]);
                                looking_for_newline = false;
                            }
                        } else if buffer[i] != ('\r' as u8) {
                            vec.push(buffer[i]);
                        } else {
                            looking_for_newline = true;
                        }
                    }
                    digest.input(vec.as_slice());
                    vec.clear();
                } else {
                    digest.input(buffer.slice(0, nread));
                }
            },
            Err(e) => match e.kind {
                EndOfFile => {
                    break;
                },
                _ => {
                    return Err(e);
                }
            }
        }
    }
    if windows && looking_for_newline {
        vec.push('\r' as u8);
        digest.input(vec.as_slice());
    }

    Ok(digest.result_str())
}
<commit_msg>Fix a mismatched types compilation error<commit_after>#![crate_name = "hashsum"]

/*
 * This file is part of the uutils coreutils package.
 *
 * (c) Arcterus <arcterus@mail.com>
 * (c) Vsevolod Velichko <torkvemada@sorokdva.net>
 * (c) Gil Cottle <gcottle@redtown.org>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

#![feature(macro_rules)]

extern crate regex;

extern crate crypto;
extern crate getopts;

use std::io::fs::File;
use std::io::stdio::stdin_raw;
use std::io::BufferedReader;
use std::io::IoError;
use std::io::EndOfFile;
use regex::Regex;
use crypto::digest::Digest;
use crypto::md5::Md5;
use crypto::sha1::Sha1;
use crypto::sha2::{Sha224, Sha256, Sha384, Sha512};

#[path = "../common/util.rs"]
mod util;

static NAME: &'static str = "hashsum";
static VERSION: &'static str = "1.0.0";

fn is_custom_binary(program: &str) -> bool {
    match program {
        "md5sum" | "sha1sum"
            | "sha224sum" | "sha256sum"
            | "sha384sum" | "sha512sum" => true,
        _ => false
    }
}

fn get_algo_opts(program: &str) -> Vec<getopts::OptGroup> {
    if is_custom_binary(program) {
        Vec::new()
    } else {
        vec!(
            getopts::optflag("", "md5", "work with MD5"),
            getopts::optflag("", "sha1", "work with SHA1"),
            getopts::optflag("", "sha224", "work with SHA224"),
            getopts::optflag("", "sha256", "work with SHA256"),
            getopts::optflag("", "sha384", "work with SHA384"),
            getopts::optflag("", "sha512", "work with SHA512")
        )
    }
}

fn detect_algo(program: &str, matches: &getopts::Matches) -> (&'static str, Box<Digest+'static>) {
    let mut alg: Option<Box<Digest>> = None;
    let mut name: &'static str = "";
    match program {
        "md5sum" => ("MD5", box Md5::new() as Box<Digest>),
        "sha1sum" => ("SHA1", box Sha1::new() as Box<Digest>),
        "sha224sum" => ("SHA224", box Sha224::new() as Box<Digest>),
        "sha256sum" => ("SHA256", box Sha256::new() as Box<Digest>),
        "sha384sum" => ("SHA384", box Sha384::new() as Box<Digest>),
        "sha512sum" => ("SHA512", box Sha512::new() as Box<Digest>),
        _ => {
            {
                let set_or_crash = |n, val| -> () {
                    if alg.is_some() { crash!(1, "You cannot combine multiple hash algorithms!") };
                    name = n;
                    alg = Some(val);
                };
                if matches.opt_present("md5") { set_or_crash("MD5", box Md5::new()) };
                if matches.opt_present("sha1") { set_or_crash("SHA1", box Sha1::new()) };
                if matches.opt_present("sha224") { set_or_crash("SHA224", box Sha224::new()) };
                if matches.opt_present("sha256") { set_or_crash("SHA256", box Sha256::new()) };
                if matches.opt_present("sha384") { set_or_crash("SHA384", box Sha384::new()) };
                if matches.opt_present("sha512") { set_or_crash("SHA512", box Sha512::new()) };
            }
            if alg.is_none() { crash!(1, "You must specify hash algorithm!") };
            (name, alg.unwrap())
        }
    }
}

pub fn uumain(args: Vec<String>) -> int {
    let program = args[0].clone();
    let binary = Path::new(program.as_slice());
    let binary_name = binary.filename_str().unwrap();

    // Default binary in Windows, text mode otherwise
    let binary_flag_default = cfg!(windows);

    let mut opts: Vec<getopts::OptGroup> = vec!(
        getopts::optflag("b", "binary", format!("read in binary mode{}", if binary_flag_default { " (default)" } else { "" }).as_slice()),
        getopts::optflag("c", "check", "read hashsums from the FILEs and check them"),
        getopts::optflag("", "tag", "create a BSD-style checksum"),
        getopts::optflag("t", "text", format!("read in text mode{}", if binary_flag_default { "" } else { " (default)" }).as_slice()),
        getopts::optflag("q", "quiet", "don't print OK for each successfully verified file"),
        getopts::optflag("s", "status", "don't output anything, status code shows success"),
        getopts::optflag("", "strict", "exit non-zero for improperly formatted checksum lines"),
        getopts::optflag("w", "warn", "warn about improperly formatted checksum lines"),
        getopts::optflag("h", "help", "display this help and exit"),
        getopts::optflag("V", "version", "output version information and exit"),
    );

    opts.extend(get_algo_opts(binary_name.as_slice()).into_iter());

    let matches = match getopts::getopts(args.tail(), opts.as_slice()) {
        Ok(m) => m,
        Err(f) => crash!(1, "{}", f)
    };

    if matches.opt_present("help") {
        usage(program.as_slice(), binary_name.as_slice(), opts.as_slice());
    } else if matches.opt_present("version") {
        version();
    } else {
        let (name, algo) = detect_algo(binary_name.as_slice(), &matches);

        let binary_flag = matches.opt_present("binary");
        let text_flag = matches.opt_present("text");
        if binary_flag && text_flag {
            crash!(1, "cannot set binary and text mode at the same time");
        }
        let binary = if binary_flag { true } else if text_flag { false } else { binary_flag_default };
        let check = matches.opt_present("check");
        let tag = matches.opt_present("tag");
        let status = matches.opt_present("status");
        let quiet = matches.opt_present("quiet") || status;
        let strict = matches.opt_present("strict");
        let warn = matches.opt_present("warn") && !status;
        let files = if matches.free.is_empty() {
            vec!("-".to_string())
        } else {
            matches.free
        };
        match hashsum(name, algo, files, binary, check, tag, status, quiet, strict, warn) {
            Ok(()) => return 0,
            Err(e) => return e
        }
    }

    0
}

fn version() {
    pipe_println!("{} v{}", NAME, VERSION);
}

fn usage(program: &str, binary_name: &str, opts: &[getopts::OptGroup]) {
    version();
    pipe_println!("");
    pipe_println!("Usage:");
    if is_custom_binary(binary_name) {
        pipe_println!("  {} [OPTION]... [FILE]...", program);
    } else {
        pipe_println!("  {} {{--md5|--sha1|--sha224|--sha256|--sha384|--sha512}} [OPTION]... [FILE]...", program);
    }
    pipe_println!("");
    pipe_print!("{}", getopts::usage("Compute and check message digests.", opts));
}

fn hashsum(algoname: &str, mut digest: Box<Digest>, files: Vec<String>, binary: bool, check: bool, tag: bool, status: bool, quiet: bool, strict: bool, warn: bool) -> Result<(), int> {
    let mut bad_format = 0u;
    let mut failed = 0u;
    let binary_marker = if binary {
        "*"
    } else {
        " "
    };
    for filename in files.iter() {
        let filename: &str = filename.as_slice();
        let mut stdin_buf;
        let mut file_buf;
        let mut file = BufferedReader::new(
            if filename == "-" {
                stdin_buf = stdin_raw();
                &mut stdin_buf as &mut Reader
            } else {
                file_buf = safe_unwrap!(File::open(&Path::new(filename)));
                &mut file_buf as &mut Reader
            }
        );
        if check {
            // Set up Regexes for line validation and parsing
            let bytes = digest.output_bits() / 4;
            let gnu_re = safe_unwrap!(
                Regex::new(
                    format!(
                        r"^(?P<digest>[a-fA-F0-9]{{{}}}) (?P<binary>[ \*])(?P<fileName>.*)",
                        bytes
                    ).as_slice()
                )
            );
            let bsd_re = safe_unwrap!(
                Regex::new(
                    format!(
                        r"^{algorithm} \((?P<fileName>.*)\) = (?P<digest>[a-fA-F0-9]{{{digest_size}}})",
                        algorithm = algoname,
                        digest_size = bytes
                    ).as_slice()
                )
            );

            let mut buffer = file;
            for (i, line) in buffer.lines().enumerate() {
                let line = safe_unwrap!(line);
                let (ck_filename, sum, binary_check): (_, Vec<Ascii>, _) = match gnu_re.captures(line.as_slice()) {
                    Some(caps) => (caps.name("fileName").unwrap(),
                                   caps.name("digest").unwrap().to_ascii().iter().map(|ch| ch.to_lowercase()).collect(),
                                   caps.name("binary").unwrap() == "*"),
                    None => match bsd_re.captures(line.as_slice()) {
                        Some(caps) => (caps.name("fileName").unwrap(),
                                       caps.name("digest").unwrap().to_ascii().iter().map(|ch| ch.to_lowercase()).collect(),
                                       true),
                        None => {
                            bad_format += 1;
                            if strict {
                                return Err(1);
                            }
                            if warn {
                                show_warning!("{}: {}: improperly formatted {} checksum line", filename, i + 1, algoname);
                            }
                            continue;
                        }
                    }
                };
                let mut ckf = safe_unwrap!(File::open(&Path::new(ck_filename)));
                let real_sum: Vec<Ascii> = safe_unwrap!(digest_reader(&mut digest, &mut ckf, binary_check))
                    .as_slice().to_ascii().iter().map(|ch| ch.to_lowercase()).collect();
                if sum.as_slice() == real_sum.as_slice() {
                    if !quiet {
                        pipe_println!("{}: OK", ck_filename);
                    }
                } else {
                    if !status {
                        pipe_println!("{}: FAILED", ck_filename);
                    }
                    failed += 1;
                }
            }
        } else {
            let sum = safe_unwrap!(digest_reader(&mut digest, &mut file, binary));
            if tag {
                pipe_println!("{} ({}) = {}", algoname, filename, sum);
            } else {
                pipe_println!("{} {}{}", sum, binary_marker, filename);
            }
        }
    }
    if !status {
        if bad_format == 1 {
            show_warning!("{} line is improperly formatted", bad_format);
        } else if bad_format > 1 {
            show_warning!("{} lines are improperly formatted", bad_format);
        }
        if failed > 0 {
            show_warning!("{} computed checksum did NOT match", failed);
        }
    }

    Ok(())
}

fn digest_reader(digest: &mut Box<Digest>, reader: &mut Reader, binary: bool) -> Result<String, IoError> {
    digest.reset();

    // Digest file, do not hold too much in memory at any given moment
    let windows = cfg!(windows);
    let mut buffer = [0, ..524288];
    let mut vec = Vec::with_capacity(524288);
    let mut looking_for_newline = false;
    loop {
        match reader.read(&mut buffer) {
            Ok(0) => {},
            Ok(nread) => {
                if windows && !binary {
                    // Windows text mode returns '\n' when reading '\r\n'
                    for i in range(0, nread) {
                        if looking_for_newline {
                            if buffer[i] != ('\n' as u8) {
                                vec.push('\r' as u8);
                            }
                            if buffer[i] != ('\r' as u8) {
                                vec.push(buffer[i]);
                                looking_for_newline = false;
                            }
                        } else if buffer[i] != ('\r' as u8) {
                            vec.push(buffer[i]);
                        } else {
                            looking_for_newline = true;
                        }
                    }
                    digest.input(vec.as_slice());
                    vec.clear();
                } else {
                    digest.input(buffer.slice(0, nread));
                }
            },
            Err(e) => match e.kind {
                EndOfFile => {
                    break;
                },
                _ => {
                    return Err(e);
                }
            }
        }
    }
    if windows && looking_for_newline {
        vec.push('\r' as u8);
        digest.input(vec.as_slice());
    }

    Ok(digest.result_str())
}
<|endoftext|>


<commit_before>extern crate rand;

#[macro_use]
extern crate lazy_static;

use rand::{XorShiftRng, Rng, thread_rng, SeedableRng};
use std::fmt;
use std::fmt::{Formatter, Debug};
use std::sync::Mutex;

trait Specimen: Sized {
    fn fitness(&self) -> f32;
    fn reevaluate(&mut self);
    fn mutate(generation: &mut[Self], rng: &mut XorShiftRng);
    fn breed(parents: &[Self], rng: &mut XorShiftRng) -> Self;
    fn filter_strongest(species: &mut Vec<Self>);

    fn initial() -> Vec<Self>;
}

fn genetic<S: Specimen>(threshold: f32, max_iters: usize, nparents: usize, nchildren: usize) -> S {
    let mut species: Vec<S> = S::initial();
    let mut best = (::std::f32::MAX, 0);
    for _ in 0..max_iters {
        species = next_gen(species, nparents, nchildren);

        for (i, specimen) in species.iter().enumerate() {
            let fitness = specimen.fitness();
            if fitness <= best.0 {
                best = (fitness, i)
            }
        }

        if best.0 <= threshold {
            println!("found!");
            break;
        }
    }

    species.swap_remove(best.1)
}

#[inline(never)]
fn next_gen<S: Specimen>(mut species: Vec<S>, nparents: usize, nchildren: usize) -> Vec<S> {
    let mut rng = RNG.lock().unwrap();

    // 1. filter strongest
    S::filter_strongest(&mut species);

    // 2. bear children
    let mut children = vec![];
    let mut family = vec![];
    for _ in 0..nchildren {
        make_family(&mut species, nparents, &mut family, &mut rng);
        let child = S::breed(&family, &mut rng);
        children.push(child);
        species.extend(family.drain(..));
    }

    // 3. mutate
    S::mutate(&mut children, &mut rng);
    for child in children.iter_mut() {
        child.reevaluate();
    }

    if KILL_PARENTS {
        children
    } else {
        species.extend(children);
        species
    }
}

fn make_family<S: Specimen>(species: &mut Vec<S>, nparents: usize, family: &mut Vec<S>, rng: &mut XorShiftRng) {
    assert!(family.is_empty());
    for _ in 0..nparents {
        let next = rng.gen_range(0, species.len());
        let s = species.swap_remove(next);
        family.push(s);
    }
}

//---------------------------------------------------

// BEST FOR SIZE=1000
//const KILL_PARENTS: bool = true;
//const SIZE: usize = 1000;
//const MUTATION_PROBABILITY: f32 = 1.0f32;
//const POPULATION: usize = 2;
//const MAX_ITERS: usize = 5000;
//const NPARENTS: usize = 2;
//const NCHILDREN: usize = 355;
const KILL_PARENTS: bool = true;
const SIZE: usize = 1000;
const MUTATION_PROBABILITY: f32 = 1.0f32;
//const ELITE: usize = 4;
const ELITE: usize = 5;
const MAX_ITERS: usize = 5000;
const NPARENTS: usize = 2;
//const NCHILDREN: usize = 130;
const NCHILDREN: usize = 230;

//
//const KILL_PARENTS: bool = true;
//const SIZE: usize = 10000;
//const MUTATION_PROBABILITY: f32 = 1.0f32;
//const POPULATION: usize = 20;
//const MAX_ITERS: usize = 5000;
//const NPARENTS: usize = 2;
//const NCHILDREN: usize = 1000;

lazy_static! {
    static ref RNG: Mutex<XorShiftRng> = Mutex::new(XorShiftRng::new_unseeded());
}

struct Board {
    fitness: f32,
    queens: Vec<usize>,
}

impl Board {
    fn new(queens: Vec<usize>) -> Board {
        Board { fitness: ::std::f32::MAX, queens: queens }
    }

    #[inline(never)]
    fn do_mutate(&mut self, rng: &mut XorShiftRng) {
        let i = rng.gen_range(0, SIZE);
        let mut j = rng.gen_range(0, SIZE-1);

        if j >= i {
            j += 1;
        }

        let t = self.queens[i];
        self.queens[i] = self.queens[j];
        self.queens[j] = t;
    }

    fn breed_pmx_norng(parents: &[Self], rng: &mut XorShiftRng) -> Self {
        let mut child = Board::new(parents[0].queens.clone());

        // A very important assert! Without it, the program runs twice slower! o_O
        assert!(parents.len() == NPARENTS);

        {
            let cq: &mut [usize] = &mut child.queens;
            let mut inverse = vec![0; SIZE];
            for i in 0..SIZE {
                let y = cq[i];
                inverse[y] = i;
            }

            let mut x = rng.gen_range(0, SIZE);
            for _ in 0..SIZE/2 {
                x += 1;
                if x == SIZE {
                    x = 0;
                }

                let parent = 1;
                let mother_y = cq[x];
                let father_y = parents[parent].queens[x];
                let father_x = inverse[father_y];
                cq[father_x] = mother_y;
                cq[x] = father_y;
                inverse[mother_y] = father_x;
                if NPARENTS > 2 {
                    // Optimization: this is not required when NPARENTS==2
                    inverse[father_y] = x;
                }
            }
        }

        child
    }

    // The algorithm is described in "Genetic Algorithm Solution of the TSP Avoiding Special Crossover and Mutation"
    // http://user.ceng.metu.edu.tr/~ucoluk/research/publications/tspnew.pdf
    #[inline(never)]
    fn breed_pmx(parents: &[Self], rng: &mut XorShiftRng) -> Self {
        // A very important assert! Without it, the program runs twice slower! o_O
        assert!(parents.len() == NPARENTS);

        let mut child = Board::new(parents[0].queens.clone());
        {
            let mut inverse = vec![0; SIZE];
            let cq = &mut child.queens;
            for i in 0..SIZE {
                let y = cq[i];
                inverse[y] = i;
            }

            for x in 0..SIZE {
                let parent = rng.gen_range(0, parents.len());
                if parent == 1 {
                    let mother_y = cq[x];
                    let father_y = parents[parent].queens[x];
                    let father_x = inverse[father_y];
                    cq[father_x] = mother_y;
                    cq[x] = father_y;
                    inverse[mother_y] = father_x;
                    if NPARENTS > 2 { // Optimization: this is not required when NPARENTS==2
                        inverse[father_y] = x;
                    }
                }
            }
        }

        child
    }

//    fn permutation_valid(p: &[usize]) -> bool {
//        let mut used = vec![0; p.len()];
//        for &i in p.iter() {
//            used[i] = 1;
//        }
//        for &u in used.iter() {
//            if u != 1 {
//                return false;
//            }
//        }
//
//        true
//    }
}

impl Specimen for Board {
    #[inline(never)]
    fn reevaluate(&mut self) {
        let q: &[usize] = &self.queens;
        let mut diag_counts = vec![0; 4*SIZE-2];
        let (diag_counts1, diag_counts2) = diag_counts.split_at_mut(2*SIZE-1);
        for x in 0..SIZE {
            let d1 = SIZE-1 + x - q[x];
            let d2 = x + q[x];
            diag_counts1[d1] += 1;
            diag_counts2[d2] += 1;
        }

        let mut f = 0;
        for x in 0..SIZE {
            let d1 = SIZE-1 + x - q[x];
            let d2 = x + q[x];
            f += diag_counts1[d1] + diag_counts2[d2];
        }

        self.fitness = f as f32;
    }

    fn fitness(&self) -> f32 {
        self.fitness
    }

    #[inline(never)]
    fn mutate(new_gen: &mut [Self], rng: &mut XorShiftRng) {
        for board in new_gen.iter_mut() {
            if rng.next_f32() < MUTATION_PROBABILITY {
                board.do_mutate(rng);
            }
        }
    }

    #[inline(never)]
    fn breed(parents: &[Self], rng: &mut XorShiftRng) -> Self {
//        Self::breed_pmx(parents, rng)
        Self::breed_pmx_norng(parents, rng)
    }

    #[inline(never)]
    fn filter_strongest(species: &mut Vec<Self>) {
        if species.len() <= ELITE {
            return;
        }

        species.sort_by(|s, t| s.fitness.partial_cmp(&t.fitness).unwrap());
        species.truncate(ELITE);
    }

    #[inline(never)]
    fn initial() -> Vec<Self> {
        let mut boards = Vec::with_capacity(NCHILDREN);

        let mut ys = Vec::with_capacity(SIZE);

        let mut rng = RNG.lock().unwrap();
        for _ in 0..NCHILDREN {
            let mut board = Board::new(Vec::with_capacity(SIZE));

            for y in 0..SIZE {
                ys.push(y);
            }

            for _ in 0..SIZE {
                let z = rng.gen_range(0, ys.len());
                let y = ys.swap_remove(z);
                board.queens.push(y);
            }

            board.reevaluate();
            boards.push(board);
        }
        boards
    }
}

impl Debug for Board {
    fn fmt(&self, f: &mut Formatter) -> fmt::Result {
        write!(f, "fitness={}, queens=[{:?}]", self.fitness, self.queens)
    }
}

fn genetic_queens() {
    {
        let mut rng = RNG.lock().unwrap();
        let mut trng = thread_rng();
        rng.reseed([trng.next_u32(), trng.next_u32(), trng.next_u32(), trng.next_u32()]);
    }

    let best = genetic::<Board>((2*SIZE) as f32 + 0.01, MAX_ITERS, NPARENTS, NCHILDREN);
    println!("best: {:?}", &best);
}

fn main() {
    for _ in 0..10 {
        genetic_queens()
    }
}

<commit_msg>a better configuration for breed_pmx_norng<commit_after>extern crate rand;

#[macro_use]
extern crate lazy_static;

use rand::{XorShiftRng, Rng, thread_rng, SeedableRng};
use std::fmt;
use std::fmt::{Formatter, Debug};
use std::sync::Mutex;

trait Specimen: Sized {
    fn fitness(&self) -> f32;
    fn reevaluate(&mut self);
    fn mutate(generation: &mut[Self], rng: &mut XorShiftRng);
    fn breed(parents: &[Self], rng: &mut XorShiftRng) -> Self;
    fn filter_strongest(species: &mut Vec<Self>);

    fn initial() -> Vec<Self>;
}

fn genetic<S: Specimen>(threshold: f32, max_iters: usize, nparents: usize, nchildren: usize) -> S {
    let mut species: Vec<S> = S::initial();
    let mut best = (::std::f32::MAX, 0);
    for _ in 0..max_iters {
        species = next_gen(species, nparents, nchildren);

        for (i, specimen) in species.iter().enumerate() {
            let fitness = specimen.fitness();
            if fitness <= best.0 {
                best = (fitness, i)
            }
        }

        if best.0 <= threshold {
            println!("found!");
            break;
        }
    }

    species.swap_remove(best.1)
}

#[inline(never)]
fn next_gen<S: Specimen>(mut species: Vec<S>, nparents: usize, nchildren: usize) -> Vec<S> {
    let mut rng = RNG.lock().unwrap();

    // 1. filter strongest
    S::filter_strongest(&mut species);

    // 2. bear children
    let mut children = vec![];
    let mut family = vec![];
    for _ in 0..nchildren {
        make_family(&mut species, nparents, &mut family, &mut rng);
        let child = S::breed(&family, &mut rng);
        children.push(child);
        species.extend(family.drain(..));
    }

    // 3. mutate
    S::mutate(&mut children, &mut rng);
    for child in children.iter_mut() {
        child.reevaluate();
    }

    if KILL_PARENTS {
        children
    } else {
        species.extend(children);
        species
    }
}

fn make_family<S: Specimen>(species: &mut Vec<S>, nparents: usize, family: &mut Vec<S>, rng: &mut XorShiftRng) {
    assert!(family.is_empty());
    for _ in 0..nparents {
        let next = rng.gen_range(0, species.len());
        let s = species.swap_remove(next);
        family.push(s);
    }
}

//---------------------------------------------------

// BEST FOR SIZE=1000
//const ELITE: usize = 3;
//const NCHILDREN: usize = 65;
//const KILL_PARENTS: bool = false;
//const SIZE: usize = 1000;
//const MUTATION_PROBABILITY: f32 = 1.0f32;
//const MAX_ITERS: usize = 5000;
//const NPARENTS: usize = 2;

//const ELITE: usize = 4;
//const NCHILDREN: usize = 130;
//const KILL_PARENTS: bool = true;
const ELITE: usize = 3;
const NCHILDREN: usize = 65;
const KILL_PARENTS: bool = false;
const SIZE: usize = 1000;
const MUTATION_PROBABILITY: f32 = 1.0f32;
const MAX_ITERS: usize = 5000;
const NPARENTS: usize = 2;

//
//const KILL_PARENTS: bool = true;
//const SIZE: usize = 10000;
//const MUTATION_PROBABILITY: f32 = 1.0f32;
//const POPULATION: usize = 20;
//const MAX_ITERS: usize = 5000;
//const NPARENTS: usize = 2;
//const NCHILDREN: usize = 1000;

lazy_static! {
    static ref RNG: Mutex<XorShiftRng> = Mutex::new(XorShiftRng::new_unseeded());
}

struct Board {
    fitness: f32,
    queens: Vec<usize>,
}

impl Board {
    fn new(queens: Vec<usize>) -> Board {
        Board { fitness: ::std::f32::MAX, queens: queens }
    }

    #[inline(never)]
    fn do_mutate(&mut self, rng: &mut XorShiftRng) {
        let i = rng.gen_range(0, SIZE);
        let mut j = rng.gen_range(0, SIZE-1);

        if j >= i {
            j += 1;
        }

        let t = self.queens[i];
        self.queens[i] = self.queens[j];
        self.queens[j] = t;
    }

    fn breed_pmx_norng(parents: &[Self], rng: &mut XorShiftRng) -> Self {
        let mut child = Board::new(parents[0].queens.clone());

        // A very important assert! Without it, the program runs twice slower! o_O
        assert!(parents.len() == NPARENTS);

        {
            let cq: &mut [usize] = &mut child.queens;
            let mut inverse = vec![0; SIZE];
            for i in 0..SIZE {
                let y = cq[i];
                inverse[y] = i;
            }

            let mut x = rng.gen_range(0, SIZE);
            for _ in 0..SIZE/2 {
                x += 1;
                if x == SIZE {
                    x = 0;
                }

                let parent = 1;
                let mother_y = cq[x];
                let father_y = parents[parent].queens[x];
                let father_x = inverse[father_y];
                cq[father_x] = mother_y;
                cq[x] = father_y;
                inverse[mother_y] = father_x;
                if NPARENTS > 2 {
                    // Optimization: this is not required when NPARENTS==2
                    inverse[father_y] = x;
                }
            }
        }

        child
    }

    // The algorithm is described in "Genetic Algorithm Solution of the TSP Avoiding Special Crossover and Mutation"
    // http://user.ceng.metu.edu.tr/~ucoluk/research/publications/tspnew.pdf
    #[inline(never)]
    fn breed_pmx(parents: &[Self], rng: &mut XorShiftRng) -> Self {
        // A very important assert! Without it, the program runs twice slower! o_O
        assert!(parents.len() == NPARENTS);

        let mut child = Board::new(parents[0].queens.clone());
        {
            let mut inverse = vec![0; SIZE];
            let cq = &mut child.queens;
            for i in 0..SIZE {
                let y = cq[i];
                inverse[y] = i;
            }

            for x in 0..SIZE {
                let parent = rng.gen_range(0, parents.len());
                if parent == 1 {
                    let mother_y = cq[x];
                    let father_y = parents[parent].queens[x];
                    let father_x = inverse[father_y];
                    cq[father_x] = mother_y;
                    cq[x] = father_y;
                    inverse[mother_y] = father_x;
                    if NPARENTS > 2 { // Optimization: this is not required when NPARENTS==2
                        inverse[father_y] = x;
                    }
                }
            }
        }

        child
    }

//    fn permutation_valid(p: &[usize]) -> bool {
//        let mut used = vec![0; p.len()];
//        for &i in p.iter() {
//            used[i] = 1;
//        }
//        for &u in used.iter() {
//            if u != 1 {
//                return false;
//            }
//        }
//
//        true
//    }
}

impl Specimen for Board {
    #[inline(never)]
    fn reevaluate(&mut self) {
        let q: &[usize] = &self.queens;
        let mut diag_counts = vec![0; 4*SIZE-2];
        let (diag_counts1, diag_counts2) = diag_counts.split_at_mut(2*SIZE-1);
        for x in 0..SIZE {
            let d1 = SIZE-1 + x - q[x];
            let d2 = x + q[x];
            diag_counts1[d1] += 1;
            diag_counts2[d2] += 1;
        }

        let mut f = 0;
        for x in 0..SIZE {
            let d1 = SIZE-1 + x - q[x];
            let d2 = x + q[x];
            f += diag_counts1[d1] + diag_counts2[d2];
        }

        self.fitness = f as f32;
    }

    fn fitness(&self) -> f32 {
        self.fitness
    }

    #[inline(never)]
    fn mutate(new_gen: &mut [Self], rng: &mut XorShiftRng) {
        for board in new_gen.iter_mut() {
            if rng.next_f32() < MUTATION_PROBABILITY {
                board.do_mutate(rng);
            }
        }
    }

    #[inline(never)]
    fn breed(parents: &[Self], rng: &mut XorShiftRng) -> Self {
//        Self::breed_pmx(parents, rng)
        Self::breed_pmx_norng(parents, rng)
    }

    #[inline(never)]
    fn filter_strongest(species: &mut Vec<Self>) {
        if species.len() <= ELITE {
            return;
        }

        species.sort_by(|s, t| s.fitness.partial_cmp(&t.fitness).unwrap());
        species.truncate(ELITE);
    }

    #[inline(never)]
    fn initial() -> Vec<Self> {
        let mut boards = Vec::with_capacity(NCHILDREN);

        let mut ys = Vec::with_capacity(SIZE);

        let mut rng = RNG.lock().unwrap();
        for _ in 0..NCHILDREN {
            let mut board = Board::new(Vec::with_capacity(SIZE));

            for y in 0..SIZE {
                ys.push(y);
            }

            for _ in 0..SIZE {
                let z = rng.gen_range(0, ys.len());
                let y = ys.swap_remove(z);
                board.queens.push(y);
            }

            board.reevaluate();
            boards.push(board);
        }
        boards
    }
}

impl Debug for Board {
    fn fmt(&self, f: &mut Formatter) -> fmt::Result {
        write!(f, "fitness={}, queens=[{:?}]", self.fitness, self.queens)
    }
}

fn genetic_queens() {
    {
        let mut rng = RNG.lock().unwrap();
        let mut trng = thread_rng();
        rng.reseed([trng.next_u32(), trng.next_u32(), trng.next_u32(), trng.next_u32()]);
    }

    let best = genetic::<Board>((2*SIZE) as f32 + 0.01, MAX_ITERS, NPARENTS, NCHILDREN);
    println!("best: {:?}", &best);
}

fn main() {
    for _ in 0..10 {
        genetic_queens()
    }
}

<|endoftext|>


<commit_before>extern crate iron;
extern crate router;

use iron::prelude::*;
use iron::status;
use router::Router;

fn main() {
    let mut router = Router::new();

    fn index(_: &mut Request) -> IronResult<Response> {
        Ok(Response::with((status::Ok, "Hello World!")))
    }

    router.get("/", index);

    fn count(req: &mut Request) -> IronResult<Response> {
        let ref index = req.extensions.get::<Router>().unwrap().find("index").unwrap_or("");

        let mut payload = String::new();
        req.body.read_to_string(&mut payload).unwrap();

        // TODO

        let mut response = Response::with((status::Ok, "{\"count\": 0}"));
        response.headers.set_raw("Content-Type", vec![b"application/json".to_vec()]);
        Ok(response)
    }

    router.get("/:index/_count", count);

    fn search(req: &mut Request) -> IronResult<Response> {
        let ref index = req.extensions.get::<Router>().unwrap().find("index").unwrap_or("");

        let mut payload = String::new();
        req.body.read_to_string(&mut payload).unwrap();

        // TODO

        let mut response = Response::with((status::Ok, "{\"hits\": {\"total\": 0, \"hits\": []}}"));
        response.headers.set_raw("Content-Type", vec![b"application/json".to_vec()]);
        Ok(response)
    }

    router.get("/:index/_search", search);

    Iron::new(router).http("localhost:9200").unwrap();
}
<commit_msg>Basic put API<commit_after>extern crate iron;
extern crate router;

use std::io::Read;

use iron::prelude::*;
use iron::status;
use router::Router;

fn main() {
    let mut router = Router::new();

    fn index(_: &mut Request) -> IronResult<Response> {
        Ok(Response::with((status::Ok, "Hello World!")))
    }

    router.get("/", index);

    fn count(req: &mut Request) -> IronResult<Response> {
        let ref index = req.extensions.get::<Router>().unwrap().find("index").unwrap_or("");

        let mut payload = String::new();
        req.body.read_to_string(&mut payload).unwrap();

        // TODO

        let mut response = Response::with((status::Ok, "{\"count\": 0}"));
        response.headers.set_raw("Content-Type", vec![b"application/json".to_vec()]);
        Ok(response)
    }

    router.get("/:index/_count", count);

    fn search(req: &mut Request) -> IronResult<Response> {
        let ref index = req.extensions.get::<Router>().unwrap().find("index").unwrap_or("");

        let mut payload = String::new();
        req.body.read_to_string(&mut payload).unwrap();

        // TODO

        let mut response = Response::with((status::Ok, "{\"hits\": {\"total\": 0, \"hits\": []}}"));
        response.headers.set_raw("Content-Type", vec![b"application/json".to_vec()]);
        Ok(response)
    }

    router.get("/:index/_search", search);

    fn put(req: &mut Request) -> IronResult<Response> {
        let ref index = req.extensions.get::<Router>().unwrap().find("index").unwrap_or("");
        let ref mapping = req.extensions.get::<Router>().unwrap().find("mapping").unwrap_or("");
        let ref doc = req.extensions.get::<Router>().unwrap().find("doc").unwrap_or("");

        let mut payload = String::new();
        req.body.read_to_string(&mut payload).unwrap();

        // TODO

        let mut response = Response::with((status::Ok, "{}"));
        response.headers.set_raw("Content-Type", vec![b"application/json".to_vec()]);
        Ok(response)
    }

    router.put("/:index/:mapping/:doc", put);

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


<commit_before>use std::fs;
use std::io;
use std::path::Path;
use std::collections::BTreeMap;

use handlebars::{Handlebars, no_escape};

const SITE_TITLE: &str = "Grauwoelfchen's Workroom";
const DST_DIR: &str = "./dst";

const LINKS: [(&str, &str); 4] = [
    ("Home", "/"),
    ("About", "/about.html"),
    ("Software", "/software.html"),
    ("Link", "/link.html"),
];

#[derive(Debug)]
enum Error {
    Io(io::Error),
    Parse(handlebars::TemplateError),
    Render(handlebars::RenderError),
}

impl From<io::Error> for Error {
    fn from(error: io::Error) -> Self {
        Self::Io(error)
    }
}

impl From<handlebars::TemplateError> for Error {
    fn from(error: handlebars::TemplateError) -> Self {
        Self::Parse(error)
    }
}

impl From<handlebars::RenderError> for Error {
    fn from(error: handlebars::RenderError) -> Self {
        Self::Render(error)
    }
}

fn main() -> Result<(), Error> {
    let mut reg = Handlebars::new();

    let layout = include_str!("./layout.hbs");
    reg.register_template_string("layout", layout)?;
    reg.register_escape_fn(no_escape);

    let dst = Path::new(&DST_DIR);

    // error
    let dat = include_str!("./error.hbs");
    fs::write(dst.join("error.html"), &dat.as_bytes())?;

    // index
    let data = load("Home", include_str!("./index.hbs"));
    let result = reg.render("layout", &data)?;
    fs::write(dst.join("index.html"), result)?;

    // about
    let data = load("About", include_str!("./about.hbs"));
    let result = reg.render("layout", &data).unwrap();
    fs::write(dst.join("about.html"), result)?;

    // software
    let data = load("Software", include_str!("./software.hbs"));
    let result = reg.render("layout", &data).unwrap();
    fs::write(dst.join("software.html"), result)?;

    // link
    let data = load("Link", include_str!("./link.hbs"));
    let result = reg.render("layout", &data).unwrap();
    fs::write(dst.join("link.html"), result)?;

    reg.unregister_escape_fn();

    Ok(())
}

fn load(heading: &str, content: &str) -> BTreeMap<String, String> {
    let mut data = BTreeMap::new();

    let mut nav = "".to_string();
    for link in LINKS {
        let title = link.0;
        let href = link.1;

        let class = if title == heading {
            "active"
        } else {
            ""
        };
        let n = format!(r#"

  {}

"#,
            title,
            class,
            href,
            title,
        );
        nav = format!("{}{}", &nav, &n);
    }
    data.insert("navi".to_string(), nav);
    data.insert("content".to_string(), content.to_string());

    // meta
    if heading != "Home" {
        data.insert("page_title".to_string(), heading.to_string());
    }
    data.insert("site_title".to_string(), SITE_TITLE.to_string());
    data
}
<commit_msg>Fix navigations<commit_after>use std::fs;
use std::io;
use std::path::Path;
use std::collections::BTreeMap;

use handlebars::{Handlebars, no_escape};

const SITE_TITLE: &str = "Grauwoelfchen's Workroom";
const DST_DIR: &str = "./dst";

const LINKS: [(&str, &str); 4] = [
    ("Home", "/"),
    ("About", "/about.html"),
    ("Software", "/software.html"),
    ("Link", "/link.html"),
];

#[derive(Debug)]
enum Error {
    Io(io::Error),
    Parse(handlebars::TemplateError),
    Render(handlebars::RenderError),
}

impl From<io::Error> for Error {
    fn from(error: io::Error) -> Self {
        Self::Io(error)
    }
}

impl From<handlebars::TemplateError> for Error {
    fn from(error: handlebars::TemplateError) -> Self {
        Self::Parse(error)
    }
}

impl From<handlebars::RenderError> for Error {
    fn from(error: handlebars::RenderError) -> Self {
        Self::Render(error)
    }
}

fn main() -> Result<(), Error> {
    let mut reg = Handlebars::new();

    let layout = include_str!("./layout.hbs");
    reg.register_template_string("layout", layout)?;
    reg.register_escape_fn(no_escape);

    let dst = Path::new(&DST_DIR);

    // error
    let dat = include_str!("./error.hbs");
    fs::write(dst.join("error.html"), &dat.as_bytes())?;

    // index
    let data = load("Home", include_str!("./index.hbs"));
    let result = reg.render("layout", &data)?;
    fs::write(dst.join("index.html"), result)?;

    // about
    let data = load("About", include_str!("./about.hbs"));
    let result = reg.render("layout", &data).unwrap();
    fs::write(dst.join("about.html"), result)?;

    // software
    let data = load("Software", include_str!("./software.hbs"));
    let result = reg.render("layout", &data).unwrap();
    fs::write(dst.join("software.html"), result)?;

    // link
    let data = load("Link", include_str!("./link.hbs"));
    let result = reg.render("layout", &data).unwrap();
    fs::write(dst.join("link.html"), result)?;

    reg.unregister_escape_fn();

    Ok(())
}

/// Returns built an entry for navigations list.
fn build_nav(heading: &str, link: (&str, &str)) -> String {
    let title = link.0;
    let href = link.1;

    let class = if title == heading {
        " class=\"active\""
    } else {
        ""
    };
    format!(r#"

  {}

"#,
        class,
        href,
        title,
    )
}

fn load(heading: &str, content: &str) -> BTreeMap<String, String> {
    let mut data = BTreeMap::new();

    let mut nav = "".to_string();
    for link in LINKS {
        nav.push_str(&build_nav(heading, link));
    }
    data.insert("navi".to_string(), nav);
    data.insert("content".to_string(), content.to_string());

    // meta
    if heading != "Home" {
        data.insert("page_title".to_string(), heading.to_string());
    }
    data.insert("site_title".to_string(), SITE_TITLE.to_string());
    data
}

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

    #[test]
    fn test_build_nav() {
        let active = build_nav("Foo", ("Foo", "/foo.html"));
        assert_eq!(active, r#"

  Foo

"#);

        let inactive = build_nav("Bar", ("Foo", "/foo.html"));
        assert_eq!(inactive, r#"

  Foo

"#);
    }
}
<|endoftext|>


<commit_before>use std::io;

fn main() {
    let mut w = String::new();
    let mut k = String::new();

    println!("Type in a message to write");
    io::stdin().read_line(&mut w).expect("Error!");

    println!("Type in a key");
    io::stdin().read_line(&mut k).expect("Error!");

    let k: i32 = match k.trim().parse() {
        Ok(x) => x,
        Err(_) => 0
    };

    println!("Your translated string is\n{:?}", csr(w.trim(), k));
}

fn key_v(starting: &str, key: i32) -> Vec<char> {
    let k: i32 = key;
    let s = starting;

    let s_v: Vec<char> = s.chars().collect();
    let mut new_v: Vec<char> = Vec::new();

    let mut i: i32 = k-1;

    while i < (s_v.len() as i32) {
        new_v.push(s_v[(i as usize)]);
        i += 1;
    }

    let mut new_i = 0;
    while new_i <= k-2 {
        new_v.push(s_v[(new_i as usize)]);
        new_i += 1;
    }

    return new_v;
}

fn l_to_n(l: char) -> i16 {
    match l {
        'A' => 0,
        'B' => 1,
        'C' => 2,
        'D' => 3,
        'E' => 4,
        'F' => 5,
        'G' => 6,
        'H' => 7,
        'I' => 8,
        'J' => 9,
        'K' => 10,
        'L' => 11,
        'M' => 12,
        'N' => 13,
        'O' => 14,
        'P' => 15,
        'Q' => 16,
        'R' => 17,
        'S' => 18,
        'T' => 19,
        'U' => 20,
        'V' => 21,
        'W' => 22,
        'X' => 23,
        'Y' => 24,
        'Z' => 25,
        _ => 30
    }
}

fn csr_w(word: &str, key: i32) -> String {
    let starting = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
    let key_v = key_v(starting, key);

    let mut index_v: Vec<i16> = Vec::new();

    for l in word.to_uppercase().chars() {
        index_v.push(l_to_n(l));
    }

    let mut new_w_v: Vec<char> = Vec::new();

    for i in index_v {
        new_w_v.push(key_v[(i as usize)]);
    }

    let s: String = new_w_v.into_iter().collect();

    return s;
}

fn csr(word: &str, key: i32) -> Vec<String> {
    let sp_w: Vec<&str> = word.split(" ").collect();
    let mut w_v: Vec<String> = Vec::new();

    for cur_w in sp_w {
        w_v.push(csr_w(cur_w, key));
    }

    return w_v;
}
<commit_msg>Little fix in encipher algorithm<commit_after>use std::io;

fn main() {
    let mut w = String::new();
    let mut k = String::new();

    println!("Type in a message to write");
    io::stdin().read_line(&mut w).expect("Error!");

    println!("Type in a key");
    io::stdin().read_line(&mut k).expect("Error!");

    let k: i32 = match k.trim().parse() {
        Ok(x) => x,
        Err(_) => 0
    };

    println!("Your translated string is\n{:?}", encsr(w.trim(), k));
}

fn key_v(starting: &str, key: i32) -> Vec<char> {
    let k: i32 = key;
    let s = starting;

    let s_v: Vec<char> = s.chars().collect();
    let mut new_v: Vec<char> = Vec::new();

    let mut i: i32 = k;

    while i < (s_v.len() as i32) {
        new_v.push(s_v[(i as usize)]);
        i += 1;
    }

    let mut new_i = 0;
    while new_i <= k-2 {
        new_v.push(s_v[(new_i as usize)]);
        new_i += 1;
    }

    return new_v;
}

fn l_to_n(l: char) -> i16 {
    match l {
        'A' => 0,
        'B' => 1,
        'C' => 2,
        'D' => 3,
        'E' => 4,
        'F' => 5,
        'G' => 6,
        'H' => 7,
        'I' => 8,
        'J' => 9,
        'K' => 10,
        'L' => 11,
        'M' => 12,
        'N' => 13,
        'O' => 14,
        'P' => 15,
        'Q' => 16,
        'R' => 17,
        'S' => 18,
        'T' => 19,
        'U' => 20,
        'V' => 21,
        'W' => 22,
        'X' => 23,
        'Y' => 24,
        'Z' => 25,
        _ => 30
    }
}

fn encsr_w(word: &str, key: i32) -> String {
    let starting = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
    let key_v = key_v(starting, key);

    let mut index_v: Vec<i16> = Vec::new();

    for l in word.to_uppercase().chars() {
        index_v.push(l_to_n(l));
    }

    let mut new_w_v: Vec<char> = Vec::new();

    for i in index_v {
        new_w_v.push(key_v[(i as usize)]);
    }

    let s: String = new_w_v.into_iter().collect();

    return s;
}

fn encsr(word: &str, key: i32) -> Vec<String> {
    let sp_w: Vec<&str> = word.split(" ").collect();
    let mut w_v: Vec<String> = Vec::new();

    for cur_w in sp_w {
        w_v.push(encsr_w(cur_w, key));
    }

    return w_v;
}
<|endoftext|>


<commit_before>
mod curses;

use std::ffi::CString;

use curses::*;

// TODO delete active rectangle
// TODO save to file (just save shape coords and types, etc)
// TODO load file

// TODO use struct with common fields and use an enum for unshared ones
enum DrawMe {
    Rec { width : i32, height : i32, x : i32, y : i32 },
    Character { c : char, x : i32, y : i32 },
}

enum Mode { Normal, EnterRec, MoveRec, EnterCharacter }

fn inc_width( d : DrawMe ) -> DrawMe {
    match d {
        DrawMe::Rec { width, height, x, y } => DrawMe::Rec { width: width + 1, height: height, x: x, y: y },
        _ => panic!( "inc width encounters non-rec" ),
    }
}

fn inc_height( d : DrawMe ) -> DrawMe {
    match d {
        DrawMe::Rec { width, height, x, y } => DrawMe::Rec { width: width, height: height + 1, x: x, y: y },
        _ => panic!( "inc height encounters non-rec" ),
    }
}

fn dec_width( d : DrawMe ) -> DrawMe {
    match d {
        DrawMe::Rec { width, height, x, y } => DrawMe::Rec { width: width - 1, height: height, x: x, y: y },
        _ => panic!( "dec width encounters non-rec" ),
    }
}

fn dec_height( d : DrawMe ) -> DrawMe {
    match d {
        DrawMe::Rec { width, height, x, y } => DrawMe::Rec { width: width, height: height - 1, x: x, y: y },
        _ => panic!( "dec height encounters non-rec" ),
    }
}

fn inc_x( d : DrawMe ) -> DrawMe {
    match d {
        DrawMe::Rec { width, height, x, y } => DrawMe::Rec { width: width, height: height, x: x + 1, y: y },
        _ => panic!( "inc x encounters non-rec" ),
    }
}

fn inc_y( d : DrawMe ) -> DrawMe {
    match d {
        DrawMe::Rec { width, height, x, y } => DrawMe::Rec { width: width, height: height, x: x, y: y + 1 },
        _ => panic!( "inc y encounters non-rec" ),
    }
}

fn dec_x( d : DrawMe ) -> DrawMe {
    match d {
        DrawMe::Rec { width, height, x, y } => DrawMe::Rec { width: width, height: height, x: x - 1, y: y },
        _ => panic!( "dec x encounters non-rec" ),
    }
}

fn dec_y( d : DrawMe ) -> DrawMe {
    match d {
        DrawMe::Rec { width, height, x, y } => DrawMe::Rec { width: width, height: height, x: x, y: y - 1 },
        _ => panic!( "dec y encounters non-rec" ),
    }
}
fn mod_rec<F>( maybe_d : Option<DrawMe>, f : F ) -> Option<DrawMe>
    where F : Fn( DrawMe ) -> DrawMe {

    match maybe_d {
        Some( d ) => Some( f( d ) ),
        None => { None },
    }
}

unsafe fn render_shape( s : &DrawMe ) {
    match s {
        &DrawMe::Rec { width, height, x, y } => render_rec( width, height, x, y ),
        &DrawMe::Character { c, x, y } => render_character( c, x, y ),
        _ => (),
    }
}

unsafe fn render_character( c : char, x : i32, y : i32 ) {
    mvaddch( y + UserY, x + UserX, c );
}

unsafe fn render_rec( w : i32, h : i32, x : i32, y : i32 ) {
    let dot = CString::new( "." ).unwrap();
    let h_line = CString::new( "-" ).unwrap();
    let v_line = CString::new( "|" ).unwrap();
    let plus = CString::new( "+" ).unwrap();

    let mut h2 = h + 2;
    while h2 > 0 {
        let d : &CString = if h2 == h + 2 {
            &h_line
        } else if h2 == 1 {
            &h_line
        } else {
            &dot
        };
        let mut w2 = w;

        let other_d : &CString = if h2 == h + 2 {
            &plus
        } else if h2 == 1 {
            &plus
        } else {
            &v_line
        };
        mvprintw( y + h2 + UserY, x + w2 + 1 + UserX, other_d.as_ptr() );
        while w2 > 0 {
            mvprintw( y + h2 + UserY, x + w2 + UserX, d.as_ptr() );
            w2 -= 1;
        }
        mvprintw( y + h2 + UserY, x + UserX, other_d.as_ptr() );
        h2 -= 1;
    }
}

static mut UserX : i32 = 0;
static mut UserY : i32 = 0;

fn main() {
    let mut x = 0;
    let mut y = 0;
    unsafe {
        initscr();
        cbreak();
        noecho();

        let mut c = getch();
        let mut shapes : Vec<DrawMe> = vec! [];
        let mut mode : Mode = Mode::Normal;
        let mut active_rec : Option<DrawMe> = None;

        while c as u8 as char != 'q' {
            let c2 = c as u8 as char;

            match c2 {
                'c' => {
                    match mode {
                        Mode::Normal => {
                            mode = Mode::EnterCharacter;
                        },
                        Mode::EnterRec => {},
                        Mode::MoveRec => {},
                        Mode::EnterCharacter => {
                            shapes.push( DrawMe::Character{ c: 'c', x: x - UserX, y: y - UserY } );
                            mode = Mode::Normal;
                        },
                    }
                },
                'r' => {
                    match mode {
                        Mode::Normal => {
                            active_rec = Some( DrawMe::Rec { width: 0, height: 0, x: x - UserX, y: y - UserY });
                            mode = Mode::EnterRec;
                        },
                        Mode::EnterRec => {
                            mode = Mode::MoveRec;
                        },
                        Mode::MoveRec => {
                            mode = Mode::Normal;
                            shapes.push( active_rec.unwrap() );
                            active_rec = None;
                        },
                        Mode::EnterCharacter => {
                            shapes.push( DrawMe::Character{ c: 'r', x: x - UserX, y: y - UserY } );
                            mode = Mode::Normal;
                        },
                    }
                },
                'j' => {
                    match mode {
                        Mode::Normal => {
                            y+=1;
                        },
                        Mode::EnterRec => {
                            active_rec = mod_rec( active_rec, inc_height );
                        },
                        Mode::MoveRec => {
                            active_rec = mod_rec( active_rec, inc_y );
                        },

                        Mode::EnterCharacter => {
                            shapes.push( DrawMe::Character{ c: 'j', x: x - UserX, y: y - UserY } );
                            mode = Mode::Normal;
                        },
                    }
                },
                'k' => {
                    match mode {
                       Mode::Normal => {
                           y-=1;
                       },
                       Mode::EnterRec => {
                            active_rec = mod_rec( active_rec, dec_height );
                       },
                       Mode::MoveRec => {
                            active_rec = mod_rec( active_rec, dec_y );
                       },

                        Mode::EnterCharacter => {
                            shapes.push( DrawMe::Character{ c: 'k', x: x - UserX, y: y - UserY } );
                            mode = Mode::Normal;
                        },
                    }
                },
                'l' => {
                    match mode {
                        Mode::Normal => {
                            x+=1;
                        },
                        Mode::EnterRec => {
                            active_rec = mod_rec( active_rec, inc_width );
                        },
                        Mode::MoveRec => {
                            active_rec = mod_rec( active_rec, inc_x );
                        },
                        Mode::EnterCharacter => {
                            shapes.push( DrawMe::Character{ c: 'l', x: x - UserX, y: y - UserY } );
                            mode = Mode::Normal;
                        },

                    }
                },
                'h' => {
                    match mode {
                        Mode::Normal => {
                            x-=1;
                        },
                        Mode::EnterRec => {
                            active_rec = mod_rec( active_rec, dec_width );
                        },
                        Mode::MoveRec => {
                            active_rec = mod_rec( active_rec, dec_x );
                        },
                        Mode::EnterCharacter => {
                            shapes.push( DrawMe::Character{ c: 'h', x: x - UserX, y: y - UserY } );
                            mode = Mode::Normal;
                        },
                    }
                },
                'J' => {
                    match mode {
                        Mode::Normal => {
                            UserY += 1;
                        },
                        Mode::EnterCharacter => {
                            shapes.push( DrawMe::Character{ c: 'J', x: x - UserX, y: y - UserY } );
                            mode = Mode::Normal;
                        },
                        _ => {},
                    }
                },
                'K' => {
                    match mode {
                        Mode::Normal => {
                            UserY -= 1;
                        },
                        Mode::EnterCharacter => {
                            shapes.push( DrawMe::Character{ c: 'K', x: x - UserX, y: y - UserY } );
                            mode = Mode::Normal;
                        },
                        _ => {},
                    }
                },
                'L' => {
                    match mode {
                        Mode::Normal => {
                            UserX += 1;
                        },
                        Mode::EnterCharacter => {
                            shapes.push( DrawMe::Character{ c: 'L', x: x - UserX, y: y - UserY } );
                            mode = Mode::Normal;
                        },
                        _ => {},
                    }
                },
                'H' => {
                    match mode {
                        Mode::Normal => {
                            UserX -= 1;
                        },
                        Mode::EnterCharacter => {
                            shapes.push( DrawMe::Character{ c: 'H', x: x - UserX, y: y - UserY } );
                            mode = Mode::Normal;
                        },
                        _ => {},
                    }
                },
                c3 @ _ => {
                    match mode {
                        Mode::EnterCharacter => {
                            shapes.push( DrawMe::Character{ c: c3, x: x - UserX, y: y - UserY } );
                            mode = Mode::Normal;
                        },
                        _ => {},
                    }
                },

            }

            clear();

            match active_rec {
                Some( ref shape ) => render_shape( &shape ),
                None => {},
            }

            for s in &shapes {
                render_shape( s );
            }

            cursor_move( y, x );
            refresh();

            c = getch();
        }

        endwin();
    }
}

<commit_msg>started adding file io stuff<commit_after>
mod curses;

use std::ffi::CString;

use std::env::args;
use std::path::Path;
use std::fs::File;

use curses::*;

// TODO delete active rectangle
// TODO save to file (just save shape coords and types, etc)
// TODO load file

// TODO use struct with common fields and use an enum for unshared ones
enum DrawMe {
    Rec { width : i32, height : i32, x : i32, y : i32 },
    Character { c : char, x : i32, y : i32 },
}

enum Mode { Normal, EnterRec, MoveRec, EnterCharacter }

fn inc_width( d : DrawMe ) -> DrawMe {
    match d {
        DrawMe::Rec { width, height, x, y } => DrawMe::Rec { width: width + 1, height: height, x: x, y: y },
        _ => panic!( "inc width encounters non-rec" ),
    }
}

fn inc_height( d : DrawMe ) -> DrawMe {
    match d {
        DrawMe::Rec { width, height, x, y } => DrawMe::Rec { width: width, height: height + 1, x: x, y: y },
        _ => panic!( "inc height encounters non-rec" ),
    }
}

fn dec_width( d : DrawMe ) -> DrawMe {
    match d {
        DrawMe::Rec { width, height, x, y } => DrawMe::Rec { width: width - 1, height: height, x: x, y: y },
        _ => panic!( "dec width encounters non-rec" ),
    }
}

fn dec_height( d : DrawMe ) -> DrawMe {
    match d {
        DrawMe::Rec { width, height, x, y } => DrawMe::Rec { width: width, height: height - 1, x: x, y: y },
        _ => panic!( "dec height encounters non-rec" ),
    }
}

fn inc_x( d : DrawMe ) -> DrawMe {
    match d {
        DrawMe::Rec { width, height, x, y } => DrawMe::Rec { width: width, height: height, x: x + 1, y: y },
        _ => panic!( "inc x encounters non-rec" ),
    }
}

fn inc_y( d : DrawMe ) -> DrawMe {
    match d {
        DrawMe::Rec { width, height, x, y } => DrawMe::Rec { width: width, height: height, x: x, y: y + 1 },
        _ => panic!( "inc y encounters non-rec" ),
    }
}

fn dec_x( d : DrawMe ) -> DrawMe {
    match d {
        DrawMe::Rec { width, height, x, y } => DrawMe::Rec { width: width, height: height, x: x - 1, y: y },
        _ => panic!( "dec x encounters non-rec" ),
    }
}

fn dec_y( d : DrawMe ) -> DrawMe {
    match d {
        DrawMe::Rec { width, height, x, y } => DrawMe::Rec { width: width, height: height, x: x, y: y - 1 },
        _ => panic!( "dec y encounters non-rec" ),
    }
}
fn mod_rec<F>( maybe_d : Option<DrawMe>, f : F ) -> Option<DrawMe>
    where F : Fn( DrawMe ) -> DrawMe {

    match maybe_d {
        Some( d ) => Some( f( d ) ),
        None => { None },
    }
}

unsafe fn render_shape( s : &DrawMe ) {
    match s {
        &DrawMe::Rec { width, height, x, y } => render_rec( width, height, x, y ),
        &DrawMe::Character { c, x, y } => render_character( c, x, y ),
        _ => (),
    }
}

unsafe fn render_character( c : char, x : i32, y : i32 ) {
    mvaddch( y + UserY, x + UserX, c );
}

unsafe fn render_rec( w : i32, h : i32, x : i32, y : i32 ) {
    let dot = CString::new( "." ).unwrap();
    let h_line = CString::new( "-" ).unwrap();
    let v_line = CString::new( "|" ).unwrap();
    let plus = CString::new( "+" ).unwrap();

    let mut h2 = h + 2;
    while h2 > 0 {
        let d : &CString = if h2 == h + 2 {
            &h_line
        } else if h2 == 1 {
            &h_line
        } else {
            &dot
        };
        let mut w2 = w;

        let other_d : &CString = if h2 == h + 2 {
            &plus
        } else if h2 == 1 {
            &plus
        } else {
            &v_line
        };
        mvprintw( y + h2 + UserY, x + w2 + 1 + UserX, other_d.as_ptr() );
        while w2 > 0 {
            mvprintw( y + h2 + UserY, x + w2 + UserX, d.as_ptr() );
            w2 -= 1;
        }
        mvprintw( y + h2 + UserY, x + UserX, other_d.as_ptr() );
        h2 -= 1;
    }
}

static mut UserX : i32 = 0;
static mut UserY : i32 = 0;

fn main() {

    let mut level_file : Option<File> = None;
    for a in args() {
        let p = Path::new( &a );
        if p.exists() {
            let fr = File::open( p );
            match fr {
                Ok( f ) => { level_file = Some( f ); },
                _ => panic!( "error opening file"),
            }
            break;
        }
    }

    // TODO check to make sure the file exists
    // TODO parse the contents

    let mut x = 0;
    let mut y = 0;
    unsafe {
        initscr();
        cbreak();
        noecho();

        let mut c = getch();
        let mut shapes : Vec<DrawMe> = vec! [];
        let mut mode : Mode = Mode::Normal;
        let mut active_rec : Option<DrawMe> = None;

        while c as u8 as char != 'q' {
            let c2 = c as u8 as char;

            match c2 {
                'c' => {
                    match mode {
                        Mode::Normal => {
                            mode = Mode::EnterCharacter;
                        },
                        Mode::EnterRec => {},
                        Mode::MoveRec => {},
                        Mode::EnterCharacter => {
                            shapes.push( DrawMe::Character{ c: 'c', x: x - UserX, y: y - UserY } );
                            mode = Mode::Normal;
                        },
                    }
                },
                'r' => {
                    match mode {
                        Mode::Normal => {
                            active_rec = Some( DrawMe::Rec { width: 0, height: 0, x: x - UserX, y: y - UserY });
                            mode = Mode::EnterRec;
                        },
                        Mode::EnterRec => {
                            mode = Mode::MoveRec;
                        },
                        Mode::MoveRec => {
                            mode = Mode::Normal;
                            shapes.push( active_rec.unwrap() );
                            active_rec = None;
                        },
                        Mode::EnterCharacter => {
                            shapes.push( DrawMe::Character{ c: 'r', x: x - UserX, y: y - UserY } );
                            mode = Mode::Normal;
                        },
                    }
                },
                'j' => {
                    match mode {
                        Mode::Normal => {
                            y+=1;
                        },
                        Mode::EnterRec => {
                            active_rec = mod_rec( active_rec, inc_height );
                        },
                        Mode::MoveRec => {
                            active_rec = mod_rec( active_rec, inc_y );
                        },

                        Mode::EnterCharacter => {
                            shapes.push( DrawMe::Character{ c: 'j', x: x - UserX, y: y - UserY } );
                            mode = Mode::Normal;
                        },
                    }
                },
                'k' => {
                    match mode {
                       Mode::Normal => {
                           y-=1;
                       },
                       Mode::EnterRec => {
                            active_rec = mod_rec( active_rec, dec_height );
                       },
                       Mode::MoveRec => {
                            active_rec = mod_rec( active_rec, dec_y );
                       },

                        Mode::EnterCharacter => {
                            shapes.push( DrawMe::Character{ c: 'k', x: x - UserX, y: y - UserY } );
                            mode = Mode::Normal;
                        },
                    }
                },
                'l' => {
                    match mode {
                        Mode::Normal => {
                            x+=1;
                        },
                        Mode::EnterRec => {
                            active_rec = mod_rec( active_rec, inc_width );
                        },
                        Mode::MoveRec => {
                            active_rec = mod_rec( active_rec, inc_x );
                        },
                        Mode::EnterCharacter => {
                            shapes.push( DrawMe::Character{ c: 'l', x: x - UserX, y: y - UserY } );
                            mode = Mode::Normal;
                        },

                    }
                },
                'h' => {
                    match mode {
                        Mode::Normal => {
                            x-=1;
                        },
                        Mode::EnterRec => {
                            active_rec = mod_rec( active_rec, dec_width );
                        },
                        Mode::MoveRec => {
                            active_rec = mod_rec( active_rec, dec_x );
                        },
                        Mode::EnterCharacter => {
                            shapes.push( DrawMe::Character{ c: 'h', x: x - UserX, y: y - UserY } );
                            mode = Mode::Normal;
                        },
                    }
                },
                'J' => {
                    match mode {
                        Mode::Normal => {
                            UserY += 1;
                        },
                        Mode::EnterCharacter => {
                            shapes.push( DrawMe::Character{ c: 'J', x: x - UserX, y: y - UserY } );
                            mode = Mode::Normal;
                        },
                        _ => {},
                    }
                },
                'K' => {
                    match mode {
                        Mode::Normal => {
                            UserY -= 1;
                        },
                        Mode::EnterCharacter => {
                            shapes.push( DrawMe::Character{ c: 'K', x: x - UserX, y: y - UserY } );
                            mode = Mode::Normal;
                        },
                        _ => {},
                    }
                },
                'L' => {
                    match mode {
                        Mode::Normal => {
                            UserX += 1;
                        },
                        Mode::EnterCharacter => {
                            shapes.push( DrawMe::Character{ c: 'L', x: x - UserX, y: y - UserY } );
                            mode = Mode::Normal;
                        },
                        _ => {},
                    }
                },
                'H' => {
                    match mode {
                        Mode::Normal => {
                            UserX -= 1;
                        },
                        Mode::EnterCharacter => {
                            shapes.push( DrawMe::Character{ c: 'H', x: x - UserX, y: y - UserY } );
                            mode = Mode::Normal;
                        },
                        _ => {},
                    }
                },
                c3 @ _ => {
                    match mode {
                        Mode::EnterCharacter => {
                            shapes.push( DrawMe::Character{ c: c3, x: x - UserX, y: y - UserY } );
                            mode = Mode::Normal;
                        },
                        _ => {},
                    }
                },

            }

            clear();

            match active_rec {
                Some( ref shape ) => render_shape( &shape ),
                None => {},
            }

            for s in &shapes {
                render_shape( s );
            }

            cursor_move( y, x );
            refresh();

            c = getch();
        }

        endwin();
    }
}

<|endoftext|>


<commit_before>mod genetic;
use genetic::population::{Population, Range};
use genetic::fitness::max_alternating_bits;
use genetic::crossover::one_point_crossover;
use genetic::mutation::bit_flip;

fn main() {
    let total_generations = 1000;

    let population_size = 5;
    let genome_size = 10;
    let crossover_probability = 0.95;
    let mutation_probability = 0.05;
    let has_elitism = true;
    let fitness_function = max_alternating_bits;
    let mutation_function = bit_flip;
    let mut population = Population::<u8>::new(population_size,
                                               genome_size,
                                               crossover_probability,
                                               mutation_probability,
                                               Range::new(0, 2),
                                               has_elitism,
                                               fitness_function,
                                               one_point_crossover,
                                               mutation_function);

    for current_generation in 0..total_generations {
        println!("A E S T H E T I C S: {}", current_generation);

        for i in 0..population.individuals.len() {
            let individual = &population.individuals[i];
            let fitness = population.fitnesses[i];
            println!("{:?} : {}", individual, fitness);
        }

        population.iterate_generation();
    }

}
<commit_msg>Did osmething?<commit_after>mod genetic;
use genetic::population::{Population, Range};
use genetic::fitness::max_alternating_bits;
use genetic::crossover::one_point_crossover;
use genetic::mutation::bit_flip;

fn main() {
    let total_generations = 1000;

    let population_size = 5;
    let genome_size = 10;
    let crossover_probability = 0.95;
    let mutation_probability = 0.05;
    let has_elitism = true;
    let fitness_function = max_alternating_bits;
    let mutation_function = bit_flip;
    let mut population = Population::<u8>::new(population_size,
                                               genome_size,
                                               crossover_probability,
                                               mutation_probability,
                                               Range::new(0, 2),
                                               has_elitism,
                                               fitness_function,
                                               one_point_crossover,
                                               mutation_function);

    for current_generation in 0..total_generations {
        println!("A E S T H E T I C S: {}", current_generation);

        for i in 0..population.individuals.len() {
            let individual = &population.individuals[i];
            let fitness = population.fitnesses[i];
            println!("{:?} : {}", individual, fitness);
        }

        population.iterate_generation();
    }

}
<|endoftext|>


<commit_before>#[cfg(not(windows))]
compile_error!("This demo only runs on Windows.");

extern crate directcomposition;
extern crate winit;

use directcomposition::DirectComposition;
use winit::os::windows::WindowExt;

fn main() {
    let mut events_loop = winit::EventsLoop::new();
    let window = winit::WindowBuilder::new()
        .with_title("Hello, world!")
        .with_dimensions(1024, 768)
        .build(&events_loop)
        .unwrap();

    let composition = direct_composition_from_window(&window);

    let visual1 = composition.create_d3d_visual(300, 200).unwrap();
    visual1.set_offset_x(100.).unwrap();
    visual1.set_offset_y(50.).unwrap();

    let visual2 = composition.create_d3d_visual(400, 300).unwrap();
    let mut offset_y = 100.;
    visual2.set_offset_x(200.).unwrap();
    visual2.set_offset_y(offset_y).unwrap();

    composition.commit().unwrap();

    visual1.render_and_present_solid_frame(&composition, &[0., 0.2, 0.4, 1.]).unwrap();
    visual2.render_and_present_solid_frame(&composition, &[0., 0.5, 0., 0.5]).unwrap();

    events_loop.run_forever(|event| match event {
        winit::Event::WindowEvent { event: winit::WindowEvent::Closed, .. } => {
            winit::ControlFlow::Break
        }
        winit::Event::DeviceEvent { event: winit::DeviceEvent::MouseWheel { delta }, .. } => {
            let dy = match delta {
                winit::MouseScrollDelta::LineDelta(_, dy) => dy,
                winit::MouseScrollDelta::PixelDelta(_, dy) => dy,
            };
            offset_y = (offset_y - 10. * dy).max(0.).min(468.);

            visual2.set_offset_y(offset_y).unwrap();
            composition.commit().unwrap();

            winit::ControlFlow::Continue
        }
        _ => {
            winit::ControlFlow::Continue
        }
    });
}

fn direct_composition_from_window(window: &winit::Window) -> DirectComposition {
    unsafe {
        DirectComposition::new(window.get_hwnd() as _).unwrap()
    }
}
<commit_msg>Repaint one of the visuals on click<commit_after>#[cfg(not(windows))]
compile_error!("This demo only runs on Windows.");

extern crate directcomposition;
extern crate winit;

use directcomposition::DirectComposition;
use winit::os::windows::WindowExt;

fn main() {
    let mut events_loop = winit::EventsLoop::new();
    let window = winit::WindowBuilder::new()
        .with_title("Hello, world!")
        .with_dimensions(1024, 768)
        .build(&events_loop)
        .unwrap();

    let composition = direct_composition_from_window(&window);

    let visual1 = composition.create_d3d_visual(300, 200).unwrap();
    visual1.set_offset_x(100.).unwrap();
    visual1.set_offset_y(50.).unwrap();

    let visual2 = composition.create_d3d_visual(400, 300).unwrap();
    let mut offset_y = 100.;
    visual2.set_offset_x(200.).unwrap();
    visual2.set_offset_y(offset_y).unwrap();

    composition.commit().unwrap();

    let mut green = 0.5;
    visual1.render_and_present_solid_frame(&composition, &[0., 0.2, 0.4, 1.]).unwrap();
    visual2.render_and_present_solid_frame(&composition, &[0., green, 0., 0.5]).unwrap();

    events_loop.run_forever(|event| {
        if let winit::Event::WindowEvent { event, .. } = event {
            match event {
                winit::WindowEvent::Closed => {
                    return winit::ControlFlow::Break
                }
                winit::WindowEvent::MouseWheel { delta, .. } => {
                    let dy = match delta {
                        winit::MouseScrollDelta::LineDelta(_, dy) => dy,
                        winit::MouseScrollDelta::PixelDelta(_, dy) => dy,
                    };
                    offset_y = (offset_y - 10. * dy).max(0.).min(468.);

                    visual2.set_offset_y(offset_y).unwrap();
                    composition.commit().unwrap();
                }
                winit::WindowEvent::MouseInput {
                    button: winit::MouseButton::Left,
                    state: winit::ElementState::Pressed,
                    ..
                } => {
                    green += 0.1;
                    green %= 1.;
                    visual2.render_and_present_solid_frame(
                        &composition, &[0., green, 0., 0.5]
                    ).unwrap();
                }
                _ => {}
            }
        }
        winit::ControlFlow::Continue
    });
}

fn direct_composition_from_window(window: &winit::Window) -> DirectComposition {
    unsafe {
        DirectComposition::new(window.get_hwnd() as _).unwrap()
    }
}
<|endoftext|>


<commit_before>fn main(expr: &str) -> f32 {
  let mut result = 0.0;
  let mut stack:Vec<f32> = Vec::new();
  for token in expr.split_whitespace() {
    let wrapped_operand = token.parse::<f32>();
    let is_operator = wrapped_operand.is_err();
    if is_operator {
      if stack.len() < 2 {
        panic!("Unsufficient operands before operator");
      }
      // xxxFlorent: Any way to destructure like this? Not sure of what I am doing below
      // let [ operand1, operand2 ] = stack.drain((token.len() - 3)..).collect();
      let operand2 = stack.pop().expect("expected f32 values only in stack");
      let operand1 = stack.pop().expect("expected f32 values only in stack");
      result += match token {
        "+" => operand1 + operand2,
        "-" => operand1 - operand2,
        "*" => operand1 * operand2,
        "/" => operand1 / operand2,
        _ => panic!("Unsupported operator")
      }
    } else {
      stack.push(wrapped_operand.unwrap());
    }
  }

  if stack.len() > 0 {
    panic!("Remaining untreated operands. Probably missing operator.");
  }
  return result;
}

#[test]
fn it_adds() {
  let result = main("1 2 +");
  assert_eq!(result, 3.0);
}

#[test]
fn it_substracts() {
  let result = main("1 2 -");
  assert_eq!(result, -1.0);
}

#[test]
fn it_multiplies() {
  let result = main("6 7 *");
  assert_eq!(result, 42.0);
}

#[test]
fn it_divides() {
  let result = main("1 2 /");
  assert_eq!(result, 0.5);
}

#[test]
#[should_panic]
fn it_panics_for_unsupported_operators() {
  main("1 2 =");
  // xxxFlorent: How to test the panic message is right?
}

#[test]
#[should_panic]
fn it_panics_for_unsufficient_operands() {
  main("1 +");
  // xxxFlorent: How to test the panic message is right?
}

#[test]
#[should_panic]
fn it_panics_for_unsufficient_operators() {
  main("1 2 3 +");
  // xxxFlorent: How to test the panic message is right?
}
<commit_msg>Support complex expressions<commit_after>fn main(expr: &str) -> f32 {
  let mut stack:Vec<f32> = Vec::new();
  for token in expr.split_whitespace() {
    let wrapped_operand = token.parse::<f32>();
    let is_operator = wrapped_operand.is_err();
    if is_operator {
      if stack.len() < 2 {
        panic!("Unsufficient operands before operator");
      }
      // xxxFlorent: Any way to destructure like this? Not sure of what I am doing below
      // let [ operand1, operand2 ] = stack.drain((token.len() - 3)..).collect();
      let operand2 = stack.pop().expect("expected f32 values only in stack");
      let operand1 = stack.pop().expect("expected f32 values only in stack");
      let result = match token {
        "+" => operand1 + operand2,
        "-" => operand1 - operand2,
        "*" => operand1 * operand2,
        "/" => operand1 / operand2,
        _ => panic!("Unsupported operator")
      };
      stack.push(result);
      println!("{}", result);
    } else {
      stack.push(wrapped_operand.unwrap());
    }
  }

  if stack.len() != 1 {
    panic!("Remaining untreated operands. Probably missing operator.");
  }
  return stack.pop().expect("expected a f32 value remaining in stack");
}

#[test]
fn it_adds() {
  let result = main("1 2 +");
  assert_eq!(result, 3.0);
}

#[test]
fn it_substracts() {
  let result = main("1 2 -");
  assert_eq!(result, -1.0);
}

#[test]
fn it_multiplies() {
  let result = main("6 7 *");
  assert_eq!(result, 42.0);
}

#[test]
fn it_divides() {
  let result = main("1 2 /");
  assert_eq!(result, 0.5);
}

#[test]
fn it_calculates_complex_expressions() {
  // ((1+2) * 8 / (5-1) - 1) / 2
  let result = main("1 2 + 8 * 5 1 - / 1 - 2 /");
  assert_eq!(result, 2.5);
}

#[test]
#[should_panic]
fn it_panics_for_unsupported_operators() {
  main("1 2 =");
  // xxxFlorent: How to test the panic message is right?
}

#[test]
#[should_panic]
fn it_panics_for_unsufficient_operands() {
  main("1 +");
  // xxxFlorent: How to test the panic message is right?
}

#[test]
#[should_panic]
fn it_panics_for_unsufficient_operators() {
  main("1 2 3 +");
  // xxxFlorent: How to test the panic message is right?
}
<|endoftext|>


<commit_before>use std::net::TcpStream;
use std::io::{Read, Write};

fn main() {
	let mut strm = TcpStream::connect("127.0.0.1:50030").ok().unwrap();
	println!("{:?}", strm);

	println!("{:?}", strm.write(&[0x41]));
	println!("{:?}", strm.flush());

	let mut rr = String::new();
	println!("{:?}", strm.read_to_string(&mut rr).unwrap());
	println!("{}", rr);
}
<commit_msg>Post "BODY", print status<commit_after>extern crate hyper;

use hyper::client::Client;

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

	match client.post("http://127.0.0.1:50030").body("BODY").send() {
		Ok(response) => println!("Server responded with status {}", response.status),
		Err(error) => println!("Error {}", error),
	}
}
<|endoftext|>