<commit_before>extern crate clap;
extern crate regex;

include!("../clap-test.rs");

#[allow(unsused_imports)]
use std::ascii::AsciiExt;

use clap::{App, Arg, ErrorKind};

#[cfg(feature="suggestions")]
static PV_ERROR: &'static str = "error: 'slo' isn't a valid value for '--Option <option3>'
\t[values: fast, slow]

\tDid you mean 'slow'?

USAGE:
    clap-test --Option <option3>

For more information try --help";

#[cfg(not(feature="suggestions"))]
static PV_ERROR: &'static str = "error: 'slo' isn't a valid value for '--Option <option3>'
\t[values: fast, slow]

USAGE:
    clap-test --Option <option3>

For more information try --help";

#[test]
fn possible_values_of_positional() {
    let m = App::new("possible_values")
        .arg(Arg::with_name("positional")
            .index(1)
            .possible_value("test123"))
        .get_matches_from_safe(vec!["myprog", "test123"]);

    assert!(m.is_ok());
    let m = m.unwrap();

    assert!(m.is_present("positional"));
    assert_eq!(m.value_of("positional"), Some("test123"));
}

#[test]
fn possible_values_of_positional_fail() {
    let m = App::new("possible_values")
        .arg(Arg::with_name("positional")
            .index(1)
            .possible_value("test123"))
        .get_matches_from_safe(vec!["myprog", "notest"]);

    assert!(m.is_err());
    assert_eq!(m.unwrap_err().kind, ErrorKind::InvalidValue);
}

#[test]
fn possible_values_of_positional_multiple() {
    let m = App::new("possible_values")
        .arg(Arg::with_name("positional")
            .index(1)
            .possible_value("test123")
            .possible_value("test321")
            .multiple(true))
        .get_matches_from_safe(vec!["myprog", "test123", "test321"]);

    assert!(m.is_ok());
    let m = m.unwrap();

    assert!(m.is_present("positional"));
    assert_eq!(m.values_of("positional").unwrap().collect::<Vec<_>>(), vec!["test123", "test321"]);
}

#[test]
fn possible_values_of_positional_multiple_fail() {
    let m = App::new("possible_values")
        .arg(Arg::with_name("positional")
            .index(1)
            .possible_value("test123")
            .possible_value("test321")
            .multiple(true))
        .get_matches_from_safe(vec!["myprog", "test123", "notest"]);

    assert!(m.is_err());
    assert_eq!(m.unwrap_err().kind, ErrorKind::InvalidValue);
}

#[test]
fn possible_values_of_option() {
    let m = App::new("possible_values")
        .arg(Arg::with_name("option")
            .short("-o")
            .long("--option")
            .takes_value(true)
            .possible_value("test123"))
        .get_matches_from_safe(vec!["myprog", "--option", "test123"]);

    assert!(m.is_ok());
    let m = m.unwrap();

    assert!(m.is_present("option"));
    assert_eq!(m.value_of("option"), Some("test123"));
}

#[test]
fn possible_values_of_option_fail() {
    let m = App::new("possible_values")
        .arg(Arg::with_name("option")
            .short("-o")
            .long("--option")
            .takes_value(true)
            .possible_value("test123"))
        .get_matches_from_safe(vec!["myprog", "--option", "notest"]);

    assert!(m.is_err());
    assert_eq!(m.unwrap_err().kind, ErrorKind::InvalidValue);
}

#[test]
fn possible_values_of_option_multiple() {
    let m = App::new("possible_values")
        .arg(Arg::with_name("option")
            .short("-o")
            .long("--option")
            .takes_value(true)
            .possible_value("test123")
            .possible_value("test321")
            .multiple(true))
        .get_matches_from_safe(vec![
            "",
            "--option", "test123",
            "--option", "test321",
        ]);

    assert!(m.is_ok());
    let m = m.unwrap();

    assert!(m.is_present("option"));
    assert_eq!(m.values_of("option").unwrap().collect::<Vec<_>>(), vec!["test123", "test321"]);
}

#[test]
fn possible_values_of_option_multiple_fail() {
    let m = App::new("possible_values")
        .arg(Arg::with_name("option")
            .short("-o")
            .long("--option")
            .takes_value(true)
            .possible_value("test123")
            .possible_value("test321")
            .multiple(true))
        .get_matches_from_safe(vec![
            "",
            "--option", "test123",
            "--option", "notest",
        ]);

    assert!(m.is_err());
    assert_eq!(m.unwrap_err().kind, ErrorKind::InvalidValue);
}

#[test]
fn possible_values_output() {
    assert!(test::compare_output(test::complex_app(), "clap-test -O slo", PV_ERROR, true));
}
<commit_msg>tests: adds tests for using possible_values with Arg::case_insensitive<commit_after>extern crate clap;
extern crate regex;

include!("../clap-test.rs");

#[allow(unsused_imports)]
use std::ascii::AsciiExt;

use clap::{App, Arg, ErrorKind};

#[cfg(feature="suggestions")]
static PV_ERROR: &'static str = "error: 'slo' isn't a valid value for '--Option <option3>'
\t[values: fast, slow]

\tDid you mean 'slow'?

USAGE:
    clap-test --Option <option3>

For more information try --help";

#[cfg(not(feature="suggestions"))]
static PV_ERROR: &'static str = "error: 'slo' isn't a valid value for '--Option <option3>'
\t[values: fast, slow]

USAGE:
    clap-test --Option <option3>

For more information try --help";

#[test]
fn possible_values_of_positional() {
    let m = App::new("possible_values")
        .arg(Arg::with_name("positional")
            .index(1)
            .possible_value("test123"))
        .get_matches_from_safe(vec!["myprog", "test123"]);

    assert!(m.is_ok());
    let m = m.unwrap();

    assert!(m.is_present("positional"));
    assert_eq!(m.value_of("positional"), Some("test123"));
}

#[test]
fn possible_values_of_positional_fail() {
    let m = App::new("possible_values")
        .arg(Arg::with_name("positional")
            .index(1)
            .possible_value("test123"))
        .get_matches_from_safe(vec!["myprog", "notest"]);

    assert!(m.is_err());
    assert_eq!(m.unwrap_err().kind, ErrorKind::InvalidValue);
}

#[test]
fn possible_values_of_positional_multiple() {
    let m = App::new("possible_values")
        .arg(Arg::with_name("positional")
            .index(1)
            .possible_value("test123")
            .possible_value("test321")
            .multiple(true))
        .get_matches_from_safe(vec!["myprog", "test123", "test321"]);

    assert!(m.is_ok());
    let m = m.unwrap();

    assert!(m.is_present("positional"));
    assert_eq!(m.values_of("positional").unwrap().collect::<Vec<_>>(), vec!["test123", "test321"]);
}

#[test]
fn possible_values_of_positional_multiple_fail() {
    let m = App::new("possible_values")
        .arg(Arg::with_name("positional")
            .index(1)
            .possible_value("test123")
            .possible_value("test321")
            .multiple(true))
        .get_matches_from_safe(vec!["myprog", "test123", "notest"]);

    assert!(m.is_err());
    assert_eq!(m.unwrap_err().kind, ErrorKind::InvalidValue);
}

#[test]
fn possible_values_of_option() {
    let m = App::new("possible_values")
        .arg(Arg::with_name("option")
            .short("-o")
            .long("--option")
            .takes_value(true)
            .possible_value("test123"))
        .get_matches_from_safe(vec!["myprog", "--option", "test123"]);

    assert!(m.is_ok());
    let m = m.unwrap();

    assert!(m.is_present("option"));
    assert_eq!(m.value_of("option"), Some("test123"));
}

#[test]
fn possible_values_of_option_fail() {
    let m = App::new("possible_values")
        .arg(Arg::with_name("option")
            .short("-o")
            .long("--option")
            .takes_value(true)
            .possible_value("test123"))
        .get_matches_from_safe(vec!["myprog", "--option", "notest"]);

    assert!(m.is_err());
    assert_eq!(m.unwrap_err().kind, ErrorKind::InvalidValue);
}

#[test]
fn possible_values_of_option_multiple() {
    let m = App::new("possible_values")
        .arg(Arg::with_name("option")
            .short("-o")
            .long("--option")
            .takes_value(true)
            .possible_value("test123")
            .possible_value("test321")
            .multiple(true))
        .get_matches_from_safe(vec![
            "",
            "--option", "test123",
            "--option", "test321",
        ]);

    assert!(m.is_ok());
    let m = m.unwrap();

    assert!(m.is_present("option"));
    assert_eq!(m.values_of("option").unwrap().collect::<Vec<_>>(), vec!["test123", "test321"]);
}

#[test]
fn possible_values_of_option_multiple_fail() {
    let m = App::new("possible_values")
        .arg(Arg::with_name("option")
            .short("-o")
            .long("--option")
            .takes_value(true)
            .possible_value("test123")
            .possible_value("test321")
            .multiple(true))
        .get_matches_from_safe(vec![
            "",
            "--option", "test123",
            "--option", "notest",
        ]);

    assert!(m.is_err());
    assert_eq!(m.unwrap_err().kind, ErrorKind::InvalidValue);
}

#[test]
fn possible_values_output() {
    assert!(test::compare_output(test::complex_app(), "clap-test -O slo", PV_ERROR, true));
}

#[test]
fn case_insensitive() {
    let m = App::new("pv")
        .arg(Arg::with_name("option")
            .short("-o")
            .long("--option")
            .takes_value(true)
            .possible_value("test123")
            .possible_value("test321")
            .case_insensitive(true))
        .get_matches_from_safe(vec![
            "pv",
            "--option", "TeSt123",
        ]);

    assert!(m.is_ok());
    assert!(m.unwrap().value_of("option").unwrap().eq_ignore_ascii_case("test123"));
}

#[test]
fn case_insensitive_faili() {
    let m = App::new("pv")
        .arg(Arg::with_name("option")
            .short("-o")
            .long("--option")
            .takes_value(true)
            .possible_value("test123")
            .possible_value("test321"))
        .get_matches_from_safe(vec![
            "pv",
            "--option", "TeSt123",
        ]);

    assert!(m.is_err());
    assert_eq!(m.unwrap_err().kind, ErrorKind::InvalidValue);
}

