<commit_before>extern crate getopts;
use getopts::{optflag,getopts,OptGroup,usage};
use std::os;

use std::num::FromPrimitive;
use std::num::Int;
use std::char;
use std::old_io;
use std::old_io::{IoResult, IoError};
use std::old_io::BufferedReader;
use std::old_io::File;
use std::old_io::stdio;

pub fn print_usage(program: &str, opts: &[OptGroup]) {
    let brief = format!("Usage: {} [options]", program);
    print!("{}", usage(brief.as_slice(), opts));
}

pub fn cat(v: &Vec<String>, options: &getopts::Matches) {
    if options.opt_present("u") {
        let writer = Box::new(stdio::stdout_raw());
        stdio::set_stdout(writer);
    }
    if v.is_empty() {
        cat_stdin(options);
    }
    else {
        // read files
        cat_files(v, options);
    }
}

fn cat_files(v: &Vec<String>, options: &getopts::Matches) {
    let mut linenum = 1u32;
    for filename in v.iter() {
        let path = Path::new(filename);
        match File::open(&path) {
            Ok(fh) => {
                let mut file = BufferedReader::new(fh);
                linenum = cat_file(file, options, linenum);
            },
            Err(f) => {
                println!("{}", f);
            }
        }
    }
}

fn cat_stdin(options: &getopts::Matches) {
    let mut linenum = 1u32;
    let mut printempty: bool = false;
    for line in old_io::stdin().lock().lines() {
        let (a, b) = handle_line(line.unwrap(), &mut printempty, linenum, options);
        printempty = a;
        linenum = b;
    }
}

fn cat_file<'a>(
    mut file: old_io::BufferedReader<std::old_io::fs::File>,
    options: &getopts::Matches,
    mut linenum: u32,
    ) -> u32 {
    let mut printempty: bool = false;
    let mut read_buf = [0, 4096];
    let mut out_buf: Vec<u8> = vec![];
    loop {
        match file.read(&mut read_buf) {
            Ok(n) => {
                for c in read_buf[..n].iter() {
                    out_buf.push(*c);
                    if is_nl(c) {
                        let (a, b) = handle_buf(&out_buf, &mut printempty, linenum, options);
                        printempty = a;
                        linenum = b;
                        out_buf.clear();
                    }
                }
            },
            Err(f) => {
                let mut o = 0u32;
                if out_buf.len() > 0 {
                    handle_buf(&out_buf, &mut printempty, linenum, options);
                }
                break
            }
        }
    }
    linenum
}

fn handle_line<'a>(
    linestr: String,
    printempty: &'a mut bool,
    mut linenum: u32,
    options: &getopts::Matches) -> (bool, u32) {
    if options.opt_present("s") {
        if !is_empty(&linestr) {
            if *printempty == true {
                println!("");
            }
            linenum = print_string(&linestr, linenum, options);
        }
        else {
            *printempty = true;
        }
    }
    else {
        linenum = print_string(&linestr, linenum, options);
    }
    (*printempty, linenum)
}

fn handle_buf<'a>(
    out_buf: &Vec<u8>,
    printempty: &'a mut bool,
    mut linenum: u32,
    options: &getopts::Matches) -> (bool, u32) {
    if options.opt_present("s") {
        if !is_empty_out_buf(out_buf) {
            if *printempty == true {
                if options.opt_present("n") {
                    println!("     {}\t", linenum);
                    linenum = linenum + 1;
                }
                else {
                    println!("");
                }
            }
            linenum = print_buf(&out_buf, linenum, options);
        }
        else {
            *printempty = true;
        }
    }
    else {
        linenum = print_buf(&out_buf, linenum, options);
    }
    (*printempty, linenum)
}

fn print_string<'a>(s: &String, mut linenum: u32, options: &getopts::Matches) -> u32 {
    if options.opt_present("b") {
        if !is_empty(s) {
            print_numbered(s, linenum, options);
            linenum = linenum + 1;
        }
        else {
            print_unnumbered(s, options);
        }
    }
    else if options.opt_present("n") {
        print_numbered(s, linenum, options);
        linenum = linenum + 1;
    }
    else {
        print_unnumbered(s, options);
    }
    linenum
}

fn print_buf<'a>(out_buf: &Vec<u8>, mut linenum: u32, options: &getopts::Matches) -> u32 {
    if options.opt_present("b") {
        if !is_empty_out_buf(out_buf) {
            print_numbered_buf(out_buf, linenum, options);
            linenum = linenum + 1;
        }
        else {
            print_unnumbered_buf(out_buf, options);
        }
    }
    else if options.opt_present("n") {
        print_numbered_buf(out_buf, linenum, options);
        linenum = linenum + 1;
    }
    else {
        print_unnumbered_buf(out_buf, options);
    }
    linenum
}

fn print_numbered<'a>(s: &String, linenum: u32, options: &getopts::Matches) {
    if options.opt_present("v") || options.opt_present("t") {
        print!("     {}\t", linenum);
        for b in s.as_bytes().iter() {
            print_byte(b, options);
        }
    }
    else {
        print!("     {}\t{}", linenum, s);
    }
}

fn print_numbered_buf<'a>(out_buf: &Vec<u8>, linenum: u32, options: &getopts::Matches) {
    // if options.opt_present("v") || options.opt_present("t") {
        print!("     {}\t", linenum);
        let mut t = 0u8;
        for b in out_buf.iter() {
            if t > 0 {
                t = t + *b;
                // print!("t: {} ", t);
                print!("{}", t as char);
                t = 0;
            }
            else {
                if *b > 160 {
                    t = *b;
                }
                else {
                    print_byte(b, options);
                }
            }
        }
    // }
}

fn print_unnumbered(s: &String, options: &getopts::Matches) {
    if options.opt_present("v") || options.opt_present("t") {
        for b in s.as_bytes().iter() {
            print_byte(b, options);
        }
    }
    else {
        print!("{}", s);
    }
}

fn print_unnumbered_buf(out_buf: &Vec<u8>, options: &getopts::Matches) {
    // if options.opt_present("v") || options.opt_present("t") {
        let mut t = 0;
        let mut buf: Vec<u8> = vec![];
        for b in out_buf.iter() {
            if t > 0 {
                buf.push(*b);
                t = t - 1;
                if t == 0 {
                    print_u8_buf(&mut buf, options);
                    buf.clear();
                }
            }
            else {
                if *b >= 240 {
                    //4th byte
                    t = 3;
                    buf.push(*b);
                }
                else if *b >= 224 {
                    t = 2;
                    buf.push(*b);
                }
                else if *b >= 192 {
                    t = 1;
                    buf.push(*b);
                }
                else {
                    print_byte(b, options);
                }
            }
        }
    // }
    // else {
        // print!("{}", s);
    // }
}

fn print_u8_buf(buf: &mut Vec<u8>, options: &getopts::Matches) {
    match convert_buf_to_codepoint(buf) {
        Ok(codepoint) => {
            match char::from_u32(codepoint) {
                Some(c) => print!("{}", c),
                None => {
                    for b in buf.iter() {
                        print_byte(b, options);
                    }
                }

            }
        },
        Err(_) => {
            for b in buf.iter() {
                print_byte(b, options);
            }
        }
    }
}

fn convert_buf_to_codepoint(buf: &mut Vec<u8>) -> Result<u32, String> {
    let mut s = 0u32;
    let mut l = buf.len();
    let orig_l = l;
    for b in buf.iter() {
        if l == 4 {
            s = s + ((*b as u32 | 240) - 240) << 19;
        }
        else if l == 3 {
            if orig_l == 4 && *b > 191 {
                return Err("Couldn't parse".to_string());
            }
            else {
                s = s + ((*b as u32 | 224) - 224) << 12;
            }
        }
        else if l == 2 {
            if (orig_l == 4 || orig_l == 3) && *b > 191 {
                return Err("Couldn't parse".to_string());
            }
            else {
                s = s + (((*b as u32 | 192) - 192) << 6);
            }
        }
        else if l == 1 {
            if orig_l > 1 {
                if *b > 191 {
                    return Err("Couldn't parse".to_string());
                }
                else {
                    s = s + ((*b as u32 | 128) - 128);
                }
            }
            else {
                s = s + ((*b as u32 | 192) - 192);
            }
        }
        l = l - 1;
    }
    Ok(s)
}

fn is_empty(line: &String) -> bool {
    let newline_str = "\n".to_string();
    let crlf_str = "\r\n".to_string();
    if line.is_empty() {
        true
    }
    else if line.eq(&newline_str) || line.eq(&crlf_str) {
        true
    }
    else {
        false
    }
}

fn is_empty_out_buf(v: &Vec<u8>) -> bool {
    if v.len() > 1 {
        false
    }
    else if is_nl(&v[0]) {
        true
    }
    else {
        false
    }
}

fn is_nl(c: &u8) -> bool {
    *c == 10u8
}

fn print_byte(b: &u8, options: &getopts::Matches) {
    if (*b > 31 && *b < 127) || *b == 10 || *b == 9 {
        if options.opt_present("t") && *b == 9 {
            print_tab();
        }
        else {
            print!("{}", *b as char);
        }
    }
    else {
        if options.opt_present("v") || options.opt_present("t") {
            if *b < 32 {
                print!("^{}", (*b + 64) as char);
            }
            else if *b == 127 {
                // del char
                print!("^?");
            }
            else if *b > 127 {
                if *b == 255 {
                    print!("M-^?");
                }
                else {
                    let x = *b - 128;
                    if x < 32 {
                        print!("M-^{}", (x + 64) as char);
                    }
                    else {
                        print!("M-{}", (*b - 128) as char);
                    }
                }
            }
        }
    }
}

fn print_tab() {
    print!("^I");
}

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

    #[test]
    fn assert_is_empty() {
        let s = "".to_string();
        assert!(is_empty(&s));
    }
    #[test]
    fn assert_is_empty_newline() {
        let s = "\n".to_string();
        assert!(is_empty(&s));
    }

    #[test]
    fn assert_is_empty_crlf() {
        let s = "\r\n".to_string();
        assert!(is_empty(&s));
    }

    #[test]
    fn assert_is_empty_char() {
        let s = "d".to_string();
        assert!(!is_empty(&s));
    }

    #[test]
    fn assert_is_empty_ctrl_char() {
        let s = "".to_string();
        assert!(!is_empty(&s));
    }

    #[test]
    fn assert_buf_to_codepoint_24() {
        let mut b = vec![24u8];
        assert_eq!(convert_buf_to_codepoint(&mut b).unwrap(), 24u32);
    }

    #[test]
    fn assert_buf_to_codepoint_36() {
        let mut b = vec![164u8];
        assert_eq!(convert_buf_to_codepoint(&mut b).unwrap(), 36);
    }

    #[test]
    fn assert_buf_to_codepoint_162() {
        // ¢
        // C2 A2
        // 11000010 10100010
        // 00010100010
        let mut b = vec![194u8, 162];
        assert_eq!(convert_buf_to_codepoint(&mut b).unwrap(), 162);
    }

    #[test]
    fn assert_buf_to_codepoint_8364() {
        // €
        // E2 82 AC
        // 11100010 10000010 10101100
        // 0010000010101100
        let mut b = vec![226u8, 130, 172];
        assert_eq!(convert_buf_to_codepoint(&mut b).unwrap(), 8364);
    }

    #[test]
    fn assert_buf_to_codepoint_294() {
        // c4 a6
        // 11000100 10100110
        // 00100100110
        let mut b = vec![196u8, 166];
        assert_eq!(convert_buf_to_codepoint(&mut b).unwrap(), 294);
    }

    #[test]
    fn assert_buf_to_codepoint_66376() {
        // F0 90 8D 88
        // 11110000 10010000 10001101 10001000
        // 00001 00000011 01001000
        let mut b = vec![240u8, 144, 141, 136];
        assert_eq!(convert_buf_to_codepoint(&mut b).unwrap(), 66376);
    }

    #[test]
    fn assert_buf_to_codepoint_192193_err() {
        let mut b = vec![192u8, 193];
        assert!(convert_buf_to_codepoint(&mut b).is_err());
    }

}
<commit_msg>Delegate most of print_numbered_buf to print_unnumbered_buf<commit_after>extern crate getopts;
use getopts::{optflag,getopts,OptGroup,usage};
use std::os;

