<commit_before>// compile-flags: -Zmiri-tag-raw-pointers
// Gather all references from a mutable iterator and make sure Miri notices if
// using them is dangerous.
fn test_all_refs<'a, T: 'a>(dummy: &mut T, iter: impl Iterator<Item = &'a mut T>) {
    // Gather all those references.
    let mut refs: Vec<&mut T> = iter.collect();
    // Use them all. Twice, to be sure we got all interleavings.
    for r in refs.iter_mut() {
        std::mem::swap(dummy, r);
    }
    for r in refs {
        std::mem::swap(dummy, r);
    }
}

fn make_vec() -> Vec<u8> {
    let mut v = Vec::with_capacity(4);
    v.push(1);
    v.push(2);
    v
}

fn make_vec_macro() -> Vec<u8> {
    vec![1, 2]
}

fn make_vec_macro_repeat() -> Vec<u8> {
    vec![42; 5]
}

fn make_vec_macro_repeat_zeroed() -> Vec<u8> {
    vec![0; 7]
}

fn vec_into_iter() -> u8 {
    vec![1, 2, 3, 4]
        .into_iter()
        .map(|x| x * x)
        .fold(0, |x, y| x + y)
}

fn vec_into_iter_rev() -> u8 {
    vec![1, 2, 3, 4]
        .into_iter()
        .map(|x| x * x)
        .fold(0, |x, y| x + y)
}

fn vec_into_iter_zst() -> usize {
    vec![[0u64; 0], [0u64; 0]]
        .into_iter()
        .rev()
        .map(|x| x.len())
        .sum()
}

fn vec_into_iter_rev_zst() -> usize {
    vec![[0u64; 0], [0u64; 0]]
        .into_iter()
        .rev()
        .map(|x| x.len())
        .sum()
}

fn vec_iter_and_mut() {
    let mut v = vec![1,2,3,4];
    for i in v.iter_mut() {
        *i += 1;
    }
    assert_eq!(v.iter().sum::<i32>(), 2+3+4+5);

    test_all_refs(&mut 13, v.iter_mut());
}

fn vec_iter_and_mut_rev() {
    let mut v = vec![1,2,3,4];
    for i in v.iter_mut().rev() {
        *i += 1;
    }
    assert_eq!(v.iter().sum::<i32>(), 2+3+4+5);
}

fn vec_reallocate() -> Vec<u8> {
    let mut v = vec![1, 2];
    v.push(3);
    v.push(4);
    v.push(5);
    v
}

fn vec_push_ptr_stable() {
    let mut v = Vec::with_capacity(10);
    v.push(0);
    let v0 = unsafe { &mut *(&mut v[0] as *mut _) }; // laundering the lifetime -- we take care that `v` does not reallocate, so that's okay.
    v.push(1);
    let _val = *v0;
}

fn vec_extend_ptr_stable() {
    let mut v = Vec::with_capacity(10);
    v.push(0);
    let v0 = unsafe { &mut *(&mut v[0] as *mut _) }; // laundering the lifetime -- we take care that `v` does not reallocate, so that's okay.
    // `slice::Iter` (with `T: Copy`) specialization
    v.extend(&[1]);
    let _val = *v0;
    // `vec::IntoIter` specialization
    v.extend(vec![2]);
    let _val = *v0;
    // `TrustedLen` specialization
    v.extend(std::iter::once(3));
    let _val = *v0;
    // base case
    v.extend(std::iter::once(3).filter(|_| true));
    let _val = *v0;
}

fn vec_truncate_ptr_stable() {
    let mut v = vec![0; 10];
    let v0 = unsafe { &mut *(&mut v[0] as *mut _) }; // laundering the lifetime -- we take care that `v` does not reallocate, so that's okay.
    v.truncate(5);
    let _val = *v0;
}

fn push_str_ptr_stable() {
    let mut buf = String::with_capacity(11);
    buf.push_str("hello");
    let hello: &str = unsafe { &*(buf.as_str() as *const _) }; // laundering the lifetime -- we take care that `buf` does not reallocate, so that's okay.
    buf.push_str(" world");
    assert_eq!(format!("{}", hello), "hello");
}

fn sort() {
    let mut v = vec![1; 20];
    v.push(0);
    v.sort();
}

fn swap() {
    let mut v = vec![1, 2, 3, 4];
    v.swap(2, 2);
}

fn swap_remove() {
    let mut a = 0;
    let mut b = 1;
    let mut vec = vec![&mut a, &mut b];

    vec.swap_remove(1);
}

fn main() {
    assert_eq!(vec_reallocate().len(), 5);

    assert_eq!(vec_into_iter(), 30);
    assert_eq!(vec_into_iter_rev(), 30);
    vec_iter_and_mut();
    assert_eq!(vec_into_iter_zst(), 0);
    assert_eq!(vec_into_iter_rev_zst(), 0);
    vec_iter_and_mut_rev();

    assert_eq!(make_vec().capacity(), 4);
    assert_eq!(make_vec_macro(), [1, 2]);
    assert_eq!(make_vec_macro_repeat(), [42; 5]);
    assert_eq!(make_vec_macro_repeat_zeroed(), [0; 7]);

    // Test interesting empty slice comparison
    // (one is a real pointer, one an integer pointer).
    assert_eq!((200..-5).step_by(1).collect::<Vec<isize>>(), []);

    // liballoc has a more extensive test of this, but let's at least do a smoke test here.
    vec_push_ptr_stable();
    vec_extend_ptr_stable();
    vec_truncate_ptr_stable();
    push_str_ptr_stable();

    sort();
    swap();
    swap_remove();
}
<commit_msg>Auto merge of #2036 - RalfJung:vec, r=RalfJung<commit_after>// compile-flags: -Zmiri-tag-raw-pointers -Zmiri-check-number-validity
// Gather all references from a mutable iterator and make sure Miri notices if
// using them is dangerous.
fn test_all_refs<'a, T: 'a>(dummy: &mut T, iter: impl Iterator<Item = &'a mut T>) {
    // Gather all those references.
    let mut refs: Vec<&mut T> = iter.collect();
    // Use them all. Twice, to be sure we got all interleavings.
    for r in refs.iter_mut() {
        std::mem::swap(dummy, r);
    }
    for r in refs {
        std::mem::swap(dummy, r);
    }
}

fn make_vec() -> Vec<u8> {
    let mut v = Vec::with_capacity(4);
    v.push(1);
    v.push(2);
    v
}

fn make_vec_macro() -> Vec<u8> {
    vec![1, 2]
}

fn make_vec_macro_repeat() -> Vec<u8> {
    vec![42; 5]
}

fn make_vec_macro_repeat_zeroed() -> Vec<u8> {
    vec![0; 7]
}

fn vec_into_iter() -> u8 {
    vec![1, 2, 3, 4]
        .into_iter()
        .map(|x| x * x)
        .fold(0, |x, y| x + y)
}

fn vec_into_iter_rev() -> u8 {
    vec![1, 2, 3, 4]
        .into_iter()
        .map(|x| x * x)
        .fold(0, |x, y| x + y)
}

fn vec_into_iter_zst() -> usize {
    vec![[0u64; 0], [0u64; 0]]
        .into_iter()
        .rev()
        .map(|x| x.len())
        .sum()
}

fn vec_into_iter_rev_zst() -> usize {
    vec![[0u64; 0], [0u64; 0]]
        .into_iter()
        .rev()
        .map(|x| x.len())
        .sum()
}

fn vec_iter_and_mut() {
    let mut v = vec![1,2,3,4];
    for i in v.iter_mut() {
        *i += 1;
    }
    assert_eq!(v.iter().sum::<i32>(), 2+3+4+5);

    test_all_refs(&mut 13, v.iter_mut());
}

fn vec_iter_and_mut_rev() {
    let mut v = vec![1,2,3,4];
    for i in v.iter_mut().rev() {
        *i += 1;
    }
    assert_eq!(v.iter().sum::<i32>(), 2+3+4+5);
}

fn vec_reallocate() -> Vec<u8> {
    let mut v = vec![1, 2];
    v.push(3);
    v.push(4);
    v.push(5);
    v
}

fn vec_push_ptr_stable() {
    let mut v = Vec::with_capacity(10);
    v.push(0);
    let v0 = unsafe { &mut *(&mut v[0] as *mut _) }; // laundering the lifetime -- we take care that `v` does not reallocate, so that's okay.
    v.push(1);
    let _val = *v0;
}

fn vec_extend_ptr_stable() {
    let mut v = Vec::with_capacity(10);
    v.push(0);
    let v0 = unsafe { &mut *(&mut v[0] as *mut _) }; // laundering the lifetime -- we take care that `v` does not reallocate, so that's okay.
    // `slice::Iter` (with `T: Copy`) specialization
    v.extend(&[1]);
    let _val = *v0;
    // `vec::IntoIter` specialization
    v.extend(vec![2]);
    let _val = *v0;
    // `TrustedLen` specialization
    v.extend(std::iter::once(3));
    let _val = *v0;
    // base case
    v.extend(std::iter::once(3).filter(|_| true));
    let _val = *v0;
}

fn vec_truncate_ptr_stable() {
    let mut v = vec![0; 10];
    let v0 = unsafe { &mut *(&mut v[0] as *mut _) }; // laundering the lifetime -- we take care that `v` does not reallocate, so that's okay.
    v.truncate(5);
    let _val = *v0;
}

fn push_str_ptr_stable() {
    let mut buf = String::with_capacity(11);
    buf.push_str("hello");
    let hello: &str = unsafe { &*(buf.as_str() as *const _) }; // laundering the lifetime -- we take care that `buf` does not reallocate, so that's okay.
    buf.push_str(" world");
    assert_eq!(format!("{}", hello), "hello");
}

fn sort() {
    let mut v = vec![1; 20];
    v.push(0);
    v.sort();
}

fn swap() {
    let mut v = vec![1, 2, 3, 4];
    v.swap(2, 2);
}

fn swap_remove() {
    let mut a = 0;
    let mut b = 1;
    let mut vec = vec![&mut a, &mut b];

    vec.swap_remove(1);
}

fn reverse() {
    #[repr(align(2))]
    #[derive(Debug)]
    struct Foo(u8);

    let mut v: Vec<_> = (0..50).map(Foo).collect();
    v.reverse();
    assert!(v[0].0 == 49);
}

fn main() {
    assert_eq!(vec_reallocate().len(), 5);

    assert_eq!(vec_into_iter(), 30);
    assert_eq!(vec_into_iter_rev(), 30);
    vec_iter_and_mut();
    assert_eq!(vec_into_iter_zst(), 0);
    assert_eq!(vec_into_iter_rev_zst(), 0);
    vec_iter_and_mut_rev();

    assert_eq!(make_vec().capacity(), 4);
    assert_eq!(make_vec_macro(), [1, 2]);
    assert_eq!(make_vec_macro_repeat(), [42; 5]);
    assert_eq!(make_vec_macro_repeat_zeroed(), [0; 7]);

    // Test interesting empty slice comparison
    // (one is a real pointer, one an integer pointer).
    assert_eq!((200..-5).step_by(1).collect::<Vec<isize>>(), []);

    // liballoc has a more extensive test of this, but let's at least do a smoke test here.
    vec_push_ptr_stable();
    vec_extend_ptr_stable();
    vec_truncate_ptr_stable();
    push_str_ptr_stable();

    sort();
    swap();
    swap_remove();
    reverse();
}
<|endoftext|>


<commit_before>//! Integration tests for rustfmt.

use std::env;
use std::fs::remove_file;
use std::path::Path;
use std::process::Command;

/// Run the rustfmt executable and return its output.
fn rustfmt(args: &[&str]) -> (String, String) {
    let mut bin_dir = env::current_exe().unwrap();
    bin_dir.pop(); // chop off test exe name
    if bin_dir.ends_with("deps") {
        bin_dir.pop();
    }
    let cmd = bin_dir.join(format!("rustfmt{}", env::consts::EXE_SUFFIX));

    // Ensure the rustfmt binary runs from the local target dir.
    let path = env::var_os("PATH").unwrap_or_default();
    let mut paths = env::split_paths(&path).collect::<Vec<_>>();
    paths.insert(0, bin_dir);
    let new_path = env::join_paths(paths).unwrap();

    match Command::new(&cmd).args(args).env("PATH", new_path).output() {
        Ok(output) => (
            String::from_utf8(output.stdout).expect("utf-8"),
            String::from_utf8(output.stderr).expect("utf-8"),
        ),
        Err(e) => panic!("failed to run `{:?} {:?}`: {}", cmd, args, e),
    }
}