#[test]
fn case_insensitive_multiple() {
    let m = App::new("pv")
        .arg(Arg::with_name("option")
            .short("-o")
            .long("--option")
            .takes_value(true)
            .possible_value("test123")
            .possible_value("test321")
            .multiple(true)
            .case_insensitive(true))
        .get_matches_from_safe(vec![
            "pv",
            "--option", "TeSt123", "teST123", "tESt321"
        ]);

    assert!(m.is_ok());
    assert_eq!(m.unwrap().values_of("option").unwrap().collect::<Vec<_>>(), &["TeSt123", "teST123", "tESt321"]);
}

#[test]
fn case_insensitive_multiple_fail() {
    let m = App::new("pv")
        .arg(Arg::with_name("option")
            .short("-o")
            .long("--option")
            .takes_value(true)
            .possible_value("test123")
            .possible_value("test321")
            .multiple(true))
        .get_matches_from_safe(vec![
            "pv",
            "--option", "test123", "teST123", "test321"
        ]);

    assert!(m.is_err());
    assert_eq!(m.unwrap_err().kind, ErrorKind::InvalidValue);
}<|endoftext|>


<commit_before>#![feature(nll)]

trait S: Sized {
    fn tpb(&mut self, _s: Self) {}
}

impl S for i32 {}

fn two_phase1() {
    let mut x = 3;
    x.tpb(x);
}

fn two_phase2() {
    let mut v = vec![];
    v.push(v.len());
}

/*
fn two_phase_overlapping1() {
    let mut x = vec![];
    let p = &x;
    x.push(p.len());
}

fn two_phase_overlapping2() {
    use std::ops::AddAssign;
    let mut x = 1;
    let l = &x;
    x.add_assign(x + *l);
}
*/

fn match_two_phase() {
    let mut x = 3;
    match x {
        ref mut y if { let _val = x; let _val = *y; true } => {},
        _ => (),
    }
}

fn with_interior_mutability() {
    use std::cell::Cell;

    trait Thing: Sized {
        fn do_the_thing(&mut self, _s: i32) {}
    }

    impl<T> Thing for Cell<T> {}

    let mut x = Cell::new(1);
    let l = &x;
    x
        .do_the_thing({
            x.set(3);
            l.set(4);
            x.get() + l.get()
        })
    ;
}

fn main() {
    two_phase1();
    two_phase2();
    match_two_phase();
    with_interior_mutability();
    //FIXME: enable these, or remove them, depending on how https://github.com/rust-lang/rust/issues/56254 gets resolved
    //two_phase_overlapping1();
    //two_phase_overlapping2();
}
<commit_msg>test some more 2PB stuff<commit_after>#![feature(nll)]

trait S: Sized {
    fn tpb(&mut self, _s: Self) {}
}

impl S for i32 {}

fn two_phase1() {
    let mut x = 3;
    x.tpb(x);
}

fn two_phase2() {
    let mut v = vec![];
    v.push(v.len());
}

fn two_phase3(b: bool) {
    let mut x = &mut vec![];
    let mut y = vec![];
    x.push((
        {
            if b { x = &mut y };
            22
        },
        x.len(),
    ));
}

/*
fn two_phase_overlapping1() {
    let mut x = vec![];
    let p = &x;
    x.push(p.len());
}

fn two_phase_overlapping2() {
    use std::ops::AddAssign;
    let mut x = 1;
    let l = &x;
    x.add_assign(x + *l);
}
*/

fn match_two_phase() {
    let mut x = 3;
    match x {
        ref mut y if { let _val = x; let _val = *y; true } => {},
        _ => (),
    }
}

fn with_interior_mutability() {
    use std::cell::Cell;

    trait Thing: Sized {
        fn do_the_thing(&mut self, _s: i32) {}
    }

    impl<T> Thing for Cell<T> {}

    let mut x = Cell::new(1);
    let l = &x;
    x
        .do_the_thing({
            x.set(3);
            l.set(4);
            x.get() + l.get()
        })
    ;
}

fn main() {
    two_phase1();
    two_phase2();
    two_phase3(false);
    two_phase3(true);
    match_two_phase();
    with_interior_mutability();
    //FIXME: enable these, or remove them, depending on how https://github.com/rust-lang/rust/issues/56254 gets resolved
    //two_phase_overlapping1();
    //two_phase_overlapping2();
}
<|endoftext|>


<commit_before>//ignore-windows: Uses POSIX APIs

#![feature(rustc_private)]

use core::slice;

extern crate libc;

fn main() {
    unsafe {
        let p1 = libc::calloc(0, 0);
        assert!(p1.is_null());

        let p2 = libc::calloc(20, 0);
        assert!(p2.is_null());

        let p3 = libc::calloc(0, 20);
        assert!(p3.is_null());

        let p4 = libc::calloc(4, 8) as *const u8;
        assert!(!p4.is_null());

        let slice = slice::from_raw_parts(p4, 4 * 8);
        assert_eq!(&slice, &[0_u8; 4 * 8]);
    }
}
<commit_msg>Fix calloc test<commit_after>//ignore-windows: Uses POSIX APIs

#![feature(rustc_private)]

use core::slice;

extern crate libc;

fn main() {
    unsafe {
        let p1 = libc::calloc(0, 0);
        assert!(p1.is_null());

        let p2 = libc::calloc(20, 0);
        assert!(p2.is_null());

        let p3 = libc::calloc(0, 20);
        assert!(p3.is_null());

        let p4 = libc::calloc(4, 8);
        assert!(!p4.is_null());
        let slice = slice::from_raw_parts(p4 as *const u8, 4 * 8);
        assert_eq!(&slice, &[0_u8; 4 * 8]);
        libc::free(p4);
    }
}
<|endoftext|>


<commit_before>use itertools::Itertools;
use std::fmt::Debug;
use quickcheck::quickcheck;

struct Unspecialized<I>(I);
impl<I> Iterator for Unspecialized<I>
where
    I: Iterator,
{
    type Item = I::Item;

    #[inline(always)]
    fn next(&mut self) -> Option<Self::Item> {
        self.0.next()
    }

    #[inline(always)]
    fn size_hint(&self) -> (usize, Option<usize>) {
        self.0.size_hint()
    }
}

fn check_specialized<'a, V, IterItem, Iter, F>(iterator: &Iter, mapper: F)
where
    V: Eq + Debug,
    IterItem: 'a,
    Iter: Iterator<Item = IterItem> + Clone + 'a,
    F: Fn(Box<dyn Iterator<Item = IterItem> + 'a>) -> V,
{
    assert_eq!(
        mapper(Box::new(Unspecialized(iterator.clone()))),
        mapper(Box::new(iterator.clone()))
    )
}

fn check_specialized_count_last_nth_sizeh<'a, IterItem, Iter>(
    it: &Iter,
    known_expected_size: Option<usize>,
) where
    IterItem: 'a + Eq + Debug,
    Iter: Iterator<Item = IterItem> + Clone + 'a,
{
    let size = it.clone().count();
    if let Some(expected_size) = known_expected_size {
        assert_eq!(size, expected_size);
    }
    check_specialized(it, |i| i.count());
    check_specialized(it, |i| i.last());
    for n in 0..size + 2 {
        check_specialized(it, |mut i| i.nth(n));
    }
    let mut it_sh = it.clone();
    for n in 0..size + 2 {
        let len = it_sh.clone().count();
        let (min, max) = it_sh.size_hint();
        assert_eq!((size - n.min(size)), len);
        assert!(min <= len);
        if let Some(max) = max {
            assert!(len <= max);
        }
        it_sh.next();
    }
}

fn check_specialized_fold<IterItem, Iter>(it: &Iter)
where
    IterItem: Eq + Debug + Clone,
    Iter: Iterator<Item = IterItem> + Clone,
{
    check_specialized(it, |i| {
        let mut parameters_from_fold = vec![];
        let fold_result = i.fold(vec![], |mut acc, v: IterItem| {
            parameters_from_fold.push((acc.clone(), v.clone()));
            acc.push(v);
            acc
        });
        (parameters_from_fold, fold_result)
    });
}

fn put_back_test(test_vec: Vec<i32>, known_expected_size: Option<usize>) {
    {
        // Lexical lifetimes support
        let pb = itertools::put_back(test_vec.iter());
        check_specialized_count_last_nth_sizeh(&pb, known_expected_size);
        check_specialized_fold(&pb);
    }

    let mut pb = itertools::put_back(test_vec.into_iter());
    pb.put_back(1);
    check_specialized_count_last_nth_sizeh(&pb, known_expected_size.map(|x| x + 1));
    check_specialized_fold(&pb)
}

#[test]
fn put_back() {
    put_back_test(vec![7, 4, 1], Some(3));
}

quickcheck! {
    fn put_back_qc(test_vec: Vec<i32>) -> () {
        put_back_test(test_vec, None)
    }
}

fn merge_join_by_test(i1: Vec<usize>, i2: Vec<usize>, known_expected_size: Option<usize>) {
    let i1 = i1.into_iter();
    let i2 = i2.into_iter();
    let mjb = i1.clone().merge_join_by(i2.clone(), std::cmp::Ord::cmp);
    check_specialized_count_last_nth_sizeh(&mjb, known_expected_size);
    check_specialized_fold(&mjb);

    // And the other way around
    let mjb = i2.merge_join_by(i1, std::cmp::Ord::cmp);
    check_specialized_count_last_nth_sizeh(&mjb, known_expected_size);
    check_specialized_fold(&mjb);
}

#[test]
fn merge_join_by() {
    let i1 = vec![1, 3, 5, 7, 8, 9];
    let i2 = vec![0, 3, 4, 5];
    merge_join_by_test(i1, i2, Some(8));
}

quickcheck! {
    fn merge_join_by_qc(i1: Vec<usize>, i2: Vec<usize>) -> () {
        merge_join_by_test(i1, i2, None)
    }
}
<commit_msg>Remove unused specialization of size_hint<commit_after>use itertools::Itertools;
use std::fmt::Debug;
use quickcheck::quickcheck;