use std::num::FromPrimitive;
use std::num::Int;
use std::char;
use std::old_io;
use std::old_io::{IoResult, IoError};
use std::old_io::BufferedReader;
use std::old_io::File;
use std::old_io::stdio;

pub fn print_usage(program: &str, opts: &[OptGroup]) {
    let brief = format!("Usage: {} [options]", program);
    print!("{}", usage(brief.as_slice(), opts));
}

pub fn cat(v: &Vec<String>, options: &getopts::Matches) {
    if options.opt_present("u") {
        let writer = Box::new(stdio::stdout_raw());
        stdio::set_stdout(writer);
    }
    if v.is_empty() {
        cat_stdin(options);
    }
    else {
        // read files
        cat_files(v, options);
    }
}

fn cat_files(v: &Vec<String>, options: &getopts::Matches) {
    let mut linenum = 1u32;
    for filename in v.iter() {
        let path = Path::new(filename);
        match File::open(&path) {
            Ok(fh) => {
                let mut file = BufferedReader::new(fh);
                linenum = cat_file(file, options, linenum);
            },
            Err(f) => {
                println!("{}", f);
            }
        }
    }
}

fn cat_stdin(options: &getopts::Matches) {
    let mut linenum = 1u32;
    let mut printempty: bool = false;
    for line in old_io::stdin().lock().lines() {
        let (a, b) = handle_line(line.unwrap(), &mut printempty, linenum, options);
        printempty = a;
        linenum = b;
    }
}

fn cat_file<'a>(
    mut file: old_io::BufferedReader<std::old_io::fs::File>,
    options: &getopts::Matches,
    mut linenum: u32,
    ) -> u32 {
    let mut printempty: bool = false;
    let mut read_buf = [0, 4096];
    let mut out_buf: Vec<u8> = vec![];
    loop {
        match file.read(&mut read_buf) {
            Ok(n) => {
                for c in read_buf[..n].iter() {
                    out_buf.push(*c);
                    if is_nl(c) {
                        let (a, b) = handle_buf(&out_buf, &mut printempty, linenum, options);
                        printempty = a;
                        linenum = b;
                        out_buf.clear();
                    }
                }
            },
            Err(f) => {
                let mut o = 0u32;
                if out_buf.len() > 0 {
                    handle_buf(&out_buf, &mut printempty, linenum, options);
                }
                break
            }
        }
    }
    linenum
}

fn handle_line<'a>(
    linestr: String,
    printempty: &'a mut bool,
    mut linenum: u32,
    options: &getopts::Matches) -> (bool, u32) {
    if options.opt_present("s") {
        if !is_empty(&linestr) {
            if *printempty == true {
                println!("");
            }
            linenum = print_string(&linestr, linenum, options);
        }
        else {
            *printempty = true;
        }
    }
    else {
        linenum = print_string(&linestr, linenum, options);
    }
    (*printempty, linenum)
}

fn handle_buf<'a>(
    out_buf: &Vec<u8>,
    printempty: &'a mut bool,
    mut linenum: u32,
    options: &getopts::Matches) -> (bool, u32) {
    if options.opt_present("s") {
        if !is_empty_out_buf(out_buf) {
            if *printempty == true {
                if options.opt_present("n") {
                    println!("     {}\t", linenum);
                    linenum = linenum + 1;
                }
                else {
                    println!("");
                }
            }
            linenum = print_buf(&out_buf, linenum, options);
        }
        else {
            *printempty = true;
        }
    }
    else {
        linenum = print_buf(&out_buf, linenum, options);
    }
    (*printempty, linenum)
}

fn print_string<'a>(s: &String, mut linenum: u32, options: &getopts::Matches) -> u32 {
    if options.opt_present("b") {
        if !is_empty(s) {
            print_numbered(s, linenum, options);
            linenum = linenum + 1;
        }
        else {
            print_unnumbered(s, options);
        }
    }
    else if options.opt_present("n") {
        print_numbered(s, linenum, options);
        linenum = linenum + 1;
    }
    else {
        print_unnumbered(s, options);
    }
    linenum
}

fn print_buf<'a>(out_buf: &Vec<u8>, mut linenum: u32, options: &getopts::Matches) -> u32 {
    if options.opt_present("b") {
        if !is_empty_out_buf(out_buf) {
            print_numbered_buf(out_buf, linenum, options);
            linenum = linenum + 1;
        }
        else {
            print_unnumbered_buf(out_buf, options);
        }
    }
    else if options.opt_present("n") {
        print_numbered_buf(out_buf, linenum, options);
        linenum = linenum + 1;
    }
    else {
        print_unnumbered_buf(out_buf, options);
    }
    linenum
}

fn print_numbered<'a>(s: &String, linenum: u32, options: &getopts::Matches) {
    if options.opt_present("v") || options.opt_present("t") {
        print!("     {}\t", linenum);
        for b in s.as_bytes().iter() {
            print_byte(b, options);
        }
    }
    else {
        print!("     {}\t{}", linenum, s);
    }
}

fn print_numbered_buf<'a>(out_buf: &Vec<u8>, linenum: u32, options: &getopts::Matches) {
    print!("     {}\t", linenum);
    print_unnumbered_buf(out_buf, options);
}

fn print_unnumbered(s: &String, options: &getopts::Matches) {
    if options.opt_present("v") || options.opt_present("t") {
        for b in s.as_bytes().iter() {
            print_byte(b, options);
        }
    }
    else {
        print!("{}", s);
    }
}

fn print_unnumbered_buf(out_buf: &Vec<u8>, options: &getopts::Matches) {
    // if options.opt_present("v") || options.opt_present("t") {
        let mut t = 0;
        let mut buf: Vec<u8> = vec![];
        for b in out_buf.iter() {
            if t > 0 {
                buf.push(*b);
                t = t - 1;
                if t == 0 {
                    print_u8_buf(&mut buf, options);
                    buf.clear();
                }
            }
            else {
                if *b >= 240 {
                    //4th byte
                    t = 3;
                    buf.push(*b);
                }
                else if *b >= 224 {
                    t = 2;
                    buf.push(*b);
                }
                else if *b >= 192 {
                    t = 1;
                    buf.push(*b);
                }
                else {
                    print_byte(b, options);
                }
            }
        }
    // }
    // else {
        // print!("{}", s);
    // }
}

fn print_u8_buf(buf: &mut Vec<u8>, options: &getopts::Matches) {
    match convert_buf_to_codepoint(buf) {
        Ok(codepoint) => {
            match char::from_u32(codepoint) {
                Some(c) => print!("{}", c),
                None => {
                    for b in buf.iter() {
                        print_byte(b, options);
                    }
                }

            }
        },
        Err(_) => {
            for b in buf.iter() {
                print_byte(b, options);
            }
        }
    }
}

fn convert_buf_to_codepoint(buf: &mut Vec<u8>) -> Result<u32, String> {
    let mut s = 0u32;
    let mut l = buf.len();
    let orig_l = l;
    for b in buf.iter() {
        if l == 4 {
            s = s + ((*b as u32 | 240) - 240) << 19;
        }
        else if l == 3 {
            if orig_l == 4 && *b > 191 {
                return Err("Couldn't parse".to_string());
            }
            else {
                s = s + ((*b as u32 | 224) - 224) << 12;
            }
        }
        else if l == 2 {
            if (orig_l == 4 || orig_l == 3) && *b > 191 {
                return Err("Couldn't parse".to_string());
            }
            else {
                s = s + (((*b as u32 | 192) - 192) << 6);
            }
        }
        else if l == 1 {
            if orig_l > 1 {
                if *b > 191 {
                    return Err("Couldn't parse".to_string());
                }
                else {
                    s = s + ((*b as u32 | 128) - 128);
                }
            }
            else {
                s = s + ((*b as u32 | 192) - 192);
            }
        }
        l = l - 1;
    }
    Ok(s)
}

fn is_empty(line: &String) -> bool {
    let newline_str = "\n".to_string();
    let crlf_str = "\r\n".to_string();
    if line.is_empty() {
        true
    }
    else if line.eq(&newline_str) || line.eq(&crlf_str) {
        true
    }
    else {
        false
    }
}

fn is_empty_out_buf(v: &Vec<u8>) -> bool {
    if v.len() > 1 {
        false
    }
    else if is_nl(&v[0]) {
        true
    }
    else {
        false
    }
}

fn is_nl(c: &u8) -> bool {
    *c == 10u8
}

fn print_byte(b: &u8, options: &getopts::Matches) {
    if (*b > 31 && *b < 127) || *b == 10 || *b == 9 {
        if options.opt_present("t") && *b == 9 {
            print_tab();
        }
        else {
            print!("{}", *b as char);
        }
    }
    else {
        if options.opt_present("v") || options.opt_present("t") {
            if *b < 32 {
                print!("^{}", (*b + 64) as char);
            }
            else if *b == 127 {
                // del char
                print!("^?");
            }
            else if *b > 127 {
                if *b == 255 {
                    print!("M-^?");
                }
                else {
                    let x = *b - 128;
                    if x < 32 {
                        print!("M-^{}", (x + 64) as char);
                    }
                    else {
                        print!("M-{}", (*b - 128) as char);
                    }
                }
            }
        }
    }
}