macro_rules! assert_that {
    ($args:expr, $($check:ident $check_args:tt)&&+) => {
        let (stdout, stderr) = rustfmt($args);
        if $(!stdout.$check$check_args && !stderr.$check$check_args)||* {
            panic!(
                "Output not expected for rustfmt {:?}\n\
                 expected: {}\n\
                 actual stdout:\n{}\n\
                 actual stderr:\n{}",
                $args,
                stringify!($( $check$check_args )&&*),
                stdout,
                stderr
            );
        }
    };
}

#[ignore]
#[test]
fn print_config() {
    assert_that!(
        &["--print-config", "unknown"],
        starts_with("Unknown print-config option")
    );
    assert_that!(&["--print-config", "default"], contains("max_width = 100"));
    assert_that!(&["--print-config", "minimal"], contains("PATH required"));
    assert_that!(
        &["--print-config", "minimal", "minimal-config"],
        contains("doesn't work with standard input.")
    );

    let (stdout, stderr) = rustfmt(&[
        "--print-config",
        "minimal",
        "minimal-config",
        "src/shape.rs",
    ]);
    assert!(
        Path::new("minimal-config").exists(),
        "stdout:\n{}\nstderr:\n{}",
        stdout,
        stderr
    );
    remove_file("minimal-config").unwrap();
}

#[ignore]
#[test]
fn inline_config() {
    // single invocation
    assert_that!(
        &[
            "--print-config",
            "current",
            ".",
            "--config=color=Never,edition=2018"
        ],
        contains("color = \"Never\"") && contains("edition = \"2018\"")
    );

    // multiple overriding invocations
    assert_that!(
        &[
            "--print-config",
            "current",
            ".",
            "--config",
            "color=never,edition=2018",
            "--config",
            "color=always,format_strings=true"
        ],
        contains("color = \"Always\"")
            && contains("edition = \"2018\"")
            && contains("format_strings = true")
    );
}

#[test]
fn rustfmt_usage_text() {
    let args = [
        "--help",
    ];
    let (stdout, _) = rustfmt(&args);
    assert!(stdout.contains(&format!("Format Rust code\n\nusage: rustfmt [options] <file>...")));
}
<commit_msg>fix: formatting in new test<commit_after>//! Integration tests for rustfmt.

use std::env;
use std::fs::remove_file;
use std::path::Path;
use std::process::Command;

/// Run the rustfmt executable and return its output.
fn rustfmt(args: &[&str]) -> (String, String) {
    let mut bin_dir = env::current_exe().unwrap();
    bin_dir.pop(); // chop off test exe name
    if bin_dir.ends_with("deps") {
        bin_dir.pop();
    }
    let cmd = bin_dir.join(format!("rustfmt{}", env::consts::EXE_SUFFIX));

    // Ensure the rustfmt binary runs from the local target dir.
    let path = env::var_os("PATH").unwrap_or_default();
    let mut paths = env::split_paths(&path).collect::<Vec<_>>();
    paths.insert(0, bin_dir);
    let new_path = env::join_paths(paths).unwrap();

    match Command::new(&cmd).args(args).env("PATH", new_path).output() {
        Ok(output) => (
            String::from_utf8(output.stdout).expect("utf-8"),
            String::from_utf8(output.stderr).expect("utf-8"),
        ),
        Err(e) => panic!("failed to run `{:?} {:?}`: {}", cmd, args, e),
    }
}

macro_rules! assert_that {
    ($args:expr, $($check:ident $check_args:tt)&&+) => {
        let (stdout, stderr) = rustfmt($args);
        if $(!stdout.$check$check_args && !stderr.$check$check_args)||* {
            panic!(
                "Output not expected for rustfmt {:?}\n\
                 expected: {}\n\
                 actual stdout:\n{}\n\
                 actual stderr:\n{}",
                $args,
                stringify!($( $check$check_args )&&*),
                stdout,
                stderr
            );
        }
    };
}

#[ignore]
#[test]
fn print_config() {
    assert_that!(
        &["--print-config", "unknown"],
        starts_with("Unknown print-config option")
    );
    assert_that!(&["--print-config", "default"], contains("max_width = 100"));
    assert_that!(&["--print-config", "minimal"], contains("PATH required"));
    assert_that!(
        &["--print-config", "minimal", "minimal-config"],
        contains("doesn't work with standard input.")
    );

    let (stdout, stderr) = rustfmt(&[
        "--print-config",
        "minimal",
        "minimal-config",
        "src/shape.rs",
    ]);
    assert!(
        Path::new("minimal-config").exists(),
        "stdout:\n{}\nstderr:\n{}",
        stdout,
        stderr
    );
    remove_file("minimal-config").unwrap();
}

#[ignore]
#[test]
fn inline_config() {
    // single invocation
    assert_that!(
        &[
            "--print-config",
            "current",
            ".",
            "--config=color=Never,edition=2018"
        ],
        contains("color = \"Never\"") && contains("edition = \"2018\"")
    );

    // multiple overriding invocations
    assert_that!(
        &[
            "--print-config",
            "current",
            ".",
            "--config",
            "color=never,edition=2018",
            "--config",
            "color=always,format_strings=true"
        ],
        contains("color = \"Always\"")
            && contains("edition = \"2018\"")
            && contains("format_strings = true")
    );
}

#[test]
fn rustfmt_usage_text() {
    let args = ["--help"];
    let (stdout, _) = rustfmt(&args);
    assert!(stdout.contains("Format Rust code\n\nusage: rustfmt [options] <file>..."));
}
<|endoftext|>


<commit_before>extern crate interval_tree;

use interval_tree::segmentpoint::{SegmentPointTree};

#[test]
fn queries_on_empty() {
    let t = SegmentPointTree::new(0, 10, 0, Box::new(|x: &i64, y: &i64| x + y));

    assert_eq!(t.query(-1), None);
    assert_eq!(t.query(11), None);
    assert_eq!(t.query(1), Some(0));
    assert_eq!(t.query(5), Some(0));
}

#[test]
#[should_panic]
fn invalid_tree() {
    let _ = SegmentPointTree::new(1000, 10, 0, Box::new(|x: &i64, y: &i64| x + y));
}

#[test]
#[should_panic]
fn invalid_insert() {
    let mut t = SegmentPointTree::new(0, 10, 0, Box::new(|x: &i64, y: &i64| x + y));
    t.insert(5, 15, 1);
}

#[test]
fn singleton_tree() {
    let mut t = SegmentPointTree::new(0, 0, 0, Box::new(|x: &i64, y: &i64| x + y));
    t.insert(0, 0, 10);
    assert_eq!(t.query(0), Some(10));
    t.insert(0, 0, 11);
    assert_eq!(t.query(0), Some(21));
    assert_eq!(t.query(1), None);
    assert_eq!(t.query(-11), None);
    assert_eq!(t.bounds(), (0, 0));
}

#[test]
fn small_queries() {
    let mut t = SegmentPointTree::new(0, 10, 0, Box::new(|x: &i32, y: &i32| x + y));
    t.insert(0, 2, 1);
    t.insert(0, 5, 10);
    t.insert(5, 6, 2);
    t.insert(5, 7, 1);
    t.insert(10, 10, 5);
    assert_eq!(t.bounds(), (0, 10));
    let values = vec![11, 11, 11, 10, 10, 13, 3, 1, 0, 0, 5];
    assert_eq!(t.query(-1), None);
    assert_eq!(t.query(11), None);
    assert_eq!(t.query(100), None);
    for (p, v) in (0..10).zip(values) {
        assert_eq!(t.query(p), Some(v));
    }
}

#[test]
fn small_queries_2() {
    let mut t = SegmentPointTree::new(0, 10, 1, Box::new(|x: &i32, y: &i32| x * y));
    t.insert(0, 2, 1);
    t.insert(0, 5, 3);
    t.insert(5, 6, 2);
    t.insert(5, 7, 1);
    t.insert(10, 10, 0);
    assert_eq!(t.bounds(), (0, 10));
    let values = vec![3, 3, 3, 3, 3, 6, 2, 1, 1, 1, 0];
    assert_eq!(t.query(-1), None);
    assert_eq!(t.query(11), None);
    assert_eq!(t.query(100), None);
    for (p, v) in (0..10).zip(values) {
        assert_eq!(t.query(p), Some(v));
    }
}

#[test]
fn small_queries_3() {
    let concat_f = Box::new(|x: &String, y: &String| (x.clone() + &*y).to_string());
    let mut t:SegmentPointTree<i64, String> = SegmentPointTree::new(4, 6, "".to_string(), concat_f);
    assert_eq!(t.bounds(), (4, 6));
    t.insert(4, 5, "a".to_string());
    t.insert(5, 6, "b".to_string());
    t.insert(5, 5, "c".to_string());
    t.insert(6, 6, "x".to_string());
    let values = vec!["a".to_string(), "abc".to_string(), "bx".to_string()];
    assert_eq!(t.query(3), None);
    assert_eq!(t.query(11), None);
    for (p, v) in (4..6).zip(values) {
        assert_eq!(t.query(p), Some(v));
    }
}

<commit_msg>Added bigger test<commit_after>extern crate interval_tree;

use interval_tree::segmentpoint::{SegmentPointTree};

#[test]
fn queries_on_empty() {
    let t = SegmentPointTree::new(0, 10, 0, Box::new(|x: &i64, y: &i64| x + y));

    assert_eq!(t.query(-1), None);
    assert_eq!(t.query(11), None);
    assert_eq!(t.query(1), Some(0));
    assert_eq!(t.query(5), Some(0));
}

#[test]
#[should_panic]
fn invalid_tree() {
    let _ = SegmentPointTree::new(1000, 10, 0, Box::new(|x: &i64, y: &i64| x + y));
}

#[test]
#[should_panic]
fn invalid_insert() {
    let mut t = SegmentPointTree::new(0, 10, 0, Box::new(|x: &i64, y: &i64| x + y));
    t.insert(5, 15, 1);
}

#[test]
fn singleton_tree() {
    let mut t = SegmentPointTree::new(0, 0, 0, Box::new(|x: &i64, y: &i64| x + y));
    t.insert(0, 0, 10);
    assert_eq!(t.query(0), Some(10));
    t.insert(0, 0, 11);
    assert_eq!(t.query(0), Some(21));
    assert_eq!(t.query(1), None);
    assert_eq!(t.query(-11), None);
    assert_eq!(t.bounds(), (0, 0));
}

#[test]
fn small_queries() {
    let mut t = SegmentPointTree::new(0, 10, 0, Box::new(|x: &i32, y: &i32| x + y));
    t.insert(0, 2, 1);
    t.insert(0, 5, 10);
    t.insert(5, 6, 2);
    t.insert(5, 7, 1);
    t.insert(10, 10, 5);
    assert_eq!(t.bounds(), (0, 10));
    let values = vec![11, 11, 11, 10, 10, 13, 3, 1, 0, 0, 5];
    assert_eq!(t.query(-1), None);
    assert_eq!(t.query(11), None);
    assert_eq!(t.query(100), None);
    for (p, v) in (0..10).zip(values) {
        assert_eq!(t.query(p), Some(v));
    }
}

#[test]
fn small_queries_2() {
    let mut t = SegmentPointTree::new(0, 10, 1, Box::new(|x: &i32, y: &i32| x * y));
    t.insert(0, 2, 1);
    t.insert(0, 5, 3);
    t.insert(5, 6, 2);
    t.insert(5, 7, 1);
    t.insert(10, 10, 0);
    assert_eq!(t.bounds(), (0, 10));
    let values = vec![3, 3, 3, 3, 3, 6, 2, 1, 1, 1, 0];
    assert_eq!(t.query(-1), None);
    assert_eq!(t.query(11), None);
    assert_eq!(t.query(100), None);
    for (p, v) in (0..10).zip(values) {
        assert_eq!(t.query(p), Some(v));
    }
}

#[test]
fn small_queries_3() {
    let concat_f = Box::new(|x: &String, y: &String| (x.clone() + &*y).to_string());
    let mut t:SegmentPointTree<i64, String> = SegmentPointTree::new(4, 6, "".to_string(), concat_f);
    assert_eq!(t.bounds(), (4, 6));
    t.insert(4, 5, "a".to_string());
    t.insert(5, 6, "b".to_string());
    t.insert(5, 5, "c".to_string());
    t.insert(6, 6, "x".to_string());
    let values = vec!["a".to_string(), "abc".to_string(), "bx".to_string()];
    assert_eq!(t.query(3), None);
    assert_eq!(t.query(11), None);
    for (p, v) in (4..6).zip(values) {
        assert_eq!(t.query(p), Some(v));
    }
}