struct Unspecialized<I>(I);
impl<I> Iterator for Unspecialized<I>
where
    I: Iterator,
{
    type Item = I::Item;

    #[inline(always)]
    fn next(&mut self) -> Option<Self::Item> {
        self.0.next()
    }
}

fn check_specialized<'a, V, IterItem, Iter, F>(iterator: &Iter, mapper: F)
where
    V: Eq + Debug,
    IterItem: 'a,
    Iter: Iterator<Item = IterItem> + Clone + 'a,
    F: Fn(Box<dyn Iterator<Item = IterItem> + 'a>) -> V,
{
    assert_eq!(
        mapper(Box::new(Unspecialized(iterator.clone()))),
        mapper(Box::new(iterator.clone()))
    )
}

fn check_specialized_count_last_nth_sizeh<'a, IterItem, Iter>(
    it: &Iter,
    known_expected_size: Option<usize>,
) where
    IterItem: 'a + Eq + Debug,
    Iter: Iterator<Item = IterItem> + Clone + 'a,
{
    let size = it.clone().count();
    if let Some(expected_size) = known_expected_size {
        assert_eq!(size, expected_size);
    }
    check_specialized(it, |i| i.count());
    check_specialized(it, |i| i.last());
    for n in 0..size + 2 {
        check_specialized(it, |mut i| i.nth(n));
    }
    let mut it_sh = it.clone();
    for n in 0..size + 2 {
        let len = it_sh.clone().count();
        let (min, max) = it_sh.size_hint();
        assert_eq!((size - n.min(size)), len);
        assert!(min <= len);
        if let Some(max) = max {
            assert!(len <= max);
        }
        it_sh.next();
    }
}

fn check_specialized_fold<IterItem, Iter>(it: &Iter)
where
    IterItem: Eq + Debug + Clone,
    Iter: Iterator<Item = IterItem> + Clone,
{
    check_specialized(it, |i| {
        let mut parameters_from_fold = vec![];
        let fold_result = i.fold(vec![], |mut acc, v: IterItem| {
            parameters_from_fold.push((acc.clone(), v.clone()));
            acc.push(v);
            acc
        });
        (parameters_from_fold, fold_result)
    });
}

fn put_back_test(test_vec: Vec<i32>, known_expected_size: Option<usize>) {
    {
        // Lexical lifetimes support
        let pb = itertools::put_back(test_vec.iter());
        check_specialized_count_last_nth_sizeh(&pb, known_expected_size);
        check_specialized_fold(&pb);
    }

    let mut pb = itertools::put_back(test_vec.into_iter());
    pb.put_back(1);
    check_specialized_count_last_nth_sizeh(&pb, known_expected_size.map(|x| x + 1));
    check_specialized_fold(&pb)
}

#[test]
fn put_back() {
    put_back_test(vec![7, 4, 1], Some(3));
}

quickcheck! {
    fn put_back_qc(test_vec: Vec<i32>) -> () {
        put_back_test(test_vec, None)
    }
}

fn merge_join_by_test(i1: Vec<usize>, i2: Vec<usize>, known_expected_size: Option<usize>) {
    let i1 = i1.into_iter();
    let i2 = i2.into_iter();
    let mjb = i1.clone().merge_join_by(i2.clone(), std::cmp::Ord::cmp);
    check_specialized_count_last_nth_sizeh(&mjb, known_expected_size);
    check_specialized_fold(&mjb);

    // And the other way around
    let mjb = i2.merge_join_by(i1, std::cmp::Ord::cmp);
    check_specialized_count_last_nth_sizeh(&mjb, known_expected_size);
    check_specialized_fold(&mjb);
}

#[test]
fn merge_join_by() {
    let i1 = vec![1, 3, 5, 7, 8, 9];
    let i2 = vec![0, 3, 4, 5];
    merge_join_by_test(i1, i2, Some(8));
}

quickcheck! {
    fn merge_join_by_qc(i1: Vec<usize>, i2: Vec<usize>) -> () {
        merge_join_by_test(i1, i2, None)
    }
}
<|endoftext|>