fn print_tab() {
    print!("^I");
}

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

    #[test]
    fn assert_is_empty() {
        let s = "".to_string();
        assert!(is_empty(&s));
    }
    #[test]
    fn assert_is_empty_newline() {
        let s = "\n".to_string();
        assert!(is_empty(&s));
    }

    #[test]
    fn assert_is_empty_crlf() {
        let s = "\r\n".to_string();
        assert!(is_empty(&s));
    }

    #[test]
    fn assert_is_empty_char() {
        let s = "d".to_string();
        assert!(!is_empty(&s));
    }

    #[test]
    fn assert_is_empty_ctrl_char() {
        let s = "".to_string();
        assert!(!is_empty(&s));
    }

    #[test]
    fn assert_buf_to_codepoint_24() {
        let mut b = vec![24u8];
        assert_eq!(convert_buf_to_codepoint(&mut b).unwrap(), 24u32);
    }

    #[test]
    fn assert_buf_to_codepoint_36() {
        let mut b = vec![164u8];
        assert_eq!(convert_buf_to_codepoint(&mut b).unwrap(), 36);
    }

    #[test]
    fn assert_buf_to_codepoint_162() {
        // ¢
        // C2 A2
        // 11000010 10100010
        // 00010100010
        let mut b = vec![194u8, 162];
        assert_eq!(convert_buf_to_codepoint(&mut b).unwrap(), 162);
    }

    #[test]
    fn assert_buf_to_codepoint_8364() {
        // €
        // E2 82 AC
        // 11100010 10000010 10101100
        // 0010000010101100
        let mut b = vec![226u8, 130, 172];
        assert_eq!(convert_buf_to_codepoint(&mut b).unwrap(), 8364);
    }

    #[test]
    fn assert_buf_to_codepoint_294() {
        // c4 a6
        // 11000100 10100110
        // 00100100110
        let mut b = vec![196u8, 166];
        assert_eq!(convert_buf_to_codepoint(&mut b).unwrap(), 294);
    }

    #[test]
    fn assert_buf_to_codepoint_66376() {
        // F0 90 8D 88
        // 11110000 10010000 10001101 10001000
        // 00001 00000011 01001000
        let mut b = vec![240u8, 144, 141, 136];
        assert_eq!(convert_buf_to_codepoint(&mut b).unwrap(), 66376);
    }

    #[test]
    fn assert_buf_to_codepoint_192193_err() {
        let mut b = vec![192u8, 193];
        assert!(convert_buf_to_codepoint(&mut b).is_err());
    }

}
<|endoftext|>


<commit_before>#![allow(dead_code)]

use std::cell::RefCell;

thread_local!(static EVENT_LOOP: Option<RefCell<EventLoop>> = None);

fn with_current_event_loop<F, R>(f: F) -> R
    where F: FnOnce(&RefCell<EventLoop>) -> R {
        EVENT_LOOP.with(|maybe_event_loop| {
            match maybe_event_loop {
                &None => panic!("current thread has no event loop"),
                &Some(ref event_loop) => f(event_loop),
            }
        })
    }

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

pub struct Promise<T> {
    pub node : Box<PromiseNode<T>>,
}

impl <T> Promise <T> {
    pub fn then<F, G, R>(self, _func: F, _error_handler: G) -> Promise<R>
        where F: FnOnce(T) -> Result<R> {
            unimplemented!()
        }

    pub fn wait(self) -> Result<T> {
        unimplemented!()
    }
}

pub trait Event {
    fn fire(&mut self);
}

pub trait PromiseNode<T> {
    /// Arms the given event when the promised value is ready.
    fn on_ready(&mut self, event : Box<Event>);

    fn set_self_pointer(&mut self) {}
    fn get(self) -> Result<T>;
}

/// A PromiseNode that transforms the result of another PromiseNode through an application-provided
/// function (implements `then()`).
pub struct TransformPromiseNode<T, DepT, Func, ErrorFunc>
where Func: FnOnce(DepT) -> Result<T>, ErrorFunc: FnOnce(Error) -> Result<T> {
    dependency: Box<PromiseNode<DepT>>,
    func: Func,
    error_handler: ErrorFunc,
}

impl <T, DepT, Func, ErrorFunc> PromiseNode<T> for TransformPromiseNode<T, DepT, Func, ErrorFunc>
where Func: FnOnce(DepT) -> Result<T>, ErrorFunc: FnOnce(Error) -> Result<T> {
    fn on_ready(&mut self, event: Box<Event>) {
        self.dependency.on_ready(event);
    }
    fn get(self) -> Result<T> {
//        let dep_result = self.dependency.get();
        unimplemented!()
//        self.result
    }
}

/// A promise that has already been resolved to an immediate value or error.
pub struct ImmediatePromiseNode<T> {
    result: Result<T>,
}

impl <T> PromiseNode<T> for ImmediatePromiseNode<T> {

    fn on_ready(&mut self, event: Box<Event>) {
        with_current_event_loop(|event_loop| {
            event_loop.borrow_mut().arm_breadth_first(event);
        });
    }
    fn get(self) -> Result<T> {
        self.result
    }
}

trait ErrorHandler {
    fn task_failed(error: Error);
}

struct TaskSetImpl {
    error_handler: Box<ErrorHandler>,
}

/// A Deque with an insertion point in the middle.
struct InsertDeque<T> {
    front: ::std::collections::VecDeque<T>,
    back: ::std::collections::VecDeque<T>,
}

/// A queue of events being executed in a loop.
pub struct EventLoop {
    daemons: TaskSetImpl,
    running: bool,
    last_runnable_state: bool,
    events: ::std::collections::VecDeque<Box<Event>>,
    depth_first_events: ::std::collections::VecDeque<Box<Event>>,
}

impl EventLoop {

    fn arm_depth_first(&mut self, event: Box<Event>) {
        self.depth_first_events.push_front(event);
    }

    fn arm_breadth_first(&mut self, event: Box<Event>) {
        self.events.push_back(event);
    }

    /// Run the even loop for `max_turn_count` turns or until there is nothing left to be done,
    /// whichever comes first. This never calls the `EventPort`'s `sleep()` or `poll()`. It will
    /// call the `EventPort`'s `set_runnable(false)` if the queue becomes empty.
    pub fn run(&mut self, max_turn_count : u32) {
        self.running = true;

        for _ in 0..max_turn_count {
            if !self.turn() {
                break;
            }
        }
    }

    fn turn(&mut self) -> bool {
        assert!(self.depth_first_events.is_empty());
        match self.events.pop_front() {
            None => return false,
            Some(mut event) => {
                // event->firing = true ?
                event.fire();
            }
        }
        while !self.depth_first_events.is_empty() {
            self.events.push_front(self.depth_first_events.pop_back().unwrap());
        }
        return true;
    }
}
<commit_msg>implementation of Promise::then()<commit_after>#![allow(dead_code)]

use std::cell::RefCell;

thread_local!(static EVENT_LOOP: Option<RefCell<EventLoop>> = None);

fn with_current_event_loop<F, R>(f: F) -> R
    where F: FnOnce(&RefCell<EventLoop>) -> R {
        EVENT_LOOP.with(|maybe_event_loop| {
            match maybe_event_loop {
                &None => panic!("current thread has no event loop"),
                &Some(ref event_loop) => f(event_loop),
            }
        })
    }

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

pub struct Promise<T> {
    pub node : Box<PromiseNode<T>>,
}

impl <T> Promise <T> where T: 'static {
    pub fn then<F, G, R>(self, func: F, error_handler: G) -> Promise<R>
        where F: 'static + FnOnce(T) -> Result<R>,
              G: 'static + FnOnce(Error) -> Result<R>,
              R: 'static {
            let node : Box<PromiseNode<R>> = Box::new(TransformPromiseNode::new(self.node, func, error_handler));
            Promise { node: node }
        }

    pub fn wait(self) -> Result<T> {
        unimplemented!()
    }
}

pub trait Event {
    fn fire(&mut self);
}

pub trait PromiseNode<T> {
    /// Arms the given event when the promised value is ready.
    fn on_ready(&mut self, event : Box<Event>);

    fn set_self_pointer(&mut self) {}
    fn get(self: Box<Self>) -> Result<T>;
}

/// A PromiseNode that transforms the result of another PromiseNode through an application-provided
/// function (implements `then()`).
pub struct TransformPromiseNode<T, DepT, Func, ErrorFunc>
where Func: FnOnce(DepT) -> Result<T>, ErrorFunc: FnOnce(Error) -> Result<T> {
    dependency: Box<PromiseNode<DepT>>,
    func: Func,
    error_handler: ErrorFunc,
}

impl <T, DepT, Func, ErrorFunc> TransformPromiseNode<T, DepT, Func, ErrorFunc>
where Func: FnOnce(DepT) -> Result<T>, ErrorFunc: FnOnce(Error) -> Result<T> {
    fn new(dependency: Box<PromiseNode<DepT>>, func: Func, error_handler: ErrorFunc)
           -> TransformPromiseNode<T, DepT, Func, ErrorFunc> {
        TransformPromiseNode { dependency : dependency,
                               func: func, error_handler: error_handler }
    }
}

impl <T, DepT, Func, ErrorFunc> PromiseNode<T> for TransformPromiseNode<T, DepT, Func, ErrorFunc>
where Func: FnOnce(DepT) -> Result<T>, ErrorFunc: FnOnce(Error) -> Result<T> {
    fn on_ready(&mut self, event: Box<Event>) {
        self.dependency.on_ready(event);
    }
    fn get(self: Box<Self>) -> Result<T> {
        let tmp = *self;
        let TransformPromiseNode {dependency, func, error_handler} = tmp;
        match dependency.get() {
            Ok(value) => {
                func(value)
            }
            Err(e) => {
                error_handler(e)
            }
        }
    }
}

/// A promise that has already been resolved to an immediate value or error.
pub struct ImmediatePromiseNode<T> {
    result: Result<T>,
}

impl <T> PromiseNode<T> for ImmediatePromiseNode<T> {

    fn on_ready(&mut self, event: Box<Event>) {
        with_current_event_loop(|event_loop| {
            event_loop.borrow_mut().arm_breadth_first(event);
        });
    }
    fn get(self: Box<Self>) -> Result<T> {
        self.result
    }
}

trait ErrorHandler {
    fn task_failed(error: Error);
}

struct TaskSetImpl {
    error_handler: Box<ErrorHandler>,
}

/// A Deque with an insertion point in the middle.
struct InsertDeque<T> {
    front: ::std::collections::VecDeque<T>,
    back: ::std::collections::VecDeque<T>,
}

/// A queue of events being executed in a loop.
pub struct EventLoop {
    daemons: TaskSetImpl,
    running: bool,
    last_runnable_state: bool,
    events: ::std::collections::VecDeque<Box<Event>>,
    depth_first_events: ::std::collections::VecDeque<Box<Event>>,
}

impl EventLoop {

    fn arm_depth_first(&mut self, event: Box<Event>) {
        self.depth_first_events.push_front(event);
    }

    fn arm_breadth_first(&mut self, event: Box<Event>) {
        self.events.push_back(event);
    }

    /// Run the even loop for `max_turn_count` turns or until there is nothing left to be done,
    /// whichever comes first. This never calls the `EventPort`'s `sleep()` or `poll()`. It will
    /// call the `EventPort`'s `set_runnable(false)` if the queue becomes empty.
    pub fn run(&mut self, max_turn_count : u32) {
        self.running = true;

        for _ in 0..max_turn_count {
            if !self.turn() {
                break;
            }
        }
    }