#[test]
fn test_big() {
    let mut t = SegmentPointTree::new(0, 1_000_000, 0, Box::new(|x: &i64, y: &i64| x + y));
    assert_eq!(t.bounds(), (0, 1_000_000));
    assert_eq!(t.query(-1), None);
    assert_eq!(t.query(2_000_000), None);
    t.insert(0, 1000, 1000);
    t.insert(1, 1000, 1000);
    t.insert(2, 1000, 1000);
    t.insert(3, 1000, 1000);
    t.insert(4, 1000, 1000);

    assert_eq!(t.query(0), Some(1000));
    assert_eq!(t.query(1), Some(2000));
    assert_eq!(t.query(2), Some(3000));
    assert_eq!(t.query(3), Some(4000));
    assert_eq!(t.query(4), Some(5000));
    assert_eq!(t.query(100), Some(5000));
    assert_eq!(t.query(1000), Some(5000));

    t.insert(2000, 10_000, 2000);
    t.insert(2000, 20_000, 2000);
    t.insert(120_444, 120_444, 8);
    t.insert(3000, 100_000, 2000);
    t.insert(3000, 200_000, 2000);

    assert_eq!(t.query(2000), Some(4000));
    assert_eq!(t.query(3000), Some(8000));
    assert_eq!(t.query(100_000), Some(4000));
    assert_eq!(t.query(120_443), Some(2000));
    assert_eq!(t.query(120_444), Some(2008));
    assert_eq!(t.query(120_445), Some(2000));
    assert_eq!(t.query(200_000), Some(2000));

    assert_eq!(t.query(0), Some(1000));
    assert_eq!(t.query(1_000_000), Some(0));
    assert_eq!(t.query(1_000_001), None);
}
<|endoftext|>


<commit_before>use std::fmt::Debug;
use std::str::{FromStr, from_utf8};
use nom::{IResult, anychar, is_space};

/// Parses a token (i.e. a terminal symbol or a non-terminal symbol).
/// A *token* can be of one of the following two forms:
///
/// * It is a string containing neither of the symbols `'"'`, `' '`, `'-'`, `'→'`, `','`, `';'`, `')'`, `']'`.
/// * It is delimited by the symbol `'"'` on both sides and each occurrence of `'\\'` or `'"'` inside the delimiters is escaped.
pub fn parse_token<A>(input: &[u8]) -> IResult<&[u8], A>
    where A: FromStr,
          A::Err: Debug,
{
    named!(
        parse_token_s<&str>,
        map_res!(
            alt!(
                delimited!(
                    char!('\"'),
                    escaped!(is_not!("\\\""), '\\', anychar),
                    char!('\"')
                ) |
                is_not!(" \"-→,;)]")
            ),
            from_utf8
        )
    );

    parse_token_s(input).map(|x| x.parse().unwrap())
}

/// Parses the `input` into a `Vec<A>` given an `inner_parser` for type `A`, an `opening` delimiter, a `closing` delimiter, and a `separator`.
/// The `inner_parser` must not consume the `separator`s or the `closing` delimiter of the given `input`.
pub fn parse_vec<'a, A, P>(input: &'a [u8], inner_parser: P, opening: &str, closing: &str, separator: &str) -> IResult<&'a [u8], Vec<A>>
    where P: Fn(&'a [u8]) -> IResult<&'a [u8], A>
{
    do_parse!(
        input,
        tag!(opening) >>
            take_while!(is_space) >>
            result: many0!(
                do_parse!(
                    opt!(tag!(separator)) >>
                        take_while!(is_space) >>
                        the_token: inner_parser >>
                        take_while!(is_space) >>
                        (the_token)
                )
            ) >>
            tag!(closing) >>
            (result)
    )
}
/// parses initials of the form `initials: [...]` into a vector of type `N`
pub fn parse_initials<A>(input: &[u8]) -> IResult<&[u8], Vec<A>>
    where A: FromStr,
          A::Err: Debug,
{
    do_parse!(
        input,
        tag!("initial:") >>
            take_while!(is_space) >>
            result: call!(|x| parse_vec(x, parse_token, "[", "]", ",")) >>
            (result)
    )
}
<commit_msg>src/util/parsing.rs: added tests for all functions<commit_after>use nom::{IResult, anychar, is_space};
use std::fmt::Debug;
use std::str::{FromStr, from_utf8};

/// Parses a token (i.e. a terminal symbol or a non-terminal symbol).
/// A *token* can be of one of the following two forms:
///
/// * It is a string containing neither of the symbols `'"'`, `' '`, `'-'`, `'→'`, `','`, `';'`, `')'`, `']'`.
/// * It is delimited by the symbol `'"'` on both sides and each occurrence of `'\\'` or `'"'` inside the delimiters is escaped.
pub fn parse_token<A>(input: &[u8]) -> IResult<&[u8], A>
    where A: FromStr,
          A::Err: Debug,
{
    named!(
        parse_token_s<&str>,
        map_res!(
            alt!(
                delimited!(
                    char!('\"'),
                    escaped!(is_not!("\\\""), '\\', anychar),
                    char!('\"')
                ) |
                is_not!(" \"-→,;)]")
            ),
            from_utf8
        )
    );

    parse_token_s(input).map(|x| x.parse().unwrap())
}

/// Parses the `input` into a `Vec<A>` given an `inner_parser` for type `A`, an `opening` delimiter, a `closing` delimiter, and a `separator`.
/// The `inner_parser` must not consume the `separator`s or the `closing` delimiter of the given `input`.
pub fn parse_vec<'a, A, P>(input: &'a [u8], inner_parser: P, opening: &str, closing: &str, separator: &str) -> IResult<&'a [u8], Vec<A>>
    where P: Fn(&'a [u8]) -> IResult<&'a [u8], A>
{
    do_parse!(
        input,
        tag!(opening) >>
            take_while!(is_space) >>
            result: many0!(
                do_parse!(
                    opt!(tag!(separator)) >>
                        take_while!(is_space) >>
                        the_token: inner_parser >>
                        take_while!(is_space) >>
                        (the_token)
                )
            ) >>
            tag!(closing) >>
            (result)
    )
}
/// parses initials of the form `initials: [...]` into a vector of type `N`
pub fn parse_initials<A>(input: &[u8]) -> IResult<&[u8], Vec<A>>
    where A: FromStr,
          A::Err: Debug,
{
    do_parse!(
        input,
        tag!("initial:") >>
            take_while!(is_space) >>
            result: call!(|x| parse_vec(x, parse_token, "[", "]", ",")) >>
            (result)
    )
}

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

    #[test]
    fn test_parse_token_legal_input() {
        let legal_inputs = vec![
            ("\"a\"xyz", "xyz", String::from("a")),
            ("\"a\\\\b\\\"c\"xyz", "xyz", String::from("a\\\\b\\\"c")),
        ];

        for (legal_input, control_rest, control_parsed) in legal_inputs {
            assert_eq!(
                (control_rest.as_bytes(), control_parsed),
                parse_token::<String>(legal_input.as_bytes()).unwrap()
            );
        }
    }

    #[test]
    fn test_parse_token_illegal_input() {
        let illegal_inputs = vec![
            "\'a\'",
            "\"\"\"",
            "\" \"",
            "\"-\"",
            "\"→\"",
            "\",\"",
            "\";\"",
            "\")\"",
            "\"]\"",
            "\"\\\"",
            " \"a\"",
        ];

        for illegal_input in illegal_inputs {
            match parse_token::<String>(illegal_input.as_bytes()) {
                IResult::Done(_, _) | IResult::Incomplete(_) =>
                    panic!("Was able to parse the illegal input \'{}\'", illegal_input),
                IResult::Error(_) => (),
            }
        }
    }

    #[test]
    fn test_parse_token_incomplete_input() {
        let incomplete_inputs = vec![
            "\"a",
        ];

        for incomplete_input in incomplete_inputs {
            match parse_token::<String>(incomplete_input.as_bytes()) {
                IResult::Done(_, _) | IResult::Error(_) =>
                    panic!("The input was not handled as incomplete: \'{}\'", incomplete_input),
                IResult::Incomplete(_) => (),
            }
        }
    }

    #[test]
    fn test_parse_vec_legal_input() {
        let legal_inputs = vec![
            ("[]xyz", "xyz", vec![]),
            ("[\"a\",\"bc\",\"d\"]xyz", "xyz",
                vec![String::from("a"), String::from("bc"), String::from("d")]),
            ("[  \"a\", \"b\" ,\"c\"]xyz", "xyz",
                vec![String::from("a"), String::from("b"), String::from("c")]),
        ];

        for (legal_input, control_rest, control_parsed) in legal_inputs {
            assert_eq!(
                (control_rest.as_bytes(), control_parsed),
                parse_vec(legal_input.as_bytes(), parse_token, "[", "]", ",").unwrap()
            );
        }
    }

    #[test]
    fn test_parse_vec_illegal_input() {
        let illegal_inputs = vec![
            "(\"a\")xyz",
            "[\"a\"]xyz",
            "[\"a\",\"b\";\"c\")xyz",
            " []xyz",
        ];

        for illegal_input in illegal_inputs {
            match parse_vec::<String, _>(illegal_input.as_bytes(), parse_token, "[", ")", ",") {
                IResult::Done(_, _) | IResult::Incomplete(_) =>
                    panic!("Was able to parse the illegal input \'{}\'", illegal_input),
                IResult::Error(_) => (),
            }
        }
    }

    #[test]
    fn test_parse_vec_incomplete_input() {
        let incomplete_inputs = vec![
            "[\"a\"",
        ];

        for incomplete_input in incomplete_inputs {
            match parse_vec::<String, _>(incomplete_input.as_bytes(), parse_token, "[", "]", ",") {
                IResult::Done(_, _) | IResult::Error(_) =>
                    panic!("The input was not handled as incomplete: \'{}\'", incomplete_input),
                IResult::Incomplete(_) => (),
            }
        }
    }

    #[test]
    fn test_parse_initials_legal_input() {
        let legal_inputs = vec![
            ("initial: [\"a\"]xyz", "xyz", vec![String::from("a")]),
            ("initial:  []xyz", "xyz", vec![]),
        ];

        for (legal_input, control_rest, control_parsed) in legal_inputs {
            assert_eq!(
                (control_rest.as_bytes(), control_parsed),
                parse_initials(legal_input.as_bytes()).unwrap()
            );
        }
    }

    #[test]
    fn test_parse_initials_illegal_input() {
        let illegal_inputs = vec![
            "initials: []xyz",
            " initial: []xyz",
        ];

        for illegal_input in illegal_inputs {
            match parse_initials::<String>(illegal_input.as_bytes()) {
                IResult::Done(_, _) | IResult::Incomplete(_) =>
                    panic!("Was able to parse the illegal input \'{}\'", illegal_input),
                IResult::Error(_) => (),
            }
        }
    }

    #[test]
    fn test_parse_initials_incomplete_input() {
        let incomplete_inputs = vec![
            "init",
            "initial: [",
        ];

        for incomplete_input in incomplete_inputs {
            match parse_initials::<String>(incomplete_input.as_bytes()) {
                IResult::Done(_, _) | IResult::Error(_) =>
                    panic!("The input was not handled as incomplete: \'{}\'", incomplete_input),
                IResult::Incomplete(_) => (),
            }
        }
    }
}
<|endoftext|>


<commit_before>fn main() {
    // `print!` is like `println!` but it doesn't add a newline at the end
    print!("January has ");

    // `{}` are placeholders for arguments that will be stringified
    println!("{} days", 31);
    // Without a suffix, 31 becomes an i32. You can change what type 31 is,
    // with a suffix, and that is covered in the next chapter.

    // The positional arguments can be reused along the template
    println!("{0}, this is {1}. {1}, this is {0}", "Alice", "Bob");

    // Named arguments can also be used
    println!("{subject} {verb} {predicate}",
             predicate="over the lazy dog",
             subject="the quick brown fox",
             verb="jumps");

    // Special formatting can be specified in the placeholder after a `:`
    println!("{} of {:b} people know binary, the other half don't", 1, 2);

    // Error! You are missing an argument
    println!("My name is {0}, {1} {0}", "Bond");
    // FIXME ^ Add the missing argument: "James"
}
<commit_msg>Print adjustments<commit_after>fn main() {
    // `{}` are placeholders for arguments that will be stringified.
    println!("{} days", 31);

    // Without a suffix, 31 becomes an i32. You can change what type 31 is,
    // with a suffix, and that is covered in the next chapter.

    // The positional arguments can be reused along the template.
    println!("{0}, this is {1}. {1}, this is {0}", "Alice", "Bob");

    // Named arguments can also be used.
    println!("{subject} {verb} {predicate}",
             predicate="over the lazy dog",
             subject="the quick brown fox",
             verb="jumps");

    // Special formatting can be specified in the placeholder after a `:`.
    println!("{} of {:b} people know binary, the other half don't", 1, 2);

    // Error! You are missing an argument.
    println!("My name is {0}, {1} {0}", "Bond");
    // FIXME ^ Add the missing argument: "James"
}
<|endoftext|>


