<commit_before>#![feature(test)]

extern crate dnfa;
extern crate test;

use std::iter;

use dnfa::nfa::{NFA};
use dnfa::automaton::*;
use test::Bencher;

const HAYSTACK_RANDOM: &'static str = include_str!("random.txt");
const HAYSTACK_SHERLOCK: &'static str = include_str!("sherlock.txt");

fn bench_aut_no_match(
    b: &mut Bencher,
    aut: NFA,
    haystack: &str,
) {
    b.bytes = haystack.len() as u64;
    b.iter(|| assert!(aut.find(haystack.as_bytes()).next().is_none()));
}

fn bench_box_aut_no_match(
    b: &mut Bencher,
    aut: NFA,
    haystack: &str,
) {
    b.bytes = haystack.len() as u64;
    let aut: &NFA = &aut;
    b.iter(|| assert!(Automaton::find(aut, haystack.as_bytes()).next().is_none()));
}

//fn bench_full_aut_no_match(
//    b: &mut Bencher,
//    aut: NFA,
//    haystack: &str,
//) {
//    let aut = aut.into_full();
//    b.bytes = haystack.len() as u64;
//    b.iter(|| assert!(aut.find(haystack.as_bytes()).next().is_none()));
//}

//fn bench_full_aut_overlapping_no_match(
//    b: &mut Bencher,
//    aut: NFA,
//    haystack: &str,
//) {
//    let aut = aut.into_full();
//    b.bytes = haystack.len() as u64;
//    b.iter(|| assert!(aut.find_overlapping(haystack.as_bytes()).count() == 0));
//}

fn bench_naive_no_match<S>(b: &mut Bencher, needles: Vec<S>, haystack: &str)
        where S: Into<String> {
    b.bytes = haystack.len() as u64;
    let needles: Vec<String> = needles.into_iter().map(Into::into).collect();
    b.iter(|| assert!(!naive_find(&needles, haystack)));
}

fn haystack_same(letter: char) -> String {
    iter::repeat(letter).take(10000).collect()
}

macro_rules! aut_benches {
    ($prefix:ident, $aut:expr, $bench:expr) => {
        mod $prefix {
#![allow(unused_imports)]
use dnfa::nfa::{NFA};
use dnfa::automaton::{Automaton};
use test::Bencher;

use super::{
    HAYSTACK_RANDOM, haystack_same,
    bench_aut_no_match, bench_box_aut_no_match,
//    bench_full_aut_no_match, bench_full_aut_overlapping_no_match,
};

#[bench]
fn ac_one_byte(b: &mut Bencher) {
    let aut = $aut(vec!["a"]);
    $bench(b, aut, &haystack_same('z'));
}

#[bench]
fn ac_one_prefix_byte_no_match(b: &mut Bencher) {
    let aut = $aut(vec!["zbc"]);
    $bench(b, aut, &haystack_same('y'));
}

#[bench]
fn ac_one_prefix_byte_every_match(b: &mut Bencher) {
    // We lose the benefit of `memchr` because the first byte matches
    // in every position in the haystack.
    let aut = $aut(vec!["zbc"]);
    $bench(b, aut, &haystack_same('z'));
}

#[bench]
fn ac_one_prefix_byte_random(b: &mut Bencher) {
    let aut = $aut(vec!["zbc\x00"]);
    $bench(b, aut, HAYSTACK_RANDOM);
}

#[bench]
fn ac_two_bytes(b: &mut Bencher) {
    let aut = $aut(vec!["a", "b"]);
    $bench(b, aut, &haystack_same('z'));
}

#[bench]
fn ac_two_diff_prefix(b: &mut Bencher) {
    let aut = $aut(vec!["abcdef", "bmnopq"]);
    $bench(b, aut, &haystack_same('z'));
}

#[bench]
fn ac_two_one_prefix_byte_every_match(b: &mut Bencher) {
    let aut = $aut(vec!["zbcdef", "zmnopq"]);
    $bench(b, aut, &haystack_same('z'));
}

#[bench]
fn ac_two_one_prefix_byte_no_match(b: &mut Bencher) {
    let aut = $aut(vec!["zbcdef", "zmnopq"]);
    $bench(b, aut, &haystack_same('y'));
}

#[bench]
fn ac_two_one_prefix_byte_random(b: &mut Bencher) {
    let aut = $aut(vec!["zbcdef\x00", "zmnopq\x00"]);
    $bench(b, aut, HAYSTACK_RANDOM);
}

#[bench]
fn ac_ten_bytes(b: &mut Bencher) {
    let aut = $aut(vec!["a", "b", "c", "d", "e",
                        "f", "g", "h", "i", "j"]);
    $bench(b, aut, &haystack_same('z'));
}

#[bench]
fn ac_ten_diff_prefix(b: &mut Bencher) {
    let aut = $aut(vec!["abcdef", "bbcdef", "cbcdef", "dbcdef",
                        "ebcdef", "fbcdef", "gbcdef", "hbcdef",
                        "ibcdef", "jbcdef"]);
    $bench(b, aut, &haystack_same('z'));
}

#[bench]
fn ac_ten_one_prefix_byte_every_match(b: &mut Bencher) {
    let aut = $aut(vec!["zacdef", "zbcdef", "zccdef", "zdcdef",
                        "zecdef", "zfcdef", "zgcdef", "zhcdef",
                        "zicdef", "zjcdef"]);
    $bench(b, aut, &haystack_same('z'));
}

#[bench]
fn ac_ten_one_prefix_byte_no_match(b: &mut Bencher) {
    let aut = $aut(vec!["zacdef", "zbcdef", "zccdef", "zdcdef",
                        "zecdef", "zfcdef", "zgcdef", "zhcdef",
                        "zicdef", "zjcdef"]);
    $bench(b, aut, &haystack_same('y'));
}

#[bench]
fn ac_ten_one_prefix_byte_random(b: &mut Bencher) {
    let aut = $aut(vec!["zacdef\x00", "zbcdef\x00", "zccdef\x00",
                        "zdcdef\x00", "zecdef\x00", "zfcdef\x00",
                        "zgcdef\x00", "zhcdef\x00", "zicdef\x00",
                        "zjcdef\x00"]);
    $bench(b, aut, HAYSTACK_RANDOM);
}
        }
    }
}

aut_benches!(dense, NFA::from_dictionary, bench_aut_no_match);
aut_benches!(dense_boxed, NFA::from_dictionary, bench_box_aut_no_match);
//aut_benches!(sparse, AcAutomaton::<&str, Sparse>::with_transitions,
//             bench_aut_no_match);
//aut_benches!(full, AcAutomaton::new, bench_full_aut_no_match);
//aut_benches!(full_overlap, AcAutomaton::new, bench_full_aut_overlapping_no_match);

// A naive multi-pattern search.
// We use this to benchmark *throughput*, so it should never match anything.
fn naive_find(needles: &[String], haystack: &str) -> bool {
    for hi in 0..haystack.len() {
        let rest = &haystack.as_bytes()[hi..];
        for needle in needles {
            let needle = needle.as_bytes();
            if needle.len() > rest.len() {
                continue;
            }
            if needle == &rest[..needle.len()] {
                // should never happen in throughput benchmarks.
                return true;
            }
        }
    }
    false
}

#[bench]
fn naive_one_byte(b: &mut Bencher) {
    bench_naive_no_match(b, vec!["a"], &haystack_same('z'));
}

#[bench]
fn naive_one_prefix_byte_no_match(b: &mut Bencher) {
    bench_naive_no_match(b, vec!["zbc"], &haystack_same('y'));
}

#[bench]
fn naive_one_prefix_byte_every_match(b: &mut Bencher) {
    bench_naive_no_match(b, vec!["zbc"], &haystack_same('z'));
}

#[bench]
fn naive_one_prefix_byte_random(b: &mut Bencher) {
    bench_naive_no_match(b, vec!["zbc\x00"], HAYSTACK_RANDOM);
}

#[bench]
fn naive_two_bytes(b: &mut Bencher) {
    bench_naive_no_match(b, vec!["a", "b"], &haystack_same('z'));
}

#[bench]
fn naive_two_diff_prefix(b: &mut Bencher) {
    bench_naive_no_match(b, vec!["abcdef", "bmnopq"], &haystack_same('z'));
}

#[bench]
fn naive_two_one_prefix_byte_every_match(b: &mut Bencher) {
    bench_naive_no_match(b, vec!["zbcdef", "zmnopq"], &haystack_same('z'));
}

#[bench]
fn naive_two_one_prefix_byte_no_match(b: &mut Bencher) {
    bench_naive_no_match(b, vec!["zbcdef", "zmnopq"], &haystack_same('y'));
}

#[bench]
fn naive_two_one_prefix_byte_random(b: &mut Bencher) {
    bench_naive_no_match(b, vec!["zbcdef\x00", "zmnopq\x00"], HAYSTACK_RANDOM);
}

#[bench]
fn naive_ten_bytes(b: &mut Bencher) {
    let needles = vec!["a", "b", "c", "d", "e",
                       "f", "g", "h", "i", "j"];
    bench_naive_no_match(b, needles, &haystack_same('z'));
}

#[bench]
fn naive_ten_diff_prefix(b: &mut Bencher) {
    let needles = vec!["abcdef", "bbcdef", "cbcdef", "dbcdef",
                       "ebcdef", "fbcdef", "gbcdef", "hbcdef",
                       "ibcdef", "jbcdef"];
    bench_naive_no_match(b, needles, &haystack_same('z'));
}

#[bench]
fn naive_ten_one_prefix_byte_every_match(b: &mut Bencher) {
    let needles = vec!["zacdef", "zbcdef", "zccdef", "zdcdef",
                       "zecdef", "zfcdef", "zgcdef", "zhcdef",
                       "zicdef", "zjcdef"];
    bench_naive_no_match(b, needles, &haystack_same('z'));
}

#[bench]
fn naive_ten_one_prefix_byte_no_match(b: &mut Bencher) {
    let needles = vec!["zacdef", "zbcdef", "zccdef", "zdcdef",
                       "zecdef", "zfcdef", "zgcdef", "zhcdef",
                       "zicdef", "zjcdef"];
    bench_naive_no_match(b, needles, &haystack_same('y'));
}

#[bench]
fn naive_ten_one_prefix_byte_random(b: &mut Bencher) {
    let needles = vec!["zacdef\x00", "zbcdef\x00", "zccdef\x00",
                       "zdcdef\x00", "zecdef\x00", "zfcdef\x00",
                       "zgcdef\x00", "zhcdef\x00", "zicdef\x00",
                       "zjcdef\x00"];
    bench_naive_no_match(b, needles, HAYSTACK_RANDOM);
}

// The organization above is just awful. Let's start over...

mod sherlock {
    use dnfa::nfa::{NFA};
    use dnfa::automaton::{Automaton};
    use test::Bencher;
    use super::HAYSTACK_SHERLOCK;

    macro_rules! sherlock {
        ($name:ident, $count:expr, $pats:expr) => {
            #[bench]
            fn $name(b: &mut Bencher) {
                let haystack = HAYSTACK_SHERLOCK;
                let mut aut = NFA::from_dictionary($pats);
                aut.ignore_prefixes();
                b.bytes = haystack.len() as u64;
                b.iter(|| assert_eq!($count, aut.find(haystack.as_bytes()).count()));
            }
        }
    }

    sherlock!(name_alt1, 158, vec!["Sherlock", "Street"]);

    sherlock!(name_alt2, 558, vec!["Sherlock", "Holmes"]);

    sherlock!(name_alt3, 740, vec![
        "Sherlock", "Holmes", "Watson", "Irene", "Adler", "John", "Baker",
    ]);

    sherlock!(name_alt3_nocase, 1764, vec![
        "ADL", "ADl", "AdL", "Adl", "BAK", "BAk", "BAK", "BaK", "Bak", "BaK",
        "HOL", "HOl", "HoL", "Hol", "IRE", "IRe", "IrE", "Ire", "JOH", "JOh",
        "JoH", "Joh", "SHE", "SHe", "ShE", "She", "WAT", "WAt", "WaT", "Wat",
        "aDL", "aDl", "adL", "adl", "bAK", "bAk", "bAK", "baK", "bak", "baK",
        "hOL", "hOl", "hoL", "hol", "iRE", "iRe", "irE", "ire", "jOH", "jOh",
        "joH", "joh", "sHE", "sHe", "shE", "she", "wAT", "wAt", "waT", "wat",
        "ſHE", "ſHe", "ſhE", "ſhe",
    ]);

    sherlock!(name_alt4, 582, vec!["Sher", "Hol"]);