    fn turn(&mut self) -> bool {
        assert!(self.depth_first_events.is_empty());
        match self.events.pop_front() {
            None => return false,
            Some(mut event) => {
                // event->firing = true ?
                event.fire();
            }
        }
        while !self.depth_first_events.is_empty() {
            self.events.push_front(self.depth_first_events.pop_back().unwrap());
        }
        return true;
    }
}
<|endoftext|>


<commit_before>#![feature(io, core)]
#![cfg_attr(test, deny(warnings))]

extern crate time;
extern crate conduit;
extern crate "conduit-middleware" as middleware;

use conduit::{Request, Method};
use middleware::Middleware;
use std::borrow::Cow;
use std::error::Error;
use std::old_io::util::NullReader;
use std::string::CowString;
use time::{Tm, strptime, ParseError};

type Response = Result<conduit::Response, Box<Error+Send>>;

#[allow(missing_copy_implementations)]
pub struct ConditionalGet;

impl Middleware for ConditionalGet {
    fn after(&self, req: &mut Request, res: Response) -> Response {
        let mut res = try!(res);

        match req.method() {
            Method::Get | Method::Head => {
                if is_ok(&res) && is_fresh(req, &res) {
                    res.status = (304, "Not Modified");
                    res.headers.remove("Content-Type");
                    res.headers.remove("Content-Length");
                    res.body = Box::new(NullReader);
                }
            },
            _ => ()
        }

        Ok(res)
    }
}

fn is_ok(response: &conduit::Response) -> bool {
    match *response {
        conduit::Response { status: (200, _), .. } => true,
        _ => false
    }
}

fn is_fresh(req: &Request, res: &conduit::Response) -> bool {
    let modified_since = req.headers().find("If-Modified-Since").map(header_val);
    let none_match     = req.headers().find("If-None-Match").map(header_val);

    if modified_since.as_ref().or_else(|| none_match.as_ref()).is_none() {
        return false;
    }

    let mut success = true;

    modified_since.and_then(|modified_since| {
        parse_http_date(modified_since).map_err(|_| { success = false; }).ok()
    }).map(|parsed| {
        success = success && is_modified_since(parsed, res);
    });

    none_match.map(|none_match| {
        success = success && etag_matches(none_match, res);
    });

    success
}

fn etag_matches<S: Str>(none_match: S, res: &conduit::Response) -> bool {
    res.headers.get("ETag").map(|etag| {
        res_header_val(etag).as_slice() == none_match.as_slice()
    }).unwrap_or(false)
}

fn is_modified_since(modified_since: Tm, res: &conduit::Response) -> bool {
    res.headers.get("Last-Modified").and_then(|last_modified| {
        parse_http_date(res_header_val(last_modified).as_slice()).ok()
    }).map(|last_modified| {
        modified_since.to_timespec() >= last_modified.to_timespec()
    }).unwrap_or(false)
}

fn header_val<'a>(header: Vec<&'a str>) -> CowString<'a> {
    if header.len() == 1 {
        Cow::Borrowed(header[0])
    } else {
        Cow::Owned(header.concat())
    }
}

fn res_header_val<'a>(header: &'a Vec<String>) -> CowString<'a> {
    if header.len() == 1 {
        Cow::Borrowed(header[0].as_slice())
    } else {
        Cow::Owned(header.concat())
    }
}

fn parse_http_date<S: Str>(string: S) -> Result<Tm, ()> {
    let string = string.as_slice();

    parse_rfc1123(string)
        .or_else(|_| parse_rfc850(string))
        .or_else(|_| parse_asctime(string))
        .map_err(|_| ())
}

fn parse_rfc1123(string: &str) -> Result<Tm, ParseError> {
    time::strptime(string, "%a, %d %b %Y %T GMT")
}

fn parse_rfc850(string: &str) -> Result<Tm, ParseError> {
    time::strptime(string, "%a, %d-%m-%y %T GMT")
}

fn parse_asctime(string: &str) -> Result<Tm, ParseError> {
    time::strptime(string, "%a %m%t%d %T %Y")
}

#[cfg(test)]
mod tests {
    extern crate "conduit-test" as test;

    use std::collections::HashMap;
    use std::error::Error;
    use std::old_io::MemReader;
    use time;
    use time::Tm;
    use conduit;
    use conduit::{Request, Response, Handler, Method};
    use middleware::MiddlewareBuilder;

    use super::ConditionalGet;

    macro_rules! returning {
        ($code:expr, $($header:expr => $value:expr),+) => ({
            let mut headers = HashMap::new();
            $(headers.insert($header.to_string(), vec!($value.to_string()));)+
            let handler = SimpleHandler::new(headers, $code, "hello");
            let mut stack = MiddlewareBuilder::new(handler);
            stack.add(ConditionalGet);
            stack
        });
        ($($header:expr => $value:expr),+) => ({
            returning!((200, "OK"), $($header => $value),+)
        })
    }

    macro_rules! request {
        ($($header:expr => $value:expr),+) => ({
            let mut req = test::MockRequest::new(Method::Get, "/");
            $(req.header($header, $value.to_string().as_slice());)+
            req
        })
    }

    #[test]
    fn test_sends_304() {
        let handler = returning!("Last-Modified" => httpdate(time::now()));
        expect_304(handler.call(&mut request!(
            "If-Modified-Since" => httpdate(time::now())
        ) as &mut conduit::Request));
    }

    #[test]
    fn test_sends_304_if_older_than_now() {
        let handler = returning!("Last-Modified" => before_now());
        expect_304(handler.call(&mut request!(
            "If-Modified-Since" => httpdate(time::now())
        ) as &mut conduit::Request));
    }

    #[test]
    fn test_sends_304_with_etag() {
        let handler = returning!("ETag" => "1234");
        expect_304(handler.call(&mut request!(
            "If-None-Match" => "1234"
        ) as &mut conduit::Request));
    }

    #[test]
    fn test_sends_200_with_fresh_time_but_not_etag() {
        let handler = returning!("Last-Modified" => before_now(), "ETag" => "1234");
        expect_200(handler.call(&mut request!(
            "If-Modified-Since" => now(),
            "If-None-Match" => "4321"
        ) as &mut conduit::Request));
    }

    #[test]
    fn test_sends_200_with_fresh_etag_but_not_time() {
        let handler = returning!("Last-Modified" => now(), "ETag" => "1234");
        expect_200(handler.call(&mut request!(
            "If-Modified-Since" => before_now(),
            "If-None-Match" => "1234"
        ) as &mut conduit::Request));
    }

    #[test]
    fn test_sends_200_with_fresh_etag() {
        let handler = returning!("ETag" => "1234");
        expect_200(handler.call(&mut request!(
            "If-None-Match" => "4321"
        ) as &mut conduit::Request));
    }

    #[test]
    fn test_sends_200_with_fresh_time() {
        let handler = returning!("Last-Modified" => now());
        expect_200(handler.call(&mut request!(
            "If-Modified-Since" => before_now()
        ) as &mut conduit::Request));
    }

    #[test]
    fn test_sends_304_with_fresh_time_and_etag() {
        let handler = returning!("Last-Modified" => before_now(), "ETag" => "1234");
        expect_304(handler.call(&mut request!(
            "If-Modified-Since" => now(),
            "If-None-Match" => "1234"
        ) as &mut conduit::Request));
    }

    #[test]
    fn test_does_not_affect_non_200() {
        let code = (302, "Found");
        let handler = returning!(code, "Last-Modified" => before_now(), "ETag" => "1234");
        expect(code, handler.call(&mut request!(
            "If-Modified-Since" => now(),
            "If-None-Match" => "1234"
        ) as &mut conduit::Request));
    }

    #[test]
    fn test_does_not_affect_malformed_timestamp() {
        let bad_stamp = time::now().strftime("%Y-%m-%d %H:%M:%S %z").unwrap().to_string();
        let handler = returning!("Last-Modified" => before_now());
        expect_200(handler.call(&mut request!(
            "If-Modified-Since" => bad_stamp
        ) as &mut conduit::Request));
    }

    fn expect_304(response: Result<Response, Box<Error+Send>>) {
        let mut response = response.ok().expect("No response");
        let body = response.body.read_to_string().ok().expect("No body");

        assert_eq!(response.status, (304, "Not Modified"));
        assert_eq!(body.as_slice(), "");
    }

    fn expect_200(response: Result<Response, Box<Error+Send>>) {
        expect((200, "OK"), response);
    }

    fn expect(status: (u32, &'static str), response: Result<Response, Box<Error+Send>>) {
        let mut response = response.ok().expect("No response");
        let body = response.body.read_to_string().ok().expect("No body");

        assert_eq!(response.status, status);
        assert_eq!(body.as_slice(), "hello");
    }

    struct SimpleHandler {
        map: HashMap<String, Vec<String>>,
        status: Status,
        body: &'static str
    }

    type Status = (u32, &'static str);

    impl SimpleHandler {
        fn new(map: HashMap<String, Vec<String>>, status: Status, body: &'static str) -> SimpleHandler {
            SimpleHandler { map: map, status: status, body: body }
        }
    }

    impl Handler for SimpleHandler {
        fn call(&self, _: &mut Request) -> Result<Response, Box<Error+Send>> {
            Ok(Response {
                status: self.status,
                headers: self.map.clone(),
                body: Box::new(MemReader::new(self.body.to_string().into_bytes())),
            })
        }
    }

    fn before_now() -> String {
        let mut now = time::now();
        now.tm_year -= 1;
        httpdate(now)
    }

    fn now() -> String {
        httpdate(time::now())
    }

    fn httpdate(time: Tm) -> String {
        time.strftime("%a, %d-%m-%y %T GMT").unwrap().to_string()
    }
}
<commit_msg>Update to rust master<commit_after>#![feature(old_io, core)]
#![cfg_attr(test, deny(warnings))]

extern crate time;
extern crate conduit;
extern crate "conduit-middleware" as middleware;

use conduit::{Request, Method};
use middleware::Middleware;
use std::borrow::Cow;
use std::error::Error;
use std::old_io::util::NullReader;
use std::string::CowString;
use time::{Tm, strptime, ParseError};

type Response = Result<conduit::Response, Box<Error+Send>>;

#[allow(missing_copy_implementations)]
pub struct ConditionalGet;

impl Middleware for ConditionalGet {
    fn after(&self, req: &mut Request, res: Response) -> Response {
        let mut res = try!(res);

        match req.method() {
            Method::Get | Method::Head => {
                if is_ok(&res) && is_fresh(req, &res) {
                    res.status = (304, "Not Modified");
                    res.headers.remove("Content-Type");
                    res.headers.remove("Content-Length");
                    res.body = Box::new(NullReader);
                }
            },
            _ => ()
        }

        Ok(res)
    }
}

fn is_ok(response: &conduit::Response) -> bool {
    match *response {
        conduit::Response { status: (200, _), .. } => true,
        _ => false
    }
}

fn is_fresh(req: &Request, res: &conduit::Response) -> bool {
    let modified_since = req.headers().find("If-Modified-Since").map(header_val);
    let none_match     = req.headers().find("If-None-Match").map(header_val);

    if modified_since.as_ref().or_else(|| none_match.as_ref()).is_none() {
        return false;
    }

    let mut success = true;

    modified_since.and_then(|modified_since| {
        parse_http_date(modified_since).map_err(|_| { success = false; }).ok()
    }).map(|parsed| {
        success = success && is_modified_since(parsed, res);
    });

    none_match.map(|none_match| {
        success = success && etag_matches(none_match, res);
    });

    success
}

fn etag_matches<S: Str>(none_match: S, res: &conduit::Response) -> bool {
    res.headers.get("ETag").map(|etag| {
        res_header_val(etag).as_slice() == none_match.as_slice()
    }).unwrap_or(false)
}

fn is_modified_since(modified_since: Tm, res: &conduit::Response) -> bool {
    res.headers.get("Last-Modified").and_then(|last_modified| {
        parse_http_date(res_header_val(last_modified).as_slice()).ok()
    }).map(|last_modified| {
        modified_since.to_timespec() >= last_modified.to_timespec()
    }).unwrap_or(false)
}

fn header_val<'a>(header: Vec<&'a str>) -> CowString<'a> {
    if header.len() == 1 {
        Cow::Borrowed(header[0])
    } else {
        Cow::Owned(header.concat())
    }
}