<commit_before>//  Copyright (C) 2020 Éloïs SANCHEZ.
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU Affero General Public License as
// published by the Free Software Foundation, either version 3 of the
// License, or (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
// GNU Affero General Public License for more details.
//
// You should have received a copy of the GNU Affero General Public License
// along with this program.  If not, see <https://www.gnu.org/licenses/>.

use crate::*;

fn gen_start_args(args: &DuniterStartArgs, duniter_ts_args: &mut Vec<String>) {
    if args.gva {
        duniter_ts_args.push("--gva".to_owned());
    }
    if let Some(ref keyfile) = args.keyfile {
        duniter_ts_args.push("--keyfile".to_owned());
        duniter_ts_args.push(
            keyfile
                .to_str()
                .expect("keyfile path is invalid")
                .to_owned(),
        );
    }
}

fn gen_webstart_args(args: &DuniterWebstartArgs, duniter_ts_args: &mut Vec<String>) {
    if let Some(ref web_ui_host) = args.web_ui_host {
        duniter_ts_args.push("--webmhost".to_owned());
        duniter_ts_args.push(web_ui_host.into());
    }
    if let Some(ref web_ui_port) = args.web_ui_port {
        duniter_ts_args.push("--webmport".to_owned());
        duniter_ts_args.push(web_ui_port.into());
    }
}

pub(crate) fn gen_duniter_ts_args(args: &DuniterArgs, duniter_js_exe: String) -> Vec<String> {
    let mut duniter_ts_args = Vec::new();
    duniter_ts_args.push(duniter_js_exe);
    if let Some(ref home) = args.home {
        duniter_ts_args.push("--mdb".to_owned());
        duniter_ts_args.push(home.to_str().expect("invalid home path").to_owned());
    }
    if let Some(ref log_level) = args.log {
        duniter_ts_args.push("--loglevel".to_owned());
        duniter_ts_args.push(log_level.to_string().to_lowercase());
    }
    if let Some(ref profile) = args.profile {
        duniter_ts_args.push("--mdb".to_owned());
        duniter_ts_args.push(profile.clone());
    }
    match args.command {
        DuniterCommand::Completions { .. } => unreachable!(),
        DuniterCommand::DirectStart {
            keyprompt,
            ref start_args,
        } => {
            duniter_ts_args.push("direct_start".to_owned());
            if keyprompt {
                duniter_ts_args.push("--keyprompt".to_owned());
            }
            gen_start_args(start_args, &mut duniter_ts_args);
        }
        DuniterCommand::DirectWebstart {
            keyprompt,
            ref start_args,
            ref webstart_args,
        } => {
            duniter_ts_args.push("direct_webstart".to_owned());
            if keyprompt {
                duniter_ts_args.push("--keyprompt".to_owned());
            }
            gen_start_args(start_args, &mut duniter_ts_args);
            gen_webstart_args(webstart_args, &mut duniter_ts_args);
        }
        DuniterCommand::Start(ref start_args) => {
            duniter_ts_args.push("direct_start".to_owned());
            gen_start_args(start_args, &mut duniter_ts_args);
        }
        DuniterCommand::Webstart {
            ref start_args,
            ref webstart_args,
        } => {
            duniter_ts_args.push("direct_webstart".to_owned());
            gen_start_args(start_args, &mut duniter_ts_args);
            gen_webstart_args(webstart_args, &mut duniter_ts_args);
        }
        DuniterCommand::Stop => duniter_ts_args.push("stop".to_owned()),
        DuniterCommand::Sync(ref sync_args) => {
            duniter_ts_args.push("sync".to_owned());
            sync::gen_args(sync_args, &mut duniter_ts_args);
        }
        DuniterCommand::Config(ref config_args) => {
            duniter_ts_args.push("config".to_owned());
            config::gen_args(config_args, &mut duniter_ts_args);
        }
        DuniterCommand::Reset(ref reset_command) => {
            duniter_ts_args.push("reset".to_owned());
            match reset_command {
                ResetCommand::Config => duniter_ts_args.push("config".to_owned()),
                ResetCommand::Data => duniter_ts_args.push("data".to_owned()),
                ResetCommand::Peers => duniter_ts_args.push("peers".to_owned()),
                ResetCommand::Stats => duniter_ts_args.push("stats".to_owned()),
                ResetCommand::All => duniter_ts_args.push("all".to_owned()),
            }
        }
        DuniterCommand::Wizard(ref wizard_command) => {
            duniter_ts_args.push("wizard".to_owned());
            match wizard_command {
                WizardCommand::Bma => duniter_ts_args.push("network".to_owned()),
                WizardCommand::Key { n, r, p } => {
                    duniter_ts_args.push("key".to_owned());
                    if let Some(n) = n {
                        duniter_ts_args.push("--keyN".to_owned());
                        duniter_ts_args.push(n.to_string());
                    }
                    if let Some(r) = r {
                        duniter_ts_args.push("--keyr".to_owned());
                        duniter_ts_args.push(r.to_string());
                    }
                    if let Some(p) = p {
                        duniter_ts_args.push("--keyp".to_owned());
                        duniter_ts_args.push(p.to_string());
                    }
                }
            }
        }
        DuniterCommand::WS2P(ref ws2p_command) => {
            duniter_ts_args.push("ws2p".to_owned());
            match ws2p_command {
                WS2PCommand::ListNodes => duniter_ts_args.push("list-nodes".to_owned()),
                WS2PCommand::ListPrefered => duniter_ts_args.push("list-prefered".to_owned()),
                WS2PCommand::ListPrivileged => duniter_ts_args.push("list-privileged".to_owned()),
                WS2PCommand::ShowConf => duniter_ts_args.push("show-conf".to_owned()),
            }
        }
        DuniterCommand::Logs | DuniterCommand::Restart | DuniterCommand::Status => {}
    }
    duniter_ts_args
}
<commit_msg>[fix] launcher: param --home is not forwarded correctly<commit_after>//  Copyright (C) 2020 Éloïs SANCHEZ.
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU Affero General Public License as
// published by the Free Software Foundation, either version 3 of the
// License, or (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
// GNU Affero General Public License for more details.
//
// You should have received a copy of the GNU Affero General Public License
// along with this program.  If not, see <https://www.gnu.org/licenses/>.

use crate::*;

fn gen_start_args(args: &DuniterStartArgs, duniter_ts_args: &mut Vec<String>) {
    if args.gva {
        duniter_ts_args.push("--gva".to_owned());
    }
    if let Some(ref keyfile) = args.keyfile {
        duniter_ts_args.push("--keyfile".to_owned());
        duniter_ts_args.push(
            keyfile
                .to_str()
                .expect("keyfile path is invalid")
                .to_owned(),
        );
    }
}

fn gen_webstart_args(args: &DuniterWebstartArgs, duniter_ts_args: &mut Vec<String>) {
    if let Some(ref web_ui_host) = args.web_ui_host {
        duniter_ts_args.push("--webmhost".to_owned());
        duniter_ts_args.push(web_ui_host.into());
    }
    if let Some(ref web_ui_port) = args.web_ui_port {
        duniter_ts_args.push("--webmport".to_owned());
        duniter_ts_args.push(web_ui_port.into());
    }
}

pub(crate) fn gen_duniter_ts_args(args: &DuniterArgs, duniter_js_exe: String) -> Vec<String> {
    let mut duniter_ts_args = Vec::new();
    duniter_ts_args.push(duniter_js_exe);
    if let Some(ref home) = args.home {
        duniter_ts_args.push("--home".to_owned());
        duniter_ts_args.push(home.to_str().expect("invalid home path").to_owned());
    }
    if let Some(ref log_level) = args.log {
        duniter_ts_args.push("--loglevel".to_owned());
        duniter_ts_args.push(log_level.to_string().to_lowercase());
    }
    if let Some(ref profile) = args.profile {
        duniter_ts_args.push("--mdb".to_owned());
        duniter_ts_args.push(profile.clone());
    }
    match args.command {
        DuniterCommand::Completions { .. } => unreachable!(),
        DuniterCommand::DirectStart {
            keyprompt,
            ref start_args,
        } => {
            duniter_ts_args.push("direct_start".to_owned());
            if keyprompt {
                duniter_ts_args.push("--keyprompt".to_owned());
            }
            gen_start_args(start_args, &mut duniter_ts_args);
        }
        DuniterCommand::DirectWebstart {
            keyprompt,
            ref start_args,
            ref webstart_args,
        } => {
            duniter_ts_args.push("direct_webstart".to_owned());
            if keyprompt {
                duniter_ts_args.push("--keyprompt".to_owned());
            }
            gen_start_args(start_args, &mut duniter_ts_args);
            gen_webstart_args(webstart_args, &mut duniter_ts_args);
        }
        DuniterCommand::Start(ref start_args) => {
            duniter_ts_args.push("direct_start".to_owned());
            gen_start_args(start_args, &mut duniter_ts_args);
        }
        DuniterCommand::Webstart {
            ref start_args,
            ref webstart_args,
        } => {
            duniter_ts_args.push("direct_webstart".to_owned());
            gen_start_args(start_args, &mut duniter_ts_args);
            gen_webstart_args(webstart_args, &mut duniter_ts_args);
        }
        DuniterCommand::Stop => duniter_ts_args.push("stop".to_owned()),
        DuniterCommand::Sync(ref sync_args) => {
            duniter_ts_args.push("sync".to_owned());
            sync::gen_args(sync_args, &mut duniter_ts_args);
        }
        DuniterCommand::Config(ref config_args) => {
            duniter_ts_args.push("config".to_owned());
            config::gen_args(config_args, &mut duniter_ts_args);
        }
        DuniterCommand::Reset(ref reset_command) => {
            duniter_ts_args.push("reset".to_owned());
            match reset_command {
                ResetCommand::Config => duniter_ts_args.push("config".to_owned()),
                ResetCommand::Data => duniter_ts_args.push("data".to_owned()),
                ResetCommand::Peers => duniter_ts_args.push("peers".to_owned()),
                ResetCommand::Stats => duniter_ts_args.push("stats".to_owned()),
                ResetCommand::All => duniter_ts_args.push("all".to_owned()),
            }
        }
        DuniterCommand::Wizard(ref wizard_command) => {
            duniter_ts_args.push("wizard".to_owned());
            match wizard_command {
                WizardCommand::Bma => duniter_ts_args.push("network".to_owned()),
                WizardCommand::Key { n, r, p } => {
                    duniter_ts_args.push("key".to_owned());
                    if let Some(n) = n {
                        duniter_ts_args.push("--keyN".to_owned());
                        duniter_ts_args.push(n.to_string());
                    }
                    if let Some(r) = r {
                        duniter_ts_args.push("--keyr".to_owned());
                        duniter_ts_args.push(r.to_string());
                    }
                    if let Some(p) = p {
                        duniter_ts_args.push("--keyp".to_owned());
                        duniter_ts_args.push(p.to_string());
                    }
                }
            }
        }
        DuniterCommand::WS2P(ref ws2p_command) => {
            duniter_ts_args.push("ws2p".to_owned());
            match ws2p_command {
                WS2PCommand::ListNodes => duniter_ts_args.push("list-nodes".to_owned()),
                WS2PCommand::ListPrefered => duniter_ts_args.push("list-prefered".to_owned()),
                WS2PCommand::ListPrivileged => duniter_ts_args.push("list-privileged".to_owned()),
                WS2PCommand::ShowConf => duniter_ts_args.push("show-conf".to_owned()),
            }
        }
        DuniterCommand::Logs | DuniterCommand::Restart | DuniterCommand::Status => {}
    }
    duniter_ts_args
}
<|endoftext|>


<commit_before>
// Copyright 2017 The gltf Library Developers
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.