    sherlock!(name_alt4_nocase, 1307, vec![
        "HOL", "HOl", "HoL", "Hol", "SHE", "SHe", "ShE", "She", "hOL", "hOl",
        "hoL", "hol", "sHE", "sHe", "shE", "she", "ſHE", "ſHe", "ſhE", "ſhe",
    ]);

    sherlock!(name_alt5, 639, vec!["Sherlock", "Holmes", "Watson"]);

    sherlock!(name_alt5_nocase, 1442, vec![
        "HOL", "HOl", "HoL", "Hol", "SHE", "SHe", "ShE", "She", "WAT", "WAt",
        "WaT", "Wat", "hOL", "hOl", "hoL", "hol", "sHE", "sHe", "shE", "she",
        "wAT", "wAt", "waT", "wat", "ſHE", "ſHe", "ſhE", "ſhe",
    ]);
}
<commit_msg>Removed old commented code that won't get reinstated anyway<commit_after>#![feature(test)]

extern crate dnfa;
extern crate test;

use std::iter;

use dnfa::nfa::{NFA};
use dnfa::automaton::*;
use test::Bencher;

const HAYSTACK_RANDOM: &'static str = include_str!("random.txt");
const HAYSTACK_SHERLOCK: &'static str = include_str!("sherlock.txt");

fn bench_aut_no_match(
    b: &mut Bencher,
    aut: NFA,
    haystack: &str,
) {
    b.bytes = haystack.len() as u64;
    b.iter(|| assert!(aut.find(haystack.as_bytes()).next().is_none()));
}

fn bench_box_aut_no_match(
    b: &mut Bencher,
    aut: NFA,
    haystack: &str,
) {
    b.bytes = haystack.len() as u64;
    let aut: &NFA = &aut;
    b.iter(|| assert!(Automaton::find(aut, haystack.as_bytes()).next().is_none()));
}

fn bench_naive_no_match<S>(b: &mut Bencher, needles: Vec<S>, haystack: &str)
        where S: Into<String> {
    b.bytes = haystack.len() as u64;
    let needles: Vec<String> = needles.into_iter().map(Into::into).collect();
    b.iter(|| assert!(!naive_find(&needles, haystack)));
}

fn haystack_same(letter: char) -> String {
    iter::repeat(letter).take(10000).collect()
}

macro_rules! aut_benches {
    ($prefix:ident, $aut:expr, $bench:expr) => {
        mod $prefix {
#![allow(unused_imports)]
use dnfa::nfa::{NFA};
use dnfa::automaton::{Automaton};
use test::Bencher;

use super::{
    HAYSTACK_RANDOM, haystack_same,
    bench_aut_no_match, bench_box_aut_no_match,
};

#[bench]
fn ac_one_byte(b: &mut Bencher) {
    let aut = $aut(vec!["a"]);
    $bench(b, aut, &haystack_same('z'));
}

#[bench]
fn ac_one_prefix_byte_no_match(b: &mut Bencher) {
    let aut = $aut(vec!["zbc"]);
    $bench(b, aut, &haystack_same('y'));
}

#[bench]
fn ac_one_prefix_byte_every_match(b: &mut Bencher) {
    // We lose the benefit of `memchr` because the first byte matches
    // in every position in the haystack.
    let aut = $aut(vec!["zbc"]);
    $bench(b, aut, &haystack_same('z'));
}

#[bench]
fn ac_one_prefix_byte_random(b: &mut Bencher) {
    let aut = $aut(vec!["zbc\x00"]);
    $bench(b, aut, HAYSTACK_RANDOM);
}

#[bench]
fn ac_two_bytes(b: &mut Bencher) {
    let aut = $aut(vec!["a", "b"]);
    $bench(b, aut, &haystack_same('z'));
}

#[bench]
fn ac_two_diff_prefix(b: &mut Bencher) {
    let aut = $aut(vec!["abcdef", "bmnopq"]);
    $bench(b, aut, &haystack_same('z'));
}

#[bench]
fn ac_two_one_prefix_byte_every_match(b: &mut Bencher) {
    let aut = $aut(vec!["zbcdef", "zmnopq"]);
    $bench(b, aut, &haystack_same('z'));
}

#[bench]
fn ac_two_one_prefix_byte_no_match(b: &mut Bencher) {
    let aut = $aut(vec!["zbcdef", "zmnopq"]);
    $bench(b, aut, &haystack_same('y'));
}

#[bench]
fn ac_two_one_prefix_byte_random(b: &mut Bencher) {
    let aut = $aut(vec!["zbcdef\x00", "zmnopq\x00"]);
    $bench(b, aut, HAYSTACK_RANDOM);
}

#[bench]
fn ac_ten_bytes(b: &mut Bencher) {
    let aut = $aut(vec!["a", "b", "c", "d", "e",
                        "f", "g", "h", "i", "j"]);
    $bench(b, aut, &haystack_same('z'));
}

#[bench]
fn ac_ten_diff_prefix(b: &mut Bencher) {
    let aut = $aut(vec!["abcdef", "bbcdef", "cbcdef", "dbcdef",
                        "ebcdef", "fbcdef", "gbcdef", "hbcdef",
                        "ibcdef", "jbcdef"]);
    $bench(b, aut, &haystack_same('z'));
}

#[bench]
fn ac_ten_one_prefix_byte_every_match(b: &mut Bencher) {
    let aut = $aut(vec!["zacdef", "zbcdef", "zccdef", "zdcdef",
                        "zecdef", "zfcdef", "zgcdef", "zhcdef",
                        "zicdef", "zjcdef"]);
    $bench(b, aut, &haystack_same('z'));
}

#[bench]
fn ac_ten_one_prefix_byte_no_match(b: &mut Bencher) {
    let aut = $aut(vec!["zacdef", "zbcdef", "zccdef", "zdcdef",
                        "zecdef", "zfcdef", "zgcdef", "zhcdef",
                        "zicdef", "zjcdef"]);
    $bench(b, aut, &haystack_same('y'));
}

#[bench]
fn ac_ten_one_prefix_byte_random(b: &mut Bencher) {
    let aut = $aut(vec!["zacdef\x00", "zbcdef\x00", "zccdef\x00",
                        "zdcdef\x00", "zecdef\x00", "zfcdef\x00",
                        "zgcdef\x00", "zhcdef\x00", "zicdef\x00",
                        "zjcdef\x00"]);
    $bench(b, aut, HAYSTACK_RANDOM);
}
        }
    }
}

aut_benches!(dense, NFA::from_dictionary, bench_aut_no_match);
aut_benches!(dense_boxed, NFA::from_dictionary, bench_box_aut_no_match);

// A naive multi-pattern search.
// We use this to benchmark *throughput*, so it should never match anything.
fn naive_find(needles: &[String], haystack: &str) -> bool {
    for hi in 0..haystack.len() {
        let rest = &haystack.as_bytes()[hi..];
        for needle in needles {
            let needle = needle.as_bytes();
            if needle.len() > rest.len() {
                continue;
            }
            if needle == &rest[..needle.len()] {
                // should never happen in throughput benchmarks.
                return true;
            }
        }
    }
    false
}

#[bench]
fn naive_one_byte(b: &mut Bencher) {
    bench_naive_no_match(b, vec!["a"], &haystack_same('z'));
}

#[bench]
fn naive_one_prefix_byte_no_match(b: &mut Bencher) {
    bench_naive_no_match(b, vec!["zbc"], &haystack_same('y'));
}

#[bench]
fn naive_one_prefix_byte_every_match(b: &mut Bencher) {
    bench_naive_no_match(b, vec!["zbc"], &haystack_same('z'));
}

#[bench]
fn naive_one_prefix_byte_random(b: &mut Bencher) {
    bench_naive_no_match(b, vec!["zbc\x00"], HAYSTACK_RANDOM);
}

#[bench]
fn naive_two_bytes(b: &mut Bencher) {
    bench_naive_no_match(b, vec!["a", "b"], &haystack_same('z'));
}

#[bench]
fn naive_two_diff_prefix(b: &mut Bencher) {
    bench_naive_no_match(b, vec!["abcdef", "bmnopq"], &haystack_same('z'));
}

#[bench]
fn naive_two_one_prefix_byte_every_match(b: &mut Bencher) {
    bench_naive_no_match(b, vec!["zbcdef", "zmnopq"], &haystack_same('z'));
}

#[bench]
fn naive_two_one_prefix_byte_no_match(b: &mut Bencher) {
    bench_naive_no_match(b, vec!["zbcdef", "zmnopq"], &haystack_same('y'));
}

#[bench]
fn naive_two_one_prefix_byte_random(b: &mut Bencher) {
    bench_naive_no_match(b, vec!["zbcdef\x00", "zmnopq\x00"], HAYSTACK_RANDOM);
}

#[bench]
fn naive_ten_bytes(b: &mut Bencher) {
    let needles = vec!["a", "b", "c", "d", "e",
                       "f", "g", "h", "i", "j"];
    bench_naive_no_match(b, needles, &haystack_same('z'));
}

#[bench]
fn naive_ten_diff_prefix(b: &mut Bencher) {
    let needles = vec!["abcdef", "bbcdef", "cbcdef", "dbcdef",
                       "ebcdef", "fbcdef", "gbcdef", "hbcdef",
                       "ibcdef", "jbcdef"];
    bench_naive_no_match(b, needles, &haystack_same('z'));
}

#[bench]
fn naive_ten_one_prefix_byte_every_match(b: &mut Bencher) {
    let needles = vec!["zacdef", "zbcdef", "zccdef", "zdcdef",
                       "zecdef", "zfcdef", "zgcdef", "zhcdef",
                       "zicdef", "zjcdef"];
    bench_naive_no_match(b, needles, &haystack_same('z'));
}

#[bench]
fn naive_ten_one_prefix_byte_no_match(b: &mut Bencher) {
    let needles = vec!["zacdef", "zbcdef", "zccdef", "zdcdef",
                       "zecdef", "zfcdef", "zgcdef", "zhcdef",
                       "zicdef", "zjcdef"];
    bench_naive_no_match(b, needles, &haystack_same('y'));
}

#[bench]
fn naive_ten_one_prefix_byte_random(b: &mut Bencher) {
    let needles = vec!["zacdef\x00", "zbcdef\x00", "zccdef\x00",
                       "zdcdef\x00", "zecdef\x00", "zfcdef\x00",
                       "zgcdef\x00", "zhcdef\x00", "zicdef\x00",
                       "zjcdef\x00"];
    bench_naive_no_match(b, needles, HAYSTACK_RANDOM);
}

// The organization above is just awful. Let's start over...

mod sherlock {
    use dnfa::nfa::{NFA};
    use dnfa::automaton::{Automaton};
    use test::Bencher;
    use super::HAYSTACK_SHERLOCK;

    macro_rules! sherlock {
        ($name:ident, $count:expr, $pats:expr) => {
            #[bench]
            fn $name(b: &mut Bencher) {
                let haystack = HAYSTACK_SHERLOCK;
                let mut aut = NFA::from_dictionary($pats);
                aut.ignore_prefixes();
                b.bytes = haystack.len() as u64;
                b.iter(|| assert_eq!($count, aut.find(haystack.as_bytes()).count()));
            }
        }
    }

    sherlock!(name_alt1, 158, vec!["Sherlock", "Street"]);

    sherlock!(name_alt2, 558, vec!["Sherlock", "Holmes"]);

    sherlock!(name_alt3, 740, vec![
        "Sherlock", "Holmes", "Watson", "Irene", "Adler", "John", "Baker",
    ]);

    sherlock!(name_alt3_nocase, 1764, vec![
        "ADL", "ADl", "AdL", "Adl", "BAK", "BAk", "BAK", "BaK", "Bak", "BaK",
        "HOL", "HOl", "HoL", "Hol", "IRE", "IRe", "IrE", "Ire", "JOH", "JOh",
        "JoH", "Joh", "SHE", "SHe", "ShE", "She", "WAT", "WAt", "WaT", "Wat",
        "aDL", "aDl", "adL", "adl", "bAK", "bAk", "bAK", "baK", "bak", "baK",
        "hOL", "hOl", "hoL", "hol", "iRE", "iRe", "irE", "ire", "jOH", "jOh",
        "joH", "joh", "sHE", "sHe", "shE", "she", "wAT", "wAt", "waT", "wat",
        "ſHE", "ſHe", "ſhE", "ſhe",
    ]);

    sherlock!(name_alt4, 582, vec!["Sher", "Hol"]);

    sherlock!(name_alt4_nocase, 1307, vec![
        "HOL", "HOl", "HoL", "Hol", "SHE", "SHe", "ShE", "She", "hOL", "hOl",
        "hoL", "hol", "sHE", "sHe", "shE", "she", "ſHE", "ſHe", "ſhE", "ſhe",
    ]);