fn res_header_val<'a>(header: &'a Vec<String>) -> CowString<'a> {
    if header.len() == 1 {
        Cow::Borrowed(header[0].as_slice())
    } else {
        Cow::Owned(header.concat())
    }
}

fn parse_http_date<S: Str>(string: S) -> Result<Tm, ()> {
    let string = string.as_slice();

    parse_rfc1123(string)
        .or_else(|_| parse_rfc850(string))
        .or_else(|_| parse_asctime(string))
        .map_err(|_| ())
}

fn parse_rfc1123(string: &str) -> Result<Tm, ParseError> {
    time::strptime(string, "%a, %d %b %Y %T GMT")
}

fn parse_rfc850(string: &str) -> Result<Tm, ParseError> {
    time::strptime(string, "%a, %d-%m-%y %T GMT")
}

fn parse_asctime(string: &str) -> Result<Tm, ParseError> {
    time::strptime(string, "%a %m%t%d %T %Y")
}

#[cfg(test)]
mod tests {
    extern crate "conduit-test" as test;

    use std::collections::HashMap;
    use std::error::Error;
    use std::old_io::MemReader;
    use time;
    use time::Tm;
    use conduit;
    use conduit::{Request, Response, Handler, Method};
    use middleware::MiddlewareBuilder;

    use super::ConditionalGet;

    macro_rules! returning {
        ($code:expr, $($header:expr => $value:expr),+) => ({
            let mut headers = HashMap::new();
            $(headers.insert($header.to_string(), vec!($value.to_string()));)+
            let handler = SimpleHandler::new(headers, $code, "hello");
            let mut stack = MiddlewareBuilder::new(handler);
            stack.add(ConditionalGet);
            stack
        });
        ($($header:expr => $value:expr),+) => ({
            returning!((200, "OK"), $($header => $value),+)
        })
    }

    macro_rules! request {
        ($($header:expr => $value:expr),+) => ({
            let mut req = test::MockRequest::new(Method::Get, "/");
            $(req.header($header, $value.to_string().as_slice());)+
            req
        })
    }

    #[test]
    fn test_sends_304() {
        let handler = returning!("Last-Modified" => httpdate(time::now()));
        expect_304(handler.call(&mut request!(
            "If-Modified-Since" => httpdate(time::now())
        ) as &mut conduit::Request));
    }

    #[test]
    fn test_sends_304_if_older_than_now() {
        let handler = returning!("Last-Modified" => before_now());
        expect_304(handler.call(&mut request!(
            "If-Modified-Since" => httpdate(time::now())
        ) as &mut conduit::Request));
    }

    #[test]
    fn test_sends_304_with_etag() {
        let handler = returning!("ETag" => "1234");
        expect_304(handler.call(&mut request!(
            "If-None-Match" => "1234"
        ) as &mut conduit::Request));
    }

    #[test]
    fn test_sends_200_with_fresh_time_but_not_etag() {
        let handler = returning!("Last-Modified" => before_now(), "ETag" => "1234");
        expect_200(handler.call(&mut request!(
            "If-Modified-Since" => now(),
            "If-None-Match" => "4321"
        ) as &mut conduit::Request));
    }

    #[test]
    fn test_sends_200_with_fresh_etag_but_not_time() {
        let handler = returning!("Last-Modified" => now(), "ETag" => "1234");
        expect_200(handler.call(&mut request!(
            "If-Modified-Since" => before_now(),
            "If-None-Match" => "1234"
        ) as &mut conduit::Request));
    }

    #[test]
    fn test_sends_200_with_fresh_etag() {
        let handler = returning!("ETag" => "1234");
        expect_200(handler.call(&mut request!(
            "If-None-Match" => "4321"
        ) as &mut conduit::Request));
    }

    #[test]
    fn test_sends_200_with_fresh_time() {
        let handler = returning!("Last-Modified" => now());
        expect_200(handler.call(&mut request!(
            "If-Modified-Since" => before_now()
        ) as &mut conduit::Request));
    }

    #[test]
    fn test_sends_304_with_fresh_time_and_etag() {
        let handler = returning!("Last-Modified" => before_now(), "ETag" => "1234");
        expect_304(handler.call(&mut request!(
            "If-Modified-Since" => now(),
            "If-None-Match" => "1234"
        ) as &mut conduit::Request));
    }

    #[test]
    fn test_does_not_affect_non_200() {
        let code = (302, "Found");
        let handler = returning!(code, "Last-Modified" => before_now(), "ETag" => "1234");
        expect(code, handler.call(&mut request!(
            "If-Modified-Since" => now(),
            "If-None-Match" => "1234"
        ) as &mut conduit::Request));
    }

    #[test]
    fn test_does_not_affect_malformed_timestamp() {
        let bad_stamp = time::now().strftime("%Y-%m-%d %H:%M:%S %z").unwrap().to_string();
        let handler = returning!("Last-Modified" => before_now());
        expect_200(handler.call(&mut request!(
            "If-Modified-Since" => bad_stamp
        ) as &mut conduit::Request));
    }

    fn expect_304(response: Result<Response, Box<Error+Send>>) {
        let mut response = response.ok().expect("No response");
        let body = response.body.read_to_string().ok().expect("No body");

        assert_eq!(response.status, (304, "Not Modified"));
        assert_eq!(body.as_slice(), "");
    }

    fn expect_200(response: Result<Response, Box<Error+Send>>) {
        expect((200, "OK"), response);
    }

    fn expect(status: (u32, &'static str), response: Result<Response, Box<Error+Send>>) {
        let mut response = response.ok().expect("No response");
        let body = response.body.read_to_string().ok().expect("No body");

        assert_eq!(response.status, status);
        assert_eq!(body.as_slice(), "hello");
    }

    struct SimpleHandler {
        map: HashMap<String, Vec<String>>,
        status: Status,
        body: &'static str
    }

    type Status = (u32, &'static str);

    impl SimpleHandler {
        fn new(map: HashMap<String, Vec<String>>, status: Status, body: &'static str) -> SimpleHandler {
            SimpleHandler { map: map, status: status, body: body }
        }
    }

    impl Handler for SimpleHandler {
        fn call(&self, _: &mut Request) -> Result<Response, Box<Error+Send>> {
            Ok(Response {
                status: self.status,
                headers: self.map.clone(),
                body: Box::new(MemReader::new(self.body.to_string().into_bytes())),
            })
        }
    }

    fn before_now() -> String {
        let mut now = time::now();
        now.tm_year -= 1;
        httpdate(now)
    }

    fn now() -> String {
        httpdate(time::now())
    }

    fn httpdate(time: Tm) -> String {
        time.strftime("%a, %d-%m-%y %T GMT").unwrap().to_string()
    }
}
<|endoftext|>


<commit_before>#![cfg_attr(feature = "benchmarks", feature(test))]
#[cfg(feature = "benchmarks")]
extern crate test;

mod corpus;
mod markovchain;

use std::fs::File;
use std::io;
use std::io::Read;
use std::path::PathBuf;

#[derive(Debug, Clone)]
pub struct GenPassphraseOptions {
    pub files: Vec<PathBuf>,
    pub number: usize,
    pub min_entropy: f64,
    pub ngram_length: usize,
    pub min_word_length: usize,
}

pub fn gen_passphrases(
    options: &GenPassphraseOptions,
) -> Result<Vec<(String, f64)>, Box<dyn std::error::Error>> {
    let reader = get_input_reader(&options.files)?;
    let corpus = corpus::Corpus::new(reader, options.ngram_length, options.min_word_length)?;
    let chain = markovchain::PassphraseMarkovChain::new(corpus.ngrams())?;

    let passphrases = (0..options.number)
        .map(|_| chain.passphrase(options.min_entropy))
        .collect();

    Ok(passphrases)
}

fn get_input_reader(files: &[PathBuf]) -> Result<Box<dyn io::Read>, Box<dyn std::error::Error>> {
    match files {
        [head, tail @ ..] => {
            let mut reader: Box<dyn io::Read> = Box::new(io::BufReader::new(File::open(head)?));
            for f in tail {
                reader = Box::new(reader.chain(io::BufReader::new(File::open(f)?)));
            }
            Ok(reader)
        }
        [] => Ok(Box::new(io::stdin())),
    }
}

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

    #[test]
    fn test_gen_passphrases() {
        let result = gen_passphrases(&get_test_options());
        assert!(result.is_ok(), "Passphrase generation failed.");
        let passphrases = result.unwrap();
        assert_eq!(passphrases.len(), 5);
    }

    #[cfg(feature = "benchmarks")]
    #[bench]
    fn bench_gen_passphrases(b: &mut test::Bencher) {
        let options = get_test_options();
        b.iter(|| gen_passphrases(&options));
    }

    fn get_testdata_pathbuf() -> PathBuf {
        let mut p = PathBuf::from(env!("CARGO_MANIFEST_DIR"));
        p.push("testdata/Jane Austen - Pride and Prejudice.txt");

        p
    }

    fn get_test_options() -> GenPassphraseOptions {
        GenPassphraseOptions {
            files: vec![get_testdata_pathbuf()],
            number: 5,
            min_entropy: 80.0,
            ngram_length: 3,
            min_word_length: 5,
        }
    }
}

mod bench {}
<commit_msg>Remove unecessary nested BufReader use<commit_after>#![cfg_attr(feature = "benchmarks", feature(test))]
#[cfg(feature = "benchmarks")]
extern crate test;

mod corpus;
mod markovchain;

use std::fs::File;
use std::io;
use std::io::Read;
use std::path::PathBuf;

#[derive(Debug, Clone)]
pub struct GenPassphraseOptions {
    pub files: Vec<PathBuf>,
    pub number: usize,
    pub min_entropy: f64,
    pub ngram_length: usize,
    pub min_word_length: usize,
}

pub fn gen_passphrases(
    options: &GenPassphraseOptions,
) -> Result<Vec<(String, f64)>, Box<dyn std::error::Error>> {
    let reader = get_input_reader(&options.files)?;
    let corpus = corpus::Corpus::new(reader, options.ngram_length, options.min_word_length)?;
    let chain = markovchain::PassphraseMarkovChain::new(corpus.ngrams())?;

    let passphrases = (0..options.number)
        .map(|_| chain.passphrase(options.min_entropy))
        .collect();

    Ok(passphrases)
}

fn get_input_reader(files: &[PathBuf]) -> Result<Box<dyn io::Read>, Box<dyn std::error::Error>> {
    match files {
        [head, tail @ ..] => {
            let mut reader: Box<dyn io::Read> = Box::new(File::open(head)?);
            for f in tail {
                reader = Box::new(reader.chain(File::open(f)?));
            }
            Ok(Box::new(io::BufReader::new(reader)))
        }
        [] => Ok(Box::new(io::stdin())),
    }
}

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