use std::collections::HashMap;
use v2::json::{accessor, material, Extras, Index};

/// Extension specific data for `Mesh`.
#[derive(Clone, Debug, Default, Deserialize, Serialize, Validate)]
pub struct MeshExtensions {
    #[serde(default)]
    _allow_unknown_fields: (),
}

/// A set of primitives to be rendered.
///
/// A node can contain one or more meshes and its transform places the meshes in
/// the scene.
#[derive(Clone, Debug, Deserialize, Serialize, Validate)]
#[serde(deny_unknown_fields)]
pub struct Mesh {
    /// Extension specific data.
    #[serde(default)]
    pub extensions: MeshExtensions,

    /// Optional application specific data.
    #[serde(default)]
    pub extras: Extras,

    /// Optional user-defined name for this object.
    pub name: Option<String>,

    /// Defines the geometry to be renderered with a material.
    pub primitives: Vec<Primitive>,

    /// Defines the weights to be applied to the morph targets.
    pub weights: Option<Vec<f32>>,
}

/// Geometry to be rendered with the given material.
#[derive(Clone, Debug, Deserialize, Serialize, Validate)]
#[serde(deny_unknown_fields)]
pub struct Primitive {
    /// Maps attribute semantic names to the `Accessor`s containing the
    /// corresponding attribute data.
    pub attributes: HashMap<String, Index<accessor::Accessor>>,

    /// Extension specific data.
    #[serde(default)]
    pub extensions: PrimitiveExtensions,

    /// Optional application specific data.
    #[serde(default)]
    pub extras: Extras,

    /// The index of the accessor that contains the indices.
    pub indices: Option<Index<accessor::Accessor>>,

    /// The index of the material to apply to this primitive when rendering
    pub material: Option<Index<material::Material>>,

    /// The type of primitives to render.
    #[serde(default = "primitive_mode_default")]
    pub mode: u32,

    /// An array of Morph Targets, each  Morph Target is a dictionary mapping attributes (only `POSITION`, `NORMAL`, and `TANGENT` supported) to their deviations in the Morph Target.
    pub targets: Option<Vec<HashMap<String, Index<accessor::Accessor>>>>,
}

fn primitive_mode_default() -> u32 {
    4
}

/// Extension specific data for `Primitive`.
#[derive(Clone, Debug, Default, Deserialize, Serialize, Validate)]
pub struct PrimitiveExtensions {
    #[serde(default)]
    _allow_unknown_fields: (),
}
<commit_msg>Added validation for Mesh<commit_after>
// Copyright 2017 The gltf Library Developers
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.

use std::collections::HashMap;
use v2::json::{accessor, material, Extras, Index, Root};
use v2::validation::{Error, JsonPath, Validate};

/// Corresponds to `GL_POINTS`.
pub const POINTS: u32 = 0;

/// Corresponds to `GL_LINES`.
pub const LINES: u32 = 1;

/// Corresponds to `GL_LINE_LOOP`.
pub const LINE_LOOP: u32 = 2;

/// Corresponds to `GL_LINE_STRIP`.
pub const LINE_STRIP: u32 = 3;

/// Corresponds to `GL_TRIANGLES`.
pub const TRIANGLES: u32 = 4;

/// Corresponds to `GL_TRIANGLE_STRIP`.
pub const TRIANGLE_STRIP: u32 = 5;

/// Corresponds to `GL_TRIANGLE_FAN`.
pub const TRIANGLE_FAN: u32 = 6;

/// All valid primitive rendering modes.
pub const VALID_MODES: &'static [u32] = &[
    POINTS,
    LINES,
    LINE_LOOP,
    LINE_STRIP,
    TRIANGLES,
    TRIANGLE_STRIP,
    TRIANGLE_FAN,
];

/// All valid semantic names for Morph targets.
pub const VALID_MORPH_TARGETS: &'static [&'static str] = &[
    "POSITION",
    "NORMAL",
    "TANGENT",
];

/// Extension specific data for `Mesh`.
#[derive(Clone, Debug, Default, Deserialize, Serialize, Validate)]
pub struct MeshExtensions {
    #[serde(default)]
    _allow_unknown_fields: (),
}

/// A set of primitives to be rendered.
///
/// A node can contain one or more meshes and its transform places the meshes in
/// the scene.
#[derive(Clone, Debug, Deserialize, Serialize, Validate)]
#[serde(deny_unknown_fields)]
pub struct Mesh {
    /// Extension specific data.
    #[serde(default)]
    pub extensions: MeshExtensions,

    /// Optional application specific data.
    #[serde(default)]
    pub extras: Extras,

    /// Optional user-defined name for this object.
    pub name: Option<String>,

    /// Defines the geometry to be renderered with a material.
    pub primitives: Vec<Primitive>,

    /// Defines the weights to be applied to the morph targets.
    pub weights: Option<Vec<f32>>,
}

/// Geometry to be rendered with the given material.
#[derive(Clone, Debug, Deserialize, Serialize, Validate)]
#[serde(deny_unknown_fields)]
pub struct Primitive {
    /// Maps attribute semantic names to the `Accessor`s containing the
    /// corresponding attribute data.
    pub attributes: HashMap<String, Index<accessor::Accessor>>,

    /// Extension specific data.
    #[serde(default)]
    pub extensions: PrimitiveExtensions,

    /// Optional application specific data.
    #[serde(default)]
    pub extras: Extras,

    /// The index of the accessor that contains the indices.
    pub indices: Option<Index<accessor::Accessor>>,

    /// The index of the material to apply to this primitive when rendering
    pub material: Option<Index<material::Material>>,

    /// The type of primitives to render.
    #[serde(default)]
    pub mode: Mode,

    /// An array of Morph Targets, each  Morph Target is a dictionary mapping attributes (only `POSITION`, `NORMAL`, and `TANGENT` supported) to their deviations in the Morph Target.
    pub targets: Option<Vec<MorphTargets>>,
}

/// Extension specific data for `Primitive`.
#[derive(Clone, Debug, Default, Deserialize, Serialize, Validate)]
pub struct PrimitiveExtensions {
    #[serde(default)]
    _allow_unknown_fields: (),
}

/// The type of primitives to render.
#[derive(Clone, Copy, Debug, Deserialize, Serialize)]
pub struct Mode(pub u32);

/// A dictionary mapping attributes to their deviations in the Morph Target.
#[derive(Clone, Debug, Deserialize, Serialize)]
pub struct MorphTargets(pub HashMap<String, Index<accessor::Accessor>>);

impl Default for Mode {
    fn default() -> Mode {
        Mode(TRIANGLES)
    }
}

impl Validate for Mode {
    fn validate<F>(&self, _: &Root, path: JsonPath, report: &mut F)
        where F: FnMut(Error)
    {
        if !VALID_MODES.contains(&self.0) {
            report(Error::invalid_value(path, self.0));
        }
    }
}

impl Validate for MorphTargets {
    fn validate<F>(&self, _: &Root, path: JsonPath, report: &mut F)
        where F: FnMut(Error)
    {
        for attribute in self.0.keys() {
            if !VALID_MORPH_TARGETS.contains(&attribute.as_str()) {
                report(Error::invalid_value(path.key(attribute), attribute.clone()));
            }
        }
    }
}
<|endoftext|>


<commit_before>// Copyright 2018 Developers of the Rand project.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// https://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or https://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.
use crate::Error;

extern crate std;
use std::thread_local;

use wasm_bindgen::prelude::*;

enum RngSource {
    Node(NodeCrypto),
    Browser(BrowserCrypto),
}

// JsValues are always per-thread, so we initialize RngSource for each thread.
//   See: https://github.com/rustwasm/wasm-bindgen/pull/955
thread_local!(
    static RNG_SOURCE: Result<RngSource, Error> = getrandom_init();
);

pub(crate) fn getrandom_inner(dest: &mut [u8]) -> Result<(), Error> {
    RNG_SOURCE.with(|result| {
        let source = result.as_ref().map_err(|&e| e)?;

        match source {
            RngSource::Node(n) => {
                if n.random_fill_sync(dest).is_err() {
                    return Err(Error::NODE_RANDOM_FILL_SYNC);
                }
            }
            RngSource::Browser(n) => {
                // see https://developer.mozilla.org/en-US/docs/Web/API/Crypto/getRandomValues
                //
                // where it says:
                //
                // > A QuotaExceededError DOMException is thrown if the
                // > requested length is greater than 65536 bytes.
                for chunk in dest.chunks_mut(65536) {
                    if n.get_random_values(chunk).is_err() {
                        return Err(Error::WEB_GET_RANDOM_VALUES);
                    }
                }
            }
        };
        Ok(())
    })
}

fn getrandom_init() -> Result<RngSource, Error> {
    if let Ok(self_) = Global::get_self() {
        // If `self` is defined then we're in a browser somehow (main window
        // or web worker). We get `self.crypto` (called `msCrypto` on IE), so we
        // can call `crypto.getRandomValues`. If `crypto` isn't defined, we
        // assume we're in an older web browser and the OS RNG isn't available.

        let crypto: BrowserCrypto = match (self_.crypto(), self_.ms_crypto()) {
            (crypto, _) if !crypto.is_undefined() => crypto,
            (_, crypto) if !crypto.is_undefined() => crypto,
            _ => return Err(Error::WEB_CRYPTO),
        };
        return Ok(RngSource::Browser(crypto));
    }

    let crypto = MODULE.require("crypto").map_err(|_| Error::NODE_CRYPTO)?;
    Ok(RngSource::Node(crypto))
}

#[wasm_bindgen]
extern "C" {
    type Global;
    #[wasm_bindgen(getter, catch, static_method_of = Global, js_class = self, js_name = self)]
    fn get_self() -> Result<Self_, JsValue>;

    type Self_;
    #[wasm_bindgen(method, getter, js_name = "msCrypto")]
    fn ms_crypto(me: &Self_) -> BrowserCrypto;
    #[wasm_bindgen(method, getter)]
    fn crypto(me: &Self_) -> BrowserCrypto;

    type BrowserCrypto;
    #[wasm_bindgen(method, js_name = getRandomValues, catch)]
    fn get_random_values(me: &BrowserCrypto, buf: &mut [u8]) -> Result<(), JsValue>;

    #[wasm_bindgen(js_name = module)]
    static MODULE: NodeModule;

    type NodeModule;
    #[wasm_bindgen(method, catch)]
    fn require(this: &NodeModule, s: &str) -> Result<NodeCrypto, JsValue>;

    type NodeCrypto;
    #[wasm_bindgen(method, js_name = randomFillSync, catch)]
    fn random_fill_sync(crypto: &NodeCrypto, buf: &mut [u8]) -> Result<(), JsValue>;
}
<commit_msg>rustfmt: Run cargo fmt<commit_after>// Copyright 2018 Developers of the Rand project.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// https://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or https://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.
use crate::Error;

extern crate std;
use std::thread_local;

use wasm_bindgen::prelude::*;

enum RngSource {
    Node(NodeCrypto),
    Browser(BrowserCrypto),
}

// JsValues are always per-thread, so we initialize RngSource for each thread.
//   See: https://github.com/rustwasm/wasm-bindgen/pull/955
thread_local!(
    static RNG_SOURCE: Result<RngSource, Error> = getrandom_init();
);

pub(crate) fn getrandom_inner(dest: &mut [u8]) -> Result<(), Error> {
    RNG_SOURCE.with(|result| {
        let source = result.as_ref().map_err(|&e| e)?;

        match source {
            RngSource::Node(n) => {
                if n.random_fill_sync(dest).is_err() {
                    return Err(Error::NODE_RANDOM_FILL_SYNC);
                }
            }
            RngSource::Browser(n) => {
                // see https://developer.mozilla.org/en-US/docs/Web/API/Crypto/getRandomValues
                //
                // where it says:
                //
                // > A QuotaExceededError DOMException is thrown if the
                // > requested length is greater than 65536 bytes.
                for chunk in dest.chunks_mut(65536) {
                    if n.get_random_values(chunk).is_err() {
                        return Err(Error::WEB_GET_RANDOM_VALUES);
                    }
                }
            }
        };
        Ok(())
    })
}