    sherlock!(name_alt5, 639, vec!["Sherlock", "Holmes", "Watson"]);

    sherlock!(name_alt5_nocase, 1442, vec![
        "HOL", "HOl", "HoL", "Hol", "SHE", "SHe", "ShE", "She", "WAT", "WAt",
        "WaT", "Wat", "hOL", "hOl", "hoL", "hol", "sHE", "sHe", "shE", "she",
        "wAT", "wAt", "waT", "wat", "ſHE", "ſHe", "ſhE", "ſhe",
    ]);
}
<|endoftext|>


<commit_before>#[macro_use] extern crate derive_builder;

use std::convert::From;

#[derive(PartialEq, Default, Debug, Clone)]
struct Uuid(i32);
#[derive(PartialEq, Default, Debug, Clone)]
struct Authentication(i32);

impl From<i32> for Uuid {
    fn from(x: i32) -> Uuid {
        Uuid(x)
    }
}

impl From<i32> for Authentication {
    fn from(x: i32) -> Authentication {
        Authentication(x)
    }
}

#[derive(Debug, Default, Builder)]
struct Channel {
    id: Uuid,
    token: Authentication,
    special_info: i32
}

fn main() {
    let mut ch = Channel::default();
    ch.special_info(42);
    println!("{:?}", ch);
}
<commit_msg>fix example: channel.rs<commit_after>#[macro_use] extern crate derive_builder;

use std::convert::From;

#[derive(PartialEq, Default, Debug, Clone)]
struct Uuid(i32);
#[derive(PartialEq, Default, Debug, Clone)]
struct Authentication(i32);

impl From<i32> for Uuid {
    fn from(x: i32) -> Uuid {
        Uuid(x)
    }
}

impl From<i32> for Authentication {
    fn from(x: i32) -> Authentication {
        Authentication(x)
    }
}

#[derive(Debug, Default, Builder)]
struct Channel {
    id: Uuid,
    token: Authentication,
    special_info: i32
}

fn main() {
    let ch = ChannelBuilder::default()
        .special_info(42)
        .id(0)
        .token(54915641902)
        .build()
        .unwrap();
    println!("{:?}", ch);
}
<|endoftext|>


<commit_before>extern crate iup;

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

fn main() {
    let _iup = iup::open().unwrap();

    let text = Rc::new(RefCell::new(iup::text()));
    {
        let mut text = text.borrow_mut();
        iup::set_handle("text", &mut text);
        iup::set_str_attribute(&mut text, "READONLY", "YES");
        iup::set_str_attribute(&mut text, "VALUE", "0");
    }

    let mut button = iup::button("Count");
    {
        let text = text.clone();
        iup::callback::set_action(&mut button, Some(move |_ih| {
            let mut text = text.borrow_mut();
            let count = iup::get_attribute(&mut text, "VALUE").unwrap().parse::<i32>().unwrap();
            iup::set_str_attribute(&mut text, "VALUE", &(count + 1).to_string());
            CallbackReturn::Default
        }));
        iup::callback::set_destroy_cb(&mut button, Some(|_ih|{
            println!("The button is getting destroyed!!");
        }));
    }

    let mut hbox = iup::hboxv(vec!(text.borrow().clone(), button));
    iup::set_str_attribute(&mut hbox, "ALIGNMENT", "ACENTER");
    iup::set_str_attribute(&mut hbox, "MARGIN", "10x10");
    iup::set_str_attribute(&mut hbox, "GAP", "10");

    iup::show(&mut iup::dialog(hbox)).unwrap();

    iup::main_loop();
}
<commit_msg>Post-rebase fixes<commit_after>extern crate iup;

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

fn main() {
    let _iup = iup::open().unwrap();

    let text = Rc::new(RefCell::new(iup::text()));
    {
        let mut text = text.borrow_mut();
        iup::set_handle("text", &mut text);
        iup::set_str_attribute(&mut text, "READONLY", "YES");
        iup::set_str_attribute(&mut text, "VALUE", "0");
    }

    let mut button = iup::button("Count");
    {
        let text = text.clone();
        iup::callback::set_action(&mut button, Some(move |_ih| {
            let mut text = text.borrow_mut();
            let count = iup::get_attribute(&mut text, "VALUE").unwrap().parse::<i32>().unwrap();
            iup::set_str_attribute(&mut text, "VALUE", &(count + 1).to_string());
            CallbackReturn::Default
        }));
        iup::callback::set_destroy_cb(&mut button, Some(|_ih|{
            println!("The button is getting destroyed!!");
        }));
    }

    let mut hbox = iup::hboxv(&[text.borrow().clone(), button]);
    iup::set_str_attribute(&mut hbox, "ALIGNMENT", "ACENTER");
    iup::set_str_attribute(&mut hbox, "MARGIN", "10x10");
    iup::set_str_attribute(&mut hbox, "GAP", "10");

    iup::show(&mut iup::dialog(hbox)).unwrap();

    iup::main_loop();
}
<|endoftext|>


<commit_before>extern crate http;
extern crate floor;

use floor::{ Floor, Request, Response, FromFn };

fn main() {

    let mut server = Floor::new();

    // we would love to use a closure for the handler but it seems to be hard
    // to achieve with the current version of rust.

    //this is an example middleware function that just logs each request
    fn logger (req: &Request, res: &mut Response) -> bool{
        println!("logging request: {}", req.origin.request_uri);

        // a request is supposed to return a `bool` to indicate whether additional
        // middleware should continue executing or should be stopped.
        true
    }

    // middleware is optional and can be registered with `utilize`
    server.utilize(FromFn::new(logger));
    server.utilize(Floor::static_files("some/absolute/path"));

    fn user_handler (request: &Request, response: &mut Response) {
        let text = format!("This is user: {}", request.params.get(&"userid".to_string()));
        response.send(text.as_slice());
    };

    // go to http://localhost:6767/user/4711 to see this route in action
    server.get("/user/:userid", user_handler);

    fn bar_handler (request: &Request, response: &mut Response) {
        response.send("This is the /bar handler");
    };

    // go to http://localhost:6767/bar to see this route in action
    server.get("/bar", bar_handler);

    fn simple_wildcard (request: &Request, response: &mut Response) {
        response.send("This matches /some/crazy/route but not /some/super/crazy/route");
    };

    // go to http://localhost:6767/some/crazy/route to see this route in action
    server.get("/some/*/route", simple_wildcard);

    fn double_wildcard (request: &Request, response: &mut Response) {
        response.send("This matches /a/crazy/route and also /a/super/crazy/route");
    };

    // go to http://localhost:6767/a/nice/route or http://localhost:6767/a/super/nice/route to see this route in action
    server.get("/a/**/route", double_wildcard);

    fn post_handler (request: &Request, response: &mut Response) {
        response.send("This matches a POST request to /a/post/request");
    };

    // go to http://localhost:6767/a/post/request to see this route in action
    server.post("/a/post/request", post_handler);

    server.listen(6767);
}
<commit_msg>fix(example): use real example path for static files<commit_after>extern crate http;
extern crate floor;

use floor::{ Floor, Request, Response, FromFn };

fn main() {

    let mut server = Floor::new();

    // we would love to use a closure for the handler but it seems to be hard
    // to achieve with the current version of rust.

    //this is an example middleware function that just logs each request
    fn logger (req: &Request, res: &mut Response) -> bool{
        println!("logging request: {}", req.origin.request_uri);

        // a request is supposed to return a `bool` to indicate whether additional
        // middleware should continue executing or should be stopped.
        true
    }

    // middleware is optional and can be registered with `utilize`
    server.utilize(FromFn::new(logger));

    // go to http://localhost:6767/thoughtram_logo_brain.png to see static file serving in action
    server.utilize(Floor::static_files("examples/assets/"));

    fn user_handler (request: &Request, response: &mut Response) {
        let text = format!("This is user: {}", request.params.get(&"userid".to_string()));
        response.send(text.as_slice());
    };

    // go to http://localhost:6767/user/4711 to see this route in action
    server.get("/user/:userid", user_handler);

    fn bar_handler (request: &Request, response: &mut Response) {
        response.send("This is the /bar handler");
    };

    // go to http://localhost:6767/bar to see this route in action
    server.get("/bar", bar_handler);

    fn simple_wildcard (request: &Request, response: &mut Response) {
        response.send("This matches /some/crazy/route but not /some/super/crazy/route");
    };

    // go to http://localhost:6767/some/crazy/route to see this route in action
    server.get("/some/*/route", simple_wildcard);

    fn double_wildcard (request: &Request, response: &mut Response) {
        response.send("This matches /a/crazy/route and also /a/super/crazy/route");
    };

    // go to http://localhost:6767/a/nice/route or http://localhost:6767/a/super/nice/route to see this route in action
    server.get("/a/**/route", double_wildcard);

    fn post_handler (request: &Request, response: &mut Response) {
        response.send("This matches a POST request to /a/post/request");
    };

    // go to http://localhost:6767/a/post/request to see this route in action
    server.post("/a/post/request", post_handler);

    server.listen(6767);
}
<|endoftext|>


<commit_before>use stable_deref_trait::StableDeref;
use std::convert::TryInto;
use std::mem;
use std::ops::{Deref, Range};
use std::sync::Arc;
use std::{fmt, io};

/// An OwnedBytes simply wraps an object that owns a slice of data and exposes
/// this data as a static slice.
///
/// The backing object is required to be `StableDeref`.
#[derive(Clone)]
pub struct OwnedBytes {
    data: &'static [u8],
    box_stable_deref: Arc<dyn Deref<Target = [u8]> + Sync + Send>,
}

impl OwnedBytes {
    /// Creates an empty `OwnedBytes`.
    pub fn empty() -> OwnedBytes {
        OwnedBytes::new(&[][..])
    }

    /// Creates an `OwnedBytes` intance given a `StableDeref` object.
    pub fn new<T: StableDeref + Deref<Target = [u8]> + 'static + Send + Sync>(
        data_holder: T,
    ) -> OwnedBytes {
        let box_stable_deref = Arc::new(data_holder);
        let bytes: &[u8] = box_stable_deref.as_ref();
        let data = unsafe { mem::transmute::<_, &'static [u8]>(bytes.deref()) };
        OwnedBytes {
            data,
            box_stable_deref,
        }
    }

    /// creates a fileslice that is just a view over a slice of the data.
    pub fn slice(&self, range: Range<usize>) -> Self {
        OwnedBytes {
            data: &self.data[range],
            box_stable_deref: self.box_stable_deref.clone(),
        }
    }

    /// Returns the underlying slice of data.
    /// `Deref` and `AsRef` are also available.
    #[inline]
    pub fn as_slice(&self) -> &[u8] {
        self.data
    }

    /// Returns the len of the slice.
    #[inline]
    pub fn len(&self) -> usize {
        self.data.len()
    }

    /// Splits the OwnedBytes into two OwnedBytes `(left, right)`.
    ///
    /// Left will hold `split_len` bytes.
    ///
    /// This operation is cheap and does not require to copy any memory.
    /// On the other hand, both `left` and `right` retain a handle over
    /// the entire slice of memory. In other words, the memory will only
    /// be released when both left and right are dropped.
    pub fn split(self, split_len: usize) -> (OwnedBytes, OwnedBytes) {
        let right_box_stable_deref = self.box_stable_deref.clone();
        let left = OwnedBytes {
            data: &self.data[..split_len],
            box_stable_deref: self.box_stable_deref,
        };
        let right = OwnedBytes {
            data: &self.data[split_len..],
            box_stable_deref: right_box_stable_deref,
        };
        (left, right)
    }

    /// Returns true iff this `OwnedBytes` is empty.
    #[inline]
    pub fn is_empty(&self) -> bool {
        self.as_slice().is_empty()
    }

    /// Drops the left most `advance_len` bytes.
    ///
    /// See also [.clip(clip_len: usize))](#method.clip).
    #[inline]
    pub fn advance(&mut self, advance_len: usize) {
        self.data = &self.data[advance_len..]
    }

    /// Reads an `u8` from the `OwnedBytes` and advance by one byte.
    pub fn read_u8(&mut self) -> u8 {
        assert!(!self.is_empty());

        let byte = self.as_slice()[0];
        self.advance(1);
        byte
    }

    /// Reads an `u64` encoded as little-endian from the `OwnedBytes` and advance by 8 bytes.
    pub fn read_u64(&mut self) -> u64 {
        assert!(self.len() > 7);

        let octlet: [u8; 8] = self.as_slice()[..8].try_into().unwrap();
        self.advance(8);
        u64::from_le_bytes(octlet)
    }
}