    #[test]
    fn test_gen_passphrases() {
        let result = gen_passphrases(&get_test_options());
        assert!(result.is_ok(), "Passphrase generation failed.");
        let passphrases = result.unwrap();
        assert_eq!(passphrases.len(), 5);
    }

    #[cfg(feature = "benchmarks")]
    #[bench]
    fn bench_gen_passphrases(b: &mut test::Bencher) {
        let options = get_test_options();
        b.iter(|| gen_passphrases(&options));
    }

    fn get_testdata_pathbuf() -> PathBuf {
        let mut p = PathBuf::from(env!("CARGO_MANIFEST_DIR"));
        p.push("testdata/Jane Austen - Pride and Prejudice.txt");

        p
    }

    fn get_test_options() -> GenPassphraseOptions {
        GenPassphraseOptions {
            files: vec![get_testdata_pathbuf()],
            number: 5,
            min_entropy: 80.0,
            ngram_length: 3,
            min_word_length: 5,
        }
    }
}

mod bench {}
<|endoftext|>


<commit_before>use std::fmt::{FormatError, Formatter, Show};

pub struct Tree<T> {
    pub data: T,
    pub children: Vec<Tree<T>>,
}

pub struct Zipper<T> {
    pub here: Tree<T>,
    lefts: Vec<Tree<T>>,
    rights: Vec<Tree<T>>,
    parent_path: Vec<(Vec<Tree<T>>, T, Vec<Tree<T>>)>,
}

pub enum Modified<T> {
    Old(Zipper<T>),
    New(Zipper<T>),
}

impl<T> Modified<T> {
    pub fn is_new(&self) -> bool {
        match *self {
            Modified::New(z) => true,
            _ => false,
        }
    }

    pub fn is_old(&self) -> bool {
        match *self {
            Modified::Old(z) => true,
            _ => false,
        }
    }

    pub fn unwrap(self) -> Zipper<T> {
        match self {
            Modified::New(z) => z,
            Modified::Old(z) => z,
        }
    }
}

impl<T> Tree<T> {
    pub fn new(data: T, children: Vec<Tree<T>>) -> Tree<T> {
        Tree {
            data: data,
            children: children,
        }
    }

    pub fn leaf(data: T) -> Tree<T> {
        Tree {
            data: data,
            children: Vec::new(),
        }
    }

    pub fn zipper(self) -> Zipper<T> {
        Zipper {
            lefts: Vec::new(),
            here: self,
            rights: Vec::new(),
            parent_path: Vec::new(),
        }
    }
}

impl<T: Show> Show for Tree<T> {
    fn fmt(&self, f: &mut Formatter) -> Result<(), FormatError> {
        match write!(f, "({}", self.data) {
            Err(e) => return Err(e),
            _ => (),
        }
        for c in self.children.iter() {
            match write!(f, " {}", c) {
                Err(e) => return Err(e),
                _ => (),
            }
        }
        write!(f, ")")
    }
}

impl<T: Clone> Clone for Tree<T> {
    fn clone(&self) -> Tree<T> {
        Tree {
            data: self.data.clone(),
            children: self.children.clone(),
        }
    }

    fn clone_from(&mut self, source: &Tree<T>) {
        self.data.clone_from(&source.data);
        self.children.clone_from(&source.children);
    }
}

impl<T> Zipper<T> {
    pub fn to_root(mut self) -> Zipper<T> {
        let mut lefts = self.lefts;
        let mut here = self.here;
        let mut rights = self.rights;
        loop {
            match self.parent_path.pop() {
                None => return Zipper {
                    lefts: Vec::new(),
                    rights: Vec::new(),
                    here: here,
                    parent_path: Vec::new(),
                },
                Some((parent_lefts, parent_data, parent_rights)) => {
                    let mut new_children = Vec::with_capacity(lefts.len() + rights.len() + 1);
                    new_children.extend(lefts.into_iter());
                    new_children.push(here);
                    new_children.extend(rights.into_iter());
                    here = Tree::new(parent_data, new_children);
                    lefts = parent_lefts;
                    rights = parent_rights;
                },
            }
        }
    }

    pub fn to_left(mut self) -> Modified<T> {
        let sibling = self.lefts.pop();
        if sibling.is_none() {
            Modified::Old(self)
        } else {
            self.rights.push(self.here);
            self.here = sibling.unwrap();
            Modified::New(self)
        }
    }

    pub fn to_right(mut self) -> Modified<T> {
        let sibling = self.rights.pop();
        if sibling.is_none() {
            Modified::Old(self)
        } else {
            self.lefts.push(self.here);
            self.here = sibling.unwrap();
            Modified::New(self)
        }
    }

    pub fn tree(self) -> Tree<T> {
        self.to_root().here
    }

    pub fn to_parent(mut self) -> Modified<T> {
        match self.parent_path.pop() {
            None => Modified::Old(self),
            Some((parent_lefts, parent_data, parent_rights)) => {
                let mut new_children = Vec::with_capacity(self.lefts.len() + self.rights.len() + 1);
                new_children.extend(self.lefts.into_iter());
                new_children.push(self.here);
                new_children.extend(self.rights.into_iter());
                self.lefts = parent_lefts;
                self.here = Tree::new(parent_data, new_children);
                self.rights = parent_rights;
                Modified::New(self)
            },
        }
    }

    pub fn to_first_child(self) -> Modified<T> {
        self.to_child_at(0u)
    }

    pub fn to_child_at(mut self, child_index: uint) -> Modified<T> {
        if self.here.children.len() <= child_index {
            Modified::Old(self)
        } else {
            let child = self.here.children.remove(child_index).unwrap();
            let mut lefts = Vec::with_capacity(child_index);
            let mut rights = Vec::with_capacity(self.here.children.len() - child_index);
            let mut i = self.here.children.into_iter();
            for _ in range(0, child_index) {
                lefts.push(i.next().unwrap());
            }
            for x in i.rev() {
                rights.push(x);
            }
            self.parent_path.push((self.lefts, self.here.data, self.rights));
            self.lefts = lefts;
            self.here = child;
            self.rights = rights;
            Modified::New(self)
        }
    }

    pub fn to_last_child(self) -> Modified<T> {
        if self.here.children.is_empty() {
            Modified::Old(self)
        } else {
            let child_index = self.here.children.len() - 1;
            self.to_child_at(child_index)
        }
    }

    pub fn set_tree(&mut self, here: Tree<T>) {
        self.here = here;
    }

    pub fn shrink_to_fit(&mut self) {
        self.here.children.shrink_to_fit();
        self.lefts.shrink_to_fit();
        self.rights.shrink_to_fit();
        self.parent_path.shrink_to_fit();
    }

    pub fn push_left(&mut self, sibling: Tree<T>) {
        self.lefts.push(sibling);
    }

    pub fn to_push_left(mut self, sibling: Tree<T>) -> Zipper<T> {
        self.rights.push(self.here);
        Zipper {
            lefts: self.lefts,
            here: sibling,
            rights: self.rights,
            parent_path: self.parent_path,
        }
    }

    pub fn push_right(&mut self, sibling: Tree<T>) {
        self.rights.push(sibling);
    }

    pub fn to_push_right(mut self, sibling: Tree<T>) -> Zipper<T> {
        self.lefts.push(self.here);
        Zipper {
            lefts: self.lefts,
            here: sibling,
            rights: self.rights,
            parent_path: self.parent_path,
        }
    }

    pub fn push_child_at(&mut self, index: uint, child: Tree<T>) -> bool {
        if index <= self.here.children.len() {
            self.here.children.insert(index, child);
            true
        } else {
            false
        }
    }

    pub fn to_push_child_at(mut self, index: uint, child: Tree<T>) -> Option<Zipper<T>> {
        if index > self.here.children.len() {
            None
        } else {
            self.parent_path.push((self.lefts, self.here.data, self.rights));
            let mut left_children = Vec::with_capacity(index);
            let mut right_children = Vec::with_capacity(self.here.children.len() - index);
            let mut i = self.here.children.into_iter();
            for _ in range(0, index) {
                left_children.push(i.next().unwrap());
            }
            for x in i {
                right_children.push(x);
            }
            Some(Zipper {
                lefts: left_children,
                here: child,
                rights: right_children,
                parent_path: self.parent_path,
            })
        }
    }

    pub fn drop_left(&mut self) -> bool {
        if self.lefts.is_empty() {
            false
        } else {
            self.lefts.pop();
            true
        }
    }

    pub fn drop_right(&mut self) -> bool {
        if self.rights.is_empty() {
            false
        } else {
            self.rights.pop();
            true
        }
    }

    pub fn make_orphan(&mut self) {
        self.lefts.clear();
        self.rights.clear();
        self.parent_path.clear();
    }

    pub fn make_leaf(&mut self) {
        self.here.children.clear();
    }

    pub fn delete(mut self) -> Option<Zipper<T>> {
        match self.rights.pop() {
            Some(new_here) => {
                self.here = new_here;
                Some(self)
            },
            None => match self.lefts.pop() {
                Some(new_here) => {
                    self.here = new_here;
                    Some(self)
                },
                None => match self.parent_path.pop() {
                    None => None,
                    Some((parent_lefts, parent_data, parent_rights)) => {
                        self.lefts = parent_lefts;
                        self.here = Tree::leaf(parent_data);
                        self.rights = parent_rights;
                        Some(self)
                    },
                },
            },
        }
    }
}

impl<T: Clone> Clone for Zipper<T> {
    fn clone(&self) -> Zipper<T> {
        Zipper {
            here: self.here.clone(),
            lefts: self.lefts.clone(),
            rights: self.rights.clone(),
            parent_path: self.parent_path.clone(),
        }
    }

    fn clone_from(&mut self, source: &Zipper<T> ) {
        self.here = source.here.clone();
        self.lefts = source.lefts.clone();
        self.rights = source.rights.clone();
        self.parent_path = source.parent_path.clone();
    }
}
<commit_msg>Improved trait impls and more basic tests.<commit_after>use std::fmt::{FormatError, Formatter, Show};