fn getrandom_init() -> Result<RngSource, Error> {
    if let Ok(self_) = Global::get_self() {
        // If `self` is defined then we're in a browser somehow (main window
        // or web worker). We get `self.crypto` (called `msCrypto` on IE), so we
        // can call `crypto.getRandomValues`. If `crypto` isn't defined, we
        // assume we're in an older web browser and the OS RNG isn't available.

        let crypto: BrowserCrypto = match (self_.crypto(), self_.ms_crypto()) {
            (crypto, _) if !crypto.is_undefined() => crypto,
            (_, crypto) if !crypto.is_undefined() => crypto,
            _ => return Err(Error::WEB_CRYPTO),
        };
        return Ok(RngSource::Browser(crypto));
    }

    let crypto = MODULE.require("crypto").map_err(|_| Error::NODE_CRYPTO)?;
    Ok(RngSource::Node(crypto))
}

#[wasm_bindgen]
extern "C" {
    type Global;
    #[wasm_bindgen(getter, catch, static_method_of = Global, js_class = self, js_name = self)]
    fn get_self() -> Result<Self_, JsValue>;

    type Self_;
    #[wasm_bindgen(method, getter, js_name = "msCrypto")]
    fn ms_crypto(me: &Self_) -> BrowserCrypto;
    #[wasm_bindgen(method, getter)]
    fn crypto(me: &Self_) -> BrowserCrypto;

    type BrowserCrypto;
    #[wasm_bindgen(method, js_name = getRandomValues, catch)]
    fn get_random_values(me: &BrowserCrypto, buf: &mut [u8]) -> Result<(), JsValue>;

    #[wasm_bindgen(js_name = module)]
    static MODULE: NodeModule;

    type NodeModule;
    #[wasm_bindgen(method, catch)]
    fn require(this: &NodeModule, s: &str) -> Result<NodeCrypto, JsValue>;

    type NodeCrypto;
    #[wasm_bindgen(method, js_name = randomFillSync, catch)]
    fn random_fill_sync(crypto: &NodeCrypto, buf: &mut [u8]) -> Result<(), JsValue>;
}
<|endoftext|>


<commit_before>// See LICENSE file for copyright and license details.

use extra::json;
use serialize::Decodable;
use glfw;
use gl;
use gl::types::{
  GLfloat,
  GLint,
  GLuint,
};
use cgmath::vector::{
  Vec3,
  Vec2,
};
use glh = gl_helpers;
use camera::Camera;
use map::TileIterator;
use geom::Geom;
use tile_picker::TilePicker;
use obj;
use mesh::Mesh;
use misc::read_file;

pub struct Visualizer {
  program: GLuint,
  map_mesh: Mesh,
  unit_mesh: Mesh,
  mat_id: GLint,
  win: Option<glfw::Window>,
  mouse_pos: Vec2<f32>,
  camera: Camera,
  picker: TilePicker,
  selected_tile_pos: Option<Vec2<i32>>,
  geom: Geom,
}

fn init_win(win_size: Vec2<int>) -> glfw::Window {
  glfw::set_error_callback(~glfw::LogErrorHandler);
  let init_status = glfw::init();
  if !init_status.is_ok() {
    fail!("Failed to initialize GLFW");
  }
  let win = glfw::Window::create(
    win_size.x as u32,
    win_size.y as u32,
    "OpenGL",
    glfw::Windowed,
  ).unwrap();
  win.make_context_current();
  win.set_cursor_pos_polling(true);
  win.set_key_polling(true);
  win
}

#[deriving(Decodable)]
struct Size2<T> {
  x: T,
  y: T,
}

fn read_win_size(config_path: &str) -> Vec2<int> {
  let path = Path::new(config_path);
  let json = json::from_str(read_file(&path)).unwrap();
  let mut decoder = json::Decoder::new(json);
  let size: Size2<int> = Decodable::decode(&mut decoder);
  Vec2{x: size.x, y: size.y}
}

impl Visualizer {
  pub fn new() -> ~Visualizer {
    let win_size = read_win_size("config.json");
    let win = init_win(win_size);
    let geom = Geom::new();
    let mut vis = ~Visualizer {
      program: 0,
      map_mesh: Mesh::new(),
      unit_mesh: Mesh::new(),
      mat_id: 0,
      win: Some(win),
      mouse_pos: Vec2::zero(),
      camera: Camera::new(),
      picker: TilePicker::new(),
      selected_tile_pos: None,
      geom: geom,
    };
    vis.init_opengl();
    vis.picker.init(&geom);
    vis.init_models();
    vis
  }

  fn win<'a>(&'a self) -> &'a glfw::Window {
    self.win.get_ref()
  }

  fn build_hex_mesh(&self) -> ~[Vec3<GLfloat>] {
    let mut vertex_data = ~[];
    for tile_pos in TileIterator::new() {
      let pos3d = self.geom.v2i_to_v2f(tile_pos).extend(0.0);
      for num in range(0, 6) {
        let vertex = self.geom.index_to_hex_vertex(num);
        let next_vertex = self.geom.index_to_hex_vertex(num + 1);
        let data = &mut vertex_data;
        data.push(pos3d + vertex.extend(0.0));
        data.push(pos3d + next_vertex.extend(0.0));
        data.push(pos3d + Vec3::zero());
      }
    }
    vertex_data
  }

  fn init_models(&mut self) {
    self.program = glh::compile_program(
      read_file(&Path::new("normal.vs.glsl")),
      read_file(&Path::new("normal.fs.glsl")),
    );
    gl::UseProgram(self.program);
    self.mat_id = glh::get_uniform(self.program, "mvp_mat");
    let pos_attr = glh::get_attr(self.program, "position");
    glh::vertex_attrib_pointer(pos_attr);
    let map_vertex_data = self.build_hex_mesh();
    self.map_mesh.init(map_vertex_data);
    let unit_obj = obj::Model::new("tank.obj");
    self.unit_mesh.init(unit_obj.build());
  }

  fn init_opengl(&mut self) {
    gl::load_with(glfw::get_proc_address);
  }

  fn cleanup_opengl(&self) {
    gl::DeleteProgram(self.program);
  }

  fn draw(&self) {
    gl::ClearColor(0.3, 0.3, 0.3, 1.0);
    gl::Clear(gl::COLOR_BUFFER_BIT);
    gl::UseProgram(self.program);
    glh::uniform_mat4f(self.mat_id, &self.camera.mat());
    self.map_mesh.draw(self.program);
    self.unit_mesh.draw(self.program);
    self.win().swap_buffers();
  }

  pub fn is_running(&self) -> bool {
    return !self.win().should_close()
  }

  fn handle_key_event(&mut self, key: glfw::Key) {
    match key {
      glfw::KeyEscape | glfw::KeyQ => {
        self.win().set_should_close(true);
      },
      glfw::KeySpace => println!("space"),
      glfw::KeyUp => self.camera.move(270.0),
      glfw::KeyDown => self.camera.move(90.0),
      glfw::KeyRight => self.camera.move(0.0),
      glfw::KeyLeft => self.camera.move(180.0),
      _ => {},
    }
  }

  fn handle_cursor_pos_event(&mut self, pos: Vec2<f32>) {
    let button = self.win().get_mouse_button(glfw::MouseButtonRight);
    if button == glfw::Press {
      self.camera.z_angle += self.mouse_pos.x - pos.x;
      self.camera.x_angle += self.mouse_pos.y - pos.y;
    }
    self.mouse_pos = pos;
  }

  fn get_events(&mut self) -> ~[glfw::WindowEvent]{
    glfw::poll_events();
    let mut events = ~[];
    for (_, event) in self.win().flush_events() {
      events.push(event);
    }
    events
  }

  fn handle_event(&mut self, event: glfw::WindowEvent) {
    match event {
      glfw::KeyEvent(key, _, glfw::Press, _) => {
        self.handle_key_event(key);
      },
      glfw::CursorPosEvent(x, y) => {
        let p = Vec2{x: x as f32, y: y as f32};
        self.handle_cursor_pos_event(p);
      },
      _ => {},
    }
  }

  fn handle_events(&mut self) {
    for event in self.get_events().iter() {
      self.handle_event(*event);
    }
  }

  fn close_window(&mut self) {
    // destroy glfw::Window before terminating glfw
    self.win = None;
  }

  fn pick_tile(&mut self) {
    let mouse_pos = Vec2 {
      x: self.mouse_pos.x as i32,
      y: self.mouse_pos.y as i32,
    };
    let win_size = self.win().get_size();
    self.selected_tile_pos = self.picker.pick_tile(
      win_size, &self.camera, mouse_pos);
    println!("selected: {:?}", self.selected_tile_pos);
  }

  pub fn tick(&mut self) {
    self.handle_events();
    self.pick_tile();
    self.draw();
  }
}

impl Drop for Visualizer {
  fn drop(&mut self) {
    self.cleanup_opengl();
    self.close_window();
    glfw::terminate();
  }
}

// vim: set tabstop=2 shiftwidth=2 softtabstop=2 expandtab:
<commit_msg>Visualizer: win.set_all_polling(true)<commit_after>// See LICENSE file for copyright and license details.

use extra::json;
use serialize::Decodable;
use glfw;
use gl;
use gl::types::{
  GLfloat,
  GLint,
  GLuint,
};
use cgmath::vector::{
  Vec3,
  Vec2,
};
use glh = gl_helpers;
use camera::Camera;
use map::TileIterator;
use geom::Geom;
use tile_picker::TilePicker;
use obj;
use mesh::Mesh;
use misc::read_file;

pub struct Visualizer {
  program: GLuint,
  map_mesh: Mesh,
  unit_mesh: Mesh,
  mat_id: GLint,
  win: Option<glfw::Window>,
  mouse_pos: Vec2<f32>,
  camera: Camera,
  picker: TilePicker,
  selected_tile_pos: Option<Vec2<i32>>,
  geom: Geom,
}

fn init_win(win_size: Vec2<int>) -> glfw::Window {
  glfw::set_error_callback(~glfw::LogErrorHandler);
  let init_status = glfw::init();
  if !init_status.is_ok() {
    fail!("Failed to initialize GLFW");
  }
  let win = glfw::Window::create(
    win_size.x as u32,
    win_size.y as u32,
    "OpenGL",
    glfw::Windowed,
  ).unwrap();
  win.make_context_current();
  win.set_all_polling(true);
  win
}

#[deriving(Decodable)]
struct Size2<T> {
  x: T,
  y: T,
}

fn read_win_size(config_path: &str) -> Vec2<int> {
  let path = Path::new(config_path);
  let json = json::from_str(read_file(&path)).unwrap();
  let mut decoder = json::Decoder::new(json);
  let size: Size2<int> = Decodable::decode(&mut decoder);
  Vec2{x: size.x, y: size.y}
}

impl Visualizer {
  pub fn new() -> ~Visualizer {
    let win_size = read_win_size("config.json");
    let win = init_win(win_size);
    let geom = Geom::new();
    let mut vis = ~Visualizer {
      program: 0,
      map_mesh: Mesh::new(),
      unit_mesh: Mesh::new(),
      mat_id: 0,
      win: Some(win),
      mouse_pos: Vec2::zero(),
      camera: Camera::new(),
      picker: TilePicker::new(),
      selected_tile_pos: None,
      geom: geom,
    };
    vis.init_opengl();
    vis.picker.init(&geom);
    vis.init_models();
    vis
  }