impl fmt::Debug for OwnedBytes {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        // We truncate the bytes in order to make sure the debug string
        // is not too long.
        let bytes_truncated: &[u8] = if self.len() > 8 {
            &self.as_slice()[..10]
        } else {
            self.as_slice()
        };
        write!(f, "OwnedBytes({:?}, len={})", bytes_truncated, self.len())
    }
}

impl Deref for OwnedBytes {
    type Target = [u8];

    fn deref(&self) -> &Self::Target {
        self.as_slice()
    }
}

impl io::Read for OwnedBytes {
    fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> {
        let read_len = {
            let data = self.as_slice();
            if data.len() >= buf.len() {
                let buf_len = buf.len();
                buf.copy_from_slice(&data[..buf_len]);
                buf.len()
            } else {
                let data_len = data.len();
                buf[..data_len].copy_from_slice(data);
                data_len
            }
        };
        self.advance(read_len);
        Ok(read_len)
    }
    fn read_to_end(&mut self, buf: &mut Vec<u8>) -> io::Result<usize> {
        let read_len = {
            let data = self.as_slice();
            buf.extend(data);
            data.len()
        };
        self.advance(read_len);
        Ok(read_len)
    }
    fn read_exact(&mut self, buf: &mut [u8]) -> io::Result<()> {
        let read_len = self.read(buf)?;
        if read_len != buf.len() {
            return Err(io::Error::new(
                io::ErrorKind::UnexpectedEof,
                "failed to fill whole buffer",
            ));
        }
        Ok(())
    }
}

impl AsRef<[u8]> for OwnedBytes {
    fn as_ref(&self) -> &[u8] {
        self.as_slice()
    }
}

#[cfg(test)]
mod tests {
    use std::io::{self, Read};

    use super::OwnedBytes;

    #[test]
    fn test_owned_bytes_debug() {
        let short_bytes = OwnedBytes::new(b"abcd".as_ref());
        assert_eq!(
            format!("{:?}", short_bytes),
            "OwnedBytes([97, 98, 99, 100], len=4)"
        );
        let long_bytes = OwnedBytes::new(b"abcdefghijklmnopq".as_ref());
        assert_eq!(
            format!("{:?}", long_bytes),
            "OwnedBytes([97, 98, 99, 100, 101, 102, 103, 104, 105, 106], len=17)"
        );
    }

    #[test]
    fn test_owned_bytes_read() -> io::Result<()> {
        let mut bytes = OwnedBytes::new(b"abcdefghiklmnopqrstuvwxyz".as_ref());
        {
            let mut buf = [0u8; 5];
            bytes.read_exact(&mut buf[..]).unwrap();
            assert_eq!(&buf, b"abcde");
            assert_eq!(bytes.as_slice(), b"fghiklmnopqrstuvwxyz")
        }
        {
            let mut buf = [0u8; 2];
            bytes.read_exact(&mut buf[..]).unwrap();
            assert_eq!(&buf, b"fg");
            assert_eq!(bytes.as_slice(), b"hiklmnopqrstuvwxyz")
        }
        Ok(())
    }

    #[test]
    fn test_owned_bytes_read_right_at_the_end() -> io::Result<()> {
        let mut bytes = OwnedBytes::new(b"abcde".as_ref());
        let mut buf = [0u8; 5];
        assert_eq!(bytes.read(&mut buf[..]).unwrap(), 5);
        assert_eq!(&buf, b"abcde");
        assert_eq!(bytes.as_slice(), b"");
        assert_eq!(bytes.read(&mut buf[..]).unwrap(), 0);
        assert_eq!(&buf, b"abcde");
        Ok(())
    }
    #[test]
    fn test_owned_bytes_read_incomplete() -> io::Result<()> {
        let mut bytes = OwnedBytes::new(b"abcde".as_ref());
        let mut buf = [0u8; 7];
        assert_eq!(bytes.read(&mut buf[..]).unwrap(), 5);
        assert_eq!(&buf[..5], b"abcde");
        assert_eq!(bytes.read(&mut buf[..]).unwrap(), 0);
        Ok(())
    }

    #[test]
    fn test_owned_bytes_read_to_end() -> io::Result<()> {
        let mut bytes = OwnedBytes::new(b"abcde".as_ref());
        let mut buf = Vec::new();
        bytes.read_to_end(&mut buf)?;
        assert_eq!(buf.as_slice(), b"abcde".as_ref());
        Ok(())
    }

    #[test]
    fn test_owned_bytes_read_u8() -> io::Result<()> {
        let mut bytes = OwnedBytes::new(b"\xFF".as_ref());
        assert_eq!(bytes.read_u8(), 255);
        assert_eq!(bytes.len(), 0);
        Ok(())
    }

    #[test]
    fn test_owned_bytes_read_u64() -> io::Result<()> {
        let mut bytes = OwnedBytes::new(b"\0\xFF\xFF\xFF\xFF\xFF\xFF\xFF".as_ref());
        assert_eq!(bytes.read_u64(), u64::MAX - 255);
        assert_eq!(bytes.len(), 0);
        Ok(())
    }

    #[test]
    fn test_owned_bytes_split() {
        let bytes = OwnedBytes::new(b"abcdefghi".as_ref());
        let (left, right) = bytes.split(3);
        assert_eq!(left.as_slice(), b"abc");
        assert_eq!(right.as_slice(), b"defghi");
    }

    #[test]
    fn test_owned_bytes_split_boundary() {
        let bytes = OwnedBytes::new(b"abcdefghi".as_ref());
        {
            let (left, right) = bytes.clone().split(0);
            assert_eq!(left.as_slice(), b"");
            assert_eq!(right.as_slice(), b"abcdefghi");
        }
        {
            let (left, right) = bytes.split(9);
            assert_eq!(left.as_slice(), b"abcdefghi");
            assert_eq!(right.as_slice(), b"");
        }
    }
}
<commit_msg>more inlines<commit_after>use stable_deref_trait::StableDeref;
use std::convert::TryInto;
use std::mem;
use std::ops::{Deref, Range};
use std::sync::Arc;
use std::{fmt, io};

/// An OwnedBytes simply wraps an object that owns a slice of data and exposes
/// this data as a static slice.
///
/// The backing object is required to be `StableDeref`.
#[derive(Clone)]
pub struct OwnedBytes {
    data: &'static [u8],
    box_stable_deref: Arc<dyn Deref<Target = [u8]> + Sync + Send>,
}

impl OwnedBytes {
    /// Creates an empty `OwnedBytes`.
    pub fn empty() -> OwnedBytes {
        OwnedBytes::new(&[][..])
    }

    /// Creates an `OwnedBytes` intance given a `StableDeref` object.
    pub fn new<T: StableDeref + Deref<Target = [u8]> + 'static + Send + Sync>(
        data_holder: T,
    ) -> OwnedBytes {
        let box_stable_deref = Arc::new(data_holder);
        let bytes: &[u8] = box_stable_deref.as_ref();
        let data = unsafe { mem::transmute::<_, &'static [u8]>(bytes.deref()) };
        OwnedBytes {
            data,
            box_stable_deref,
        }
    }

    /// creates a fileslice that is just a view over a slice of the data.
    pub fn slice(&self, range: Range<usize>) -> Self {
        OwnedBytes {
            data: &self.data[range],
            box_stable_deref: self.box_stable_deref.clone(),
        }
    }

    /// Returns the underlying slice of data.
    /// `Deref` and `AsRef` are also available.
    #[inline]
    pub fn as_slice(&self) -> &[u8] {
        self.data
    }

    /// Returns the len of the slice.
    #[inline]
    pub fn len(&self) -> usize {
        self.data.len()
    }

    /// Splits the OwnedBytes into two OwnedBytes `(left, right)`.
    ///
    /// Left will hold `split_len` bytes.
    ///
    /// This operation is cheap and does not require to copy any memory.
    /// On the other hand, both `left` and `right` retain a handle over
    /// the entire slice of memory. In other words, the memory will only
    /// be released when both left and right are dropped.
    pub fn split(self, split_len: usize) -> (OwnedBytes, OwnedBytes) {
        let right_box_stable_deref = self.box_stable_deref.clone();
        let left = OwnedBytes {
            data: &self.data[..split_len],
            box_stable_deref: self.box_stable_deref,
        };
        let right = OwnedBytes {
            data: &self.data[split_len..],
            box_stable_deref: right_box_stable_deref,
        };
        (left, right)
    }

    /// Returns true iff this `OwnedBytes` is empty.
    #[inline]
    pub fn is_empty(&self) -> bool {
        self.as_slice().is_empty()
    }

    /// Drops the left most `advance_len` bytes.
    ///
    /// See also [.clip(clip_len: usize))](#method.clip).
    #[inline]
    pub fn advance(&mut self, advance_len: usize) {
        self.data = &self.data[advance_len..]
    }

    /// Reads an `u8` from the `OwnedBytes` and advance by one byte.
    #[inline]
    pub fn read_u8(&mut self) -> u8 {
        assert!(!self.is_empty());

        let byte = self.as_slice()[0];
        self.advance(1);
        byte
    }

    /// Reads an `u64` encoded as little-endian from the `OwnedBytes` and advance by 8 bytes.
    #[inline]
    pub fn read_u64(&mut self) -> u64 {
        assert!(self.len() > 7);

        let octlet: [u8; 8] = self.as_slice()[..8].try_into().unwrap();
        self.advance(8);
        u64::from_le_bytes(octlet)
    }
}

impl fmt::Debug for OwnedBytes {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        // We truncate the bytes in order to make sure the debug string
        // is not too long.
        let bytes_truncated: &[u8] = if self.len() > 8 {
            &self.as_slice()[..10]
        } else {
            self.as_slice()
        };
        write!(f, "OwnedBytes({:?}, len={})", bytes_truncated, self.len())
    }
}

impl Deref for OwnedBytes {
    type Target = [u8];

    #[inline]
    fn deref(&self) -> &Self::Target {
        self.as_slice()
    }
}

impl io::Read for OwnedBytes {
    #[inline]
    fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> {
        let read_len = {
            let data = self.as_slice();
            if data.len() >= buf.len() {
                let buf_len = buf.len();
                buf.copy_from_slice(&data[..buf_len]);
                buf.len()
            } else {
                let data_len = data.len();
                buf[..data_len].copy_from_slice(data);
                data_len
            }
        };
        self.advance(read_len);
        Ok(read_len)
    }
    #[inline]
    fn read_to_end(&mut self, buf: &mut Vec<u8>) -> io::Result<usize> {
        let read_len = {
            let data = self.as_slice();
            buf.extend(data);
            data.len()
        };
        self.advance(read_len);
        Ok(read_len)
    }
    #[inline]
    fn read_exact(&mut self, buf: &mut [u8]) -> io::Result<()> {
        let read_len = self.read(buf)?;
        if read_len != buf.len() {
            return Err(io::Error::new(
                io::ErrorKind::UnexpectedEof,
                "failed to fill whole buffer",
            ));
        }
        Ok(())
    }
}

impl AsRef<[u8]> for OwnedBytes {
    #[inline]
    fn as_ref(&self) -> &[u8] {
        self.as_slice()
    }
}

#[cfg(test)]
mod tests {
    use std::io::{self, Read};

    use super::OwnedBytes;

    #[test]
    fn test_owned_bytes_debug() {
        let short_bytes = OwnedBytes::new(b"abcd".as_ref());
        assert_eq!(
            format!("{:?}", short_bytes),
            "OwnedBytes([97, 98, 99, 100], len=4)"
        );
        let long_bytes = OwnedBytes::new(b"abcdefghijklmnopq".as_ref());
        assert_eq!(
            format!("{:?}", long_bytes),
            "OwnedBytes([97, 98, 99, 100, 101, 102, 103, 104, 105, 106], len=17)"
        );
    }

    #[test]
    fn test_owned_bytes_read() -> io::Result<()> {
        let mut bytes = OwnedBytes::new(b"abcdefghiklmnopqrstuvwxyz".as_ref());
        {
            let mut buf = [0u8; 5];
            bytes.read_exact(&mut buf[..]).unwrap();
            assert_eq!(&buf, b"abcde");
            assert_eq!(bytes.as_slice(), b"fghiklmnopqrstuvwxyz")
        }
        {
            let mut buf = [0u8; 2];
            bytes.read_exact(&mut buf[..]).unwrap();
            assert_eq!(&buf, b"fg");
            assert_eq!(bytes.as_slice(), b"hiklmnopqrstuvwxyz")
        }
        Ok(())
    }