pub struct Tree<T> {
    pub data: T,
    pub children: Vec<Tree<T>>,
}

pub struct Zipper<T> {
    pub here: Tree<T>,
    lefts: Vec<Tree<T>>,
    rights: Vec<Tree<T>>,
    parent_path: Vec<(Vec<Tree<T>>, T, Vec<Tree<T>>)>,
}

pub enum Modified<T> {
    Old(Zipper<T>),
    New(Zipper<T>),
}

impl<T> Modified<T> {
    pub fn is_new(&self) -> bool {
        match self {
            &Modified::New(_) => true,
            _ => false,
        }
    }

    pub fn is_old(&self) -> bool {
        match self {
            &Modified::Old(_) => true,
            _ => false,
        }
    }

    pub fn unwrap(self) -> Zipper<T> {
        match self {
            Modified::New(z) => z,
            Modified::Old(z) => z,
        }
    }
}

impl<T> Tree<T> {
    pub fn new(data: T, children: Vec<Tree<T>>) -> Tree<T> {
        Tree {
            data: data,
            children: children,
        }
    }

    pub fn leaf(data: T) -> Tree<T> {
        Tree {
            data: data,
            children: Vec::new(),
        }
    }

    pub fn zipper(self) -> Zipper<T> {
        Zipper {
            lefts: Vec::new(),
            here: self,
            rights: Vec::new(),
            parent_path: Vec::new(),
        }
    }
}

impl<T: Show> Show for Tree<T> {
    fn fmt(&self, f: &mut Formatter) -> Result<(), FormatError> {
        enum Walk<T> {
            Down(T),
            Up,
        };
        let mut stack = Vec::new();
        match write!(f, "({}", self.data) {
            Err(e) => return Err(e),
            _ => (),
        }
        stack.push(Walk::Up);
        for c in self.children.iter().rev() {
            stack.push(Down(c));
        }
        loop {
            match stack.pop() {
                None => return Ok(()),
                Some(Walk::Up) => match write!(f, ")") {
                    Err(e) => return Err(e),
                    _ => (),
                },
                Some(Walk::Down(t)) => match write!(f, " ({}", t.data) {
                    Err(e) => return Err(e),
                    _ => {
                        stack.push(Up);
                        for c in t.children.iter().rev() {
                            stack.push(Down(c));
                        }
                    },
                },
            }
        }
    }
}

impl<T: Clone> Clone for Tree<T> {
    fn clone(&self) -> Tree<T> {
        Tree {
            data: self.data.clone(),
            children: self.children.clone(),
        }
    }

    fn clone_from(&mut self, source: &Tree<T>) {
        self.data.clone_from(&source.data);
        self.children.clone_from(&source.children);
    }
}

impl<T: PartialEq> PartialEq for Tree<T> {
    fn eq(&self, other: &Tree<T>) -> bool {
        let mut stack = Vec::new();
        stack.push((self, other));
        loop {
            match stack.pop() {
                Some((x, y)) => {
                    if x.data != y.data {
                        return false;
                    } else if x.children.len() != y.children.len() {
                        return false;
                    } else {
                        let mut xi = x.children.iter();
                        let mut yi = y.children.iter();
                        loop {
                            match (xi.next(), yi.next()) {
                                (Some(xt), Some(yt)) => stack.push((xt, yt)),
                                (None, None) => break,
                                _ => panic!("Tree corruption"),
                            }
                        }
                    }
                },
                None => break,
            }
        }
        return true;
    }
}

impl<T> Zipper<T> {
    pub fn to_root(mut self) -> Zipper<T> {
        let mut lefts = self.lefts;
        let mut here = self.here;
        let mut rights = self.rights;
        loop {
            match self.parent_path.pop() {
                None => return Zipper {
                    lefts: Vec::new(),
                    rights: Vec::new(),
                    here: here,
                    parent_path: Vec::new(),
                },
                Some((parent_lefts, parent_data, parent_rights)) => {
                    let mut new_children = Vec::with_capacity(lefts.len() + rights.len() + 1);
                    new_children.extend(lefts.into_iter());
                    new_children.push(here);
                    new_children.extend(rights.into_iter());
                    here = Tree::new(parent_data, new_children);
                    lefts = parent_lefts;
                    rights = parent_rights;
                },
            }
        }
    }

    pub fn to_left(mut self) -> Modified<T> {
        let sibling = self.lefts.pop();
        if sibling.is_none() {
            Modified::Old(self)
        } else {
            self.rights.push(self.here);
            self.here = sibling.unwrap();
            Modified::New(self)
        }
    }

    pub fn to_right(mut self) -> Modified<T> {
        let sibling = self.rights.pop();
        if sibling.is_none() {
            Modified::Old(self)
        } else {
            self.lefts.push(self.here);
            self.here = sibling.unwrap();
            Modified::New(self)
        }
    }

    pub fn tree(self) -> Tree<T> {
        self.to_root().here
    }

    pub fn to_parent(mut self) -> Modified<T> {
        match self.parent_path.pop() {
            None => Modified::Old(self),
            Some((parent_lefts, parent_data, parent_rights)) => {
                let mut new_children = Vec::with_capacity(self.lefts.len() + self.rights.len() + 1);
                new_children.extend(self.lefts.into_iter());
                new_children.push(self.here);
                new_children.extend(self.rights.into_iter());
                self.lefts = parent_lefts;
                self.here = Tree::new(parent_data, new_children);
                self.rights = parent_rights;
                Modified::New(self)
            },
        }
    }

    pub fn to_first_child(self) -> Modified<T> {
        self.to_child_at(0u)
    }

    pub fn to_child_at(mut self, child_index: uint) -> Modified<T> {
        if self.here.children.len() <= child_index {
            Modified::Old(self)
        } else {
            let child = self.here.children.remove(child_index).unwrap();
            let mut lefts = Vec::with_capacity(child_index);
            let mut rights = Vec::with_capacity(self.here.children.len() - child_index);
            let mut i = self.here.children.into_iter();
            for _ in range(0, child_index) {
                lefts.push(i.next().unwrap());
            }
            for x in i.rev() {
                rights.push(x);
            }
            self.parent_path.push((self.lefts, self.here.data, self.rights));
            self.lefts = lefts;
            self.here = child;
            self.rights = rights;
            Modified::New(self)
        }
    }

    pub fn to_last_child(self) -> Modified<T> {
        if self.here.children.is_empty() {
            Modified::Old(self)
        } else {
            let child_index = self.here.children.len() - 1;
            self.to_child_at(child_index)
        }
    }

    pub fn set_tree(&mut self, here: Tree<T>) {
        self.here = here;
    }

    pub fn shrink_to_fit(&mut self) {
        self.here.children.shrink_to_fit();
        self.lefts.shrink_to_fit();
        self.rights.shrink_to_fit();
        self.parent_path.shrink_to_fit();
    }

    pub fn push_left(&mut self, sibling: Tree<T>) {
        self.lefts.push(sibling);
    }

    pub fn to_push_left(mut self, sibling: Tree<T>) -> Zipper<T> {
        self.rights.push(self.here);
        Zipper {
            lefts: self.lefts,
            here: sibling,
            rights: self.rights,
            parent_path: self.parent_path,
        }
    }

    pub fn push_right(&mut self, sibling: Tree<T>) {
        self.rights.push(sibling);
    }

    pub fn to_push_right(mut self, sibling: Tree<T>) -> Zipper<T> {
        self.lefts.push(self.here);
        Zipper {
            lefts: self.lefts,
            here: sibling,
            rights: self.rights,
            parent_path: self.parent_path,
        }
    }

    pub fn push_child_at(&mut self, index: uint, child: Tree<T>) -> bool {
        if index <= self.here.children.len() {
            self.here.children.insert(index, child);
            true
        } else {
            false
        }
    }

    pub fn to_push_child_at(mut self, index: uint, child: Tree<T>) -> Option<Zipper<T>> {
        if index > self.here.children.len() {
            None
        } else {
            self.parent_path.push((self.lefts, self.here.data, self.rights));
            let mut left_children = Vec::with_capacity(index);
            let mut right_children = Vec::with_capacity(self.here.children.len() - index);
            let mut i = self.here.children.into_iter();
            for _ in range(0, index) {
                left_children.push(i.next().unwrap());
            }
            for x in i {
                right_children.push(x);
            }
            Some(Zipper {
                lefts: left_children,
                here: child,
                rights: right_children,
                parent_path: self.parent_path,
            })
        }
    }

    pub fn drop_left(&mut self) -> bool {
        if self.lefts.is_empty() {
            false
        } else {
            self.lefts.pop();
            true
        }
    }

    pub fn drop_right(&mut self) -> bool {
        if self.rights.is_empty() {
            false
        } else {
            self.rights.pop();
            true
        }
    }

    pub fn make_orphan(&mut self) {
        self.lefts.clear();
        self.rights.clear();
        self.parent_path.clear();
    }

    pub fn make_leaf(&mut self) {
        self.here.children.clear();
    }

    pub fn delete(mut self) -> Option<Zipper<T>> {
        match self.rights.pop() {
            Some(new_here) => {
                self.here = new_here;
                Some(self)
            },
            None => match self.lefts.pop() {
                Some(new_here) => {
                    self.here = new_here;
                    Some(self)
                },
                None => match self.parent_path.pop() {
                    None => None,
                    Some((parent_lefts, parent_data, parent_rights)) => {
                        self.lefts = parent_lefts;
                        self.here = Tree::leaf(parent_data);
                        self.rights = parent_rights;
                        Some(self)
                    },
                },
            },
        }
    }
}

impl<T: Clone> Clone for Zipper<T> {
    fn clone(&self) -> Zipper<T> {
        Zipper {
            here: self.here.clone(),
            lefts: self.lefts.clone(),
            rights: self.rights.clone(),
            parent_path: self.parent_path.clone(),
        }
    }

    fn clone_from(&mut self, source: &Zipper<T> ) {
        self.here = source.here.clone();
        self.lefts = source.lefts.clone();
        self.rights = source.rights.clone();
        self.parent_path = source.parent_path.clone();
    }
}

impl<T: PartialEq> PartialEq for Zipper<T> {
    fn eq(&self, other: &Zipper<T>) -> bool {
        self.here == other.here
            && self.lefts == other.lefts
            && self.rights == other.rights
            && self.parent_path == other.parent_path
    }
}

#[cfg(test)]
mod tests {
    extern crate test;

    use super::Tree;

    #[test]
    fn test_new() {
        let t = Tree::new("head", vec![Tree::leaf("one"),
                                       Tree::leaf("two"),
                                       Tree::leaf("three")]);
        assert_eq!(t.data, "head");
        assert_eq!(t.children, vec![Tree::leaf("one"),
                                    Tree::leaf("two"),
                                    Tree::leaf("three")]);
    }

    #[test]
    fn test_leaf() {
        let t = Tree::leaf("asdf");
        assert_eq!(t.data, "asdf");
        assert_eq!(t.children.len(), 0);
    }