<commit_before>#[cfg_attr(aquamarine, aquamarine::aquamarine)]
/// Representations of JavaScript's core builtin types.
///
/// ## Modeling JavaScript Types
///
/// All JavaScript values in Neon implement the abstract [`Value`](crate::types::Value)
/// trait, which is the most generic way to work with JavaScript values. Neon provides a
/// number of types that implement this trait, each representing a particular
/// type of JavaScript value.
///
/// By convention, JavaScript types in Neon have the prefix `Js` in their name,
/// such as [`JsNumber`](crate::types::JsNumber) (for the JavaScript `number`
/// type) or [`JsFunction`](crate::types::JsFunction) (for the JavaScript
/// `function` type).
///
/// ### Handles and Casts
///
/// Access to JavaScript values in Neon works through [handles](crate::handle),
/// which ensure the safe interoperation between Rust and the JavaScript garbage
/// collector. This means, for example, a Rust variable that stores a JavaScript string
/// will have the type `Handle<JsString>` rather than [`JsString`](crate::types::JsString).
///
/// Neon types model the JavaScript type hierarchy through the use of *casts*.
/// The [`Handle::upcast()`](crate::handle::Handle::upcast) method safely converts
/// a handle to a JavaScript value of one type into a handle to a value of its
/// supertype. For example, it's safe to treat a [`JsArray`](crate::types::JsArray)
/// as a [`JsObject`](crate::types::JsObject), so you can do an "upcast" and it will
/// never fail:
///
/// ```
/// # use neon::prelude::*;
/// fn as_object(array: Handle<JsArray>) -> Handle<JsObject> {
///     let object: Handle<JsObject> = array.upcast();
///     object
/// }
/// ```
///
/// Unlike upcasts, the [`Handle::downcast()`](crate::handle::Handle::downcast) method
/// requires a runtime check to test a value's type at runtime, so it can fail with
/// a [`DowncastError`](crate::handle::DowncastError):
///
/// ```
/// # use neon::prelude::*;
/// fn as_array<'a>(
///     cx: &mut impl Context<'a>,
///     object: Handle<'a, JsObject>
/// ) -> JsResult<'a, JsArray> {
///     object.downcast(cx).or_throw(cx)
/// }
/// ```
///
/// ### The JavaScript Type Hierarchy
///
/// The top of the JavaScript type hierarchy is modeled with the Neon type
/// [`JsValue`](crate::types::JsValue). A [handle](crate::handle) to a `JsValue`
/// can refer to any JavaScript value. (For TypeScript programmers, this can be
/// thought of as similar to TypeScript's [`unknown`][unknown] type.)
///
/// From there, the type hierarchy divides into _object types_ and _primitive
/// types_:
///
/// ```mermaid
/// flowchart LR
/// JsValue(JsValue)
/// JsValue-->JsObject(JsObject)
/// click JsValue "./struct.JsValue.html" "JsValue"
/// click JsObject "./struct.JsObject.html" "JsObject"
/// subgraph primitives [Primitive Types]
///     JsBoolean(JsBoolean)
///     JsNumber(JsNumber)
///     JsString(JsString)
///     JsNull(JsNull)
///     JsUndefined(JsUndefined)
///     click JsBoolean "./struct.JsBoolean.html" "JsBoolean"
///     click JsNumber "./struct.JsNumber.html" "JsNumber"
///     click JsString "./struct.JsString.html" "JsString"
///     click JsNull "./struct.JsNull.html" "JsNull"
///     click JsUndefined "./struct.JsUndefined.html" "JsUndefined"
/// end
/// JsValue-->primitives
/// ```
///
/// The top of the object type hierarchy is [`JsObject`](crate::types::JsObject). A
/// handle to a `JsObject` can refer to any JavaScript object.
///
/// The primitive types are the built-in JavaScript datatypes that are not object
/// types: [`JsBoolean`](crate::types::JsBoolean), [`JsNumber`](crate::types::JsNumber),
/// [`JsString`](crate::types::JsString), [`JsNull`](crate::types::JsNull), and
/// [`JsUndefined`](crate::types::JsUndefined).
///
/// #### Object Types
///
/// The object type hierarchy further divides into a variety of different subtypes:
///
/// ```mermaid
/// flowchart LR
/// JsObject(JsObject)
/// click JsObject "./struct.JsObject.html" "JsObject"
/// subgraph objects [Standard Object Types]
///     JsFunction(JsFunction)
///     JsArray(JsArray)
///     JsDate(JsDate)
///     JsError(JsError)
///     click JsFunction "./struct.JsFunction.html" "JsFunction"
///     click JsArray "./struct.JsArray.html" "JsArray"
///     click JsDate "./struct.JsDate.html" "JsDate"
///     click JsError "./struct.JsError.html" "JsError"
/// end
/// subgraph typedarrays [Typed Arrays]
///     JsBuffer(JsBuffer)
///     JsArrayBuffer(JsArrayBuffer)
///     JsTypedArray("JsTypedArray<T>")
///     click JsBuffer "./struct.JsBuffer.html" "JsBuffer"
///     click JsArrayBuffer "./struct.JsArrayBuffer.html" "JsArrayBuffer"
///     click JsTypedArray "./struct.JsTypedArray.html" "JsTypedArray"
/// end
/// subgraph custom [Custom Types]
///     JsBox(JsBox)
///     click JsBox "./struct.JsBox.html" "JsBox"
/// end
/// JsObject-->objects
/// JsObject-->typedarrays
/// JsObject-->custom
/// ```
///
/// These include several categories of object types:
/// - **Standard object types:** [`JsFunction`](crate::types::JsFunction),
///   [`JsArray`](crate::types::JsArray), [`JsDate`](crate::types::JsDate), and
///   [`JsError`](crate::types::JsError).
/// - **Typed arrays:** [`JsBuffer`](crate::types::JsBuffer),
///   [`JsArrayBuffer`](crate::types::JsArrayBuffer), and
///   [`JsTypedArray<T>`](crate::types::JsTypedArray).
/// - **Custom types:** [`JsBox`](crate::types::JsBox), a special Neon type that allows
///   the creation of custom objects that own Rust data structures.
///
/// All object types implement the [`Object`](crate::object::Object) trait, which
/// allows getting and setting properties of an object.
///
/// [unknown]: https://mariusschulz.com/blog/the-unknown-type-in-typescript#the-unknown-type
pub mod exports {
    pub use crate::types_impl::*;
}
<commit_msg>Doc build fix: cfg_attr should do a feature test<commit_after>#[cfg_attr(feature = "aquamarine", aquamarine::aquamarine)]
/// Representations of JavaScript's core builtin types.
///
/// ## Modeling JavaScript Types
///
/// All JavaScript values in Neon implement the abstract [`Value`](crate::types::Value)
/// trait, which is the most generic way to work with JavaScript values. Neon provides a
/// number of types that implement this trait, each representing a particular
/// type of JavaScript value.
///
/// By convention, JavaScript types in Neon have the prefix `Js` in their name,
/// such as [`JsNumber`](crate::types::JsNumber) (for the JavaScript `number`
/// type) or [`JsFunction`](crate::types::JsFunction) (for the JavaScript
/// `function` type).
///
/// ### Handles and Casts
///
/// Access to JavaScript values in Neon works through [handles](crate::handle),
/// which ensure the safe interoperation between Rust and the JavaScript garbage
/// collector. This means, for example, a Rust variable that stores a JavaScript string
/// will have the type `Handle<JsString>` rather than [`JsString`](crate::types::JsString).
///
/// Neon types model the JavaScript type hierarchy through the use of *casts*.
/// The [`Handle::upcast()`](crate::handle::Handle::upcast) method safely converts
/// a handle to a JavaScript value of one type into a handle to a value of its
/// supertype. For example, it's safe to treat a [`JsArray`](crate::types::JsArray)
/// as a [`JsObject`](crate::types::JsObject), so you can do an "upcast" and it will
/// never fail:
///
/// ```
/// # use neon::prelude::*;
/// fn as_object(array: Handle<JsArray>) -> Handle<JsObject> {
///     let object: Handle<JsObject> = array.upcast();
///     object
/// }
/// ```
///
/// Unlike upcasts, the [`Handle::downcast()`](crate::handle::Handle::downcast) method
/// requires a runtime check to test a value's type at runtime, so it can fail with
/// a [`DowncastError`](crate::handle::DowncastError):
///
/// ```
/// # use neon::prelude::*;
/// fn as_array<'a>(
///     cx: &mut impl Context<'a>,
///     object: Handle<'a, JsObject>
/// ) -> JsResult<'a, JsArray> {
///     object.downcast(cx).or_throw(cx)
/// }
/// ```
///
/// ### The JavaScript Type Hierarchy
///
/// The top of the JavaScript type hierarchy is modeled with the Neon type
/// [`JsValue`](crate::types::JsValue). A [handle](crate::handle) to a `JsValue`
/// can refer to any JavaScript value. (For TypeScript programmers, this can be
/// thought of as similar to TypeScript's [`unknown`][unknown] type.)
///
/// From there, the type hierarchy divides into _object types_ and _primitive
/// types_:
///
/// ```mermaid
/// flowchart LR
/// JsValue(JsValue)
/// JsValue-->JsObject(JsObject)
/// click JsValue "./struct.JsValue.html" "JsValue"
/// click JsObject "./struct.JsObject.html" "JsObject"
/// subgraph primitives [Primitive Types]
///     JsBoolean(JsBoolean)
///     JsNumber(JsNumber)
///     JsString(JsString)
///     JsNull(JsNull)
///     JsUndefined(JsUndefined)
///     click JsBoolean "./struct.JsBoolean.html" "JsBoolean"
///     click JsNumber "./struct.JsNumber.html" "JsNumber"
///     click JsString "./struct.JsString.html" "JsString"
///     click JsNull "./struct.JsNull.html" "JsNull"
///     click JsUndefined "./struct.JsUndefined.html" "JsUndefined"
/// end
/// JsValue-->primitives
/// ```
///
/// The top of the object type hierarchy is [`JsObject`](crate::types::JsObject). A
/// handle to a `JsObject` can refer to any JavaScript object.
///
/// The primitive types are the built-in JavaScript datatypes that are not object
/// types: [`JsBoolean`](crate::types::JsBoolean), [`JsNumber`](crate::types::JsNumber),
/// [`JsString`](crate::types::JsString), [`JsNull`](crate::types::JsNull), and
/// [`JsUndefined`](crate::types::JsUndefined).
///
/// #### Object Types
///
/// The object type hierarchy further divides into a variety of different subtypes:
///
/// ```mermaid
/// flowchart LR
/// JsObject(JsObject)
/// click JsObject "./struct.JsObject.html" "JsObject"
/// subgraph objects [Standard Object Types]
///     JsFunction(JsFunction)
///     JsArray(JsArray)
///     JsDate(JsDate)
///     JsError(JsError)
///     click JsFunction "./struct.JsFunction.html" "JsFunction"
///     click JsArray "./struct.JsArray.html" "JsArray"
///     click JsDate "./struct.JsDate.html" "JsDate"
///     click JsError "./struct.JsError.html" "JsError"
/// end
/// subgraph typedarrays [Typed Arrays]
///     JsBuffer(JsBuffer)
///     JsArrayBuffer(JsArrayBuffer)
///     JsTypedArray("JsTypedArray<T>")
///     click JsBuffer "./struct.JsBuffer.html" "JsBuffer"
///     click JsArrayBuffer "./struct.JsArrayBuffer.html" "JsArrayBuffer"
///     click JsTypedArray "./struct.JsTypedArray.html" "JsTypedArray"
/// end
/// subgraph custom [Custom Types]
///     JsBox(JsBox)
///     click JsBox "./struct.JsBox.html" "JsBox"
/// end
/// JsObject-->objects
/// JsObject-->typedarrays
/// JsObject-->custom
/// ```
///
/// These include several categories of object types:
/// - **Standard object types:** [`JsFunction`](crate::types::JsFunction),
///   [`JsArray`](crate::types::JsArray), [`JsDate`](crate::types::JsDate), and
///   [`JsError`](crate::types::JsError).
/// - **Typed arrays:** [`JsBuffer`](crate::types::JsBuffer),
///   [`JsArrayBuffer`](crate::types::JsArrayBuffer), and
///   [`JsTypedArray<T>`](crate::types::JsTypedArray).
/// - **Custom types:** [`JsBox`](crate::types::JsBox), a special Neon type that allows
///   the creation of custom objects that own Rust data structures.
///
/// All object types implement the [`Object`](crate::object::Object) trait, which
/// allows getting and setting properties of an object.
///
/// [unknown]: https://mariusschulz.com/blog/the-unknown-type-in-typescript#the-unknown-type
pub mod exports {
    pub use crate::types_impl::*;
}
<|endoftext|>


<commit_before>#![allow(dead_code)]
#![allow(unused_variable)]

use pretty::mode;
use pretty::string_utils;

#[deriving(Show)]
#[deriving(Clone)]
pub enum Doc {
    Nil,
    Append(Box<Doc>, Box<Doc>),
    Nest(uint, Box<Doc>),
    Text(String),
    Break(uint, uint),
    Newline,
    Group(Box<Doc>)
}

fn fitting(xs:&Vec<(uint,mode::Mode,Doc)>, left:uint) -> bool {
    if left as int >= 0 {
        match xs.as_slice() {
            [] => true,
            [(ref i, ref mode, ref doc), ref rest..] => match *doc {
                Nil => fitting(&rest.to_vec(), left),
                Append(ref x, ref y) => {
                    let mut ys = [(*i,*mode,*x.clone()), (*i,*mode,*y.clone())].to_vec();
                    ys.push_all(*rest);
                    fitting(&ys,left)
                },
                Nest(j, ref x) => {
                    let mut ys = [(*i+j,*mode,*x.clone())].to_vec();
                    ys.push_all(*rest);
                    fitting(&ys, left)
                },
                Text(ref str) => fitting(&rest.to_vec(), left - str.len()),
                Break(sp, _) => match *mode {
                    mode::Flat => fitting(&rest.to_vec(), left - sp),
                    mode::Break => true
                },
                Newline => true,
                Group(ref x) => {
                    let mut ys = [(*i,*mode, *x.clone())].to_vec();
                    ys.push_all(*rest);
                    fitting(&ys, left)
                }
            }
        }
    }
    else {
        false
    }
}

fn prepend<A:Clone>(v: Vec<A>, x:A) -> Vec<A> {
    let mut res = v;
    res.insert(0,x);
    res
}

fn best(w:uint, s:Vec<String>, x:Doc) -> Vec<String> {
    fn go(w:uint, s:Vec<String>, k:uint, xs:Vec<(uint,mode::Mode,Doc)>) -> Vec<String> {
        match xs.as_slice() {
            [] => s.clone(),
            [(ref i, ref mode, ref doc), ref rest..] => match *doc {
                Nil => go(w, s, k, rest.to_vec()),
                Append(ref x, ref y) => {
                    let mut zs = [(*i, *mode, *x.clone()), (*i, *mode, *y.clone())].to_vec();
                    zs.push_all(*rest);
                    go(w, s, k, zs)
                },
                Nest(j, ref x) => {
                    let mut zs = [(*i + j, *mode, *x.clone())].to_vec();
                    zs.push_all(*rest);
                    go(w, s, k, zs)
                },
                Text(ref str) => go(w, prepend(s, str.clone()), k + str.len(), rest.to_vec()),
                Newline => go(w, prepend(s, string_utils::nl_space(*i)), *i, rest.to_vec()),
                Break(sp, off) => {
                    match *mode {
                        mode::Flat => go(w, prepend(s.clone(), string_utils::spaces(sp)), k + sp, rest.to_vec()),
                        mode::Break => go(w, prepend(s.clone(), string_utils::nl_space(i + off)), i + off, rest.to_vec())
                    }
                },
                Group(ref x) => {
                    match *mode {
                        mode::Flat => {
                            let mut zs = [(*i,mode::Flat,*x.clone())].to_vec();
                            zs.push_all(*rest);
                            go(w, s, k, zs)
                        },
                        mode::Break => {
                            let mut ys = [(*i,mode::Flat,*x.clone())].to_vec();
                            ys.push_all(*rest);
                            if fitting(&ys, w - k) {
                                go(w, s, k, ys)
                            } else {
                                let mut zs = [(*i,mode::Break,*x.clone())].to_vec();
                                zs.push_all(*rest);
                                go(w, s, k, zs)
                            }
                        }
                    }
                }
            }
        }
    }
    go(w, s, 0, [(0,mode::Break,x)].to_vec())
}