    #[test]
    fn test_owned_bytes_read_right_at_the_end() -> io::Result<()> {
        let mut bytes = OwnedBytes::new(b"abcde".as_ref());
        let mut buf = [0u8; 5];
        assert_eq!(bytes.read(&mut buf[..]).unwrap(), 5);
        assert_eq!(&buf, b"abcde");
        assert_eq!(bytes.as_slice(), b"");
        assert_eq!(bytes.read(&mut buf[..]).unwrap(), 0);
        assert_eq!(&buf, b"abcde");
        Ok(())
    }
    #[test]
    fn test_owned_bytes_read_incomplete() -> io::Result<()> {
        let mut bytes = OwnedBytes::new(b"abcde".as_ref());
        let mut buf = [0u8; 7];
        assert_eq!(bytes.read(&mut buf[..]).unwrap(), 5);
        assert_eq!(&buf[..5], b"abcde");
        assert_eq!(bytes.read(&mut buf[..]).unwrap(), 0);
        Ok(())
    }

    #[test]
    fn test_owned_bytes_read_to_end() -> io::Result<()> {
        let mut bytes = OwnedBytes::new(b"abcde".as_ref());
        let mut buf = Vec::new();
        bytes.read_to_end(&mut buf)?;
        assert_eq!(buf.as_slice(), b"abcde".as_ref());
        Ok(())
    }

    #[test]
    fn test_owned_bytes_read_u8() -> io::Result<()> {
        let mut bytes = OwnedBytes::new(b"\xFF".as_ref());
        assert_eq!(bytes.read_u8(), 255);
        assert_eq!(bytes.len(), 0);
        Ok(())
    }

    #[test]
    fn test_owned_bytes_read_u64() -> io::Result<()> {
        let mut bytes = OwnedBytes::new(b"\0\xFF\xFF\xFF\xFF\xFF\xFF\xFF".as_ref());
        assert_eq!(bytes.read_u64(), u64::MAX - 255);
        assert_eq!(bytes.len(), 0);
        Ok(())
    }

    #[test]
    fn test_owned_bytes_split() {
        let bytes = OwnedBytes::new(b"abcdefghi".as_ref());
        let (left, right) = bytes.split(3);
        assert_eq!(left.as_slice(), b"abc");
        assert_eq!(right.as_slice(), b"defghi");
    }

    #[test]
    fn test_owned_bytes_split_boundary() {
        let bytes = OwnedBytes::new(b"abcdefghi".as_ref());
        {
            let (left, right) = bytes.clone().split(0);
            assert_eq!(left.as_slice(), b"");
            assert_eq!(right.as_slice(), b"abcdefghi");
        }
        {
            let (left, right) = bytes.split(9);
            assert_eq!(left.as_slice(), b"abcdefghi");
            assert_eq!(right.as_slice(), b"");
        }
    }
}
<|endoftext|>


<commit_before>// Copyright 2017 The Exonum Team
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//   http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

//! This module defines the Exonum services interfaces. Like smart contracts in some other
//! blockchain platforms, Exonum services encapsulate business logic of the blockchain application.

use std::fmt;
use std::sync::{Arc, RwLock};
use std::collections::{HashMap, HashSet};
use std::net::SocketAddr;

use serde_json::Value;
use iron::Handler;

use crypto::{Hash, PublicKey, SecretKey};
use storage::{Fork, Snapshot};
use messages::RawTransaction;
use encoding::Error as MessageError;
use node::{ApiSender, Node, State, TransactionSend};
use blockchain::{Blockchain, ConsensusConfig, Schema, StoredConfiguration, ValidatorKeys};
use helpers::{Height, Milliseconds, ValidatorId};
use super::transaction::Transaction;

/// A trait that describes business logic of a concrete service.
///
/// See also [the documentation page on services][doc:services].
///
/// # Examples
///
/// The following example provides a bare-bones foundation for implementing a service.
///
/// ```
/// #[macro_use] extern crate exonum;
/// // Exports from `exonum` crate skipped
/// # use exonum::blockchain::{Service, Transaction, TransactionSet, ExecutionResult};
/// # use exonum::crypto::Hash;
/// # use exonum::messages::{ServiceMessage, Message, RawTransaction};
/// # use exonum::storage::{Fork, Snapshot};
/// use exonum::encoding::Error as EncError;
///
/// // Reused constants
/// const SERVICE_ID: u16 = 8000;
///
/// // Service schema
/// struct MyServiceSchema<T> {
///     view: T,
/// }
///
/// impl<T: AsRef<Snapshot>> MyServiceSchema<T> {
///     fn new(view: T) -> Self {
///         MyServiceSchema { view }
///     }
///
///     fn state_hash(&self) -> Vec<Hash> {
///         // Calculates the state hash of the service
/// #       vec![]
///     }
///     // Other read-only methods
/// }
///
/// impl<'a> MyServiceSchema<&'a mut Fork> {
///     // Additional read-write methods
/// }
///
/// // Transaction definitions
/// transactions! {
///     MyTransactions {
///         const SERVICE_ID = SERVICE_ID;
///
///         struct TxA {
///             // Transaction fields
///         }
///
///         struct TxB {
///             // ...
///         }
///     }
/// }
///
/// impl Transaction for TxA {
///     // Business logic implementation
/// #   fn verify(&self) -> bool { true }
/// #   fn execute(&self, fork: &mut Fork) -> ExecutionResult { Ok(()) }
/// }
///
/// impl Transaction for TxB {
/// #   fn verify(&self) -> bool { true }
/// #   fn execute(&self, fork: &mut Fork) -> ExecutionResult { Ok(()) }
/// }
///
/// // Service
/// struct MyService {}
///
/// impl Service for MyService {
///     fn service_id(&self) -> u16 {
///        SERVICE_ID
///     }
///
///     fn service_name(&self) -> &'static str {
///         "my_special_unique_service"
///     }
///
///     fn state_hash(&self, snapshot: &Snapshot) -> Vec<Hash> {
///         MyServiceSchema::new(snapshot).state_hash()
///     }
///
///     fn tx_from_raw(&self, raw: RawTransaction) -> Result<Box<Transaction>, EncError> {
///         let tx = MyTransactions::tx_from_raw(raw)?;
///         Ok(tx.into())
///     }
/// }
/// # fn main() { }
/// ```
///
/// [doc:services]: https://exonum.com/doc/architecture/services/
#[allow(unused_variables, unused_mut)]
pub trait Service: Send + Sync + 'static {
    /// Service identifier for database schema and service messages.
    /// Must be unique within the blockchain.
    fn service_id(&self) -> u16;

    /// A comprehensive string service name. Must be unique within the
    /// blockchain.
    fn service_name(&self) -> &str;

    /// Returns a list of root hashes of tables that determine the current state
    /// of the service database. These hashes are collected from all the services in a common
    /// `ProofMapIndex` accessible in the core schema as [`state_hash_aggregator`][1].
    ///
    /// An empty vector can be returned if the service does not influence the blockchain state.
    ///
    /// See also [`service_table_unique_key`][2].
    ///
    /// [1]: struct.Schema.html#method.state_hash_aggregator
    /// [2]: struct.Blockchain.html#method.service_table_unique_key
    fn state_hash(&self, snapshot: &Snapshot) -> Vec<Hash>;

    /// Tries to create a `Transaction` from the given raw message.
    fn tx_from_raw(&self, raw: RawTransaction) -> Result<Box<Transaction>, MessageError>;

    /// Initializes the information schema of the service
    /// and generates an initial service configuration.
    /// Called on genesis block creation.
    fn initialize(&self, fork: &mut Fork) -> Value {
        Value::Null
    }

    /// Handles block commit. This handler is invoked for each service after commit of the block.
    /// For example, a service can create one or more transactions if a specific condition
    /// has occurred.
    ///
    /// *Try not to perform long operations in this handler*.
    fn handle_commit(&self, context: &ServiceContext) {}

    /// Returns an API handler for public requests. The handler is mounted on
    /// the `/api/services/{service_name}` path at [the public listen address][pub-addr]
    /// of all full nodes in the blockchain network.
    ///
    /// [pub-addr]: ../node/struct.NodeApiConfig.html#structfield.public_api_address
    fn public_api_handler(&self, context: &ApiContext) -> Option<Box<Handler>> {
        None
    }

    /// Returns an API handler for private requests. The handler is mounted on
    /// the `/api/services/{service_name}` path at [the private listen address][private-addr]
    /// of all full nodes in the blockchain network.
    ///
    /// [private-addr]: ../node/struct.NodeApiConfig.html#structfield.private_api_address
    fn private_api_handler(&self, context: &ApiContext) -> Option<Box<Handler>> {
        None
    }
}

/// The current node state on which the blockchain is running, or in other words
/// execution context.
#[derive(Debug)]
pub struct ServiceContext {
    validator_id: Option<ValidatorId>,
    service_keypair: (PublicKey, SecretKey),
    api_sender: ApiSender,
    fork: Fork,
    stored_configuration: StoredConfiguration,
    height: Height,
}

impl ServiceContext {
    /// Creates the service context for the given node.
    ///
    /// This method is necessary if you want to implement an alternative exonum node.
    /// For example, you can implement special node without consensus for regression
    /// testing of services business logic.
    pub fn new(
        service_public_key: PublicKey,
        service_secret_key: SecretKey,
        api_sender: ApiSender,
        fork: Fork,
    ) -> ServiceContext {
        let (stored_configuration, height) = {
            let schema = Schema::new(fork.as_ref());
            let stored_configuration = schema.actual_configuration();
            let height = schema.height();
            (stored_configuration, height)
        };
        let validator_id = stored_configuration
            .validator_keys
            .iter()
            .position(|validator| service_public_key == validator.service_key)
            .map(|id| ValidatorId(id as u16));

        ServiceContext {
            validator_id,
            service_keypair: (service_public_key, service_secret_key),
            api_sender,
            fork,
            stored_configuration,
            height,
        }
    }

    /// If the current node is validator returns its identifier.
    /// For other nodes return `None`.
    pub fn validator_id(&self) -> Option<ValidatorId> {
        self.validator_id
    }

    /// Returns the current database snapshot.
    pub fn snapshot(&self) -> &Snapshot {
        self.fork.as_ref()
    }

    /// Returns the current blockchain height. This height is "height of the last committed block".
    pub fn height(&self) -> Height {
        self.height
    }

    /// Returns the current list of validators.
    pub fn validators(&self) -> &[ValidatorKeys] {
        self.stored_configuration.validator_keys.as_slice()
    }

    /// Returns current node's public key.
    pub fn public_key(&self) -> &PublicKey {
        &self.service_keypair.0
    }

    /// Returns current node's secret key.
    pub fn secret_key(&self) -> &SecretKey {
        &self.service_keypair.1
    }

    /// Returns the actual consensus configuration.
    pub fn actual_consensus_config(&self) -> &ConsensusConfig {
        &self.stored_configuration.consensus
    }

    /// Returns service specific global variables as json value.
    pub fn actual_service_config(&self, service: &Service) -> &Value {
        &self.stored_configuration.services[service.service_name()]
    }

    /// Returns reference to the transaction sender.
    pub fn transaction_sender(&self) -> &TransactionSend {
        &self.api_sender
    }

    /// Returns the actual blockchain global configuration.
    pub fn stored_configuration(&self) -> &StoredConfiguration {
        &self.stored_configuration
    }
}

#[derive(Debug, Default)]
pub struct ApiNodeState {
    incoming_connections: HashSet<SocketAddr>,
    outgoing_connections: HashSet<SocketAddr>,
    reconnects_timeout: HashMap<SocketAddr, Milliseconds>,
    //TODO: update on event?
    peers_info: HashMap<SocketAddr, PublicKey>,
    is_enabled: bool,
}

impl ApiNodeState {
    fn new() -> ApiNodeState {
        Self::default()
    }
}

/// Shared part of the context, used to take some values from the `Node`s `State`
/// should be used to take some metrics.
#[derive(Clone, Debug)]
pub struct SharedNodeState {
    state: Arc<RwLock<ApiNodeState>>,
    /// Timeout to update api state.
    pub state_update_timeout: Milliseconds,
}