  fn win<'a>(&'a self) -> &'a glfw::Window {
    self.win.get_ref()
  }

  fn build_hex_mesh(&self) -> ~[Vec3<GLfloat>] {
    let mut vertex_data = ~[];
    for tile_pos in TileIterator::new() {
      let pos3d = self.geom.v2i_to_v2f(tile_pos).extend(0.0);
      for num in range(0, 6) {
        let vertex = self.geom.index_to_hex_vertex(num);
        let next_vertex = self.geom.index_to_hex_vertex(num + 1);
        let data = &mut vertex_data;
        data.push(pos3d + vertex.extend(0.0));
        data.push(pos3d + next_vertex.extend(0.0));
        data.push(pos3d + Vec3::zero());
      }
    }
    vertex_data
  }

  fn init_models(&mut self) {
    self.program = glh::compile_program(
      read_file(&Path::new("normal.vs.glsl")),
      read_file(&Path::new("normal.fs.glsl")),
    );
    gl::UseProgram(self.program);
    self.mat_id = glh::get_uniform(self.program, "mvp_mat");
    let pos_attr = glh::get_attr(self.program, "position");
    glh::vertex_attrib_pointer(pos_attr);
    let map_vertex_data = self.build_hex_mesh();
    self.map_mesh.init(map_vertex_data);
    let unit_obj = obj::Model::new("tank.obj");
    self.unit_mesh.init(unit_obj.build());
  }

  fn init_opengl(&mut self) {
    gl::load_with(glfw::get_proc_address);
  }

  fn cleanup_opengl(&self) {
    gl::DeleteProgram(self.program);
  }

  fn draw(&self) {
    gl::ClearColor(0.3, 0.3, 0.3, 1.0);
    gl::Clear(gl::COLOR_BUFFER_BIT);
    gl::UseProgram(self.program);
    glh::uniform_mat4f(self.mat_id, &self.camera.mat());
    self.map_mesh.draw(self.program);
    self.unit_mesh.draw(self.program);
    self.win().swap_buffers();
  }

  pub fn is_running(&self) -> bool {
    return !self.win().should_close()
  }

  fn handle_key_event(&mut self, key: glfw::Key) {
    match key {
      glfw::KeyEscape | glfw::KeyQ => {
        self.win().set_should_close(true);
      },
      glfw::KeySpace => println!("space"),
      glfw::KeyUp => self.camera.move(270.0),
      glfw::KeyDown => self.camera.move(90.0),
      glfw::KeyRight => self.camera.move(0.0),
      glfw::KeyLeft => self.camera.move(180.0),
      _ => {},
    }
  }

  fn handle_cursor_pos_event(&mut self, pos: Vec2<f32>) {
    let button = self.win().get_mouse_button(glfw::MouseButtonRight);
    if button == glfw::Press {
      self.camera.z_angle += self.mouse_pos.x - pos.x;
      self.camera.x_angle += self.mouse_pos.y - pos.y;
    }
    self.mouse_pos = pos;
  }

  fn get_events(&mut self) -> ~[glfw::WindowEvent]{
    glfw::poll_events();
    let mut events = ~[];
    for (_, event) in self.win().flush_events() {
      events.push(event);
    }
    events
  }

  fn handle_event(&mut self, event: glfw::WindowEvent) {
    match event {
      glfw::KeyEvent(key, _, glfw::Press, _) => {
        self.handle_key_event(key);
      },
      glfw::CursorPosEvent(x, y) => {
        let p = Vec2{x: x as f32, y: y as f32};
        self.handle_cursor_pos_event(p);
      },
      _ => {},
    }
  }

  fn handle_events(&mut self) {
    for event in self.get_events().iter() {
      self.handle_event(*event);
    }
  }

  fn close_window(&mut self) {
    // destroy glfw::Window before terminating glfw
    self.win = None;
  }

  fn pick_tile(&mut self) {
    let mouse_pos = Vec2 {
      x: self.mouse_pos.x as i32,
      y: self.mouse_pos.y as i32,
    };
    let win_size = self.win().get_size();
    self.selected_tile_pos = self.picker.pick_tile(
      win_size, &self.camera, mouse_pos);
    println!("selected: {:?}", self.selected_tile_pos);
  }

  pub fn tick(&mut self) {
    self.handle_events();
    self.pick_tile();
    self.draw();
  }
}

impl Drop for Visualizer {
  fn drop(&mut self) {
    self.cleanup_opengl();
    self.close_window();
    glfw::terminate();
  }
}

// vim: set tabstop=2 shiftwidth=2 softtabstop=2 expandtab:
<|endoftext|>


<commit_before>#[cfg(test)]
extern crate quickcheck;
#[cfg(test)]
#[macro_use]
extern crate quickcheck_macros;

use std::iter::range_inclusive;
use std::cmp::min;

use Base32Type::{RFC4648Base32, CrockfordBase32, UnpaddedRFC4648Base32};

use std::ascii::AsciiExt;

#[derive(Copy)]
pub enum Base32Type {
    // Not sure if it's better to just have an additional `padding: bool`
    // argument to the encode function
    RFC4648Base32, CrockfordBase32, UnpaddedRFC4648Base32
}

const RFC4648_ALPHABET: &'static [u8]   = b"ABCDEFGHIJKLMNOPQRSTUVWXYZ234567";
const CROCKFORD_ALPHABET: &'static [u8] = b"0123456789ABCDEFGHJKMNPQRSTVWXYZ";

pub fn encode(base32_type: Base32Type, data: &[u8]) -> String {
    let alphabet = match base32_type {
        RFC4648Base32 | UnpaddedRFC4648Base32 => RFC4648_ALPHABET,
        CrockfordBase32 => CROCKFORD_ALPHABET
    };
    let mut ret = Vec::with_capacity((data.len()+3)/4*5);

    for chunk in data.chunks(5) {
        let buf = {
            let mut buf = [0u8; 5];
            buf.clone_from_slice(chunk);
            buf
        };
        ret.push(alphabet[((buf[0] & 0xF8) >> 3) as usize]);
        ret.push(alphabet[(((buf[0] & 0x07) << 2) | ((buf[1] & 0xC0) >> 6)) as usize]);
        ret.push(alphabet[((buf[1] & 0x3E) >> 1) as usize]);
        ret.push(alphabet[(((buf[1] & 0x01) << 4) | ((buf[2] & 0xF0) >> 4)) as usize]);
        ret.push(alphabet[(((buf[2] & 0x0F) << 1) | (buf[3] >> 7)) as usize]);
        ret.push(alphabet[((buf[3] & 0x7C) >> 2) as usize]);
        ret.push(alphabet[(((buf[3] & 0x03) << 3) | ((buf[4] & 0xE0) >> 5)) as usize]);
        ret.push(alphabet[(buf[4] & 0x1F) as usize]);
    }

    if data.len() % 5 != 0 {
        let len = ret.len();
        let num_extra = 8-(data.len()%5*8+4)/5;
        match base32_type {
            UnpaddedRFC4648Base32 | CrockfordBase32 => {
                ret.truncate(len-num_extra);
            }
            RFC4648Base32 => {
                for i in range_inclusive(1, num_extra) {
                    ret[len-i] = b'=';
                }
            }
        }
    }

    String::from_utf8(ret).unwrap()
}

const RFC4648_INV_ALPHABET: [u8; 43] = [-1, -1, 26, 27, 28, 29, 30, 31, -1, -1, -1, -1, -1, 0, -1, -1, -1, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25];

const CROCKFORD_INV_ALPHABET: [u8; 43] = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, -1, -1, -1, -1, -1, -1, -1, 10, 11, 12, 13, 14, 15, 16, 17, 1, 18, 19, 1, 20, 21, 0, 22, 23, 24, 25, 26, -1, 27, 28, 29, 30, 31];

pub fn decode(base32_type: Base32Type, data: &str) -> Option<Vec<u8>> {
    if !data.is_ascii() {
        return None;
    }
    let data = data.as_bytes();
    let alphabet = match base32_type {
        RFC4648Base32 | UnpaddedRFC4648Base32 => RFC4648_INV_ALPHABET,
        CrockfordBase32 => CROCKFORD_INV_ALPHABET
    };
    let mut unpadded_data_length = data.len();
    for i in range_inclusive(1, min(6, data.len())) {
        if data[data.len() - i] != b'=' {
            break;
        }
        unpadded_data_length -= 1;
    }
    let output_length = unpadded_data_length*5/8;
    let mut ret = Vec::with_capacity((output_length+4)/5*5);
    for chunk in data.chunks(8) {
        let buf = {
            let mut buf = [0u8; 8];
            for (i, &c) in chunk.iter().enumerate() {
                match alphabet.get((c.to_ascii_uppercase()-b'0') as usize) {
                    Some(&-1) | None => return None,
                    Some(&value) => buf[i] = value,
                };
            }
            buf
        };
        ret.push((buf[0] << 3) | (buf[1] >> 2));
        ret.push((buf[1] << 6) | (buf[2] << 1) | (buf[3] >> 4));
        ret.push((buf[3] << 4) | (buf[4] >> 1));
        ret.push((buf[4] << 7) | (buf[5] << 2) | (buf[6] >> 3));
        ret.push((buf[6] << 5) | buf[7]);
    }
    ret.truncate(output_length);
    Some(ret)
}

#[cfg(test)]
mod test {
    extern crate test;
    use super::{encode, decode};
    use super::Base32Type::{CrockfordBase32, RFC4648Base32, UnpaddedRFC4648Base32};
    use quickcheck;
    use std;
    use std::rand::distributions::IndependentSample;
    use std::ascii::AsciiExt;

    #[derive(Clone)]
    struct B32 {
        c: u8
    }

    impl quickcheck::Arbitrary for B32 {
        fn arbitrary<G: quickcheck::Gen>(g: &mut G) -> B32 {
            let alphabet = b"0123456789ABCDEFGHJKMNPQRSTVWXYZ";
            B32 {
                c: alphabet[std::rand::distributions::Range::new(0, alphabet.len()).ind_sample(g)]
            }
        }
    }

    impl std::fmt::Show for B32 {
        fn fmt(&self, f: &mut std::fmt::Formatter) -> Result<(), std::fmt::Error> {
            self.c.fmt(f)
        }
    }

    #[test]
    fn masks_crockford() {
        assert_eq!(encode(CrockfordBase32, &[0xF8, 0x3E, 0x0F, 0x83, 0xE0]), "Z0Z0Z0Z0");
        assert_eq!(encode(CrockfordBase32, &[0x07, 0xC1, 0xF0, 0x7C, 0x1F]), "0Z0Z0Z0Z");
        assert_eq!(decode(CrockfordBase32, "Z0Z0Z0Z0").unwrap(), [0xF8, 0x3E, 0x0F, 0x83, 0xE0]);
        assert_eq!(decode(CrockfordBase32, "0Z0Z0Z0Z").unwrap(), [0x07, 0xC1, 0xF0, 0x7C, 0x1F]);
    }

    #[test]
    fn masks_rfc4648() {
        assert_eq!(encode(RFC4648Base32, &[0xF8, 0x3E, 0x7F, 0x83, 0xE7]), "7A7H7A7H");
        assert_eq!(encode(RFC4648Base32, &[0x77, 0xC1, 0xF7, 0x7C, 0x1F]), "O7A7O7A7");
        assert_eq!(decode(RFC4648Base32, "7A7H7A7H").unwrap(), [0xF8, 0x3E, 0x7F, 0x83, 0xE7]);
        assert_eq!(decode(RFC4648Base32, "O7A7O7A7").unwrap(), [0x77, 0xC1, 0xF7, 0x7C, 0x1F]);
        assert_eq!(encode(RFC4648Base32, &[0xF8, 0x3E, 0x7F, 0x83]), "7A7H7AY=");
    }

    #[test]
    fn masks_unpadded_rfc4648() {
        assert_eq!(encode(UnpaddedRFC4648Base32, &[0xF8, 0x3E, 0x7F, 0x83, 0xE7]), "7A7H7A7H");
        assert_eq!(encode(UnpaddedRFC4648Base32, &[0x77, 0xC1, 0xF7, 0x7C, 0x1F]), "O7A7O7A7");
        assert_eq!(decode(UnpaddedRFC4648Base32, "7A7H7A7H").unwrap(), [0xF8, 0x3E, 0x7F, 0x83, 0xE7]);
        assert_eq!(decode(UnpaddedRFC4648Base32, "O7A7O7A7").unwrap(), [0x77, 0xC1, 0xF7, 0x7C, 0x1F]);
        assert_eq!(encode(UnpaddedRFC4648Base32, &[0xF8, 0x3E, 0x7F, 0x83]), "7A7H7AY");
    }

    #[test]
    fn padding() {
        let num_padding = [0u, 6, 4, 3, 1];
        for i in range(1u, 6) {
            println!("Checking padding for length == {}", i);
            let encoded = encode(RFC4648Base32, range(0u8, i as u8).collect::<Vec<u8>>().as_slice());
            assert_eq!(encoded.len(), 8u);
            for j in range(0u, num_padding[i % 5]) {
                println!("Making sure index {} is padding", encoded.len()-j-1);
                assert_eq!(encoded.as_bytes()[encoded.len()-j-1], b'=');
            }
            for j in range(0u, 8 - num_padding[i % 5]) {
                println!("Making sure index {} is not padding", j);
                assert!(encoded.as_bytes()[j] != b'=');
            }
        }
    }

    #[quickcheck]
    fn invertible_crockford(data: Vec<u8>) -> bool {
        decode(CrockfordBase32, encode(CrockfordBase32, data.as_slice()).as_slice()).unwrap() == data
    }

    #[quickcheck]
    fn invertible_rfc4648(data: Vec<u8>) -> bool {
        decode(RFC4648Base32, encode(RFC4648Base32, data.as_slice()).as_slice()).unwrap() == data
    }
    #[quickcheck]
    fn invertible_unpadded_rfc4648(data: Vec<u8>) -> bool {
        decode(UnpaddedRFC4648Base32, encode(UnpaddedRFC4648Base32, data.as_slice()).as_slice()).unwrap() == data
    }