impl Doc {
    pub fn nil() -> Doc {
        Nil
    }
/*
 *
    Append(Box<Doc>, Box<Doc>),
    Nest(uint, Box<Doc>),
    Text(String),
    Break(uint, uint),
    Newline,
    Group(Box<Doc>)
    */

    pub fn concat(ds:&[Doc]) -> Doc {
        ds.iter().fold(Nil, |a, b| a.append(b.clone()))
    }

    pub fn int(i:int) -> Doc {
        Text(format!("{}", i))
    }

    pub fn char(c:char) -> Doc {
        Text(format!("{}", c))
    }

    pub fn bool(b:bool) -> Doc {
        if b {
            Text(String::from_str("true"))
        } else {
            Text(String::from_str("false"))
        }
    }
    pub fn append(&self, e:Doc) -> Doc {
        match *self {
            Nil => e,
            ref x => match e {
                Nil => x.clone(),
                y => Append(box x.clone(), box y)
            }
        }
    }

    pub fn to_string(&self, w:uint) -> String {
        let mut strs = best(w, [].to_vec(), self.clone());
        strs.reverse();
        strs.push(String::from_str("\n"));
        strs.concat()
    }
}

<commit_msg>Remove commented stuff I didn't mean to commit<commit_after>#![allow(dead_code)]
#![allow(unused_variable)]

use pretty::mode;
use pretty::string_utils;

#[deriving(Show)]
#[deriving(Clone)]
pub enum Doc {
    Nil,
    Append(Box<Doc>, Box<Doc>),
    Nest(uint, Box<Doc>),
    Text(String),
    Break(uint, uint),
    Newline,
    Group(Box<Doc>)
}

fn fitting(xs:&Vec<(uint,mode::Mode,Doc)>, left:uint) -> bool {
    if left as int >= 0 {
        match xs.as_slice() {
            [] => true,
            [(ref i, ref mode, ref doc), ref rest..] => match *doc {
                Nil => fitting(&rest.to_vec(), left),
                Append(ref x, ref y) => {
                    let mut ys = [(*i,*mode,*x.clone()), (*i,*mode,*y.clone())].to_vec();
                    ys.push_all(*rest);
                    fitting(&ys,left)
                },
                Nest(j, ref x) => {
                    let mut ys = [(*i+j,*mode,*x.clone())].to_vec();
                    ys.push_all(*rest);
                    fitting(&ys, left)
                },
                Text(ref str) => fitting(&rest.to_vec(), left - str.len()),
                Break(sp, _) => match *mode {
                    mode::Flat => fitting(&rest.to_vec(), left - sp),
                    mode::Break => true
                },
                Newline => true,
                Group(ref x) => {
                    let mut ys = [(*i,*mode, *x.clone())].to_vec();
                    ys.push_all(*rest);
                    fitting(&ys, left)
                }
            }
        }
    }
    else {
        false
    }
}

fn prepend<A:Clone>(v: Vec<A>, x:A) -> Vec<A> {
    let mut res = v;
    res.insert(0,x);
    res
}

fn best(w:uint, s:Vec<String>, x:Doc) -> Vec<String> {
    fn go(w:uint, s:Vec<String>, k:uint, xs:Vec<(uint,mode::Mode,Doc)>) -> Vec<String> {
        match xs.as_slice() {
            [] => s.clone(),
            [(ref i, ref mode, ref doc), ref rest..] => match *doc {
                Nil => go(w, s, k, rest.to_vec()),
                Append(ref x, ref y) => {
                    let mut zs = [(*i, *mode, *x.clone()), (*i, *mode, *y.clone())].to_vec();
                    zs.push_all(*rest);
                    go(w, s, k, zs)
                },
                Nest(j, ref x) => {
                    let mut zs = [(*i + j, *mode, *x.clone())].to_vec();
                    zs.push_all(*rest);
                    go(w, s, k, zs)
                },
                Text(ref str) => go(w, prepend(s, str.clone()), k + str.len(), rest.to_vec()),
                Newline => go(w, prepend(s, string_utils::nl_space(*i)), *i, rest.to_vec()),
                Break(sp, off) => {
                    match *mode {
                        mode::Flat => go(w, prepend(s.clone(), string_utils::spaces(sp)), k + sp, rest.to_vec()),
                        mode::Break => go(w, prepend(s.clone(), string_utils::nl_space(i + off)), i + off, rest.to_vec())
                    }
                },
                Group(ref x) => {
                    match *mode {
                        mode::Flat => {
                            let mut zs = [(*i,mode::Flat,*x.clone())].to_vec();
                            zs.push_all(*rest);
                            go(w, s, k, zs)
                        },
                        mode::Break => {
                            let mut ys = [(*i,mode::Flat,*x.clone())].to_vec();
                            ys.push_all(*rest);
                            if fitting(&ys, w - k) {
                                go(w, s, k, ys)
                            } else {
                                let mut zs = [(*i,mode::Break,*x.clone())].to_vec();
                                zs.push_all(*rest);
                                go(w, s, k, zs)
                            }
                        }
                    }
                }
            }
        }
    }
    go(w, s, 0, [(0,mode::Break,x)].to_vec())
}

impl Doc {
    pub fn concat(ds:&[Doc]) -> Doc {
        ds.iter().fold(Nil, |a, b| a.append(b.clone()))
    }

    pub fn int(i:int) -> Doc {
        Text(format!("{}", i))
    }

    pub fn char(c:char) -> Doc {
        Text(format!("{}", c))
    }

    pub fn bool(b:bool) -> Doc {
        if b {
            Text(String::from_str("true"))
        } else {
            Text(String::from_str("false"))
        }
    }
    pub fn append(&self, e:Doc) -> Doc {
        match *self {
            Nil => e,
            ref x => match e {
                Nil => x.clone(),
                y => Append(box x.clone(), box y)
            }
        }
    }

    pub fn to_string(&self, w:uint) -> String {
        let mut strs = best(w, [].to_vec(), self.clone());
        strs.reverse();
        strs.push(String::from_str("\n"));
        strs.concat()
    }
}

<|endoftext|>


<commit_before>use std::io;
use std::io::prelude::*;
use std::io::BufReader;
use std::fs::{self, File, ReadDir, DirEntry};
use std::path::Path;
use std::collections::HashMap;
use std::cmp::Ordering;

pub type TaskId = u32;

fn err_str<T: ToString>(err: T) -> String {
  err.to_string()
}

fn parse_taskid(taskid_str: String) -> Result<TaskId, String> {
  taskid_str.parse().map_err(err_str)
}

#[derive(Debug)]
pub struct Proc {
  pub status: ProcStatus,
  pub cmdline: Vec<String>
}

impl Proc {
  pub fn new(pid: TaskId) -> Result<Self, String> {
    let proc_dir = format!("/proc/{}", pid);
    let proc_status = try!(ProcStatus::new(&proc_dir));
    let cmdline = try!(Self::read_cmdline(&proc_dir));

    let proc_struct = Proc{
      status: proc_status,
      cmdline: cmdline
    };

    Ok(proc_struct)
  }

  fn read_cmdline(proc_dir: &str) -> Result<Vec<String>, String> {
    File::open(Path::new(proc_dir).join("cmdline"))
      .map_err(err_str)
      .and_then(|mut file| {
        let mut contents = Vec::new();
        try!(
          file.read_to_end(&mut contents)
            .map_err(err_str)
        );
        if contents.ends_with(&['\0' as u8]) {
          let _ = contents.pop();
        }
        Ok(contents)
      }).and_then(|contents| {
        String::from_utf8(contents)
          .map_err(err_str)
      }).map(|contents|
        contents
          .split('\0')
          .map(|a| a.to_string())
          .collect()
      )
  }

  // Return true if query matches this process
  fn query(&self, query: &ProcQuery) -> bool {
    match *query {
      ProcQuery::PidQuery(q) => taskid_query(self.status.pid, q),
      ProcQuery::PpidQuery(q) => taskid_query(self.status.ppid, q),
      ProcQuery::NameQuery(ref q) => string_query(&self.status.name, &q),
      ProcQuery::CmdlineQuery(ref q) => string_s_query(&self.cmdline, &q),
      ProcQuery::NoneQuery => true
    }
  }
}

#[derive(Debug)]
pub struct ProcStatus {
  pub pid: TaskId,
  pub ppid: TaskId,
  pub tgid: TaskId,
  pub name: String,
}

macro_rules! extract_key {
  ($map:expr, $key:expr, $func:expr) =>
    (try!(
      $map.remove($key)
        .ok_or(format!("Key '{}' not found", $key))
        .and_then($func)
    ))
}

impl ProcStatus {
  // Generate ProcStatus struct given a process directory
  fn new(proc_dir: &str) -> Result<Self, String> {
    // Try opening file
    let status_file = try!(
      File::open(Path::new(proc_dir).join("status"))
        .map_err(err_str)
    );

    let mut status: HashMap<String, String> =
      BufReader::new(status_file).lines().filter_map(
        |line|
          line
            .map_err(err_str)
            .and_then(|line| {
              let split = line.splitn(2, ':').collect::<Vec<&str>>();

              match (split.get(0), split.get(1)) {
                (Some(key), Some(value)) =>
                  Ok((key.trim().to_owned(),
                     value.trim().to_owned())),
                _ => Err("Error reading status line".to_owned())
              }
             }).ok()
      ).collect();

    let pid = extract_key!(status, "Pid", parse_taskid);
    let ppid = extract_key!(status, "PPid", parse_taskid);
    let tgid = extract_key!(status, "Tgid", parse_taskid);
    let name = extract_key!(status, "Name", |a| Ok(a));

    Ok(ProcStatus{
      pid: pid,
      ppid: ppid,
      tgid: tgid,
      name: name
    })
  }
}

impl PartialEq for Proc {
  fn eq(&self, other: &Self) -> bool {
    self.status.pid.eq(&other.status.pid)
  }
}