impl SharedNodeState {
    /// Creates new `SharedNodeState`
    pub fn new(state_update_timeout: Milliseconds) -> SharedNodeState {
        SharedNodeState {
            state: Arc::new(RwLock::new(ApiNodeState::new())),
            state_update_timeout,
        }
    }
    /// Return list of connected sockets
    pub fn incoming_connections(&self) -> Vec<SocketAddr> {
        self.state
            .read()
            .expect("Expected read lock.")
            .incoming_connections
            .iter()
            .cloned()
            .collect()
    }
    /// Return list of our connection sockets
    pub fn outgoing_connections(&self) -> Vec<SocketAddr> {
        self.state
            .read()
            .expect("Expected read lock.")
            .outgoing_connections
            .iter()
            .cloned()
            .collect()
    }
    /// Return reconnects list
    pub fn reconnects_timeout(&self) -> Vec<(SocketAddr, Milliseconds)> {
        self.state
            .read()
            .expect("Expected read lock.")
            .reconnects_timeout
            .iter()
            .map(|(c, e)| (*c, *e))
            .collect()
    }
    /// Return peers info list
    pub fn peers_info(&self) -> Vec<(SocketAddr, PublicKey)> {
        self.state
            .read()
            .expect("Expected read lock.")
            .peers_info
            .iter()
            .map(|(c, e)| (*c, *e))
            .collect()
    }
    /// Update internal state, from `Node` State`
    pub fn update_node_state(&self, state: &State) {
        for (p, c) in state.peers().iter() {
            self.state
                .write()
                .expect("Expected write lock.")
                .peers_info
                .insert(c.addr(), *p);
        }
    }

    /// Is the node enabled?
    pub fn is_enabled(&self) -> bool {
        let state = self.state.read().expect("Expected read lock.");
        state.is_enabled
    }

    /// Informs internal state about node's halting.
    pub fn update_is_enabled(&self, is_enabled: bool) {
        let mut state = self.state.write().expect("Expected read lock.");
        state.is_enabled = is_enabled;
    }

    /// Returns value of the `state_update_timeout`.
    pub fn state_update_timeout(&self) -> Milliseconds {
        self.state_update_timeout
    }

    /// add incoming connection into state
    pub fn add_incoming_connection(&self, addr: SocketAddr) {
        self.state
            .write()
            .expect("Expected write lock")
            .incoming_connections
            .insert(addr);
    }
    /// add outgoing connection into state
    pub fn add_outgoing_connection(&self, addr: SocketAddr) {
        self.state
            .write()
            .expect("Expected write lock")
            .outgoing_connections
            .insert(addr);
    }

    /// remove incoming connection from state
    pub fn remove_incoming_connection(&self, addr: &SocketAddr) -> bool {
        self.state
            .write()
            .expect("Expected write lock")
            .incoming_connections
            .remove(addr)
    }

    /// remove outgoing connection from state
    pub fn remove_outgoing_connection(&self, addr: &SocketAddr) -> bool {
        self.state
            .write()
            .expect("Expected write lock")
            .outgoing_connections
            .remove(addr)
    }

    /// Add reconnect timeout
    pub fn add_reconnect_timeout(
        &self,
        addr: SocketAddr,
        timeout: Milliseconds,
    ) -> Option<Milliseconds> {
        self.state
            .write()
            .expect("Expected write lock")
            .reconnects_timeout
            .insert(addr, timeout)
    }

    /// Removes reconnect timeout and returns the previous value.
    pub fn remove_reconnect_timeout(&self, addr: &SocketAddr) -> Option<Milliseconds> {
        self.state
            .write()
            .expect("Expected write lock")
            .reconnects_timeout
            .remove(addr)
    }
}

/// Provides the current node state to api handlers.
pub struct ApiContext {
    blockchain: Blockchain,
    node_channel: ApiSender,
    public_key: PublicKey,
    secret_key: SecretKey,
}

/// Provides the current node state to api handlers.
impl ApiContext {
    /// Constructs context for the given `Node`.
    pub fn new(node: &Node) -> ApiContext {
        let handler = node.handler();
        ApiContext {
            blockchain: handler.blockchain.clone(),
            node_channel: node.channel(),
            public_key: *node.state().service_public_key(),
            secret_key: node.state().service_secret_key().clone(),
        }
    }

    /// Constructs context from raw parts.
    pub fn from_parts(
        blockchain: &Blockchain,
        node_channel: ApiSender,
        public_key: &PublicKey,
        secret_key: &SecretKey,
    ) -> ApiContext {
        ApiContext {
            blockchain: blockchain.clone(),
            node_channel,
            public_key: *public_key,
            secret_key: secret_key.clone(),
        }
    }

    /// Returns reference to the node's blockchain.
    pub fn blockchain(&self) -> &Blockchain {
        &self.blockchain
    }

    /// Returns reference to the transaction sender.
    pub fn node_channel(&self) -> &ApiSender {
        &self.node_channel
    }

    /// Returns the public key of current node.
    pub fn public_key(&self) -> &PublicKey {
        &self.public_key
    }

    /// Returns the secret key of current node.
    pub fn secret_key(&self) -> &SecretKey {
        &self.secret_key
    }
}

impl ::std::fmt::Debug for ApiContext {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        write!(
            f,
            "ApiContext(blockchain: {:?}, public_key: {:?})",
            self.blockchain,
            self.public_key
        )
    }
}

impl<'a, S: Service> From<S> for Box<Service + 'a> {
    fn from(s: S) -> Self {
        Box::new(s) as Box<Service>
    }
}
<commit_msg>Update tx_from_raw method description<commit_after>// Copyright 2017 The Exonum Team
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//   http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

//! This module defines the Exonum services interfaces. Like smart contracts in some other
//! blockchain platforms, Exonum services encapsulate business logic of the blockchain application.

use std::fmt;
use std::sync::{Arc, RwLock};
use std::collections::{HashMap, HashSet};
use std::net::SocketAddr;

use serde_json::Value;
use iron::Handler;

use crypto::{Hash, PublicKey, SecretKey};
use storage::{Fork, Snapshot};
use messages::RawTransaction;
use encoding::Error as MessageError;
use node::{ApiSender, Node, State, TransactionSend};
use blockchain::{Blockchain, ConsensusConfig, Schema, StoredConfiguration, ValidatorKeys};
use helpers::{Height, Milliseconds, ValidatorId};
use super::transaction::Transaction;

/// A trait that describes business logic of a concrete service.
///
/// See also [the documentation page on services][doc:services].
///
/// # Examples
///
/// The following example provides a bare-bones foundation for implementing a service.
///
/// ```
/// #[macro_use] extern crate exonum;
/// // Exports from `exonum` crate skipped
/// # use exonum::blockchain::{Service, Transaction, TransactionSet, ExecutionResult};
/// # use exonum::crypto::Hash;
/// # use exonum::messages::{ServiceMessage, Message, RawTransaction};
/// # use exonum::storage::{Fork, Snapshot};
/// use exonum::encoding::Error as EncError;
///
/// // Reused constants
/// const SERVICE_ID: u16 = 8000;
///
/// // Service schema
/// struct MyServiceSchema<T> {
///     view: T,
/// }
///
/// impl<T: AsRef<Snapshot>> MyServiceSchema<T> {
///     fn new(view: T) -> Self {
///         MyServiceSchema { view }
///     }
///
///     fn state_hash(&self) -> Vec<Hash> {
///         // Calculates the state hash of the service
/// #       vec![]
///     }
///     // Other read-only methods
/// }
///
/// impl<'a> MyServiceSchema<&'a mut Fork> {
///     // Additional read-write methods
/// }
///
/// // Transaction definitions
/// transactions! {
///     MyTransactions {
///         const SERVICE_ID = SERVICE_ID;
///
///         struct TxA {
///             // Transaction fields
///         }
///
///         struct TxB {
///             // ...
///         }
///     }
/// }
///
/// impl Transaction for TxA {
///     // Business logic implementation
/// #   fn verify(&self) -> bool { true }
/// #   fn execute(&self, fork: &mut Fork) -> ExecutionResult { Ok(()) }
/// }
///
/// impl Transaction for TxB {
/// #   fn verify(&self) -> bool { true }
/// #   fn execute(&self, fork: &mut Fork) -> ExecutionResult { Ok(()) }
/// }
///
/// // Service
/// struct MyService {}
///
/// impl Service for MyService {
///     fn service_id(&self) -> u16 {
///        SERVICE_ID
///     }
///
///     fn service_name(&self) -> &'static str {
///         "my_special_unique_service"
///     }
///
///     fn state_hash(&self, snapshot: &Snapshot) -> Vec<Hash> {
///         MyServiceSchema::new(snapshot).state_hash()
///     }
///
///     fn tx_from_raw(&self, raw: RawTransaction) -> Result<Box<Transaction>, EncError> {
///         let tx = MyTransactions::tx_from_raw(raw)?;
///         Ok(tx.into())
///     }
/// }
/// # fn main() { }
/// ```
///
/// [doc:services]: https://exonum.com/doc/architecture/services/
#[allow(unused_variables, unused_mut)]
pub trait Service: Send + Sync + 'static {
    /// Service identifier for database schema and service messages.
    /// Must be unique within the blockchain.
    fn service_id(&self) -> u16;

    /// A comprehensive string service name. Must be unique within the
    /// blockchain.
    fn service_name(&self) -> &str;

    /// Returns a list of root hashes of tables that determine the current state
    /// of the service database. These hashes are collected from all the services in a common
    /// `ProofMapIndex` accessible in the core schema as [`state_hash_aggregator`][1].
    ///
    /// An empty vector can be returned if the service does not influence the blockchain state.
    ///
    /// See also [`service_table_unique_key`][2].
    ///
    /// [1]: struct.Schema.html#method.state_hash_aggregator
    /// [2]: struct.Blockchain.html#method.service_table_unique_key
    fn state_hash(&self, snapshot: &Snapshot) -> Vec<Hash>;

    /// Tries to create a `Transaction` from the given raw message.
    ///
    /// Service should return an error in the following cases (see `MessageError` for more details):
    /// - Incorrect transaction identifier.
    /// - Incorrect data layout.
    ///
    /// Service _shouldn't_ perform signature check or logical validation of the transaction: these
    /// operations should be performed in the `Transaction::verify` and `Transaction::execute`
    /// methods respectively.
    fn tx_from_raw(&self, raw: RawTransaction) -> Result<Box<Transaction>, MessageError>;

    /// Initializes the information schema of the service
    /// and generates an initial service configuration.
    /// Called on genesis block creation.
    fn initialize(&self, fork: &mut Fork) -> Value {
        Value::Null
    }

    /// Handles block commit. This handler is invoked for each service after commit of the block.
    /// For example, a service can create one or more transactions if a specific condition
    /// has occurred.
    ///
    /// *Try not to perform long operations in this handler*.
    fn handle_commit(&self, context: &ServiceContext) {}

    /// Returns an API handler for public requests. The handler is mounted on
    /// the `/api/services/{service_name}` path at [the public listen address][pub-addr]
    /// of all full nodes in the blockchain network.
    ///
    /// [pub-addr]: ../node/struct.NodeApiConfig.html#structfield.public_api_address
    fn public_api_handler(&self, context: &ApiContext) -> Option<Box<Handler>> {
        None
    }

    /// Returns an API handler for private requests. The handler is mounted on
    /// the `/api/services/{service_name}` path at [the private listen address][private-addr]
    /// of all full nodes in the blockchain network.
    ///
    /// [private-addr]: ../node/struct.NodeApiConfig.html#structfield.private_api_address
    fn private_api_handler(&self, context: &ApiContext) -> Option<Box<Handler>> {
        None
    }
}

/// The current node state on which the blockchain is running, or in other words
/// execution context.
#[derive(Debug)]
pub struct ServiceContext {
    validator_id: Option<ValidatorId>,
    service_keypair: (PublicKey, SecretKey),
    api_sender: ApiSender,
    fork: Fork,
    stored_configuration: StoredConfiguration,
    height: Height,
}

impl ServiceContext {
    /// Creates the service context for the given node.
    ///
    /// This method is necessary if you want to implement an alternative exonum node.
    /// For example, you can implement special node without consensus for regression
    /// testing of services business logic.
    pub fn new(
        service_public_key: PublicKey,
        service_secret_key: SecretKey,
        api_sender: ApiSender,
        fork: Fork,
    ) -> ServiceContext {
        let (stored_configuration, height) = {
            let schema = Schema::new(fork.as_ref());
            let stored_configuration = schema.actual_configuration();
            let height = schema.height();
            (stored_configuration, height)
        };
        let validator_id = stored_configuration
            .validator_keys
            .iter()
            .position(|validator| service_public_key == validator.service_key)
            .map(|id| ValidatorId(id as u16));

        ServiceContext {
            validator_id,
            service_keypair: (service_public_key, service_secret_key),
            api_sender,
            fork,
            stored_configuration,
            height,
        }
    }

    /// If the current node is validator returns its identifier.
    /// For other nodes return `None`.
    pub fn validator_id(&self) -> Option<ValidatorId> {
        self.validator_id
    }

    /// Returns the current database snapshot.
    pub fn snapshot(&self) -> &Snapshot {
        self.fork.as_ref()
    }