    #[quickcheck]
    fn lower_case(data: Vec<B32>) -> bool {
        let data: String = data.iter().map(|e| e.c as char).collect();
        decode(CrockfordBase32, data.as_slice()) == decode(CrockfordBase32, data.as_slice().to_ascii_lowercase().as_slice())
    }

    #[test]
    #[allow(non_snake_case)]
    fn iIlL1_oO0() {
        assert_eq!(decode(CrockfordBase32, "IiLlOo"), decode(CrockfordBase32, "111100"));
    }

    #[test]
    fn invalid_chars_crockford() {
        assert_eq!(decode(CrockfordBase32, ","), None)
    }

    #[test]
    fn invalid_chars_rfc4648() {
        assert_eq!(decode(RFC4648Base32, ","), None)
    }

    #[test]
    fn invalid_chars_unpadded_rfc4648() {
        assert_eq!(decode(UnpaddedRFC4648Base32, ","), None)
    }

    #[bench]
    fn bench_encode(b: &mut test::Bencher) {
        let data = [0, 0, 0, 0, 0];
        b.iter(|| encode(CrockfordBase32, data.as_slice()));
        b.bytes = data.len() as u64;
    }

    #[bench]
    fn bench_decode(b: &mut test::Bencher) {
        let data = "00000000";
        b.iter(|| decode(CrockfordBase32, data));
        b.bytes = data.len() as u64;
    }
}
<commit_msg>`Show` -> `Display`<commit_after>#[cfg(test)]
extern crate quickcheck;
#[cfg(test)]
#[macro_use]
extern crate quickcheck_macros;

use std::iter::range_inclusive;
use std::cmp::min;

use Base32Type::{RFC4648Base32, CrockfordBase32, UnpaddedRFC4648Base32};

use std::ascii::AsciiExt;

#[derive(Copy)]
pub enum Base32Type {
    // Not sure if it's better to just have an additional `padding: bool`
    // argument to the encode function
    RFC4648Base32, CrockfordBase32, UnpaddedRFC4648Base32
}

const RFC4648_ALPHABET: &'static [u8]   = b"ABCDEFGHIJKLMNOPQRSTUVWXYZ234567";
const CROCKFORD_ALPHABET: &'static [u8] = b"0123456789ABCDEFGHJKMNPQRSTVWXYZ";

pub fn encode(base32_type: Base32Type, data: &[u8]) -> String {
    let alphabet = match base32_type {
        RFC4648Base32 | UnpaddedRFC4648Base32 => RFC4648_ALPHABET,
        CrockfordBase32 => CROCKFORD_ALPHABET
    };
    let mut ret = Vec::with_capacity((data.len()+3)/4*5);

    for chunk in data.chunks(5) {
        let buf = {
            let mut buf = [0u8; 5];
            buf.clone_from_slice(chunk);
            buf
        };
        ret.push(alphabet[((buf[0] & 0xF8) >> 3) as usize]);
        ret.push(alphabet[(((buf[0] & 0x07) << 2) | ((buf[1] & 0xC0) >> 6)) as usize]);
        ret.push(alphabet[((buf[1] & 0x3E) >> 1) as usize]);
        ret.push(alphabet[(((buf[1] & 0x01) << 4) | ((buf[2] & 0xF0) >> 4)) as usize]);
        ret.push(alphabet[(((buf[2] & 0x0F) << 1) | (buf[3] >> 7)) as usize]);
        ret.push(alphabet[((buf[3] & 0x7C) >> 2) as usize]);
        ret.push(alphabet[(((buf[3] & 0x03) << 3) | ((buf[4] & 0xE0) >> 5)) as usize]);
        ret.push(alphabet[(buf[4] & 0x1F) as usize]);
    }

    if data.len() % 5 != 0 {
        let len = ret.len();
        let num_extra = 8-(data.len()%5*8+4)/5;
        match base32_type {
            UnpaddedRFC4648Base32 | CrockfordBase32 => {
                ret.truncate(len-num_extra);
            }
            RFC4648Base32 => {
                for i in range_inclusive(1, num_extra) {
                    ret[len-i] = b'=';
                }
            }
        }
    }

    String::from_utf8(ret).unwrap()
}

const RFC4648_INV_ALPHABET: [u8; 43] = [-1, -1, 26, 27, 28, 29, 30, 31, -1, -1, -1, -1, -1, 0, -1, -1, -1, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25];

const CROCKFORD_INV_ALPHABET: [u8; 43] = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, -1, -1, -1, -1, -1, -1, -1, 10, 11, 12, 13, 14, 15, 16, 17, 1, 18, 19, 1, 20, 21, 0, 22, 23, 24, 25, 26, -1, 27, 28, 29, 30, 31];

pub fn decode(base32_type: Base32Type, data: &str) -> Option<Vec<u8>> {
    if !data.is_ascii() {
        return None;
    }
    let data = data.as_bytes();
    let alphabet = match base32_type {
        RFC4648Base32 | UnpaddedRFC4648Base32 => RFC4648_INV_ALPHABET,
        CrockfordBase32 => CROCKFORD_INV_ALPHABET
    };
    let mut unpadded_data_length = data.len();
    for i in range_inclusive(1, min(6, data.len())) {
        if data[data.len() - i] != b'=' {
            break;
        }
        unpadded_data_length -= 1;
    }
    let output_length = unpadded_data_length*5/8;
    let mut ret = Vec::with_capacity((output_length+4)/5*5);
    for chunk in data.chunks(8) {
        let buf = {
            let mut buf = [0u8; 8];
            for (i, &c) in chunk.iter().enumerate() {
                match alphabet.get((c.to_ascii_uppercase()-b'0') as usize) {
                    Some(&-1) | None => return None,
                    Some(&value) => buf[i] = value,
                };
            }
            buf
        };
        ret.push((buf[0] << 3) | (buf[1] >> 2));
        ret.push((buf[1] << 6) | (buf[2] << 1) | (buf[3] >> 4));
        ret.push((buf[3] << 4) | (buf[4] >> 1));
        ret.push((buf[4] << 7) | (buf[5] << 2) | (buf[6] >> 3));
        ret.push((buf[6] << 5) | buf[7]);
    }
    ret.truncate(output_length);
    Some(ret)
}

#[cfg(test)]
mod test {
    extern crate test;
    use super::{encode, decode};
    use super::Base32Type::{CrockfordBase32, RFC4648Base32, UnpaddedRFC4648Base32};
    use quickcheck;
    use std;
    use std::rand::distributions::IndependentSample;
    use std::ascii::AsciiExt;

    #[derive(Clone)]
    struct B32 {
        c: u8
    }

    impl quickcheck::Arbitrary for B32 {
        fn arbitrary<G: quickcheck::Gen>(g: &mut G) -> B32 {
            let alphabet = b"0123456789ABCDEFGHJKMNPQRSTVWXYZ";
            B32 {
                c: alphabet[std::rand::distributions::Range::new(0, alphabet.len()).ind_sample(g)]
            }
        }
    }

    impl std::fmt::Display for B32 {
        fn fmt(&self, f: &mut std::fmt::Formatter) -> Result<(), std::fmt::Error> {
            self.c.fmt(f)
        }
    }

    #[test]
    fn masks_crockford() {
        assert_eq!(encode(CrockfordBase32, &[0xF8, 0x3E, 0x0F, 0x83, 0xE0]), "Z0Z0Z0Z0");
        assert_eq!(encode(CrockfordBase32, &[0x07, 0xC1, 0xF0, 0x7C, 0x1F]), "0Z0Z0Z0Z");
        assert_eq!(decode(CrockfordBase32, "Z0Z0Z0Z0").unwrap(), [0xF8, 0x3E, 0x0F, 0x83, 0xE0]);
        assert_eq!(decode(CrockfordBase32, "0Z0Z0Z0Z").unwrap(), [0x07, 0xC1, 0xF0, 0x7C, 0x1F]);
    }

    #[test]
    fn masks_rfc4648() {
        assert_eq!(encode(RFC4648Base32, &[0xF8, 0x3E, 0x7F, 0x83, 0xE7]), "7A7H7A7H");
        assert_eq!(encode(RFC4648Base32, &[0x77, 0xC1, 0xF7, 0x7C, 0x1F]), "O7A7O7A7");
        assert_eq!(decode(RFC4648Base32, "7A7H7A7H").unwrap(), [0xF8, 0x3E, 0x7F, 0x83, 0xE7]);
        assert_eq!(decode(RFC4648Base32, "O7A7O7A7").unwrap(), [0x77, 0xC1, 0xF7, 0x7C, 0x1F]);
        assert_eq!(encode(RFC4648Base32, &[0xF8, 0x3E, 0x7F, 0x83]), "7A7H7AY=");
    }

    #[test]
    fn masks_unpadded_rfc4648() {
        assert_eq!(encode(UnpaddedRFC4648Base32, &[0xF8, 0x3E, 0x7F, 0x83, 0xE7]), "7A7H7A7H");
        assert_eq!(encode(UnpaddedRFC4648Base32, &[0x77, 0xC1, 0xF7, 0x7C, 0x1F]), "O7A7O7A7");
        assert_eq!(decode(UnpaddedRFC4648Base32, "7A7H7A7H").unwrap(), [0xF8, 0x3E, 0x7F, 0x83, 0xE7]);
        assert_eq!(decode(UnpaddedRFC4648Base32, "O7A7O7A7").unwrap(), [0x77, 0xC1, 0xF7, 0x7C, 0x1F]);
        assert_eq!(encode(UnpaddedRFC4648Base32, &[0xF8, 0x3E, 0x7F, 0x83]), "7A7H7AY");
    }

    #[test]
    fn padding() {
        let num_padding = [0u, 6, 4, 3, 1];
        for i in range(1u, 6) {
            println!("Checking padding for length == {}", i);
            let encoded = encode(RFC4648Base32, range(0u8, i as u8).collect::<Vec<u8>>().as_slice());
            assert_eq!(encoded.len(), 8u);
            for j in range(0u, num_padding[i % 5]) {
                println!("Making sure index {} is padding", encoded.len()-j-1);
                assert_eq!(encoded.as_bytes()[encoded.len()-j-1], b'=');
            }
            for j in range(0u, 8 - num_padding[i % 5]) {
                println!("Making sure index {} is not padding", j);
                assert!(encoded.as_bytes()[j] != b'=');
            }
        }
    }

    #[quickcheck]
    fn invertible_crockford(data: Vec<u8>) -> bool {
        decode(CrockfordBase32, encode(CrockfordBase32, data.as_slice()).as_slice()).unwrap() == data
    }

    #[quickcheck]
    fn invertible_rfc4648(data: Vec<u8>) -> bool {
        decode(RFC4648Base32, encode(RFC4648Base32, data.as_slice()).as_slice()).unwrap() == data
    }
    #[quickcheck]
    fn invertible_unpadded_rfc4648(data: Vec<u8>) -> bool {
        decode(UnpaddedRFC4648Base32, encode(UnpaddedRFC4648Base32, data.as_slice()).as_slice()).unwrap() == data
    }

    #[quickcheck]
    fn lower_case(data: Vec<B32>) -> bool {
        let data: String = data.iter().map(|e| e.c as char).collect();
        decode(CrockfordBase32, data.as_slice()) == decode(CrockfordBase32, data.as_slice().to_ascii_lowercase().as_slice())
    }

    #[test]
    #[allow(non_snake_case)]
    fn iIlL1_oO0() {
        assert_eq!(decode(CrockfordBase32, "IiLlOo"), decode(CrockfordBase32, "111100"));
    }

    #[test]
    fn invalid_chars_crockford() {
        assert_eq!(decode(CrockfordBase32, ","), None)
    }

    #[test]
    fn invalid_chars_rfc4648() {
        assert_eq!(decode(RFC4648Base32, ","), None)
    }

    #[test]
    fn invalid_chars_unpadded_rfc4648() {
        assert_eq!(decode(UnpaddedRFC4648Base32, ","), None)
    }

    #[bench]
    fn bench_encode(b: &mut test::Bencher) {
        let data = [0, 0, 0, 0, 0];
        b.iter(|| encode(CrockfordBase32, data.as_slice()));
        b.bytes = data.len() as u64;
    }

    #[bench]
    fn bench_decode(b: &mut test::Bencher) {
        let data = "00000000";
        b.iter(|| decode(CrockfordBase32, data));
        b.bytes = data.len() as u64;
    }
}
<|endoftext|>