    #[test]
    fn test_trivial_tree_equality() {
        let t1 = Tree::new("head", vec![Tree::leaf("one"),
                                        Tree::leaf("two"),
                                        Tree::leaf("three")]);
        let t2 = Tree::new("head", vec![Tree::leaf("one"),
                                        Tree::leaf("two"),
                                        Tree::leaf("three")]);
        assert_eq!(t1, t2);
        assert_eq!(t1, t1);
        assert_eq!(t2, t2);
        assert!(t1 != Tree::leaf("head"));
        assert!(t1 != Tree::new("blarg", vec![Tree::leaf("one"),
                                              Tree::leaf("two"),
                                              Tree::leaf("three")]));
    }

    #[test]
    fn test_trivial_zipper_equality() {
        let z1 = Tree::new("head", vec![Tree::leaf("one"),
                                        Tree::leaf("two"),
                                        Tree::leaf("three")]).zipper();
        let z2 = Tree::new("head", vec![Tree::leaf("one"),
                                        Tree::leaf("two"),
                                        Tree::leaf("three")]).zipper();
        assert!(z1 == z2);
        assert!(z1 != Tree::leaf("head").zipper());
        assert!(z1 !=Tree::new("blarg", vec![Tree::leaf("one"),
                                             Tree::leaf("two"),
                                             Tree::leaf("three")]).zipper());
    }

    #[test]
    fn test_trivial_clone() {
        let t1 = Tree::new("head", vec![Tree::leaf("one"),
                                                Tree::leaf("two"),
                                                Tree::leaf("three")]);
        assert_eq!(t1, t1.clone());
    }

    #[test]
    fn test_trivial_show() {
        let t1 = Tree::new("head", vec![Tree::leaf("one"),
                                        Tree::leaf("two"),
                                        Tree::leaf("three")]);
        assert_eq!(t1.to_string(),
                   "(head (one) (two) (three))".to_string());
    }
}
<|endoftext|>


<commit_before>// The MIT License (MIT)
//
// Copyright (c) 2014 J.C. Moyer
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.

#![crate_name = "lua"]
#![crate_type = "lib"]
#![comment = "Lua 5.3 bindings for Rust"]
#![license = "MIT"]

#![feature(unsafe_destructor)]

extern crate libc;

pub use wrapper::state::{
  State,

  Number,
  Integer,
  Function,
  Continuation,
  Reader,
  Writer,
  Context,
  Allocator,
  Hook,
  Index,

  Arithmetic,
  Comparison,
  ThreadStatus,
  GcOption,
  Type,

  Reference,
  REFNIL, NOREF,

  HookMask,
  MASKCALL, MASKRET, MASKLINE, MASKCOUNT,

  MULTRET, REGISTRYINDEX,
  RIDX_MAINTHREAD, RIDX_GLOBALS
};

#[cfg(target_os="windows")]
mod windows {
  #[link(name="lua53")]
  extern {}
}

#[cfg(not(target_os="windows"))]
mod unix {
  #[link(name="lua")]
  extern {}
}

pub mod ffi;
pub mod wrapper;

<commit_msg>Remove now-useless crate attributes<commit_after>// The MIT License (MIT)
//
// Copyright (c) 2014 J.C. Moyer
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.

#![crate_name = "lua"]
#![crate_type = "lib"]

#![feature(unsafe_destructor)]

extern crate libc;

pub use wrapper::state::{
  State,

  Number,
  Integer,
  Function,
  Continuation,
  Reader,
  Writer,
  Context,
  Allocator,
  Hook,
  Index,

  Arithmetic,
  Comparison,
  ThreadStatus,
  GcOption,
  Type,

  Reference,
  REFNIL, NOREF,

  HookMask,
  MASKCALL, MASKRET, MASKLINE, MASKCOUNT,

  MULTRET, REGISTRYINDEX,
  RIDX_MAINTHREAD, RIDX_GLOBALS
};

#[cfg(target_os="windows")]
mod windows {
  #[link(name="lua53")]
  extern {}
}

#[cfg(not(target_os="windows"))]
mod unix {
  #[link(name="lua")]
  extern {}
}

pub mod ffi;
pub mod wrapper;

<|endoftext|>


<commit_before>pub mod names;
mod pokemon_data;
mod types;
mod evaluation;

pub use self::pokemon_data::*;
pub use self::types::*;
pub use self::evaluation::*;
pub use self::names as Names;
<commit_msg>Organize lib.rs<commit_after>mod evaluation;
pub use self::evaluation::*;

pub mod names;

mod pokemon_data;
pub use self::pokemon_data::*;

mod types;
pub use self::types::*;
<|endoftext|>


<commit_before>extern crate bincode;
extern crate rustc_serialize;

use bincode::SizeLimit;
use bincode::rustc_serialize::{encode, decode};
use rustc_serialize::{Encodable, Decodable};

use std::error::Error;
use std::fs::File;
use std::io::{Read, Seek, SeekFrom};
use std::fs::OpenOptions;
use std::mem::{size_of};
use std::cmp::max;

const NUM_CHILDREN: usize = 32;

// specify the types for the keys & values
pub trait KeyType: Ord + Encodable + Decodable {}
pub trait ValueType: Encodable + Decodable {}

#[derive(RustcEncodable, RustcDecodable, PartialEq)]
enum Payload<K: Ord, V: ValueType> {
        Value(V),
        Children([(K,u64); NUM_CHILDREN]),
    }

#[derive(RustcEncodable, RustcDecodable, PartialEq)]
struct Node<K: KeyType, V: ValueType> {
    key: K,
    parent: u64,
    payload: Payload<K,V>, // either children, or actual values
}

/// This struct represents an on-disk B+Tree. There are NUM_CHILDREN keys at each
/// level in the tree. The on-disk format is as follows where VV is the version
/// number:
/// |-------------------------------------------|
/// | 0x2b 0x42 0x72 0x54 | 0x65 0x65 0x00 0xVV |
/// |-------------------------------------------|
/// | smallest record in bincode format         |
/// |-------------------------------------------|
/// | ...                                       |
/// |-------------------------------------------|
/// | largest record in bincode format          |
/// |-------------------------------------------|
/// | internal nodes ...                        |
/// |-------------------------------------------|
/// | root node                                 |
/// |-------------------------------------------|
pub struct BTree<K: KeyType, V: ValueType> {
    fd: File,           // the file backing the whole thing
    root: Node<K,V>,    // in-memory copy of the root node
    key_size: usize,    // the size of the key in bytes
    value_size: usize,  // the size of the value in bytes
}

impl <K: KeyType, V: ValueType> BTree<K, V> {
    pub fn new(key_size: usize, value_size: usize) -> Result<BTree<K,V>, Box<Error>> {
        let mut file = try!(OpenOptions::new()
                                  .read(true)
                                  .write(true)
                                  .create(true)
                                  .open("btree.dat"));

        // make sure we've opened a proper file
        let mut version_string = Vec::with_capacity(8);

        try!(file.read_exact(&mut version_string));

        if version_string[0] != 0x2b {
            Err("Invalid BTree File")
        }

        // total size of a Node
        let total_size = key_size + size_of::<u64>() + max(value_size, (key_size+size_of::<u64>()) * NUM_CHILDREN);
        let mut buff = Vec::with_capacity(total_size);

        // seek total_size in from the end of the file to read the root node
        try!(file.seek(SeekFrom::End(total_size as i64)));
        try!(file.read_exact(&mut buff));

        let root_node: Node<K,V> = decode(&buff[..]).unwrap();

        Ok(BTree{ fd: file, key_size: key_size, value_size: value_size, root: root_node })
    }
}

#[cfg(test)]
mod tests {
    #[test]
    fn it_works() {
        println!("It works!!!")
    }
}
<commit_msg>Fixed error check<commit_after>extern crate bincode;
extern crate rustc_serialize;

use bincode::SizeLimit;
use bincode::rustc_serialize::{encode, decode};
use rustc_serialize::{Encodable, Decodable};

use std::error::Error;
use std::fs::File;
use std::io::{Read, Seek, SeekFrom, ErrorKind};
use std::fs::OpenOptions;
use std::mem::{size_of};
use std::cmp::max;
use std::convert::From;

const NUM_CHILDREN: usize = 32;

// specify the types for the keys & values
pub trait KeyType: Ord + Encodable + Decodable {}
pub trait ValueType: Encodable + Decodable {}

#[derive(RustcEncodable, RustcDecodable, PartialEq)]
enum Payload<K: Ord, V: ValueType> {
        Value(V),
        Children([(K,u64); NUM_CHILDREN]),
    }

#[derive(RustcEncodable, RustcDecodable, PartialEq)]
struct Node<K: KeyType, V: ValueType> {
    key: K,
    parent: u64,
    payload: Payload<K,V>, // either children, or actual values
}

/// This struct represents an on-disk B+Tree. There are NUM_CHILDREN keys at each
/// level in the tree. The on-disk format is as follows where VV is the version
/// number:
/// |-------------------------------------------|
/// | 0x2b 0x42 0x72 0x54 | 0x65 0x65 0x00 0xVV |
/// |-------------------------------------------|
/// | smallest record in bincode format         |
/// |-------------------------------------------|
/// | ...                                       |
/// |-------------------------------------------|
/// | largest record in bincode format          |
/// |-------------------------------------------|
/// | internal nodes ...                        |
/// |-------------------------------------------|
/// | root node                                 |
/// |-------------------------------------------|
pub struct BTree<K: KeyType, V: ValueType> {
    fd: File,           // the file backing the whole thing
    root: Node<K,V>,    // in-memory copy of the root node
    key_size: usize,    // the size of the key in bytes
    value_size: usize,  // the size of the value in bytes
}

impl <K: KeyType, V: ValueType> BTree<K, V> {
    pub fn new(key_size: usize, value_size: usize) -> Result<BTree<K,V>, Box<Error>> {
        let mut file = try!(OpenOptions::new()
                                  .read(true)
                                  .write(true)
                                  .create(true)
                                  .open("btree.dat"));

        // make sure we've opened a proper file
        let mut version_string = Vec::with_capacity(8);

        try!(file.read_exact(&mut version_string));

        if version_string[0] != 0x2b {
            return Err(From::from(std::io::Error::new(ErrorKind::InvalidData, "Invalid BTree file version")));
        }

        // total size of a Node
        let total_size = key_size + size_of::<u64>() + max(value_size, (key_size+size_of::<u64>()) * NUM_CHILDREN);
        let mut buff = Vec::with_capacity(total_size);

        // seek total_size in from the end of the file to read the root node
        try!(file.seek(SeekFrom::End(total_size as i64)));
        try!(file.read_exact(&mut buff));

        let root_node: Node<K,V> = decode(&buff[..]).unwrap();

        Ok(BTree{ fd: file, key_size: key_size, value_size: value_size, root: root_node })
    }
}

#[cfg(test)]
mod tests {
    #[test]
    fn it_works() {
        println!("It works!!!")
    }
}
<|endoftext|>