    /// Returns the current blockchain height. This height is "height of the last committed block".
    pub fn height(&self) -> Height {
        self.height
    }

    /// Returns the current list of validators.
    pub fn validators(&self) -> &[ValidatorKeys] {
        self.stored_configuration.validator_keys.as_slice()
    }

    /// Returns current node's public key.
    pub fn public_key(&self) -> &PublicKey {
        &self.service_keypair.0
    }

    /// Returns current node's secret key.
    pub fn secret_key(&self) -> &SecretKey {
        &self.service_keypair.1
    }

    /// Returns the actual consensus configuration.
    pub fn actual_consensus_config(&self) -> &ConsensusConfig {
        &self.stored_configuration.consensus
    }

    /// Returns service specific global variables as json value.
    pub fn actual_service_config(&self, service: &Service) -> &Value {
        &self.stored_configuration.services[service.service_name()]
    }

    /// Returns reference to the transaction sender.
    pub fn transaction_sender(&self) -> &TransactionSend {
        &self.api_sender
    }

    /// Returns the actual blockchain global configuration.
    pub fn stored_configuration(&self) -> &StoredConfiguration {
        &self.stored_configuration
    }
}

#[derive(Debug, Default)]
pub struct ApiNodeState {
    incoming_connections: HashSet<SocketAddr>,
    outgoing_connections: HashSet<SocketAddr>,
    reconnects_timeout: HashMap<SocketAddr, Milliseconds>,
    //TODO: update on event?
    peers_info: HashMap<SocketAddr, PublicKey>,
    is_enabled: bool,
}

impl ApiNodeState {
    fn new() -> ApiNodeState {
        Self::default()
    }
}

/// Shared part of the context, used to take some values from the `Node`s `State`
/// should be used to take some metrics.
#[derive(Clone, Debug)]
pub struct SharedNodeState {
    state: Arc<RwLock<ApiNodeState>>,
    /// Timeout to update api state.
    pub state_update_timeout: Milliseconds,
}

impl SharedNodeState {
    /// Creates new `SharedNodeState`
    pub fn new(state_update_timeout: Milliseconds) -> SharedNodeState {
        SharedNodeState {
            state: Arc::new(RwLock::new(ApiNodeState::new())),
            state_update_timeout,
        }
    }
    /// Return list of connected sockets
    pub fn incoming_connections(&self) -> Vec<SocketAddr> {
        self.state
            .read()
            .expect("Expected read lock.")
            .incoming_connections
            .iter()
            .cloned()
            .collect()
    }
    /// Return list of our connection sockets
    pub fn outgoing_connections(&self) -> Vec<SocketAddr> {
        self.state
            .read()
            .expect("Expected read lock.")
            .outgoing_connections
            .iter()
            .cloned()
            .collect()
    }
    /// Return reconnects list
    pub fn reconnects_timeout(&self) -> Vec<(SocketAddr, Milliseconds)> {
        self.state
            .read()
            .expect("Expected read lock.")
            .reconnects_timeout
            .iter()
            .map(|(c, e)| (*c, *e))
            .collect()
    }
    /// Return peers info list
    pub fn peers_info(&self) -> Vec<(SocketAddr, PublicKey)> {
        self.state
            .read()
            .expect("Expected read lock.")
            .peers_info
            .iter()
            .map(|(c, e)| (*c, *e))
            .collect()
    }
    /// Update internal state, from `Node` State`
    pub fn update_node_state(&self, state: &State) {
        for (p, c) in state.peers().iter() {
            self.state
                .write()
                .expect("Expected write lock.")
                .peers_info
                .insert(c.addr(), *p);
        }
    }

    /// Is the node enabled?
    pub fn is_enabled(&self) -> bool {
        let state = self.state.read().expect("Expected read lock.");
        state.is_enabled
    }

    /// Informs internal state about node's halting.
    pub fn update_is_enabled(&self, is_enabled: bool) {
        let mut state = self.state.write().expect("Expected read lock.");
        state.is_enabled = is_enabled;
    }

    /// Returns value of the `state_update_timeout`.
    pub fn state_update_timeout(&self) -> Milliseconds {
        self.state_update_timeout
    }

    /// add incoming connection into state
    pub fn add_incoming_connection(&self, addr: SocketAddr) {
        self.state
            .write()
            .expect("Expected write lock")
            .incoming_connections
            .insert(addr);
    }
    /// add outgoing connection into state
    pub fn add_outgoing_connection(&self, addr: SocketAddr) {
        self.state
            .write()
            .expect("Expected write lock")
            .outgoing_connections
            .insert(addr);
    }

    /// remove incoming connection from state
    pub fn remove_incoming_connection(&self, addr: &SocketAddr) -> bool {
        self.state
            .write()
            .expect("Expected write lock")
            .incoming_connections
            .remove(addr)
    }

    /// remove outgoing connection from state
    pub fn remove_outgoing_connection(&self, addr: &SocketAddr) -> bool {
        self.state
            .write()
            .expect("Expected write lock")
            .outgoing_connections
            .remove(addr)
    }

    /// Add reconnect timeout
    pub fn add_reconnect_timeout(
        &self,
        addr: SocketAddr,
        timeout: Milliseconds,
    ) -> Option<Milliseconds> {
        self.state
            .write()
            .expect("Expected write lock")
            .reconnects_timeout
            .insert(addr, timeout)
    }

    /// Removes reconnect timeout and returns the previous value.
    pub fn remove_reconnect_timeout(&self, addr: &SocketAddr) -> Option<Milliseconds> {
        self.state
            .write()
            .expect("Expected write lock")
            .reconnects_timeout
            .remove(addr)
    }
}

/// Provides the current node state to api handlers.
pub struct ApiContext {
    blockchain: Blockchain,
    node_channel: ApiSender,
    public_key: PublicKey,
    secret_key: SecretKey,
}

/// Provides the current node state to api handlers.
impl ApiContext {
    /// Constructs context for the given `Node`.
    pub fn new(node: &Node) -> ApiContext {
        let handler = node.handler();
        ApiContext {
            blockchain: handler.blockchain.clone(),
            node_channel: node.channel(),
            public_key: *node.state().service_public_key(),
            secret_key: node.state().service_secret_key().clone(),
        }
    }

    /// Constructs context from raw parts.
    pub fn from_parts(
        blockchain: &Blockchain,
        node_channel: ApiSender,
        public_key: &PublicKey,
        secret_key: &SecretKey,
    ) -> ApiContext {
        ApiContext {
            blockchain: blockchain.clone(),
            node_channel,
            public_key: *public_key,
            secret_key: secret_key.clone(),
        }
    }

    /// Returns reference to the node's blockchain.
    pub fn blockchain(&self) -> &Blockchain {
        &self.blockchain
    }

    /// Returns reference to the transaction sender.
    pub fn node_channel(&self) -> &ApiSender {
        &self.node_channel
    }

    /// Returns the public key of current node.
    pub fn public_key(&self) -> &PublicKey {
        &self.public_key
    }

    /// Returns the secret key of current node.
    pub fn secret_key(&self) -> &SecretKey {
        &self.secret_key
    }
}

impl ::std::fmt::Debug for ApiContext {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        write!(
            f,
            "ApiContext(blockchain: {:?}, public_key: {:?})",
            self.blockchain,
            self.public_key
        )
    }
}

impl<'a, S: Service> From<S> for Box<Service + 'a> {
    fn from(s: S) -> Self {
        Box::new(s) as Box<Service>
    }
}
<|endoftext|>


<commit_before>use num::{Integer, range, ToPrimitive};

use std::marker::PhantomData;
use std::cell::Cell;

use super::{Map, Error, StorageValue, List};

pub struct ListTable<T: Map<[u8], Vec<u8>>, K, V> {
    map: T,
    count: Cell<Option<K>>,
    _v: PhantomData<V>,
}

impl<'a, T, K, V> ListTable<T, K, V>
    where T: Map<[u8], Vec<u8>>,
          K: Integer + Copy + Clone + ToPrimitive + StorageValue,
          V: StorageValue
{
    pub fn new(map: T) -> Self {
        ListTable {
            map: map,
            count: Cell::new(None),
            _v: PhantomData,
        }
    }

    // TODO: implement iterator for List
    pub fn values(&self) -> Result<Vec<V>, Error> {
        Ok(if self.is_empty()? {
            Vec::new()
        } else {
            range(K::zero(), self.len()?).map(|i| self.get(i).unwrap().unwrap()).collect()
        })
    }
}

impl<T, K: ?Sized, V> List<K, V> for ListTable<T, K, V>
    where T: Map<[u8], Vec<u8>>,
          K: Integer + Copy + Clone + ToPrimitive + StorageValue,
          V: StorageValue
{
    fn append(&self, value: V) -> Result<(), Error> {
        let len = self.len()?;
        self.map.put(&len.serialize(), value.serialize())?;
        self.map.put(&[], (len + K::one()).serialize())?;
        self.count.set(Some(len + K::one()));
        Ok(())
    }

    fn extend<I>(&self, iter: I) -> Result<(), Error>
        where I: IntoIterator<Item = V>
    {
        let mut len = self.len()?;
        for value in iter {
            self.map.put(&len.serialize(), value.serialize())?;
            len = len + K::one();
        }
        self.map.put(&[], (len + K::one()).serialize())?;
        self.count.set(Some(len + K::one()));
        Ok(())
    }

    fn get(&self, index: K) -> Result<Option<V>, Error> {
        let value = self.map.get(&index.serialize())?;
        Ok(value.map(StorageValue::deserialize))
    }

    fn set(&self, index: K, value: V) -> Result<(), Error> {
        if index >= self.len()? {
            return Err(Error::new("Wrong index!"));
        }
        self.map.put(&index.serialize(), value.serialize())
    }

    fn last(&self) -> Result<Option<V>, Error> {
        let len = self.len()?;
        if len == K::zero() {
            Ok(None)
        } else {
            self.get(len - K::one())
        }
    }

    fn is_empty(&self) -> Result<bool, Error> {
        Ok(self.len()? == K::zero())
    }

    fn len(&self) -> Result<K, Error> {
        if let Some(count) = self.count.get() {
            return Ok(count);
        }

        let v = self.map.get(&[])?;
        let c = v.map_or_else(K::zero, K::deserialize);
        self.count.set(Some(c));
        Ok(c)
    }
}
<commit_msg>Fix ListTable.extend and added test for ListTable methods<commit_after>use num::{Integer, range, ToPrimitive};

use std::marker::PhantomData;
use std::cell::Cell;

use super::{Map, Error, StorageValue, List};

pub struct ListTable<T: Map<[u8], Vec<u8>>, K, V> {
    map: T,
    count: Cell<Option<K>>,
    _v: PhantomData<V>,
}

impl<'a, T, K, V> ListTable<T, K, V>
    where T: Map<[u8], Vec<u8>>,
          K: Integer + Copy + Clone + ToPrimitive + StorageValue,
          V: StorageValue
{
    pub fn new(map: T) -> Self {
        ListTable {
            map: map,
            count: Cell::new(None),
            _v: PhantomData,
        }
    }

    // TODO: implement iterator for List
    pub fn values(&self) -> Result<Vec<V>, Error> {
        Ok(if self.is_empty()? {
            Vec::new()
        } else {
            range(K::zero(), self.len()?).map(|i| self.get(i).unwrap().unwrap()).collect()
        })
    }
}

impl<T, K: ?Sized, V> List<K, V> for ListTable<T, K, V>
    where T: Map<[u8], Vec<u8>>,
          K: Integer + Copy + Clone + ToPrimitive + StorageValue,
          V: StorageValue
{
    fn append(&self, value: V) -> Result<(), Error> {
        let len = self.len()?;
        self.map.put(&len.serialize(), value.serialize())?;
        self.map.put(&[], (len + K::one()).serialize())?;
        self.count.set(Some(len + K::one()));
        Ok(())
    }

    fn extend<I>(&self, iter: I) -> Result<(), Error>
        where I: IntoIterator<Item = V>
    {
        let mut len = self.len()?;
        for value in iter {
            self.map.put(&len.serialize(), value.serialize())?;
            len = len + K::one();
        }
        self.map.put(&[], len.serialize())?;
        self.count.set(Some(len));
        Ok(())
    }

    fn get(&self, index: K) -> Result<Option<V>, Error> {
        let value = self.map.get(&index.serialize())?;
        Ok(value.map(StorageValue::deserialize))
    }

    fn set(&self, index: K, value: V) -> Result<(), Error> {
        if index >= self.len()? {
            return Err(Error::new("Wrong index!"));
        }
        self.map.put(&index.serialize(), value.serialize())
    }

    fn last(&self) -> Result<Option<V>, Error> {
        let len = self.len()?;
        if len == K::zero() {
            Ok(None)
        } else {
            self.get(len - K::one())
        }
    }

    fn is_empty(&self) -> Result<bool, Error> {
        Ok(self.len()? == K::zero())
    }

    fn len(&self) -> Result<K, Error> {
        if let Some(count) = self.count.get() {
            return Ok(count);
        }

        let v = self.map.get(&[])?;
        let c = v.map_or_else(K::zero, K::deserialize);
        self.count.set(Some(c));
        Ok(c)
    }
}