impl Eq for Proc {}
impl PartialOrd for Proc {
  fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
    Some(self.cmp(other))
  }
}
impl Ord for Proc {
  fn cmp(&self, other: &Self) -> Ordering {
    self.status.pid.cmp(&other.status.pid)
  }
}

pub struct ProcIter {
  dir_iter: ReadDir,
  query: ProcQuery
}

impl ProcIter {
  pub fn new() -> Result<Self, String> {
    Self::new_query(ProcQuery::NoneQuery)
  }

  pub fn new_query(query: ProcQuery) -> Result<Self, String> {
    let proc_dir = Path::new("/proc");
    let dir_iter = try!(fs::read_dir(proc_dir).map_err(err_str));
    Ok(ProcIter{
      dir_iter: dir_iter,
      query: query
    })
  }

  fn proc_dir_filter(entry_opt: Result<DirEntry, io::Error>, query: &ProcQuery)
    -> Option<Proc> {
    // TODO: This sucks, find a better way
    entry_opt.ok()
      .and_then(|entry|
        entry.file_name().into_string().ok()
      ).and_then(|name|
        name.parse().ok()
      ).and_then(|pid|
        Proc::new(pid).ok()
      ).and_then(|proc_struct|
        if proc_struct.query(query) {
          Some(proc_struct)
        } else {
          None
        }
      )
  }
}

impl Iterator for ProcIter {
  type Item = Proc;

  fn next(&mut self) -> Option<Self::Item> {
    for entry in self.dir_iter.by_ref() {
      match Self::proc_dir_filter(entry, &self.query) {
        Some(p) => return Some(p),
        None => continue
      }
    }
    None
  }

  // Size may be anywhere from 0 to number of dirs
  fn size_hint(&self) -> (usize, Option<usize>) {
    (0, self.dir_iter.size_hint().1)
  }
}

pub type ProcMap = HashMap<TaskId, Proc>;

pub fn get_proc_map() -> Result<ProcMap, String> {
  let iter = try!(ProcIter::new());
  Ok(iter.map(|proc_struct|
    (proc_struct.status.pid, proc_struct)
  ).collect())
}

pub enum ProcQuery {
  PidQuery(TaskId),
  PpidQuery(TaskId),
  NameQuery(String),
  CmdlineQuery(String),
  NoneQuery
}

pub fn create_query(query: &str) -> Result<ProcQuery, String> {
  let splits: Vec<_> = query.splitn(2, '=').collect();

  match splits.len() {
    0 => Ok(ProcQuery::NoneQuery),
    1 => Ok(match query.parse().ok() {
      Some(tid) => ProcQuery::PidQuery(tid),
      None => ProcQuery::NameQuery(query.to_owned())
    }),
    _ => {
      let q_text = splits[1].to_owned();
      let q_tid = q_text.parse();
      match &*splits[0].to_lowercase() {
        "pid" => q_tid.map(|q| ProcQuery::PidQuery(q))
          .or(Err("Query value for type 'pid' not valid".to_owned())),
        "ppid" => q_tid.map(|q| ProcQuery::PpidQuery(q))
          .or(Err("Query value for type 'ppid' not valid".to_owned())),
        "name" => Ok(ProcQuery::NameQuery(q_text)),
        "cmdline" => Ok(ProcQuery::CmdlineQuery(q_text)),
        _ => Err("Invalid query type".to_owned())
      }
    }
  }
}

pub fn taskid_query(tid: TaskId, query: TaskId) -> bool {
  tid == query
}

pub fn string_query(text: &str, query: &str) -> bool {
  text == query
}

pub fn string_s_query(text_vec: &Vec<String>, query: &str) -> bool {
  for text in text_vec {
    if string_query(text, query) {
      return true;
    }
  }
  false
}