#[cfg(test)]
mod tests {
    use ::storage::{MemoryDB, List, ListTable, MapTable};

    #[test]
    fn test_list_table_methods() {
        let storage = MemoryDB::new();
        let list_table = ListTable::new(MapTable::new(vec![255], &storage));

        assert!(list_table.is_empty().unwrap());
        assert_eq!(0, list_table.len().unwrap() );
        assert!(list_table.last().unwrap().is_none());

        let extended_by = vec![45u64, 3422u64, 234u64];
        list_table.extend(extended_by.into_iter()).unwrap();
        assert!(!list_table.is_empty().unwrap());
        assert_eq!(Some(45u64), list_table.get(0u32).unwrap());
        assert_eq!(Some(3422u64), list_table.get(1).unwrap());
        assert_eq!(Some(234u64), list_table.get(2).unwrap());
        assert_eq!(3, list_table.len().unwrap() );

        list_table.set(2, 777u64).unwrap();
        assert_eq!(Some(777u64), list_table.get(2).unwrap());
        assert_eq!(Some(777u64), list_table.last().unwrap() );
        assert_eq!(3, list_table.len().unwrap() );

        let mut extended_by_again = vec![666u64, 999u64];
        for el in &extended_by_again {
            list_table.append(*el).unwrap();
        }
        assert_eq!(Some(666u64), list_table.get(3).unwrap());
        assert_eq!(Some(999u64), list_table.get(4).unwrap());
        assert_eq!(5, list_table.len().unwrap() );
        extended_by_again[1] = 1001u64;
        list_table.extend(extended_by_again).unwrap();
        assert_eq!(7, list_table.len().unwrap() );
        assert_eq!(Some(1001u64), list_table.last().unwrap() );
    }

}
<|endoftext|>


<commit_before>use cgmath;
use glutin::Event;
use gfx;
use vangers::{config, level, model, render, space};

pub struct CarView<R: gfx::Resources> {
    model: model::Model<R>,
    transform: space::Transform,
    pso: gfx::PipelineState<R, render::object::Meta>,
    psos_debug: [gfx::PipelineState<R, render::debug::Meta>; 2],
    physics: config::car::CarPhysics,
    data: render::object::Data<R>,
    data_debug: render::debug::Data<R>,
    cam: space::Camera,
}

impl<R: gfx::Resources> CarView<R> {
    pub fn new<F: gfx::Factory<R>>(settings: &config::Settings,
               out_color: gfx::handle::RenderTargetView<R, render::ColorFormat>,
               out_depth: gfx::handle::DepthStencilView<R, render::DepthFormat>,
               factory: &mut F) -> CarView<R>
    {
        use gfx::traits::FactoryExt;

        info!("Loading car registry");
        let game_reg = config::game::Registry::load(settings);
        let car_reg = config::car::load_registry(settings, &game_reg, factory);
        let cinfo = &car_reg[&settings.car.id];
        let mut model = cinfo.model.clone();
        for (ms, sid) in model.slots.iter_mut().zip(settings.car.slots.iter()) {
            let info = &game_reg.model_infos[sid];
            let mut file = settings.open(&info.path);
            ms.mesh = Some(model::load_c3d(&mut file, factory));
            ms.scale = info.scale;
        }

        let pal_data = level::load_palette(&settings.get_object_palette_path());
        let data = render::object::Data {
            vbuf: model.body.buffer.clone(),
            locals: factory.create_constant_buffer(1),
            ctable: render::Render::create_color_table(factory),
            palette: render::Render::create_palette(&pal_data, factory),
            out_color: out_color.clone(),
            out_depth: out_depth.clone(),
        };
        let data_debug = render::debug::Data {
            vbuf: match model.shape.debug {
                Some(model::DebugShape {ref bound_vb, ..}) => bound_vb.clone(),
                None => unimplemented!(),
            },
            locals: factory.create_constant_buffer(1),
            out_color: out_color,
            out_depth: out_depth,
        };

        CarView {
            model: model,
            transform: cgmath::Decomposed {
                scale: cinfo.scale,
                disp: cgmath::Vector3::unit_z(),
                rot: cgmath::One::one(),
            },
            pso: render::Render::create_object_pso(factory),
            psos_debug: render::Render::create_debug_psos(factory),
            physics: cinfo.physics.clone(),
            data: data,
            data_debug: data_debug,
            cam: space::Camera {
                loc: cgmath::vec3(0.0, -64.0, 32.0),
                rot: cgmath::Rotation3::from_axis_angle::<cgmath::Rad<_>>(
                    cgmath::Vector3::unit_x(), cgmath::Angle::turn_div_6()),
                proj: cgmath::PerspectiveFov {
                    fovy: cgmath::Deg(45.0).into(),
                    aspect: settings.get_screen_aspect(),
                    near: 1.0,
                    far: 100.0,
                },
            },
        }
    }

    fn rotate(&mut self, angle: cgmath::Rad<f32>) {
        use cgmath::Transform;
        let other = cgmath::Decomposed {
            scale: 1.0,
            rot: cgmath::Rotation3::from_axis_angle(cgmath::Vector3::unit_z(), angle),
            disp: cgmath::Zero::zero(),
        };
        self.transform = other.concat(&self.transform);
    }
}

impl<R: gfx::Resources> CarView<R> {
    pub fn update<I, F>(&mut self, events: I, delta: f32, factory: &mut F)
                        -> bool where
        I: Iterator<Item = Event>,
        F: gfx::Factory<R>,
    {
        use glutin::VirtualKeyCode as Key;
        let angle = cgmath::Rad(delta * 2.0);
        for event in events {
            match event {
                Event::KeyboardInput(_, _, Some(Key::Escape)) |
                Event::Closed => return false,
                Event::KeyboardInput(_, _, Some(Key::A)) => self.rotate(-angle),
                Event::KeyboardInput(_, _, Some(Key::D)) => self.rotate(angle),
                Event::KeyboardInput(_, _, Some(Key::L)) =>
                    self.pso = render::Render::create_object_pso(factory),
                _ => {}, //TODO
            }
        }
        true
    }

    pub fn draw<C: gfx::CommandBuffer<R>>(&mut self, enc: &mut gfx::Encoder<R, C>) {
        enc.clear(&self.data.out_color, [0.1, 0.2, 0.3, 1.0]);
        enc.clear_depth(&self.data.out_depth, 1.0);

        render::Render::draw_model(enc, &self.model,
            self.transform, &self.cam, &self.pso, &mut self.data,
            Some((&self.psos_debug, &mut self.data_debug, self.physics.scale_bound)));
    }
}
<commit_msg>Better car rotation view<commit_after>use cgmath;
use glutin::Event;
use gfx;
use vangers::{config, level, model, render, space};

pub struct CarView<R: gfx::Resources> {
    model: model::Model<R>,
    transform: space::Transform,
    pso: gfx::PipelineState<R, render::object::Meta>,
    psos_debug: [gfx::PipelineState<R, render::debug::Meta>; 2],
    physics: config::car::CarPhysics,
    data: render::object::Data<R>,
    data_debug: render::debug::Data<R>,
    cam: space::Camera,
}

impl<R: gfx::Resources> CarView<R> {
    pub fn new<F: gfx::Factory<R>>(settings: &config::Settings,
               out_color: gfx::handle::RenderTargetView<R, render::ColorFormat>,
               out_depth: gfx::handle::DepthStencilView<R, render::DepthFormat>,
               factory: &mut F) -> CarView<R>
    {
        use gfx::traits::FactoryExt;

        info!("Loading car registry");
        let game_reg = config::game::Registry::load(settings);
        let car_reg = config::car::load_registry(settings, &game_reg, factory);
        let cinfo = &car_reg[&settings.car.id];
        let mut model = cinfo.model.clone();
        for (ms, sid) in model.slots.iter_mut().zip(settings.car.slots.iter()) {
            let info = &game_reg.model_infos[sid];
            let mut file = settings.open(&info.path);
            ms.mesh = Some(model::load_c3d(&mut file, factory));
            ms.scale = info.scale;
        }

        let pal_data = level::load_palette(&settings.get_object_palette_path());
        let data = render::object::Data {
            vbuf: model.body.buffer.clone(),
            locals: factory.create_constant_buffer(1),
            ctable: render::Render::create_color_table(factory),
            palette: render::Render::create_palette(&pal_data, factory),
            out_color: out_color.clone(),
            out_depth: out_depth.clone(),
        };
        let data_debug = render::debug::Data {
            vbuf: match model.shape.debug {
                Some(model::DebugShape {ref bound_vb, ..}) => bound_vb.clone(),
                None => unimplemented!(),
            },
            locals: factory.create_constant_buffer(1),
            out_color: out_color,
            out_depth: out_depth,
        };

        CarView {
            model: model,
            transform: cgmath::Decomposed {
                scale: cinfo.scale,
                disp: cgmath::Vector3::unit_z(),
                rot: cgmath::One::one(),
            },
            pso: render::Render::create_object_pso(factory),
            psos_debug: render::Render::create_debug_psos(factory),
            physics: cinfo.physics.clone(),
            data: data,
            data_debug: data_debug,
            cam: space::Camera {
                loc: cgmath::vec3(0.0, -64.0, 32.0),
                rot: cgmath::Rotation3::from_axis_angle::<cgmath::Rad<_>>(
                    cgmath::Vector3::unit_x(), cgmath::Angle::turn_div_6()),
                proj: cgmath::PerspectiveFov {
                    fovy: cgmath::Deg(45.0).into(),
                    aspect: settings.get_screen_aspect(),
                    near: 1.0,
                    far: 100.0,
                },
            },
        }
    }

    fn rotate_z(&mut self, angle: cgmath::Rad<f32>) {
        use cgmath::Transform;
        let other = cgmath::Decomposed {
            scale: 1.0,
            rot: cgmath::Rotation3::from_axis_angle(cgmath::Vector3::unit_z(), angle),
            disp: cgmath::Zero::zero(),
        };
        self.transform = other.concat(&self.transform);
    }

    fn rotate_x(&mut self, angle: cgmath::Rad<f32>) {
        use cgmath::Transform;
        let other = cgmath::Decomposed {
            scale: 1.0,
            rot: cgmath::Rotation3::from_axis_angle(cgmath::Vector3::unit_x(), angle),
            disp: cgmath::Zero::zero(),
        };
        self.transform = self.transform.concat(&other);
    }
}

impl<R: gfx::Resources> CarView<R> {
    pub fn update<I, F>(&mut self, events: I, delta: f32, factory: &mut F)
                        -> bool where
        I: Iterator<Item = Event>,
        F: gfx::Factory<R>,
    {
        use glutin::{VirtualKeyCode as Key};
        use glutin::ElementState::Pressed;
        let angle = cgmath::Rad(delta * 2.0);
        for event in events {
            match event {
                Event::KeyboardInput(Pressed, _, Some(Key::Escape)) |
                Event::Closed => return false,
                Event::KeyboardInput(Pressed, _, Some(Key::A)) => self.rotate_z(-angle),
                Event::KeyboardInput(Pressed, _, Some(Key::D)) => self.rotate_z(angle),
                Event::KeyboardInput(Pressed, _, Some(Key::W)) => self.rotate_x(-angle),
                Event::KeyboardInput(Pressed, _, Some(Key::S)) => self.rotate_x(angle),
                Event::KeyboardInput(Pressed, _, Some(Key::L)) =>
                    self.pso = render::Render::create_object_pso(factory),
                _ => {}, //TODO
            }
        }
        true
    }

    pub fn draw<C: gfx::CommandBuffer<R>>(&mut self, enc: &mut gfx::Encoder<R, C>) {
        enc.clear(&self.data.out_color, [0.1, 0.2, 0.3, 1.0]);
        enc.clear_depth(&self.data.out_depth, 1.0);

        render::Render::draw_model(enc, &self.model,
            self.transform, &self.cam, &self.pso, &mut self.data,
            Some((&self.psos_debug, &mut self.data_debug, self.physics.scale_bound)));
    }
}
<|endoftext|>