<commit_msg>Add struct to hold /proc/*/stat<commit_after>use std::io;
use std::io::prelude::*;
use std::io::BufReader;
use std::fs::{self, File, ReadDir, DirEntry};
use std::path::Path;
use std::collections::HashMap;
use std::cmp::Ordering;

pub type TaskId = u32;

fn err_str<T: ToString>(err: T) -> String {
  err.to_string()
}

fn parse_taskid(taskid_str: String) -> Result<TaskId, String> {
  taskid_str.parse().map_err(err_str)
}

#[derive(Debug)]
pub struct Proc {
  pub status: ProcStatus,
  pub cmdline: Vec<String>
}

impl Proc {
  pub fn new(pid: TaskId) -> Result<Self, String> {
    let proc_dir = format!("/proc/{}", pid);
    let proc_status = try!(ProcStatus::new(&proc_dir));
    let cmdline = try!(Self::read_cmdline(&proc_dir));

    let proc_struct = Proc{
      status: proc_status,
      cmdline: cmdline
    };

    Ok(proc_struct)
  }

  fn read_cmdline(proc_dir: &str) -> Result<Vec<String>, String> {
    File::open(Path::new(proc_dir).join("cmdline"))
      .map_err(err_str)
      .and_then(|mut file| {
        let mut contents = Vec::new();
        try!(
          file.read_to_end(&mut contents)
            .map_err(err_str)
        );
        if contents.ends_with(&['\0' as u8]) {
          let _ = contents.pop();
        }
        Ok(contents)
      }).and_then(|contents| {
        String::from_utf8(contents)
          .map_err(err_str)
      }).map(|contents|
        contents
          .split('\0')
          .map(|a| a.to_string())
          .collect()
      )
  }

  // Return true if query matches this process
  fn query(&self, query: &ProcQuery) -> bool {
    match *query {
      ProcQuery::PidQuery(q) => taskid_query(self.status.pid, q),
      ProcQuery::PpidQuery(q) => taskid_query(self.status.ppid, q),
      ProcQuery::NameQuery(ref q) => string_query(&self.status.name, &q),
      ProcQuery::CmdlineQuery(ref q) => string_s_query(&self.cmdline, &q),
      ProcQuery::NoneQuery => true
    }
  }
}

pub enum ProcState {
  Running,
  Sleeping,
  Waiting,
  Zombie,
  Stopped,
  Tracing,
  Paging,
  Dead,
  Wakekill,
  Waking,
  Parked
}

fn get_procstate(state: char) -> Option<ProcState> {
  match state {
    'R' => Some(ProcState::Running),
    'S' => Some(ProcState::Sleeping),
    'D' => Some(ProcState::Waiting),
    'Z' => Some(ProcState::Zombie),
    'T' => Some(ProcState::Stopped),
    't' => Some(ProcState::Tracing),
    'X' | 'x' => Some(ProcState::Dead),
    'K' => Some(ProcState::Wakekill),
    'W' => Some(ProcState::Waking),
    'P' => Some(ProcState::Parked),
     _  => None
  }
}

pub struct ProcStat {
  pub pid: TaskId,
  pub comm: String,
  pub state: ProcState,
  pub ppid: TaskId,
  pub pgrp: i32,
  pub session: i32,
  pub tty_nr: i32,
  pub tpgid: i32,
  pub flags: u32,
  pub minflt: u64,
  pub cminflt: u64,
  pub majflt: u64,
  pub cmajflt: u64,
  pub utime: u64,
  pub stime: u64,
  pub cutime: i64,
  pub cstime: i64,
  pub priority: i64,
  pub nice: i64,
  pub num_threads: i64,
  pub itrealvalue: i64,
  pub starttime: u64,
  pub vsize: u64,
  pub rss: i64,
  pub rsslim: u64,
  pub startcode: u64,
  pub endcode: u64,
  pub startstack: u64,
  pub kstkesp: u64,
  pub kstkeip: u64,
  pub signal: u64,
  pub blocked: u64,
  pub sigignore: u64,
  pub sigcatch: u64,
  pub wchan: u64,
  pub nswap: u64,
  pub cnswap: u64,
  pub exit_signal: i32,
  pub processor: i32,
  pub rt_priority: u32,
  pub policy: u32,
  pub delayacct_blkio_ticks: u64,
  pub guest_time: u64,
  pub cguest_time: i64,
  pub start_data: u64,
  pub end_data: u64,
  pub start_brk: u64,
  pub arg_start: u64,
  pub arg_end: u64,
  pub env_start: u64,
  pub env_end: u64,
  pub exit_code: i32
}

#[derive(Debug)]
pub struct ProcStatus {
  pub pid: TaskId,
  pub ppid: TaskId,
  pub tgid: TaskId,
  pub name: String,
}

macro_rules! extract_key {
  ($map:expr, $key:expr, $func:expr) =>
    (try!(
      $map.remove($key)
        .ok_or(format!("Key '{}' not found", $key))
        .and_then($func)
    ))
}

impl ProcStatus {
  // Generate ProcStatus struct given a process directory
  fn new(proc_dir: &str) -> Result<Self, String> {
    // Try opening file
    let status_file = try!(
      File::open(Path::new(proc_dir).join("status"))
        .map_err(err_str)
    );

    let mut status: HashMap<String, String> =
      BufReader::new(status_file).lines().filter_map(
        |line|
          line
            .map_err(err_str)
            .and_then(|line| {
              let split = line.splitn(2, ':').collect::<Vec<&str>>();

              match (split.get(0), split.get(1)) {
                (Some(key), Some(value)) =>
                  Ok((key.trim().to_owned(),
                     value.trim().to_owned())),
                _ => Err("Error reading status line".to_owned())
              }
             }).ok()
      ).collect();

    let pid = extract_key!(status, "Pid", parse_taskid);
    let ppid = extract_key!(status, "PPid", parse_taskid);
    let tgid = extract_key!(status, "Tgid", parse_taskid);
    let name = extract_key!(status, "Name", |a| Ok(a));

    Ok(ProcStatus{
      pid: pid,
      ppid: ppid,
      tgid: tgid,
      name: name
    })
  }
}

impl PartialEq for Proc {
  fn eq(&self, other: &Self) -> bool {
    self.status.pid.eq(&other.status.pid)
  }
}

impl Eq for Proc {}
impl PartialOrd for Proc {
  fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
    Some(self.cmp(other))
  }
}
impl Ord for Proc {
  fn cmp(&self, other: &Self) -> Ordering {
    self.status.pid.cmp(&other.status.pid)
  }
}

pub struct ProcIter {
  dir_iter: ReadDir,
  query: ProcQuery
}

impl ProcIter {
  pub fn new() -> Result<Self, String> {
    Self::new_query(ProcQuery::NoneQuery)
  }

  pub fn new_query(query: ProcQuery) -> Result<Self, String> {
    let proc_dir = Path::new("/proc");
    let dir_iter = try!(fs::read_dir(proc_dir).map_err(err_str));
    Ok(ProcIter{
      dir_iter: dir_iter,
      query: query
    })
  }

  fn proc_dir_filter(entry_opt: Result<DirEntry, io::Error>, query: &ProcQuery)
    -> Option<Proc> {
    // TODO: This sucks, find a better way
    entry_opt.ok()
      .and_then(|entry|
        entry.file_name().into_string().ok()
      ).and_then(|name|
        name.parse().ok()
      ).and_then(|pid|
        Proc::new(pid).ok()
      ).and_then(|proc_struct|
        if proc_struct.query(query) {
          Some(proc_struct)
        } else {
          None
        }
      )
  }
}

impl Iterator for ProcIter {
  type Item = Proc;

  fn next(&mut self) -> Option<Self::Item> {
    for entry in self.dir_iter.by_ref() {
      match Self::proc_dir_filter(entry, &self.query) {
        Some(p) => return Some(p),
        None => continue
      }
    }
    None
  }

  // Size may be anywhere from 0 to number of dirs
  fn size_hint(&self) -> (usize, Option<usize>) {
    (0, self.dir_iter.size_hint().1)
  }
}

pub type ProcMap = HashMap<TaskId, Proc>;

pub fn get_proc_map() -> Result<ProcMap, String> {
  let iter = try!(ProcIter::new());
  Ok(iter.map(|proc_struct|
    (proc_struct.status.pid, proc_struct)
  ).collect())
}

pub enum ProcQuery {
  PidQuery(TaskId),
  PpidQuery(TaskId),
  NameQuery(String),
  CmdlineQuery(String),
  NoneQuery
}

pub fn create_query(query: &str) -> Result<ProcQuery, String> {
  let splits: Vec<_> = query.splitn(2, '=').collect();

  match splits.len() {
    0 => Ok(ProcQuery::NoneQuery),
    1 => Ok(match query.parse().ok() {
      Some(tid) => ProcQuery::PidQuery(tid),
      None => ProcQuery::NameQuery(query.to_owned())
    }),
    _ => {
      let q_text = splits[1].to_owned();
      let q_tid = q_text.parse();
      match &*splits[0].to_lowercase() {
        "pid" => q_tid.map(|q| ProcQuery::PidQuery(q))
          .or(Err("Query value for type 'pid' not valid".to_owned())),
        "ppid" => q_tid.map(|q| ProcQuery::PpidQuery(q))
          .or(Err("Query value for type 'ppid' not valid".to_owned())),
        "name" => Ok(ProcQuery::NameQuery(q_text)),
        "cmdline" => Ok(ProcQuery::CmdlineQuery(q_text)),
        _ => Err("Invalid query type".to_owned())
      }
    }
  }
}

pub fn taskid_query(tid: TaskId, query: TaskId) -> bool {
  tid == query
}

pub fn string_query(text: &str, query: &str) -> bool {
  text == query
}

pub fn string_s_query(text_vec: &Vec<String>, query: &str) -> bool {
  for text in text_vec {
    if string_query(text, query) {
      return true;
    }
  }
  false
}

<|endoftext|>


<commit_before>use chesstypes::*;
use board::MoveGenerator;

pub struct QsearchResult<T> {
    value: Value,
    searched_nodes: u64,
    hints: T,
}

/// A trait used to perform quiescence searches.
pub trait Qsearch {
    type Hints;
    type MoveGenerator: MoveGenerator;

    /// TODO
    fn qsearch(position: Self::MoveGenerator,
               halfmove_clock: u8,
               depth: Depth,
               lower_bound: Value,
               upper_bound: Value,
               static_evaluation: Value)
               -> QsearchResult<Self::Hints>;
}
<commit_msg>add QsearchParams struct<commit_after>use chesstypes::*;
use board::MoveGenerator;

/// Parameters describing a quiescence search.
pub struct QsearchParams<T: MoveGenerator> {
    /// The root position for the search.
    pub position: T,

    /// The number of half-moves since the last piece capture or pawn
    /// advance.
    pub halfmove_clock: u8,

    /// The requested search depth.
    ///
    /// This is the depth at which the main search stops and the
    /// quiescence search takes on. It should be between `DEPTH_MIN`
    /// and `DEPTH_MAX`. Normally, it will be zero or less. The
    /// quiescence search implementation may decide to perform less
    /// thorough analysis when `depth` is smaller.
    pub depth: Depth,

    /// The lower bound for the new search.
    ///
    /// Should be no lesser than `VALUE_MIN`.
    pub lower_bound: Value,

    /// The upper bound for the new search.
    ///
    /// Should be greater than `lower_bound`, but no greater than
    /// `VALUE_MAX`.
    pub upper_bound: Value,

    /// Position's static evaluation, or `VALUE_UNKNOWN`.
    ///
    /// Saves the re-calculation if position's static evaluation is
    /// already available.
    pub static_evaluation: Value,
}

/// Results from a quiescence search.
pub struct QsearchResult<T> {
    /// The calculated evaluation for the analyzed position.
    pub value: Value,

    /// The number of positions that were searched in order to
    /// calculate the evaluation.
    pub searched_nodes: u64,

    /// Auxiliary hints regarding the analyzed position.
    pub hints: T,
}

/// A trait used to perform quiescence searches.
pub trait Qsearch {
    type MoveGenerator: MoveGenerator;
    type Hints;

    /// TODO
    fn qsearch(params: QsearchParams<Self::MoveGenerator>) -> QsearchResult<Self::Hints>;
}
<|endoftext|>


<commit_before>use super::schema::*;

#[derive(Queryable, Identifiable)]
#[table_name="answer"]
pub struct Answer {
    pub id: i32,
    pub question_id: i32,
    pub text: String,
    pub is_correct: bool,
}

HasMany! {
    (answer, foreign_key = question_id)
    #[table_name(question)]
    #[derive(Queryable, Identifiable)]
    pub struct Question {
        pub id: i32,
        pub category_id: i32,
        pub text: String,
        pub answers: Vec<Answer>,
    }
}

HasMany! {
    (question, foreign_key = category_id)
    #[table_name(category)]
    #[derive(Queryable, Identifiable)]
    pub struct Category {
        pub id: i32,
        pub text: String,
    }
}

pub struct Player {}

pub struct Game {}
<commit_msg>Untangle the HasMany mess<commit_after>use super::schema::*;

#[table_name="category"]
#[derive(Queryable, Identifiable, Associations, Debug)]
#[has_many(question)]
pub struct Category {
        pub id: i32,
        pub text: String,
}

#[table_name="question"]
#[derive(Queryable, Identifiable, Associations)]
#[has_many(answer)]
#[belongs_to(Category)]
pub struct Question {
    pub id: i32,
    pub category_id: i32,
    pub text: String
}

#[table_name="answer"]
#[derive(Queryable, Identifiable, Associations)]
#[belongs_to(Question)]
pub struct Answer {
    pub id: i32,
    pub question_id: i32,
    pub text: String,
    pub is_correct: bool,
}

pub struct Player {}

pub struct Game {}
<|endoftext|>


<commit_before>use regex::RegexSet;

pub struct RouteRecognizer<T> {
    re: RegexSet,
    routes: Vec<T>,
}

impl<T> RouteRecognizer<T> {

    pub fn new<U, K>(routes: U) -> Self
        where U: IntoIterator<Item=(K, T)>, K: Into<String>,
    {
        let mut paths = Vec::new();
        let mut routes = Vec::new();
        for item in routes {
            let pattern = parse(&item.0.into());
            paths.push(pattern);
            routes.push(item.1);
        };
        let regset = RegexSet::new(&paths);

        RouteRecognizer {
            re: regset.unwrap(),
            routes: routes,
        }
    }

    pub fn recognize(&self, path: &str) -> Option<&T> {
        if path.is_empty() {
            if let Some(idx) = self.re.matches("/").into_iter().next() {
                return Some(&self.routes[idx])
            }
        } else if let Some(idx) = self.re.matches(path).into_iter().next() {
            return Some(&self.routes[idx])
        }
        None
    }
}

fn parse(pattern: &str) -> String {
    const DEFAULT_PATTERN: &str = "[^/]+";

    let mut re = String::from("^/");
    let mut in_param = false;
    let mut in_param_pattern = false;
    let mut param_name = String::new();
    let mut param_pattern = String::from(DEFAULT_PATTERN);

    for (index, ch) in pattern.chars().enumerate() {
        // All routes must have a leading slash so its optional to have one
        if index == 0 && ch == '/' {
            continue;
        }

        if in_param {
            // In parameter segment: `{....}`
            if ch == '}' {
                re.push_str(&format!(r"(?P<{}>{})", &param_name, &param_pattern));

                param_name.clear();
                param_pattern = String::from(DEFAULT_PATTERN);

                in_param_pattern = false;
                in_param = false;
            } else if ch == ':' {
                // The parameter name has been determined; custom pattern land
                in_param_pattern = true;
                param_pattern.clear();
            } else if in_param_pattern {
                // Ignore leading whitespace for pattern
                if !(ch == ' ' && param_pattern.is_empty()) {
                    param_pattern.push(ch);
                }
            } else {
                param_name.push(ch);
            }
        } else if ch == '{' {
            in_param = true;
        } else {
            re.push(ch);
        }
    }

    re.push('$');
    re
}

#[cfg(test)]
mod tests {
    use regex::Regex;
    use super::*;
    use std::iter::FromIterator;

    #[test]
    fn test_recognizer() {
        let routes = vec![
            ("/name", None, 1),
            ("/name/{val}", None, 2),
            ("/name/{val}/index.html", None, 3),
            ("/v{val}/{val2}/index.html", None, 4),
            ("/v/{tail:.*}", None, 5),
        ];
        let rec = RouteRecognizer::new("", routes);

        let (params, val) = rec.recognize("/name").unwrap();
        assert_eq!(*val, 1);
        assert!(params.unwrap().is_empty());

        let (params, val) = rec.recognize("/name/value").unwrap();
        assert_eq!(*val, 2);
        assert!(!params.as_ref().unwrap().is_empty());
        assert_eq!(params.as_ref().unwrap().get("val").unwrap(), "value");
        assert_eq!(&params.as_ref().unwrap()["val"], "value");

        let (params, val) = rec.recognize("/name/value2/index.html").unwrap();
        assert_eq!(*val, 3);
        assert!(!params.as_ref().unwrap().is_empty());
        assert_eq!(params.as_ref().unwrap().get("val").unwrap(), "value2");
        assert_eq!(params.as_ref().unwrap().by_idx(0).unwrap(), "value2");

        let (params, val) = rec.recognize("/vtest/ttt/index.html").unwrap();
        assert_eq!(*val, 4);
        assert!(!params.as_ref().unwrap().is_empty());
        assert_eq!(params.as_ref().unwrap().get("val").unwrap(), "test");
        assert_eq!(params.as_ref().unwrap().get("val2").unwrap(), "ttt");
        assert_eq!(params.as_ref().unwrap().by_idx(0).unwrap(), "test");
        assert_eq!(params.as_ref().unwrap().by_idx(1).unwrap(), "ttt");

        let (params, val) = rec.recognize("/v/blah-blah/index.html").unwrap();
        assert_eq!(*val, 5);
        assert!(!params.as_ref().unwrap().is_empty());
        assert_eq!(params.as_ref().unwrap().get("tail").unwrap(), "blah-blah/index.html");
    }

    fn assert_parse(pattern: &str, expected_re: &str) -> Regex {
        let (re_str, _) = parse(pattern);
        assert_eq!(&*re_str, expected_re);
        Regex::new(&re_str).unwrap()
    }

    #[test]
    fn test_parse_static() {
        let re = assert_parse("/", r"^/$");
        assert!(re.is_match("/"));
        assert!(!re.is_match("/a"));

        let re = assert_parse("/name", r"^/name$");
        assert!(re.is_match("/name"));
        assert!(!re.is_match("/name1"));
        assert!(!re.is_match("/name/"));
        assert!(!re.is_match("/name~"));

        let re = assert_parse("/name/", r"^/name/$");
        assert!(re.is_match("/name/"));
        assert!(!re.is_match("/name"));
        assert!(!re.is_match("/name/gs"));

        let re = assert_parse("/user/profile", r"^/user/profile$");
        assert!(re.is_match("/user/profile"));
        assert!(!re.is_match("/user/profile/profile"));
    }

    #[test]
    fn test_parse_param() {
        let re = assert_parse("/user/{id}", r"^/user/(?P<id>[^/]+)$");
        assert!(re.is_match("/user/profile"));
        assert!(re.is_match("/user/2345"));
        assert!(!re.is_match("/user/2345/"));
        assert!(!re.is_match("/user/2345/sdg"));

        let captures = re.captures("/user/profile").unwrap();
        assert_eq!(captures.get(1).unwrap().as_str(), "profile");
        assert_eq!(captures.name("id").unwrap().as_str(), "profile");

        let captures = re.captures("/user/1245125").unwrap();
        assert_eq!(captures.get(1).unwrap().as_str(), "1245125");
        assert_eq!(captures.name("id").unwrap().as_str(), "1245125");

        let re = assert_parse(
            "/v{version}/resource/{id}",
            r"^/v(?P<version>[^/]+)/resource/(?P<id>[^/]+)$",
        );
        assert!(re.is_match("/v1/resource/320120"));
        assert!(!re.is_match("/v/resource/1"));
        assert!(!re.is_match("/resource"));

        let captures = re.captures("/v151/resource/adahg32").unwrap();
        assert_eq!(captures.get(1).unwrap().as_str(), "151");
        assert_eq!(captures.name("version").unwrap().as_str(), "151");
        assert_eq!(captures.name("id").unwrap().as_str(), "adahg32");
    }
}
<commit_msg>remove unused file<commit_after><|endoftext|>


<commit_before>use std::fs::File;
use std::io::Read;
use std::path::Path;
use std::io;
use std::io::Seek;
use std::io::SeekFrom;

#[derive(Debug)]
pub enum InesError {
  Io(io::Error),
  InesFormat(String),
  Unsupported(String),
}

impl From<io::Error> for InesError {
    fn from(err: io::Error) -> InesError {
        InesError::Io(err)
    }
}
#[repr(C,packed)]
pub struct InesHeader {
  ines_identifier: u32,
  prg_rom_banks: u8,
  chr_rom_banks: u8,
  flags_6: u8,
  flags_7: u8,
  prg_ram_units: u8,
  padding: [u8;7],
}

// http://wiki.nesdev.com/w/index.php/INES
//
pub fn load_ines<P:AsRef<Path>>(file_path: P) -> Result<Vec<u8>,InesError> {
    let mut file = try!(File::open(&file_path));
    let metadata = try!(::std::fs::metadata(&file_path));
    if metadata.len() < ::std::mem::size_of::<InesHeader>() as u64 {
        return Err(InesError::InesFormat("File is smaller than the ines header.".to_string()));
    }

    let header = unsafe {
        let mut header_buf = [0u8;16];
        let _ = file.read(&mut header_buf);

        ::std::mem::transmute::<_,InesHeader>(header_buf)
    };
    if header.ines_identifier != 0x1A53454E {
        return Err(InesError::InesFormat("Did not find ines header identifier".to_string()));
    }
    if header.flags_7 != 0 {
        return Err(InesError::Unsupported("This version of the ines format is not supported".to_string()));
    }
    if header.flags_6 & 0x04 != 0 {
        return Err(InesError::Unsupported("Loading trainers is not supported".to_string()));
    }

    let _  = file.seek(SeekFrom::Start(0));

    let mut file_bytes = Vec::<u8>::new();
    try!(file.read_to_end(&mut file_bytes));

    // https://en.wikibooks.org/wiki/NES_Programming/Memory_Map
    //
    let mut nes_bytes = Vec::<u8>::with_capacity(::std::u16::MAX as usize);
    nes_bytes.resize(::std::u16::MAX as usize,0);

    let prg_addr = 16;
    let prg_page_len = 0xBFFF - 0x8000;

    // NOTE: the below implementation is terrible.  I don't know how to memcpy from 1
    //       vector to another, so we do it manually.  As far as I'm concerned, this is
    //       *more* error prone than simply calling a memcpy function, but I'm still
    //       learning rust and it is what it is.
    //

    // nes has 2 prg-rom pages at 0x8000 and 0xC000
    // if the rom has only a single prg-rom page, then we mirror it
    //
    for i in 0..prg_page_len {
        nes_bytes[0x8000+i] = file_bytes[prg_addr+i];
        if header.prg_rom_banks == 1 {
            nes_bytes[0xC000+i] = file_bytes[prg_addr+i];
        }
        else {
            nes_bytes[0xC000+i] = file_bytes[prg_addr+prg_page_len+i];
        }
    }

    Ok(nes_bytes)
}

<commit_msg>instead of squelching warnings, we're now wrapping the file operations in try!<commit_after>use std::fs::File;
use std::io::Read;
use std::path::Path;
use std::io;
use std::io::Seek;
use std::io::SeekFrom;

#[derive(Debug)]
pub enum InesError {
  Io(io::Error),
  InesFormat(String),
  Unsupported(String),
}

impl From<io::Error> for InesError {
    fn from(err: io::Error) -> InesError {
        InesError::Io(err)
    }
}
#[repr(C,packed)]
pub struct InesHeader {
  ines_identifier: u32,
  prg_rom_banks: u8,
  chr_rom_banks: u8,
  flags_6: u8,
  flags_7: u8,
  prg_ram_units: u8,
  padding: [u8;7],
}

// http://wiki.nesdev.com/w/index.php/INES
//
pub fn load_ines<P:AsRef<Path>>(file_path: P) -> Result<Vec<u8>,InesError> {
    let mut file = try!(File::open(&file_path));
    let metadata = try!(::std::fs::metadata(&file_path));
    if metadata.len() < ::std::mem::size_of::<InesHeader>() as u64 {
        return Err(InesError::InesFormat("File is smaller than the ines header.".to_string()));
    }

    let mut header_buf = [0u8;16];
    try!(file.read(&mut header_buf));
    let header = unsafe { ::std::mem::transmute::<_,InesHeader>(header_buf) };

    if header.ines_identifier != 0x1A53454E {
        return Err(InesError::InesFormat("Did not find ines header identifier".to_string()));
    }
    if header.flags_7 != 0 {
        return Err(InesError::Unsupported("This version of the ines format is not supported".to_string()));
    }
    if header.flags_6 & 0x04 != 0 {
        return Err(InesError::Unsupported("Loading trainers is not supported".to_string()));
    }

    try!(file.seek(SeekFrom::Start(0)));

    let mut file_bytes = Vec::<u8>::new();
    try!(file.read_to_end(&mut file_bytes));

    // https://en.wikibooks.org/wiki/NES_Programming/Memory_Map
    //
    let mut nes_bytes = Vec::<u8>::with_capacity(::std::u16::MAX as usize);
    nes_bytes.resize(::std::u16::MAX as usize,0);

    let prg_addr = 16;
    let prg_page_len = 0xBFFF - 0x8000;

    // NOTE: the below implementation is terrible.  I don't know how to memcpy from 1
    //       vector to another, so we do it manually.  As far as I'm concerned, this is
    //       *more* error prone than simply calling a memcpy function, but I'm still
    //       learning rust and it is what it is.
    //

    // nes has 2 prg-rom pages at 0x8000 and 0xC000
    // if the rom has only a single prg-rom page, then we mirror it
    //
    for i in 0..prg_page_len {
        nes_bytes[0x8000+i] = file_bytes[prg_addr+i];
        if header.prg_rom_banks == 1 {
            nes_bytes[0xC000+i] = file_bytes[prg_addr+i];
        }
        else {
            nes_bytes[0xC000+i] = file_bytes[prg_addr+prg_page_len+i];
        }
    }

    Ok(nes_bytes)
}

<|endoftext|>