<commit_before>//! Toolbox to make text layout easier.

use unicode_segmentation::UnicodeSegmentation;
use unicode_width::UnicodeWidthStr;

mod lines_iterator;
mod reader;

pub use self::lines_iterator::{LinesIterator, Row};
pub use self::reader::ProgressReader;

/// The length and width of a part of a string.
pub struct Prefix {
    /// The length (in bytes) of the string.
    pub length: usize,
    /// The unicode-width of the string.
    pub width: usize
}

/// Computes the length (number of bytes) and width of a prefix that fits in the given `width`.
///
/// Takes non-breakable elements from `iter`, while keeping the
/// string width under `width` (and adding the length of `delimiter`
/// between each element).
///
/// Given `total_text = iter.collect().join(delimiter)`, the result
/// is the length of the longest prefix of `width` or less cells,
/// without breaking inside an element.
///
/// Example:
///
/// ```
/// # extern crate cursive;
/// extern crate unicode_segmentation;
/// use unicode_segmentation::UnicodeSegmentation;
///
/// # use cursive::utils::prefix;
/// # fn main() {
/// let my_text = "blah...";
/// // This returns the number of bytes for a prefix of `my_text` that
/// // fits within 5 cells.
/// prefix(my_text.graphemes(true), 5, "");
/// # }
/// ```
pub fn prefix<'a, I>(iter: I, available_width: usize, delimiter: &str) -> Prefix
    where I: Iterator<Item = &'a str>
{
    let delimiter_width = delimiter.width();
    let delimiter_len = delimiter.len();

    // `current_width` is the width of everything
    // before the next token, including any space.
    let mut current_width = 0;
    let sum = iter.take_while(|token| {
            let width = token.width();
            if current_width + width > available_width {
                false
            } else {
                // Include the delimiter after this token.
                current_width += width;
                current_width += delimiter_width;
                true
            }
        })
        .map(|token| token.len() + delimiter_len)
        .fold(0, |a, b| a + b);

    // We counted delimiter once too many times,
    // but only if the iterator was non empty.
    let length = sum.saturating_sub(delimiter_len);

    // `current_width` includes a delimiter after the last token
    debug_assert!(current_width <= available_width + delimiter_width);

    Prefix {
        length: length,
        width: current_width
    }
}

/// Computes the length (number of bytes) and width of a suffix that fits in the given `width`.
///
/// Doesn't break inside elements returned by `iter`.
///
/// Returns the number of bytes of the longest
/// suffix from `text` that fits in `width`.
///
/// This is a shortcut for `prefix_length(iter.rev(), width, delimiter)`
pub fn suffix<'a, I>(iter: I, width: usize, delimiter: &str) -> Prefix
    where I: DoubleEndedIterator<Item = &'a str>
{
    prefix(iter.rev(), width, delimiter)
}

/// Computes the length (number of bytes) and width of a suffix that fits in the given `width`.
///
/// Breaks between any two graphemes.
pub fn simple_suffix(text: &str, width: usize) -> Prefix {
    suffix(text.graphemes(true), width, "")
}

#[cfg(test)]
mod tests {
    use utils;

    #[test]
    fn test_prefix() {
        assert_eq!(utils::prefix(" abra ".split(' '), 5, " ").length, 5);
        assert_eq!(utils::prefix("abra a".split(' '), 5, " ").length, 4);
        assert_eq!(utils::prefix("a a br".split(' '), 5, " ").length, 3);
    }
}
<commit_msg>use Iterator::sum() for summing instead of fold<commit_after>//! Toolbox to make text layout easier.

use unicode_segmentation::UnicodeSegmentation;
use unicode_width::UnicodeWidthStr;

mod lines_iterator;
mod reader;

pub use self::lines_iterator::{LinesIterator, Row};
pub use self::reader::ProgressReader;

/// The length and width of a part of a string.
pub struct Prefix {
    /// The length (in bytes) of the string.
    pub length: usize,
    /// The unicode-width of the string.
    pub width: usize
}

/// Computes the length (number of bytes) and width of a prefix that fits in the given `width`.
///
/// Takes non-breakable elements from `iter`, while keeping the
/// string width under `width` (and adding the length of `delimiter`
/// between each element).
///
/// Given `total_text = iter.collect().join(delimiter)`, the result
/// is the length of the longest prefix of `width` or less cells,
/// without breaking inside an element.
///
/// Example:
///
/// ```
/// # extern crate cursive;
/// extern crate unicode_segmentation;
/// use unicode_segmentation::UnicodeSegmentation;
///
/// # use cursive::utils::prefix;
/// # fn main() {
/// let my_text = "blah...";
/// // This returns the number of bytes for a prefix of `my_text` that
/// // fits within 5 cells.
/// prefix(my_text.graphemes(true), 5, "");
/// # }
/// ```
pub fn prefix<'a, I>(iter: I, available_width: usize, delimiter: &str) -> Prefix
    where I: Iterator<Item = &'a str>
{
    let delimiter_width = delimiter.width();
    let delimiter_len = delimiter.len();

    // `current_width` is the width of everything
    // before the next token, including any space.
    let mut current_width = 0;
    let sum: usize = iter.take_while(|token| {
            let width = token.width();
            if current_width + width > available_width {
                false
            } else {
                // Include the delimiter after this token.
                current_width += width;
                current_width += delimiter_width;
                true
            }
        })
        .map(|token| token.len() + delimiter_len)
        .sum();

    // We counted delimiter once too many times,
    // but only if the iterator was non empty.
    let length = sum.saturating_sub(delimiter_len);

    // `current_width` includes a delimiter after the last token
    debug_assert!(current_width <= available_width + delimiter_width);

    Prefix {
        length: length,
        width: current_width
    }
}

/// Computes the length (number of bytes) and width of a suffix that fits in the given `width`.
///
/// Doesn't break inside elements returned by `iter`.
///
/// Returns the number of bytes of the longest
/// suffix from `text` that fits in `width`.
///
/// This is a shortcut for `prefix_length(iter.rev(), width, delimiter)`
pub fn suffix<'a, I>(iter: I, width: usize, delimiter: &str) -> Prefix
    where I: DoubleEndedIterator<Item = &'a str>
{
    prefix(iter.rev(), width, delimiter)
}

/// Computes the length (number of bytes) and width of a suffix that fits in the given `width`.
///
/// Breaks between any two graphemes.
pub fn simple_suffix(text: &str, width: usize) -> Prefix {
    suffix(text.graphemes(true), width, "")
}

#[cfg(test)]
mod tests {
    use utils;

    #[test]
    fn test_prefix() {
        assert_eq!(utils::prefix(" abra ".split(' '), 5, " ").length, 5);
        assert_eq!(utils::prefix("abra a".split(' '), 5, " ").length, 4);
        assert_eq!(utils::prefix("a a br".split(' '), 5, " ").length, 3);
    }
}
<|endoftext|>


<commit_before>// Copyright (c) The Libra Core Contributors
// SPDX-License-Identifier: Apache-2.0

use libra_swarm::{client, swarm::LibraSwarm};
use std::path::Path;
use structopt::StructOpt;

#[derive(Debug, StructOpt)]
#[structopt(
    name = "libra_swarm",
    author = "Libra",
    about = "Libra swarm to start local nodes"
)]
struct Args {
    /// Number of nodes to start (1 by default)
    #[structopt(short = "n", long = "num_nodes")]
    pub num_nodes: Option<usize>,
    /// Disable logging (for performance testing)"
    #[structopt(short = "d", long = "disable_logging")]
    pub disable_logging: bool,
    /// Start client
    #[structopt(short = "s", long = "start_client")]
    pub start_client: bool,
    /// Path to the generated keypair for faucet account.  Generated by generate_keypair.
    /// If not passed, a new keypair will be generated for you and placed in a temp directory
    #[structopt(short = "m", long = "faucet_key_file_path")]
    pub faucet_key_file_path: Option<String>,
}

fn main() {
    let args = Args::from_args();
    let num_nodes = args.num_nodes.unwrap_or(1);

    let (faucet_account_keypair, faucet_key_file_path, _temp_dir) =
        generate_keypair::load_faucet_key_or_create_default(args.faucet_key_file_path);

    println!("Faucet account created in file {:?}", faucet_key_file_path);

    let swarm = LibraSwarm::launch_swarm(
        num_nodes,
        args.disable_logging,
        faucet_account_keypair,
        false, /* tee_logs */
    );

    let tmp_mnemonic_file = tempfile::NamedTempFile::new().unwrap();;
    if args.start_client {
        let client = client::InteractiveClient::new_with_inherit_io(
            *swarm.get_validators_public_ports().get(0).unwrap(),
            Path::new(&faucet_key_file_path),
            &tmp_mnemonic_file.into_temp_path(),
            swarm.get_trusted_peers_config_path(),
        );
        println!("Loading client...");
        let _output = client.output().expect("Failed to wait on child");
        println!("Exit client.");
    } else {
        println!("CTRL-C to exit.");
        loop {
            std::thread::park();
        }
    }
}
<commit_msg>[libra_swarm] retire mint key option<commit_after>// Copyright (c) The Libra Core Contributors
// SPDX-License-Identifier: Apache-2.0

use libra_swarm::{client, swarm::LibraSwarm};
use std::path::Path;
use structopt::StructOpt;

#[derive(Debug, StructOpt)]
#[structopt(
    name = "libra_swarm",
    author = "Libra",
    about = "Libra swarm to start local nodes"
)]
struct Args {
    /// Number of nodes to start (1 by default)
    #[structopt(short = "n", long = "num_nodes")]
    pub num_nodes: Option<usize>,
    /// Disable logging (for performance testing)"
    #[structopt(short = "d", long = "disable_logging")]
    pub disable_logging: bool,
    /// Start client
    #[structopt(short = "s", long = "start_client")]
    pub start_client: bool,
}

fn main() {
    let args = Args::from_args();
    let num_nodes = args.num_nodes.unwrap_or(1);

    let (faucet_account_keypair, faucet_key_file_path, _temp_dir) =
        generate_keypair::load_faucet_key_or_create_default(None);

    println!("Faucet account created in file {:?}", faucet_key_file_path);

    let swarm = LibraSwarm::launch_swarm(
        num_nodes,
        args.disable_logging,
        faucet_account_keypair,
        false, /* tee_logs */
    );

    let tmp_mnemonic_file = tempfile::NamedTempFile::new().unwrap();;
    if args.start_client {
        let client = client::InteractiveClient::new_with_inherit_io(
            *swarm.get_validators_public_ports().get(0).unwrap(),
            Path::new(&faucet_key_file_path),
            &tmp_mnemonic_file.into_temp_path(),
            swarm.get_trusted_peers_config_path(),
        );
        println!("Loading client...");
        let _output = client.output().expect("Failed to wait on child");
        println!("Exit client.");
    } else {
        println!("CTRL-C to exit.");
        loop {
            std::thread::park();
        }
    }
}
<|endoftext|>


<commit_before>use cookie_factory::*;

pub fn vint_size(i: u64) -> u8 {
    let mut val = 1;

    loop {
        if ((i + 1) >> val * 7) == 0 {
            break;
        }

        val += 1;
    }
    val
}

pub fn log2(i: u64) -> u32 {
    let res = 64 - (i | 1).leading_zeros();
    println!("log2({}) = {}", i, res);
    res
}

pub fn vid_size(i: u64) -> u8 {
    //((log2(i + 1) - 1) / 7 + 1) as u8
    ((log2(i + 1) - 1) / 7) as u8
}

pub fn gen_vint<'a>(mut input: (&'a mut [u8], usize),
                    mut num: u64)
                    -> Result<(&'a mut [u8], usize), GenError> {
    let needed_bytes = vint_size(num);
    println!("needed bytes: {}", needed_bytes);

    assert!(num < (1u64 << 56) - 1);

    num |= 1u64 << needed_bytes * 7;

    let mut i = needed_bytes - 1;
    loop {

        match gen_be_u8!(input, (num >> i * 8) as u8) {
            Ok(next) => {
                input = next;
            }
            Err(e) => return Err(e),
        }

        if i == 0 {
            break;
        }
        i -= 1;
    }

    Ok(input)
}

pub fn gen_vid<'a>(mut input: (&'a mut [u8], usize),
                   mut num: u64)
                   -> Result<(&'a mut [u8], usize), GenError> {
    let needed_bytes = vid_size(num);
    println!("needed bytes: {}", needed_bytes);

    //num |= 1u64 << needed_bytes * 7;

    let index = 0;
    let mut i = needed_bytes - 1;

    loop {

        match gen_be_u8!(input, (num >> i * 8) as u8) {
            Ok(next) => {
                input = next;
            }
            Err(e) => return Err(e),
        }

        if i == 0 {
            break;
        }
        i -= 1;
    }

    Ok(input)
}

/*
pub fn vid_size(id: u64) -> u8 {

}
*/

pub fn gen_u64<'a>(input: (&'a mut [u8], usize),
                   id: u64,
                   num: u64)
                   -> Result<(&'a mut [u8], usize), GenError> {
    do_gen!(input,
    gen_call!(gen_vid, id) >>
    gen_call!(gen_vint, 8)  >>
    gen_be_u64!(num)
  )
}

pub fn gen_u8<'a>(input: (&'a mut [u8], usize),
                  id: u64,
                  num: u8)
                  -> Result<(&'a mut [u8], usize), GenError> {
    do_gen!(input,
    gen_call!(gen_vid, id) >>
    gen_call!(gen_vint, 1)  >>
    gen_be_u8!(num)
  )
}

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

    fn test_vint_serializer(i: u64) -> bool {
        println!("testing for {}", i);

        let mut data = [0u8; 10];
        {
            let gen_res = gen_vint((&mut data[..], 0), i);
            println!("gen_res: {:?}", gen_res);
        }
        println!("{}", (&data[..]).to_hex(16));

        let parse_res = ::ebml::vint(&data[..]);
        println!("parse_res: {:?}", parse_res);
        match parse_res {
            IResult::Done(rest, o) => {
                assert_eq!(i, o);
                return true;
            }
            e => panic!(format!("parse error: {:?}", e)),
        }

        false
    }

    quickcheck! {
    fn test_vint(i: u64) -> bool {
      test_vint_serializer(i)
    }
  }

    #[test]
    fn vint() {
        test_vint_serializer(0);
        test_vint_serializer(8);
        test_vint_serializer(127);
        test_vint_serializer(128);
        test_vint_serializer(2100000);
    }

    fn test_vid_serializer(id: u64) -> bool {
        println!("\ntesting for id={}", id);

        let mut data = [0u8; 10];
        {
            let gen_res = gen_vid((&mut data[..], 0), id);
            println!("gen_res: {:?}", gen_res);
        }
        println!("{}", (&data[..]).to_hex(16));

        let parse_res = ::ebml::vid(&data[..]);
        println!("parse_res: {:?}", parse_res);
        match parse_res {
            IResult::Done(rest, o) => {
                println!("id={:08b}, parsed={:08b}", id, o);
                assert_eq!(id, o);
                return true;
            }
            e => panic!(format!("parse error: {:?}", e)),
        }

        false
    }

    #[test]
    fn vid() {
        test_vid_serializer(128);
        test_vid_serializer(0x4286);
        test_vid_serializer(0x1A45DFA3);
    }

    fn test_ebml_u64_serializer(num: u64) -> bool {
        let id = 0x9F;
        println!("\ntesting for id={}, num={}", id, num);

        let mut data = [0u8; 100];
        {
            let gen_res = gen_u64((&mut data[..], 0), id, num);
            println!("gen_res: {:?}", gen_res);
        }
        println!("{}", (&data[..]).to_hex(16));

        let parse_res = ebml_uint!(&data[..], id);
        println!("parse_res: {:?}", parse_res);
        match parse_res {
            IResult::Done(rest, o) => {
                assert_eq!(num, o);
                return true;
            }
            e => panic!(format!("parse error: {:?}", e)),
        }

        false
    }

    quickcheck! {
    fn test_ebml_u64(i: u64) -> bool {
      test_ebml_u64_serializer(i)
    }
  }

    #[test]
    fn ebml_u64() {
        test_ebml_u64_serializer(0);
        test_ebml_u64_serializer(8);
        test_ebml_u64_serializer(127);
        test_ebml_u64_serializer(128);
        test_ebml_u64_serializer(2100000);
    }

    quickcheck! {
  fn test_ebml_u8(num: u8) -> bool {
    let id = 0x9F;
    println!("testing for id={}, num={}", id, num);

    let mut data = [0u8; 100];
    {
      let gen_res = gen_u8((&mut data[..], 0), id, num);
      println!("gen_res: {:?}", gen_res);
    }
    println!("{}", (&data[..]).to_hex(16));

    let parse_res = ebml_uint!(&data[..], id);
    println!("parse_res: {:?}", parse_res);
    match parse_res {
      IResult::Done(rest, o) => {
        assert_eq!(num as u64, o);
        return true;
      },
      e => panic!(format!("parse error: {:?}", e)),
    }

    false
  }
}

}
<commit_msg>serialize the EBML header<commit_after>use cookie_factory::*;
use ebml::EBMLHeader;

pub fn vint_size(i: u64) -> u8 {
    let mut val = 1;

    loop {
        if ((i + 1) >> val * 7) == 0 {
            break;
        }

        val += 1;
    }
    val
}

pub fn log2(i: u64) -> u32 {
    let res = 64 - (i | 1).leading_zeros();
    res
}

pub fn vid_size(i: u64) -> u8 {
    ((log2(i + 1) - 1) / 7) as u8
}

pub fn gen_vint<'a>(mut input: (&'a mut [u8], usize),
                    mut num: u64)
                    -> Result<(&'a mut [u8], usize), GenError> {
    let needed_bytes = vint_size(num);

    assert!(num < (1u64 << 56) - 1);

    num |= 1u64 << needed_bytes * 7;

    let mut i = needed_bytes - 1;
    loop {

        match gen_be_u8!(input, (num >> i * 8) as u8) {
            Ok(next) => {
                input = next;
            }
            Err(e) => return Err(e),
        }

        if i == 0 {
            break;
        }
        i -= 1;
    }

    Ok(input)
}

pub fn gen_vid<'a>(mut input: (&'a mut [u8], usize),
                   mut num: u64)
                   -> Result<(&'a mut [u8], usize), GenError> {
    let needed_bytes = vid_size(num);

    let index = 0;
    let mut i = needed_bytes - 1;

    loop {

        match gen_be_u8!(input, (num >> i * 8) as u8) {
            Ok(next) => {
                input = next;
            }
            Err(e) => return Err(e),
        }

        if i == 0 {
            break;
        }
        i -= 1;
    }

    Ok(input)
}

pub fn gen_uint<'a>(mut input: (&'a mut [u8], usize),
                    mut num: u64)
                    -> Result<(&'a mut [u8], usize), GenError> {
    let needed_bytes = vint_size(num);

    let mut i = needed_bytes - 1;
    loop {

        match gen_be_u8!(input, (num >> i * 8) as u8) {
            Ok(next) => {
                input = next;
            }
            Err(e) => return Err(e),
        }

        if i == 0 {
            break;
        }
        i -= 1;
    }

    Ok(input)
}

/*
pub fn vid_size(id: u64) -> u8 {

}
*/

pub fn gen_u64<'a>(input: (&'a mut [u8], usize),
                   id: u64,
                   num: u64)
                   -> Result<(&'a mut [u8], usize), GenError> {
    do_gen!(input,
    gen_call!(gen_vid, id) >>
    gen_call!(gen_vint, 8)  >>
    gen_be_u64!(num)
  )
}

pub fn gen_u32<'a>(input: (&'a mut [u8], usize),
                   id: u64,
                   num: u32)
                   -> Result<(&'a mut [u8], usize), GenError> {
    do_gen!(input,
    gen_call!(gen_vid, id) >>
    gen_call!(gen_vint, 4)  >>
    gen_be_u32!(num)
  )
}

pub fn gen_u16<'a>(input: (&'a mut [u8], usize),
                   id: u64,
                   num: u16)
                   -> Result<(&'a mut [u8], usize), GenError> {
    do_gen!(input,
    gen_call!(gen_vid, id) >>
    gen_call!(gen_vint, 2)  >>
    gen_be_u16!(num)
  )
}

pub fn gen_u8<'a>(input: (&'a mut [u8], usize),
                  id: u64,
                  num: u8)
                  -> Result<(&'a mut [u8], usize), GenError> {
    do_gen!(input,
    gen_call!(gen_vid, id) >>
    gen_call!(gen_vint, 1)  >>
    gen_be_u8!(num)
  )
}

pub fn gen_i64<'a>(input: (&'a mut [u8], usize),
                   id: u64,
                   num: i64)
                   -> Result<(&'a mut [u8], usize), GenError> {
    do_gen!(input,
    gen_call!(gen_vid, id) >>
    gen_call!(gen_vint, 8)  >>
    gen_be_i64!(num)
  )
}

pub fn gen_i32<'a>(input: (&'a mut [u8], usize),
                   id: u64,
                   num: i32)
                   -> Result<(&'a mut [u8], usize), GenError> {
    do_gen!(input,
    gen_call!(gen_vid, id) >>
    gen_call!(gen_vint, 4)  >>
    gen_be_i32!(num)
  )
}

pub fn gen_i16<'a>(input: (&'a mut [u8], usize),
                   id: u64,
                   num: i16)
                   -> Result<(&'a mut [u8], usize), GenError> {
    do_gen!(input,
    gen_call!(gen_vid, id) >>
    gen_call!(gen_vint, 2)  >>
    gen_be_i16!(num)
  )
}

pub fn gen_i8<'a>(input: (&'a mut [u8], usize),
                  id: u64,
                  num: i8)
                  -> Result<(&'a mut [u8], usize), GenError> {
    do_gen!(input,
    gen_call!(gen_vid, id) >>
    gen_call!(gen_vint, 1)  >>
    gen_be_i8!(num)
  )
}

#[macro_export]
macro_rules! gen_ebml_size (
  (($i:expr, $idx:expr), $expected_size:expr, $size:expr) => ({
    let v = vint_size($size);
    //println!("size: {}, vint_size: {}, expected_size: {}", $size, v, $expected_size);

    if v > $expected_size {
      Err(GenError::CustomError(0))
    } else {
      gen_call!(($i, $idx), gen_vint, $size)
    }
  })
);

#[macro_export]
macro_rules! gen_ebml_master (
  (($i:expr, $idx:expr), $id:expr, $expected_size:expr, $($rest:tt)*) => (
    do_gen!(($i, $idx),
                  gen_call!(gen_vid, $id)
      >> ofs_len: gen_skip!($expected_size)
      >> start:   do_gen!($($rest)*)
      >> end:     gen_at_offset!(ofs_len, gen_ebml_size!($expected_size, (end-start) as u64))
      //>> end:     gen_dbg!(gen_at_offset!(ofs_len, gen_call!(gen_vint, (end-start) as u64)))
    )
  );
  (($i:expr, $idx:expr), $id:expr, $($rest:tt)*) => (
    gen_ebml_master!(($i, $idx), $id, 8, $($rest)*)
  );
  ($input:expr, $id:expr, $expected_size:expr, $($rest:tt)*) => (
    gen_ebml_master!(($input.0, $input.1), $id, $expected_size, $($rest)*)
  );
  ($input:expr, $id:expr, $($rest:tt)*) => (
    gen_ebml_master!(($input.0, $input.1), $id, 8, $($rest)*)
  );
);

#[macro_export]
macro_rules! gen_ebml_uint (
  (($i:expr, $idx:expr), $id:expr, $num:expr, $expected_size:expr) => (
    do_gen!(($i, $idx),
                  gen_call!(gen_vid, $id)
      >> ofs_len: gen_skip!($expected_size)
      >> start:   gen_dbg!(gen_call!(gen_uint, $num))
      >> end:     gen_at_offset!(ofs_len, gen_ebml_size!($expected_size, (end-start) as u64))
    )
  );
  (($i:expr, $idx:expr), $id:expr, $num:expr) => (
    gen_ebml_uint!(($i, $idx), $id, $num, 8)
  );
);

#[macro_export]
macro_rules! gen_ebml_str (
  (($i:expr, $idx:expr), $id:expr, $s:expr) => ({
    let v = vint_size($s.len() as u64);

    do_gen!(($i, $idx),
                  gen_call!(gen_vid, $id)
      >> ofs_len: gen_skip!(v as usize)
      >> start:   gen_slice!(($s.as_bytes()))
      >> end:     gen_at_offset!(ofs_len, gen_ebml_size!(v, (end-start) as u64))
    )
  });
);

#[macro_export]
macro_rules! gen_dbg (
  (($i:expr, $idx:expr), $submac:ident!( $($args:tt)*)) => ({
    gen_dbg!(__impl $i, $idx, $submac!($($args)*))
  });

  ($input:expr, $submac:ident!( $($args:tt)*)) => ({

    let (i, idx) = $input;
    gen_dbg!(__impl i, idx, $submac!($($args)*))
  });

  (__impl $i:expr, $idx:expr, $submac:ident!( $($args:tt)* )) => ({
    use nom::HexDisplay;
    use std::slice::from_raw_parts_mut;

    let (i, idx) = ($i, $idx);

    let p = i.as_ptr() as usize;
    let len = i.len();
    let res = ($submac!((i,idx), $($args)*)).map(|(j,idx2)| idx2 + (j.as_ptr() as usize) - p);

    match res {
      Ok(index) => {
        let sl = unsafe {
          from_raw_parts_mut(p as *mut u8, len)
        };
        println!("gen_dbg {}->{}: {}:\n{}", idx, index, stringify!($submac!($($args)*)), (&sl[idx..index]).to_hex(16));
        Ok((sl, index))
      },
      Err(e) => Err(e),
    }
  });
);

//trace_macros!(true);
pub fn gen_ebml_header<'a>(input: (&'a mut [u8], usize),
                           h: &EBMLHeader)
                           -> Result<(&'a mut [u8], usize), GenError> {
    gen_ebml_master!(input,
    0x1A45DFA3, 1,
       gen_dbg!(gen_ebml_uint!(0x4286, h.version, 1))
    >> gen_ebml_uint!(0x42F7, h.read_version, 1)
    >> gen_ebml_uint!(0x42F2, h.max_id_length, 1)
    >> gen_ebml_uint!(0x42F3, h.max_size_length, 1)
    >> gen_ebml_str!(0x4282, h.doc_type)
    >> gen_ebml_uint!(0x4287, h.doc_type_version, 1)
    >> gen_ebml_uint!(0x4285, h.doc_type_read_version, 1)

  )
}

pub fn gen_u64_a<'a>(input: (&'a mut [u8], usize),
                     num: u64)
                     -> Result<(&'a mut [u8], usize), GenError> {
    gen_dbg!((input.0, input.1), gen_be_u64!(num))
}

//trace_macros!(false);

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

    fn test_vint_serializer(i: u64) -> bool {
        println!("testing for {}", i);

        let mut data = [0u8; 10];
        {
            let gen_res = gen_vint((&mut data[..], 0), i);
            println!("gen_res: {:?}", gen_res);
        }
        println!("{}", (&data[..]).to_hex(16));

        let parse_res = ::ebml::vint(&data[..]);
        println!("parse_res: {:?}", parse_res);
        match parse_res {
            IResult::Done(rest, o) => {
                assert_eq!(i, o);
                return true;
            }
            e => panic!(format!("parse error: {:?}", e)),
        }

        false
    }

    quickcheck! {
    fn test_vint(i: u64) -> bool {
      test_vint_serializer(i)
    }
  }

    #[test]
    fn vint() {
        test_vint_serializer(0);
        test_vint_serializer(8);
        test_vint_serializer(127);
        test_vint_serializer(128);
        test_vint_serializer(2100000);
    }

    fn test_vid_serializer(id: u64) -> bool {
        println!("\ntesting for id={}", id);

        let mut data = [0u8; 10];
        {
            let gen_res = gen_vid((&mut data[..], 0), id);
            println!("gen_res: {:?}", gen_res);
        }
        println!("{}", (&data[..]).to_hex(16));

        let parse_res = ::ebml::vid(&data[..]);
        println!("parse_res: {:?}", parse_res);
        match parse_res {
            IResult::Done(rest, o) => {
                println!("id={:08b}, parsed={:08b}", id, o);
                assert_eq!(id, o);
                return true;
            }
            e => panic!(format!("parse error: {:?}", e)),
        }

        false
    }

    #[test]
    fn vid() {
        test_vid_serializer(128);
        test_vid_serializer(0x4286);
        test_vid_serializer(0x1A45DFA3);
    }

    fn test_ebml_u64_serializer(num: u64) -> bool {
        let id = 0x9F;
        println!("\ntesting for id={}, num={}", id, num);

        let mut data = [0u8; 100];
        {
            let gen_res = gen_u64((&mut data[..], 0), id, num);
            println!("gen_res: {:?}", gen_res);
        }
        println!("{}", (&data[..]).to_hex(16));

        let parse_res = ebml_uint!(&data[..], id);
        println!("parse_res: {:?}", parse_res);
        match parse_res {
            IResult::Done(rest, o) => {
                assert_eq!(num, o);
                return true;
            }
            e => panic!(format!("parse error: {:?}", e)),
        }

        false
    }

    quickcheck! {
    fn test_ebml_u64(i: u64) -> bool {
      test_ebml_u64_serializer(i)
    }
  }

    #[test]
    fn ebml_u64() {
        test_ebml_u64_serializer(0);
        test_ebml_u64_serializer(8);
        test_ebml_u64_serializer(127);
        test_ebml_u64_serializer(128);
        test_ebml_u64_serializer(2100000);
    }

    quickcheck! {
  fn test_ebml_u8(num: u8) -> bool {
    let id = 0x9F;
    println!("testing for id={}, num={}", id, num);

    let mut data = [0u8; 100];
    {
      let gen_res = gen_u8((&mut data[..], 0), id, num);
      println!("gen_res: {:?}", gen_res);
    }
    println!("{}", (&data[..]).to_hex(16));

    let parse_res = ebml_uint!(&data[..], id);
    println!("parse_res: {:?}", parse_res);
    match parse_res {
      IResult::Done(rest, o) => {
        assert_eq!(num as u64, o);
        return true;
      },
      e => panic!(format!("parse error: {:?}", e)),
    }

    false
  }
}

    quickcheck! {
    fn test_ebml_header(version: u8, read_version: u8, max_id_length: u8, max_size_length: u8, doc_type: String,
      doc_type_version: u8, doc_type_read_version: u8) -> bool {
      let header = EBMLHeader {
        version: version as u64,
        read_version: read_version as u64,
        max_id_length: max_id_length as u64,
        max_size_length: max_size_length as u64,
        doc_type: doc_type,
        doc_type_version: doc_type_version as u64,
        doc_type_read_version: doc_type_read_version as u64
      };

      println!("will serialize: {:#?}", header);
      let mut data = [0u8; 100];
      {
        let gen_res = gen_ebml_header((&mut data[..], 0), &header);
        println!("gen_res: {:?}", gen_res);
        // do not fail if quickcheck generated data that is too large
        match gen_res {
          Err(GenError::BufferTooSmall(_)) => return true,
          Err(_) => return false,
          Ok(_)  => (),
        }
      }

      println!("{}", (&data[..]).to_hex(16));
      let parse_res = ::ebml::ebml_header(&data[..]);
      println!("parse_res: {:?}", parse_res);
      match parse_res {
        IResult::Done(rest, h) => {
          assert_eq!(header, h);
          return true;
        },
        e => panic!(format!("parse error: {:?}", e)),
      }

      false
    }
  }
}
<|endoftext|>


<commit_before>//! Parser and syntax tree.

use std::char;

use charclass::CharClass;
use charclass::ascii;

/// A regular expression AST.
pub enum Expr {
    Empty,
    Range(char, char),
    Concatenate(~[Expr]),
    Alternate(~[Expr]),
    Repeat(~Expr, u32, Option<u32>, Greedy),
    Capture(~Expr)
}

impl Expr {
    pub fn accepts_empty(&self) -> bool {
        match *self {
            Empty => true,
            Range(..) => false,
            Concatenate(ref inners) => inners.iter().all(|e| e.accepts_empty()),
            Alternate(ref inners) => inners.iter().any(|e| e.accepts_empty()),
            Repeat(ref inner, min, _, _) => min == 0 || inner.accepts_empty(),
            Capture(ref inner) => inner.accepts_empty()
        }
    }
}

/// Greediness flag.
#[deriving(Eq)]
pub enum Greedy {
    NonGreedy,
    Greedy
}

///
/// The maximum number of repetitions.  Any number larger than this will
/// cause a syntax error.  By honoring this limit, we prevent integer
/// overflow bugs in the library.
///
/// The value (100000) is taken from Ruby.
///
static REPEAT_MAX: u32 = 100000;

/// Parse a regular expression into an AST.  Fails on invalid syntax.
pub fn parse(input: &str) -> Expr {
    let mut s = State::new(input);
    let e = p_alternate(&mut s);
    if s.has_input() {
        // p_alternate() only terminates on an empty string or an extra
        // paren.  Since the string isn't empty, we infer the latter.
        fail!("unbalanced parenthesis")
    } else {
        e
    }
}

/// The parser state.  This tracks the position in the input string.
struct State<'a> {
    input: &'a str,
    prev: Option<&'a str>  // See `State::retreat`
}

impl<'a> State<'a> {
    fn new<'a>(input: &'a str) -> State<'a> {
        State {
            input: input,
            prev: None
        }
    }

    /// Consume and return the next character in the input, returning
    /// `None` if empty.
    fn advance(&mut self) -> Option<char> {
        self.prev = Some(self.input);
        if self.has_input() {
            let (c, input_) = self.input.slice_shift_char();
            self.input = input_;
            Some(c)
        } else {
            None
        }
    }

    /// Push the previously read character back onto the input.  This
    /// can only be called immediately after `advance`.
    fn retreat(&mut self) {
        self.input = self.prev.expect("nowhere to retreat");
        self.prev = None;
    }

    /// Return `true` if there is input remaining.
    fn has_input(&self) -> bool {
        self.input.len() > 0
    }
}

///
/// Parse alternation, e.g. `ducks|geese|swans`.
///
/// An alternation consists of zero or more concatenations, separated by
/// vertical bars `|`.
///
fn p_alternate(s: &mut State) -> Expr {
    let mut items: ~[Expr] = ~[];

    loop {
        items.push(p_concatenate(s));
        match s.advance() {
            Some(c) => {
                match c {
                    ')' => { s.retreat(); break },
                    '|' => continue,
                    _ => fail!("something bad happened; it's really bad")
                }
            },
            None => break
        }
    }

    wrap_in(Alternate, items)
}

/// Parse concatenation, e.g. `abc`.
fn p_concatenate(s: &mut State) -> Expr {
    let mut items: ~[Expr] = ~[];
    let mut had_repeat = false;

    loop {
        let mut is_repeat = false;
        match s.advance() {
            Some(c) => match c {
                '|' | ')' => { s.retreat(); break },
                '(' => push_ignore_empty(&mut items, p_group(s)),
                '.' => items.push(Range('\0', char::MAX)),
                '\\' => items.push(cc_to_expr(p_escape(s))),
                '[' => items.push(cc_to_expr(p_charclass(s))),
                '?' => {
                    let e = pop_expr(&mut items);
                    items.push(match e {
                        Repeat(inner, min, max, greedy) => {
                            if had_repeat && greedy == Greedy {
                                Repeat(inner, min, max, NonGreedy)
                            } else {
                                fail!("multiple repeat")
                            }
                        },
                        _ => {
                            is_repeat = true;
                            Repeat(~e, 0, Some(1), Greedy)
                        }
                    });
                },
                '+' => {
                    add_repeat(&mut items, 1, None);
                    is_repeat = true;
                },
                '*' => {
                    add_repeat(&mut items, 0, None);
                    is_repeat = true;
                },
                '{' => {
                    let (min, max) = p_repetition(s);
                    add_repeat(&mut items, min, max);
                    is_repeat = true;
                },
                _ => items.push(Range(c, c))
            },
            None => break
        };
        had_repeat = is_repeat;
    }

    wrap_in(Concatenate, items)
}

#[inline]
fn wrap_in(wrapper: fn(~[Expr]) -> Expr, mut items: ~[Expr]) -> Expr {
    match items.len() {
        0 => Empty,
        1 => items.pop().unwrap(),
        _ => wrapper(items)
    }
}

#[inline]
fn push_ignore_empty(items: &mut ~[Expr], e: Expr) {
    match e {
        Empty => (),
        _ => items.push(e)
    }
}

#[inline]
fn pop_expr(items: &mut ~[Expr]) -> Expr {
    items.pop().expect("nothing to repeat")
}

#[inline]
fn add_repeat(items: &mut ~[Expr], min: u32, max: Option<u32>) {
    let e = pop_expr(items);
    items.push(match e {
        Repeat(..) => fail!("multiple repeat"),
        _ if max.is_none() && e.accepts_empty() => fail!("cannot repeat the empty string"),
        _ => Repeat(~e, min, max, Greedy)
    })
}

///
/// Parse a counted repetition (e.g. `a{2,3}`), sans the opening brace.
///
/// The following syntaxes are accepted:
///
/// * `{N}` – match exactly N repetitions;
/// * `{M,}` – at least M;
/// * `{,N}` – at most N;
/// * `{M,N}` – from M to N inclusive;
/// * `{,}` – zero or more (synonymous with `*`).
///
fn p_repetition(s: &mut State) -> (u32, Option<u32>) {
    let min = p_number(s);
    match s.advance() {
        Some(',') => {
            let max = p_number(s);
            match s.advance() {
                // {} or {M,} or {,N} or {M,N}
                Some('}') => {
                    let min_ = min.unwrap_or(0);
                    if check_repeat(min_, max) {
                        (min_, max)
                    } else {
                        fail!("bad repeat interval")
                    }
                },
                _ => fail!("invalid repeat")
            }
        },
        Some('}') => match min {
            // {N}
            Some(n) => (n, Some(n)),
            _ => fail!("invalid repeat")
        },
        _ => fail!("invalid repeat")
    }
}

#[inline]
fn check_repeat(min: u32, max: Option<u32>) -> bool {
    match max {
        Some(max_) => min <= max_,
        None => true
    }
}

///
/// Parse a non-negative integer, and return it as a `u32`.
///
/// This returns `None` if no number could be parsed, but fails directly
/// if the number is greater than `REPEAT_MAX`.
///
fn p_number(s: &mut State) -> Option<u32> {
    let mut acc = None;
    loop {
        match s.advance() {
            Some(c) if '0' <= c && c <= '9' => {
                let digit = c as u32 - '0' as u32;
                acc = Some(match acc {
                    Some(n) => {
                        let acc_ = 10 * n + digit;
                        if acc_ <= REPEAT_MAX {
                            acc_
                        } else {
                            fail!(format!("repeat must be <= {}", REPEAT_MAX))
                        }
                    },
                    None => digit
                });
            },
            _ => { s.retreat(); break }
        }
    }
    acc
}

/// Parse a group (e.g. `(hello)`), sans the opening parenthesis.
fn p_group(s: &mut State) -> Expr {
    let result = match s.advance() {
        Some('?') => match s.advance() {
            Some(c) => match c {
                ':' => p_alternate(s),
                '#' => p_comment(s),
                _ => fail!(format!("unknown extension: ?{}", c))
            },
            None => fail!("unexpected end of pattern")
        },
        _ => { s.retreat(); Capture(~p_alternate(s)) }
    };

    // Match the closing paren
    match s.advance() {
        Some(')') => result,
        _ => fail!("mismatched parenthesis")
    }
}

/// Consume all input up to the first closing parenthesis, and return
/// `Empty`.
fn p_comment(s: &mut State) -> Expr {
    loop {
        match s.advance() {
            Some(c) if c != ')' => continue,
            _ => { s.retreat(); break }
        }
    }
    Empty
}

/// Parse an escape sequence (e.g. `\d`), sans the leading backslash.
fn p_escape(s: &mut State) -> CharClass {
    match s.advance() {
        Some(c) => match c {
            'n' => CharClass::from_char('\n'),
            'r' => CharClass::from_char('\r'),
            't' => CharClass::from_char('\t'),

            'd' => ascii::digit.clone(),
            's' => ascii::space.clone(),
            'w' => ascii::word.clone(),

            'D' => ascii::digit.negate(),
            'S' => ascii::space.negate(),
            'W' => ascii::word.negate(),

            'x' => p_hex_escape(s, 2),
            'u' => p_hex_escape(s, 4),
            'U' => p_hex_escape(s, 8),

            _ if ascii::punct.includes(c) => CharClass::from_char(c),

            _ => fail!("invalid escape")
        },
        None => fail!("invalid escape")
    }
}

fn p_hex_escape(s: &mut State, n_digits: uint) -> CharClass {
    let mut acc = 0u32;
    for _ in range(0, n_digits) {
        acc = 16 * acc + match s.advance() {
            Some(c) => c.to_digit(16).expect("invalid escape") as u32,
            _ => fail!("invalid escape")
        };
    }
    let c = char::from_u32(acc).expect("character out of range");
    CharClass::from_char(c)
}

/// Parse a character class (e.g. `[a-z]`), sans the opening bracket.
fn p_charclass(s: &mut State) -> CharClass {
    let mut classes: ~[CharClass] = ~[];

    let negate = match s.advance() {
        Some('^') => true,
        _ => { s.retreat(); false }
    };

    loop {
        match s.advance() {
            Some(c) => match c {
                ']' => break,
                '-' => match p_charclass_token(s) {
                    Some(cc_hi) => match classes.pop() {
                        Some(cc_lo) => {
                            // [a-z]
                            let lo = cc_lo.to_char().expect("bad character range");
                            let hi = cc_hi.to_char().expect("bad character range");
                            classes.push(CharClass::from_range(lo, hi));
                        },
                        None => {
                            // [-z]
                            classes.push(CharClass::from_char('-'));
                            classes.push(cc_hi);
                        }
                    },
                    None => classes.push(CharClass::from_char('-'))  // [a-]
                },
                _ => {
                    s.retreat();
                    classes.push(p_charclass_token(s).expect("invalid char class"));
                }
            },
            None => fail!("unexpected end of char class")
        }
    }

    let cc = CharClass::combine(classes);
    if negate {
        cc.negate()
    } else {
        cc
    }
}

fn p_charclass_token(s: &mut State) -> Option<CharClass> {
    match s.advance() {
        Some(c) => match c {
            ']' => { s.retreat(); None },
            '[' => Some(p_charclass(s)),
            '\\' => Some(p_escape(s)),
            _ => Some(CharClass::from_char(c))
        },
        None => None
    }
}

/// Reify a character class as an `Expr`.
fn cc_to_expr(cc: CharClass) -> Expr {
    Alternate(cc.ranges().iter().map(|&(lo, hi)| Range(lo, hi)).collect())
}

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

    #[test]
    #[should_fail]
    fn issue_3() {
        let _ = parse("(?:a+)?");  // error: multiple repeat
    }

    #[test]
    #[should_fail]
    fn issue_4_a() {
        let _ = parse("()+");  // error: cannot repeat the empty string
    }

    #[test]
    #[should_fail]
    fn issue_4_b() {
        let _ = parse("(?:a|b|)*");  // error: cannot repeat the empty string
    }
}
<commit_msg>Update Rust<commit_after>//! Parser and syntax tree.

use std::char;

use charclass::CharClass;
use charclass::ascii;

/// A regular expression AST.
pub enum Expr {
    Empty,
    Range(char, char),
    Concatenate(~[Expr]),
    Alternate(~[Expr]),
    Repeat(~Expr, u32, Option<u32>, Greedy),
    Capture(~Expr)
}

impl Expr {
    pub fn accepts_empty(&self) -> bool {
        match *self {
            Empty => true,
            Range(..) => false,
            Concatenate(ref inners) => inners.iter().all(|e| e.accepts_empty()),
            Alternate(ref inners) => inners.iter().any(|e| e.accepts_empty()),
            Repeat(ref inner, min, _, _) => min == 0 || inner.accepts_empty(),
            Capture(ref inner) => inner.accepts_empty()
        }
    }
}

/// Greediness flag.
#[deriving(Eq)]
pub enum Greedy {
    NonGreedy,
    Greedy
}

///
/// The maximum number of repetitions.  Any number larger than this will
/// cause a syntax error.  By honoring this limit, we prevent integer
/// overflow bugs in the library.
///
/// The value (100000) is taken from Ruby.
///
static REPEAT_MAX: u32 = 100000;

/// Parse a regular expression into an AST.  Fails on invalid syntax.
pub fn parse(input: &str) -> Expr {
    let mut s = State::new(input);
    let e = p_alternate(&mut s);
    if s.has_input() {
        // p_alternate() only terminates on an empty string or an extra
        // paren.  Since the string isn't empty, we infer the latter.
        fail!("unbalanced parenthesis")
    } else {
        e
    }
}

/// The parser state.  This tracks the position in the input string.
struct State<'a> {
    input: &'a str,
    prev: Option<&'a str>  // See `State::retreat`
}

impl<'a> State<'a> {
    fn new<'a>(input: &'a str) -> State<'a> {
        State {
            input: input,
            prev: None
        }
    }

    /// Consume and return the next character in the input, returning
    /// `None` if empty.
    fn advance(&mut self) -> Option<char> {
        self.prev = Some(self.input);
        let (c, input_) = self.input.slice_shift_char();
        self.input = input_;
        c
    }

    /// Push the previously read character back onto the input.  This
    /// can only be called immediately after `advance`.
    fn retreat(&mut self) {
        self.input = self.prev.expect("nowhere to retreat");
        self.prev = None;
    }

    /// Return `true` if there is input remaining.
    fn has_input(&self) -> bool {
        self.input.len() > 0
    }
}

///
/// Parse alternation, e.g. `ducks|geese|swans`.
///
/// An alternation consists of zero or more concatenations, separated by
/// vertical bars `|`.
///
fn p_alternate(s: &mut State) -> Expr {
    let mut items: ~[Expr] = ~[];

    loop {
        items.push(p_concatenate(s));
        match s.advance() {
            Some(c) => {
                match c {
                    ')' => { s.retreat(); break },
                    '|' => continue,
                    _ => fail!("something bad happened; it's really bad")
                }
            },
            None => break
        }
    }

    wrap_in(Alternate, items)
}

/// Parse concatenation, e.g. `abc`.
fn p_concatenate(s: &mut State) -> Expr {
    let mut items: ~[Expr] = ~[];
    let mut had_repeat = false;

    loop {
        let mut is_repeat = false;
        match s.advance() {
            Some(c) => match c {
                '|' | ')' => { s.retreat(); break },
                '(' => push_ignore_empty(&mut items, p_group(s)),
                '.' => items.push(Range('\0', char::MAX)),
                '\\' => items.push(cc_to_expr(p_escape(s))),
                '[' => items.push(cc_to_expr(p_charclass(s))),
                '?' => {
                    let e = pop_expr(&mut items);
                    items.push(match e {
                        Repeat(inner, min, max, greedy) => {
                            if had_repeat && greedy == Greedy {
                                Repeat(inner, min, max, NonGreedy)
                            } else {
                                fail!("multiple repeat")
                            }
                        },
                        _ => {
                            is_repeat = true;
                            Repeat(~e, 0, Some(1), Greedy)
                        }
                    });
                },
                '+' => {
                    add_repeat(&mut items, 1, None);
                    is_repeat = true;
                },
                '*' => {
                    add_repeat(&mut items, 0, None);
                    is_repeat = true;
                },
                '{' => {
                    let (min, max) = p_repetition(s);
                    add_repeat(&mut items, min, max);
                    is_repeat = true;
                },
                _ => items.push(Range(c, c))
            },
            None => break
        };
        had_repeat = is_repeat;
    }

    wrap_in(Concatenate, items)
}

#[inline]
fn wrap_in(wrapper: fn(~[Expr]) -> Expr, mut items: ~[Expr]) -> Expr {
    match items.len() {
        0 => Empty,
        1 => items.pop().unwrap(),
        _ => wrapper(items)
    }
}

#[inline]
fn push_ignore_empty(items: &mut ~[Expr], e: Expr) {
    match e {
        Empty => (),
        _ => items.push(e)
    }
}

#[inline]
fn pop_expr(items: &mut ~[Expr]) -> Expr {
    items.pop().expect("nothing to repeat")
}

#[inline]
fn add_repeat(items: &mut ~[Expr], min: u32, max: Option<u32>) {
    let e = pop_expr(items);
    items.push(match e {
        Repeat(..) => fail!("multiple repeat"),
        _ if max.is_none() && e.accepts_empty() => fail!("cannot repeat the empty string"),
        _ => Repeat(~e, min, max, Greedy)
    })
}

///
/// Parse a counted repetition (e.g. `a{2,3}`), sans the opening brace.
///
/// The following syntaxes are accepted:
///
/// * `{N}` – match exactly N repetitions;
/// * `{M,}` – at least M;
/// * `{,N}` – at most N;
/// * `{M,N}` – from M to N inclusive;
/// * `{,}` – zero or more (synonymous with `*`).
///
fn p_repetition(s: &mut State) -> (u32, Option<u32>) {
    let min = p_number(s);
    match s.advance() {
        Some(',') => {
            let max = p_number(s);
            match s.advance() {
                // {} or {M,} or {,N} or {M,N}
                Some('}') => {
                    let min_ = min.unwrap_or(0);
                    if check_repeat(min_, max) {
                        (min_, max)
                    } else {
                        fail!("bad repeat interval")
                    }
                },
                _ => fail!("invalid repeat")
            }
        },
        Some('}') => match min {
            // {N}
            Some(n) => (n, Some(n)),
            _ => fail!("invalid repeat")
        },
        _ => fail!("invalid repeat")
    }
}

#[inline]
fn check_repeat(min: u32, max: Option<u32>) -> bool {
    match max {
        Some(max_) => min <= max_,
        None => true
    }
}

///
/// Parse a non-negative integer, and return it as a `u32`.
///
/// This returns `None` if no number could be parsed, but fails directly
/// if the number is greater than `REPEAT_MAX`.
///
fn p_number(s: &mut State) -> Option<u32> {
    let mut acc = None;
    loop {
        match s.advance() {
            Some(c) if '0' <= c && c <= '9' => {
                let digit = c as u32 - '0' as u32;
                acc = Some(match acc {
                    Some(n) => {
                        let acc_ = 10 * n + digit;
                        if acc_ <= REPEAT_MAX {
                            acc_
                        } else {
                            fail!(format!("repeat must be <= {}", REPEAT_MAX))
                        }
                    },
                    None => digit
                });
            },
            _ => { s.retreat(); break }
        }
    }
    acc
}

/// Parse a group (e.g. `(hello)`), sans the opening parenthesis.
fn p_group(s: &mut State) -> Expr {
    let result = match s.advance() {
        Some('?') => match s.advance() {
            Some(c) => match c {
                ':' => p_alternate(s),
                '#' => p_comment(s),
                _ => fail!(format!("unknown extension: ?{}", c))
            },
            None => fail!("unexpected end of pattern")
        },
        _ => { s.retreat(); Capture(~p_alternate(s)) }
    };

    // Match the closing paren
    match s.advance() {
        Some(')') => result,
        _ => fail!("mismatched parenthesis")
    }
}

/// Consume all input up to the first closing parenthesis, and return
/// `Empty`.
fn p_comment(s: &mut State) -> Expr {
    loop {
        match s.advance() {
            Some(c) if c != ')' => continue,
            _ => { s.retreat(); break }
        }
    }
    Empty
}

/// Parse an escape sequence (e.g. `\d`), sans the leading backslash.
fn p_escape(s: &mut State) -> CharClass {
    match s.advance() {
        Some(c) => match c {
            'n' => CharClass::from_char('\n'),
            'r' => CharClass::from_char('\r'),
            't' => CharClass::from_char('\t'),

            'd' => ascii::digit.clone(),
            's' => ascii::space.clone(),
            'w' => ascii::word.clone(),

            'D' => ascii::digit.negate(),
            'S' => ascii::space.negate(),
            'W' => ascii::word.negate(),

            'x' => p_hex_escape(s, 2),
            'u' => p_hex_escape(s, 4),
            'U' => p_hex_escape(s, 8),

            _ if ascii::punct.includes(c) => CharClass::from_char(c),

            _ => fail!("invalid escape")
        },
        None => fail!("invalid escape")
    }
}

fn p_hex_escape(s: &mut State, n_digits: uint) -> CharClass {
    let mut acc = 0u32;
    for _ in range(0, n_digits) {
        acc = 16 * acc + match s.advance() {
            Some(c) => c.to_digit(16).expect("invalid escape") as u32,
            _ => fail!("invalid escape")
        };
    }
    let c = char::from_u32(acc).expect("character out of range");
    CharClass::from_char(c)
}

/// Parse a character class (e.g. `[a-z]`), sans the opening bracket.
fn p_charclass(s: &mut State) -> CharClass {
    let mut classes: ~[CharClass] = ~[];

    let negate = match s.advance() {
        Some('^') => true,
        _ => { s.retreat(); false }
    };

    loop {
        match s.advance() {
            Some(c) => match c {
                ']' => break,
                '-' => match p_charclass_token(s) {
                    Some(cc_hi) => match classes.pop() {
                        Some(cc_lo) => {
                            // [a-z]
                            let lo = cc_lo.to_char().expect("bad character range");
                            let hi = cc_hi.to_char().expect("bad character range");
                            classes.push(CharClass::from_range(lo, hi));
                        },
                        None => {
                            // [-z]
                            classes.push(CharClass::from_char('-'));
                            classes.push(cc_hi);
                        }
                    },
                    None => classes.push(CharClass::from_char('-'))  // [a-]
                },
                _ => {
                    s.retreat();
                    classes.push(p_charclass_token(s).expect("invalid char class"));
                }
            },
            None => fail!("unexpected end of char class")
        }
    }

    let cc = CharClass::combine(classes);
    if negate {
        cc.negate()
    } else {
        cc
    }
}

fn p_charclass_token(s: &mut State) -> Option<CharClass> {
    match s.advance() {
        Some(c) => match c {
            ']' => { s.retreat(); None },
            '[' => Some(p_charclass(s)),
            '\\' => Some(p_escape(s)),
            _ => Some(CharClass::from_char(c))
        },
        None => None
    }
}

/// Reify a character class as an `Expr`.
fn cc_to_expr(cc: CharClass) -> Expr {
    Alternate(cc.ranges().iter().map(|&(lo, hi)| Range(lo, hi)).collect())
}

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

    #[test]
    #[should_fail]
    fn issue_3() {
        let _ = parse("(?:a+)?");  // error: multiple repeat
    }

    #[test]
    #[should_fail]
    fn issue_4_a() {
        let _ = parse("()+");  // error: cannot repeat the empty string
    }

    #[test]
    #[should_fail]
    fn issue_4_b() {
        let _ = parse("(?:a|b|)*");  // error: cannot repeat the empty string
    }
}
<|endoftext|>


<commit_before>#[macro_use]
extern crate derive_more;

#[derive(From)]
#[derive(Into)]
#[derive(Constructor)]
#[derive(Eq, PartialEq, Debug)]
#[derive(Add)]
#[derive(Mul)]
#[derive(Neg)]
#[derive(AddAssign)]
#[derive(MulAssign)]
#[derive(FromStr)]
#[derive(Display)]
#[derive(Octal)]
#[derive(Binary)]
struct MyInt(i32);

#[derive(Eq, PartialEq, Debug)]
#[derive(Index, IndexMut)]
struct MyVec(Vec<i32>);

#[derive(Eq, PartialEq, Debug)]
#[derive(Not)]
#[derive(From)]
struct MyBool(bool);

#[derive(From)]
#[derive(Into)]
#[derive(Constructor)]
#[derive(Add)]
#[derive(Eq, PartialEq, Debug)]
#[derive(Mul)]
#[derive(AddAssign)]
struct MyUInt(u64, u64);

#[derive(From)]
#[derive(Into)]
#[derive(Constructor)]
#[derive(FromStr)]
#[derive(Eq, PartialEq, Debug)]
#[derive(Display)]
struct SimpleStruct {
    int1: u64,
}

#[derive(From)]
#[derive(Constructor)]
#[derive(Add, Sub, Mul, Div, Rem, BitAnd, BitOr, BitXor, Shr, Shl)]
#[derive(Eq, PartialEq, Debug, Clone, Copy)]
#[derive(AddAssign)]
struct NormalStruct {
    int1: u64,
    int2: u64,
}

#[derive(From)]
#[derive(Eq, PartialEq, Debug)]
struct NestedInt(MyInt);

#[derive(Eq, PartialEq, Debug)]
#[derive(From)]
#[derive(Add, Sub)]
enum SimpleMyIntEnum {
    Int(i32),
    _UnsignedOne(u32),
    _UnsignedTwo(u32),
}
#[derive(Eq, PartialEq, Debug)]
#[derive(From)]
#[derive(Neg)]
enum SimpleSignedIntEnum {
    Int(i32),
    Int2(i16),
}

#[derive(Eq, PartialEq, Debug)]
#[derive(From)]
#[derive(Add, Sub)]
#[derive(Neg)]
enum SimpleEnum {
    Int(i32),
    _Ints(i32, i32),
    LabeledInts { a: i32, b: i32 },
    _SomeUnit,
}

#[derive(Eq, PartialEq, Debug)]
#[derive(From)]
#[derive(Add, Sub)]
enum MyIntEnum {
    SmallInt(i32),
    BigInt(i64),
    TwoInts(i32, i32),
    Point2D { x: i64, y: i64 },
    _UnsignedOne(u32),
    _UnsignedTwo(u32),
    _Uints1(u64, u64),
    _Uints2 { x: u64, y: u64 },
    Nothing,
}

#[derive(Eq, PartialEq, Debug)]
#[derive(Add, Mul)]
struct DoubleUInt(u32, u32);

#[derive(Eq, PartialEq, Debug)]
#[derive(Add, Mul)]
struct DoubleUIntStruct {
    x: u32,
    y: u32,
}

#[derive(Eq, PartialEq, Debug)]
#[derive(From, Into, Constructor)]
struct Unit;

#[test]
fn main() {
    let mut myint: MyInt = 5.into();
    let _: SimpleMyIntEnum = 5i32.into();
    let _: MyIntEnum = 5i32.into();
    let _: MyIntEnum = 6i64.into();
    let _: MyIntEnum = (5i32, 8i32).into();
    let _: MyIntEnum = (5i64, 8i64).into();
    let _: MyIntEnum = ().into();

    let _: Unit = ().into();
    assert_eq!((), Unit.into());
    assert_eq!(Unit, Unit::new());
    assert_eq!(MyInt(5), 5.into());
    assert_eq!(Ok(MyInt(5)), "5".parse());
    assert_eq!(5, MyInt(5).into());
    assert_eq!(MyInt(5), MyInt::new(5));
    assert_eq!(-MyInt(5), (-5).into());
    assert_eq!("30", format!("{}", MyInt(30)));
    assert_eq!("36", format!("{:o}", MyInt(30)));
    assert_eq!("100", format!("{:b}", MyInt(4)));
    assert_eq!(!MyBool(true), false.into());
    assert_eq!(MyIntEnum::SmallInt(5), 5.into());

    assert_eq!(SimpleStruct { int1: 5 }, 5.into());
    assert_eq!(5u64, SimpleStruct { int1: 5 }.into());
    assert_eq!(Ok(SimpleStruct { int1: 5 }), "5".parse());
    assert_eq!("5", format!("{}", SimpleStruct { int1: 5 }));
    assert_eq!(NormalStruct { int1: 5, int2: 6 }, (5, 6).into());
    assert_eq!(SimpleStruct { int1: 5 }, SimpleStruct::new(5));
    assert_eq!(NormalStruct { int1: 5, int2: 6 }, NormalStruct::new(5, 6));

    assert_eq!(MyInt(4) + MyInt(1), 5.into());
    myint += MyInt(3);
    assert_eq!(myint, 8.into());
    myint *= 5;
    assert_eq!(myint, 40.into());
    assert_eq!(MyInt(4) + MyInt(1), 5.into());
    assert_eq!(MyUInt(4, 5) + MyUInt(1, 2), MyUInt(5, 7));
    assert_eq!(MyUInt(4, 5), MyUInt::new(4, 5));
    assert_eq!((4, 5), MyUInt(4, 5).into());
    let mut s1 = NormalStruct { int1: 1, int2: 2 };
    let s2 = NormalStruct { int1: 2, int2: 3 };
    let s3 = NormalStruct { int1: 3, int2: 5 };
    assert_eq!(s1 + s2, s3);
    assert_eq!(s3 - s2, s1);
    s1 += s2;
    assert_eq!(s1, s3);

    assert_eq!((SimpleMyIntEnum::Int(6) + 5.into()).unwrap(), 11.into());
    assert_eq!((SimpleMyIntEnum::Int(6) - 5.into()).unwrap(), 1.into());
    assert_eq!((SimpleMyIntEnum::Int(6) - 5.into()).unwrap(), 1.into());
    assert_eq!(-SimpleSignedIntEnum::Int(6), (-6i32).into());
    assert_eq!(
        (SimpleEnum::LabeledInts { a: 6, b: 5 } + SimpleEnum::LabeledInts { a: 1, b: 4 }).unwrap(),
        SimpleEnum::LabeledInts { a: 7, b: 9 }
    );

    let _ = (MyIntEnum::SmallInt(5) + 6.into()).unwrap();
    assert_eq!((-SimpleEnum::Int(5)).unwrap(), (-5).into());

    assert_eq!(MyInt(50), MyInt(5) * 10);
    assert_eq!(DoubleUInt(5, 6) * 10, DoubleUInt(50, 60));
    // assert_eq!(DoubleUIntStruct{x:5, y:6} * 10, DoubleUIntStruct{x:50, y:60});

    let myvec = MyVec(vec![5, 8]);
    assert_eq!(5, myvec[0]);
    assert_eq!(8, myvec[1]);
    myvec[0] = 20
    assert_eq!(20, myvec[0]);
}
<commit_msg>IndexMut: Fix test<commit_after>#[macro_use]
extern crate derive_more;

#[derive(From)]
#[derive(Into)]
#[derive(Constructor)]
#[derive(Eq, PartialEq, Debug)]
#[derive(Add)]
#[derive(Mul)]
#[derive(Neg)]
#[derive(AddAssign)]
#[derive(MulAssign)]
#[derive(FromStr)]
#[derive(Display)]
#[derive(Octal)]
#[derive(Binary)]
struct MyInt(i32);

#[derive(Eq, PartialEq, Debug)]
#[derive(Index, IndexMut)]
struct MyVec(Vec<i32>);

#[derive(Eq, PartialEq, Debug)]
#[derive(Not)]
#[derive(From)]
struct MyBool(bool);

#[derive(From)]
#[derive(Into)]
#[derive(Constructor)]
#[derive(Add)]
#[derive(Eq, PartialEq, Debug)]
#[derive(Mul)]
#[derive(AddAssign)]
struct MyUInt(u64, u64);

#[derive(From)]
#[derive(Into)]
#[derive(Constructor)]
#[derive(FromStr)]
#[derive(Eq, PartialEq, Debug)]
#[derive(Display)]
struct SimpleStruct {
    int1: u64,
}

#[derive(From)]
#[derive(Constructor)]
#[derive(Add, Sub, Mul, Div, Rem, BitAnd, BitOr, BitXor, Shr, Shl)]
#[derive(Eq, PartialEq, Debug, Clone, Copy)]
#[derive(AddAssign)]
struct NormalStruct {
    int1: u64,
    int2: u64,
}

#[derive(From)]
#[derive(Eq, PartialEq, Debug)]
struct NestedInt(MyInt);

#[derive(Eq, PartialEq, Debug)]
#[derive(From)]
#[derive(Add, Sub)]
enum SimpleMyIntEnum {
    Int(i32),
    _UnsignedOne(u32),
    _UnsignedTwo(u32),
}
#[derive(Eq, PartialEq, Debug)]
#[derive(From)]
#[derive(Neg)]
enum SimpleSignedIntEnum {
    Int(i32),
    Int2(i16),
}

#[derive(Eq, PartialEq, Debug)]
#[derive(From)]
#[derive(Add, Sub)]
#[derive(Neg)]
enum SimpleEnum {
    Int(i32),
    _Ints(i32, i32),
    LabeledInts { a: i32, b: i32 },
    _SomeUnit,
}

#[derive(Eq, PartialEq, Debug)]
#[derive(From)]
#[derive(Add, Sub)]
enum MyIntEnum {
    SmallInt(i32),
    BigInt(i64),
    TwoInts(i32, i32),
    Point2D { x: i64, y: i64 },
    _UnsignedOne(u32),
    _UnsignedTwo(u32),
    _Uints1(u64, u64),
    _Uints2 { x: u64, y: u64 },
    Nothing,
}

#[derive(Eq, PartialEq, Debug)]
#[derive(Add, Mul)]
struct DoubleUInt(u32, u32);

#[derive(Eq, PartialEq, Debug)]
#[derive(Add, Mul)]
struct DoubleUIntStruct {
    x: u32,
    y: u32,
}

#[derive(Eq, PartialEq, Debug)]
#[derive(From, Into, Constructor)]
struct Unit;

#[test]
fn main() {
    let mut myint: MyInt = 5.into();
    let _: SimpleMyIntEnum = 5i32.into();
    let _: MyIntEnum = 5i32.into();
    let _: MyIntEnum = 6i64.into();
    let _: MyIntEnum = (5i32, 8i32).into();
    let _: MyIntEnum = (5i64, 8i64).into();
    let _: MyIntEnum = ().into();

    let _: Unit = ().into();
    assert_eq!((), Unit.into());
    assert_eq!(Unit, Unit::new());
    assert_eq!(MyInt(5), 5.into());
    assert_eq!(Ok(MyInt(5)), "5".parse());
    assert_eq!(5, MyInt(5).into());
    assert_eq!(MyInt(5), MyInt::new(5));
    assert_eq!(-MyInt(5), (-5).into());
    assert_eq!("30", format!("{}", MyInt(30)));
    assert_eq!("36", format!("{:o}", MyInt(30)));
    assert_eq!("100", format!("{:b}", MyInt(4)));
    assert_eq!(!MyBool(true), false.into());
    assert_eq!(MyIntEnum::SmallInt(5), 5.into());

    assert_eq!(SimpleStruct { int1: 5 }, 5.into());
    assert_eq!(5u64, SimpleStruct { int1: 5 }.into());
    assert_eq!(Ok(SimpleStruct { int1: 5 }), "5".parse());
    assert_eq!("5", format!("{}", SimpleStruct { int1: 5 }));
    assert_eq!(NormalStruct { int1: 5, int2: 6 }, (5, 6).into());
    assert_eq!(SimpleStruct { int1: 5 }, SimpleStruct::new(5));
    assert_eq!(NormalStruct { int1: 5, int2: 6 }, NormalStruct::new(5, 6));

    assert_eq!(MyInt(4) + MyInt(1), 5.into());
    myint += MyInt(3);
    assert_eq!(myint, 8.into());
    myint *= 5;
    assert_eq!(myint, 40.into());
    assert_eq!(MyInt(4) + MyInt(1), 5.into());
    assert_eq!(MyUInt(4, 5) + MyUInt(1, 2), MyUInt(5, 7));
    assert_eq!(MyUInt(4, 5), MyUInt::new(4, 5));
    assert_eq!((4, 5), MyUInt(4, 5).into());
    let mut s1 = NormalStruct { int1: 1, int2: 2 };
    let s2 = NormalStruct { int1: 2, int2: 3 };
    let s3 = NormalStruct { int1: 3, int2: 5 };
    assert_eq!(s1 + s2, s3);
    assert_eq!(s3 - s2, s1);
    s1 += s2;
    assert_eq!(s1, s3);

    assert_eq!((SimpleMyIntEnum::Int(6) + 5.into()).unwrap(), 11.into());
    assert_eq!((SimpleMyIntEnum::Int(6) - 5.into()).unwrap(), 1.into());
    assert_eq!((SimpleMyIntEnum::Int(6) - 5.into()).unwrap(), 1.into());
    assert_eq!(-SimpleSignedIntEnum::Int(6), (-6i32).into());
    assert_eq!(
        (SimpleEnum::LabeledInts { a: 6, b: 5 } + SimpleEnum::LabeledInts { a: 1, b: 4 }).unwrap(),
        SimpleEnum::LabeledInts { a: 7, b: 9 }
    );

    let _ = (MyIntEnum::SmallInt(5) + 6.into()).unwrap();
    assert_eq!((-SimpleEnum::Int(5)).unwrap(), (-5).into());

    assert_eq!(MyInt(50), MyInt(5) * 10);
    assert_eq!(DoubleUInt(5, 6) * 10, DoubleUInt(50, 60));
    // assert_eq!(DoubleUIntStruct{x:5, y:6} * 10, DoubleUIntStruct{x:50, y:60});

    let mut myvec = MyVec(vec![5, 8]);
    assert_eq!(5, myvec[0]);
    assert_eq!(8, myvec[1]);
    myvec[0] = 20;
    assert_eq!(20, myvec[0]);
}
<|endoftext|>


<commit_before>#![no_std]
#[macro_use]
extern crate generic_array;
use generic_array::typenum::{U1, U3, U97};
use generic_array::GenericArray;
use core::ops::Drop;

#[test]
fn test() {
    let mut list97 = [0; 97];
    for i in 0..97 {
        list97[i] = i as i32;
    }
    let l: GenericArray<i32, U97> = GenericArray::clone_from_slice(&list97);
    assert_eq!(l[0], 0);
    assert_eq!(l[1], 1);
    assert_eq!(l[32], 32);
    assert_eq!(l[56], 56);
}

#[allow(non_upper_case_globals)]
static mut drop_counter: u32 = 0;

#[derive(Clone)]
struct TestDrop(u32);

impl Drop for TestDrop {
    fn drop(&mut self) {
        unsafe {
            drop_counter += 1;
        }
    }
}

#[test]
fn test_drop() {
    unsafe {
        drop_counter = 0;
    }
    {
        // This clones the structs, so we will have 6 drops, not 3
        let _: GenericArray<TestDrop, U3> = arr![TestDrop; TestDrop(1), TestDrop(2), TestDrop(3)];
    }
    unsafe {
        assert_eq!(drop_counter, 6); // 6 drops, as explained above
    }
}

#[test]
fn test_arr() {
    let test: GenericArray<u32, U3> = arr![u32; 1, 2, 3];
    assert_eq!(test[1], 2);
}

#[test]
fn test_copy() {
    let test = arr![u32; 1, 2, 3];
    let test2 = test;
    // if GenericArray is not copy, this should fail as a use of a moved value
    assert_eq!(test[1], 2);
    assert_eq!(test2[0], 1);
}

#[test]
fn test_iter_flat_map() {
    assert!((0..5)
                .flat_map(|i| arr![i32; 2 * i, 2 * i + 1])
                .eq(0..10));
}

#[test]
fn test_from_slice() {
    let arr = [1, 2, 3, 4];
    let gen_arr = GenericArray::<_, U3>::from_slice(&arr[..3]);
    assert_eq!(&arr[..3], gen_arr.as_slice());
}

#[test]
fn test_from_mut_slice() {
    let mut arr = [1, 2, 3, 4];
    {
        let mut gen_arr = GenericArray::<_, U3>::from_mut_slice(&mut arr[..3]);
        gen_arr[2] = 10;
    }
    assert_eq!(arr, [1, 2, 10, 4]);
}

#[test]
fn test_default() {
    let arr = GenericArray::<u8, U1>::default();
    assert_eq!(arr[0], 0);
}

#[test]
fn test_unit_macro() {
    let arr = arr![f32; 3.14];
    assert_eq!(arr[0], 3.14);
}

#[test]
fn test_empty_macro() {
    let arr = arr![f32;];
}

/// This test should cause a helpful compile error if uncommented.
// #[test]
// fn test_empty_macro2(){
//     let arr = arr![];
// }
#[cfg(feature="serde")]
mod impl_serde {
    extern crate serde_json;

    use generic_array::GenericArray;
    use generic_array::typenum::U6;

    #[test]
    fn test_serde_implementation() {
        let array: GenericArray<f64, U6> = arr![f64; 0.0, 5.0, 3.0, 7.07192, 76.0, -9.0];
        let string = serde_json::to_string(&array).unwrap();
        assert_eq!(string, "[0.0,5.0,3.0,7.07192,76.0,-9.0]");

        let test_array: GenericArray<f64, U6> = serde_json::from_str(&string).unwrap();
        assert_eq!(test_array, array);
    }
}
<commit_msg>Use a cell to test drops instead of a global<commit_after>#![no_std]
#[macro_use]
extern crate generic_array;
use generic_array::typenum::{U1, U3, U97};
use generic_array::GenericArray;
use core::ops::Drop;
use core::cell::Cell;

#[test]
fn test() {
    let mut list97 = [0; 97];
    for i in 0..97 {
        list97[i] = i as i32;
    }
    let l: GenericArray<i32, U97> = GenericArray::clone_from_slice(&list97);
    assert_eq!(l[0], 0);
    assert_eq!(l[1], 1);
    assert_eq!(l[32], 32);
    assert_eq!(l[56], 56);
}

#[test]
fn test_drop() {
    #[derive(Clone)]
    struct TestDrop<'a>(&'a Cell<u32>);

    impl<'a> Drop for TestDrop<'a> {
        fn drop(&mut self) {
            self.0.set(self.0.get() + 1);
        }
    }

    let drop_counter = Cell::new(0);
    {
        // This clones the structs, so we will have 6 drops, not 3
        let _: GenericArray<TestDrop, U3> = arr![TestDrop; TestDrop(&drop_counter), TestDrop(&drop_counter), TestDrop(&drop_counter)];
    }
    assert_eq!(drop_counter.get(), 6); // 6 drops, as explained above
}

#[test]
fn test_arr() {
    let test: GenericArray<u32, U3> = arr![u32; 1, 2, 3];
    assert_eq!(test[1], 2);
}

#[test]
fn test_copy() {
    let test = arr![u32; 1, 2, 3];
    let test2 = test;
    // if GenericArray is not copy, this should fail as a use of a moved value
    assert_eq!(test[1], 2);
    assert_eq!(test2[0], 1);
}

#[test]
fn test_iter_flat_map() {
    assert!((0..5)
                .flat_map(|i| arr![i32; 2 * i, 2 * i + 1])
                .eq(0..10));
}

#[test]
fn test_from_slice() {
    let arr = [1, 2, 3, 4];
    let gen_arr = GenericArray::<_, U3>::from_slice(&arr[..3]);
    assert_eq!(&arr[..3], gen_arr.as_slice());
}

#[test]
fn test_from_mut_slice() {
    let mut arr = [1, 2, 3, 4];
    {
        let mut gen_arr = GenericArray::<_, U3>::from_mut_slice(&mut arr[..3]);
        gen_arr[2] = 10;
    }
    assert_eq!(arr, [1, 2, 10, 4]);
}

#[test]
fn test_default() {
    let arr = GenericArray::<u8, U1>::default();
    assert_eq!(arr[0], 0);
}

#[test]
fn test_unit_macro() {
    let arr = arr![f32; 3.14];
    assert_eq!(arr[0], 3.14);
}

#[test]
fn test_empty_macro() {
    let arr = arr![f32;];
}

/// This test should cause a helpful compile error if uncommented.
// #[test]
// fn test_empty_macro2(){
//     let arr = arr![];
// }
#[cfg(feature="serde")]
mod impl_serde {
    extern crate serde_json;

    use generic_array::GenericArray;
    use generic_array::typenum::U6;

    #[test]
    fn test_serde_implementation() {
        let array: GenericArray<f64, U6> = arr![f64; 0.0, 5.0, 3.0, 7.07192, 76.0, -9.0];
        let string = serde_json::to_string(&array).unwrap();
        assert_eq!(string, "[0.0,5.0,3.0,7.07192,76.0,-9.0]");

        let test_array: GenericArray<f64, U6> = serde_json::from_str(&string).unwrap();
        assert_eq!(test_array, array);
    }
}
<|endoftext|>


<commit_before>#[macro_use]
extern crate nom;

use nom::{IResult,FlatMapper,Mapper,Mapper2,Producer,ProducerState,FileProducer,HexDisplay};
use nom::IResult::*;

use std::str;
use std::collections::HashMap;

fn mp4_box(input:&[u8]) -> IResult<&[u8], &[u8]> {

  take!(offset_parser 4);
  match offset_parser(input) {
    Done(i, offset_bytes) => {
      let offset:u32 = (offset_bytes[3] as u32) + (offset_bytes[2] as u32) * 0x100 + (offset_bytes[1] as u32) * 0x10000 + (offset_bytes[0] as u32) * 0x1000000;
      let sz: usize = offset as usize;
      //println!("box size: {} -> {}", offset_bytes.to_hex(8), sz);
      if i.len() >= sz {
        return Done(&i[(sz-4)..], &i[0..(sz-4)])
      } else {
        return Incomplete(0)
      }
    },
    e => e
  }
}

#[derive(PartialEq,Eq,Debug)]
struct FileType<'a> {
  major_brand:         &'a str,
  major_brand_version: &'a [u8],
  compatible_brands:   Vec<&'a str>
}

#[derive(PartialEq,Eq,Debug)]
pub enum MoovBox {
  Mdra,
  Dref,
  Cmov,
  Rmra,
  Iods,
  Mvhd,
  Clip,
  Trak,
  Udta
}

#[derive(PartialEq,Eq,Debug)]
enum MP4Box<'a> {
  Ftyp(FileType<'a>),
  Moov(Vec<MoovBox>),
  Mdat,
  Free,
  Skip,
  Wide,
  Unknown
}

take!(offset 4);
tag!(ftyp    "ftyp".as_bytes());

fn brand_name(input:&[u8]) -> IResult<&[u8],&str> {
  take!(major_brand_bytes 4);
  major_brand_bytes(input).map_res(str::from_utf8)
}
take!(major_brand_version 4);
many0!(compatible_brands<&[u8], &str> brand_name);

fn filetype_parser<'a>(input: &'a[u8]) -> IResult<&'a [u8], FileType<'a> > {
  chaining_parser!(input, ||{FileType{major_brand: m, major_brand_version:v, compatible_brands: c}},
    m: brand_name,
    v: major_brand_version,
    c: compatible_brands,)
}

o!(filetype <&[u8], FileType>  ftyp ~ [ filetype_parser ]);

fn filetype_box(input:&[u8]) -> IResult<&[u8], MP4Box> {
  match filetype(input) {
    Error(a)      => Error(a),
    Incomplete(a) => Incomplete(a),
    Done(i, o)    => {
      Done(i, MP4Box::Ftyp(o))
    }
  }
}

tag!(moov_tag "moov".as_bytes());

tag!(mdra    "mdra".as_bytes());
fn moov_mdra(input:&[u8]) -> IResult<&[u8], MoovBox> {
  mdra(input).map(|o| MoovBox::Mdra)
}

tag!(dref    "dref".as_bytes());
fn moov_dref(input:&[u8]) -> IResult<&[u8], MoovBox> {
  dref(input).map(|o| MoovBox::Dref)
}

tag!(cmov    "cmov".as_bytes());
fn moov_cmov(input:&[u8]) -> IResult<&[u8], MoovBox> {
  cmov(input).map(|o| MoovBox::Cmov)
}

tag!(rmra    "rmra".as_bytes());
fn moov_rmra(input:&[u8]) -> IResult<&[u8], MoovBox> {
  rmra(input).map(|o| MoovBox::Rmra)
}

tag!(iods    "iods".as_bytes());
fn moov_iods(input:&[u8]) -> IResult<&[u8], MoovBox> {
  iods(input).map(|o| MoovBox::Iods)
}

tag!(mvhd    "mvhd".as_bytes());
fn moov_mvhd(input:&[u8]) -> IResult<&[u8], MoovBox> {
  mvhd(input).map(|o| MoovBox::Mvhd)
}

tag!(clip    "clip".as_bytes());
fn moov_clip(input:&[u8]) -> IResult<&[u8], MoovBox> {
  clip(input).map(|o| MoovBox::Clip)
}

tag!(trak    "trak".as_bytes());
fn moov_trak(input:&[u8]) -> IResult<&[u8], MoovBox> {
  trak(input).map(|o| MoovBox::Trak)
}

tag!(udta   "udta".as_bytes());
fn moov_udta(input:&[u8]) -> IResult<&[u8], MoovBox> {
  udta(input).map(|o| MoovBox::Udta)
}

alt!(moov_internal<&[u8], MoovBox>, moov_mdra | moov_dref | moov_cmov |
     moov_rmra | moov_iods | moov_mvhd | moov_clip | moov_trak | moov_udta);

fn moov(input:&[u8]) -> IResult<&[u8], MoovBox> {
  match mp4_box(input) {
    Error(a)      => Error(a),
    Incomplete(a) => Incomplete(a),
    Done(i, o)    => {
      match moov_internal(o) {
        Error(a)      => Error(a),
        Incomplete(a) => Incomplete(a),
        Done(i2, o2)  => {
          Done(i, o2)
        }

      }
    }
  }
}

many0!(moov_many<&[u8],MoovBox> moov);

o!(moov_box_internal <&[u8], Vec<MoovBox> >  moov_tag ~ [ moov_many ]);
fn moov_box(input:&[u8]) -> IResult<&[u8], MP4Box> {
  match moov_box_internal(input) {
    Error(a)      => Error(a),
    Incomplete(a) => Incomplete(a),
    Done(i, o)  => {
      Done(i, MP4Box::Moov(o))
    }
  }
}

tag!(mdat    "mdat".as_bytes());
fn mdat_box(input:&[u8]) -> IResult<&[u8], MP4Box> {
  match mdat(input) {
    Error(a)      => Error(a),
    Incomplete(a) => Incomplete(a),
    Done(i, _)    => {
      Done(i, MP4Box::Mdat)
    }
  }
}
tag!(free    "free".as_bytes());
fn free_box(input:&[u8]) -> IResult<&[u8], MP4Box> {
  match free(input) {
    Error(a)      => Error(a),
    Incomplete(a) => Incomplete(a),
    Done(i, _)    => {
      Done(i, MP4Box::Free)
    }
  }
}

tag!(skip    "skip".as_bytes());
fn skip_box(input:&[u8]) -> IResult<&[u8], MP4Box> {
  match free(input) {
    Error(a)      => Error(a),
    Incomplete(a) => Incomplete(a),
    Done(i, _)    => {
      Done(i, MP4Box::Skip)
    }
  }
}

tag!(wide    "wide".as_bytes());
fn wide_box(input:&[u8]) -> IResult<&[u8], MP4Box> {
  match free(input) {
    Error(a)      => Error(a),
    Incomplete(a) => Incomplete(a),
    Done(i, _)    => {
      Done(i, MP4Box::Wide)
    }
  }
}

fn unknown_box(input:&[u8]) -> IResult<&[u8], MP4Box> {
  println!("calling UNKNOWN");
  Done(input, MP4Box::Unknown)
}

alt!(box_parser_internal<&[u8], MP4Box>, filetype_box | moov_box | mdat_box | free_box | skip_box | wide_box | unknown_box);
fn box_parser(input:&[u8]) -> IResult<&[u8], MP4Box> {
  match mp4_box(input) {
    Error(a)      => Error(a),
    Incomplete(a) => Incomplete(a),
    Done(i, o)    => {
      match box_parser_internal(o) {
        Error(a)      => Error(a),
        Incomplete(a) => Incomplete(a),
        Done(i2, o2)  => {
          Done(i, o2)
        }
      }
    }
  }
}

fn data_interpreter(bytes:&[u8]) -> IResult<&[u8], ()> {
  //println!("bytes:\n{}", bytes.to_hex(8));
  match box_parser(bytes) {
    Done(i, o) => {
      match o {
        MP4Box::Ftyp(f) => println!("-> FTYP: {:?}", f),
        MP4Box::Moov(m) => {println!("-> MOOV: {:?}", m); println!("remaining:\n{}", i.to_hex(8))},
        MP4Box::Mdat    => println!("-> MDAT"),
        MP4Box::Free    => println!("-> FREE"),
        MP4Box::Skip    => println!("-> SKIP"),
        MP4Box::Wide    => println!("-> WIDE"),
        MP4Box::Unknown => println!("-> UNKNOWN")
      }
      //println!("remaining:\n{}", i.to_hex(8));
      Done(i,())
    },
    Error(a) => {
      println!("mp4 parsing error: {:?}", a);
      Error(a)
    },
    Incomplete(a) => {
      //println!("incomplete: {:?}", a);
      Incomplete(a)
    }
  }
}

fn multiple_data_interpreter(bytes:&[u8]) -> IResult<&[u8], ()> {
  match data_interpreter(bytes) {
    Error(a)      => Error(a),
    Incomplete(a) => Incomplete(a),
    Done(i, ())   => {
      println!("NEXT BOX");
      match data_interpreter(i) {
        Error(a)      => Error(a),
        Incomplete(a) => Incomplete(a),
        Done(i2,())   => {
          println!("NEXT BOX 2");
          match data_interpreter(i2) {
            Error(a)      => Error(a),
            Incomplete(a) => Incomplete(a),
            Done(i3,())   => {
              println!("NEXT BOX 3");
              match data_interpreter(i3) {
                Error(a)      => Error(a),
                Incomplete(a) => Incomplete(a),
                Done(i4,())   => {
                  println!("NEXT BOX 4");
                  let res = data_interpreter(i4);
                  println!("res4: {:?}", res);
                  res
                }
              }
            }
          }
        }
      }
    },
  }
}

many0!(full_data_interpreter<&[u8],()> data_interpreter);

fn parse_mp4_file(filename: &str) {
  FileProducer::new(filename, 40000).map(|producer: FileProducer| {
    let mut p = producer;
    match p.produce() {
      ProducerState::Data(bytes) => {
        multiple_data_interpreter(bytes);
      },
      _ => println!("got error")
    }
    /*
    pusher!(ps, full_data_interpreter);
    ps(&mut p);
    */
    //assert!(false);
  });

}
#[test]
fn file_test() {
  parse_mp4_file("small.mp4");
}
#[test]
fn bunny_test() {
  parse_mp4_file("bigbuckbunny.mp4");
}
<commit_msg>create the mvhd structs, but too lazy to parse them now<commit_after>#[macro_use]
extern crate nom;

use nom::{IResult,FlatMapper,Mapper,Mapper2,Producer,ProducerState,FileProducer,HexDisplay};
use nom::IResult::*;

use std::str;
use std::collections::HashMap;

fn mp4_box(input:&[u8]) -> IResult<&[u8], &[u8]> {

  take!(offset_parser 4);
  match offset_parser(input) {
    Done(i, offset_bytes) => {
      let offset:u32 = (offset_bytes[3] as u32) + (offset_bytes[2] as u32) * 0x100 + (offset_bytes[1] as u32) * 0x10000 + (offset_bytes[0] as u32) * 0x1000000;
      let sz: usize = offset as usize;
      //println!("box size: {} -> {}", offset_bytes.to_hex(8), sz);
      if i.len() >= sz {
        return Done(&i[(sz-4)..], &i[0..(sz-4)])
      } else {
        return Incomplete(0)
      }
    },
    e => e
  }
}

#[derive(PartialEq,Eq,Debug)]
struct FileType<'a> {
  major_brand:         &'a str,
  major_brand_version: &'a [u8],
  compatible_brands:   Vec<&'a str>
}

#[derive(PartialEq,Eq,Debug)]
pub struct Mvhd1 {
  version:       u8,
  flags:         u32,
  created_date:  u32,
  modified_date: u32
}

#[derive(PartialEq,Eq,Debug)]
pub struct Mvhd2 {
  created_date:  u64,
  modified_date: u64,
  scale:         u32,
  duration:      u32
}

/*
#[derive(PartialEq,Eq,Debug)]
struct Mvhd3 {
  duration:      u64,
  speed:         f32,
  volume:        f32, // 2 bytes
*/
  /* 10 bytes reserved */
/*  scaleA:        f32,
  rotateB:       f32,
  angleU:        f32,
  rotateC:       f32,
  scaleD:        f32,
  angleV:        f32,
  positionX:     f32,
  positionY:     f32,
  scaleW:        f32,
  preview:       u64,
  poster:        u32,
  selection:     u64,
  current_time:  u32,
  track_id:      u32
}*/

#[derive(PartialEq,Eq,Debug)]
pub enum MvhdBox {
  M1(Mvhd1),
  M2(Mvhd2),
  M3
  /*M3(Mvhd3)*/
}

#[derive(PartialEq,Eq,Debug)]
pub enum MoovBox {
  Mdra,
  Dref,
  Cmov,
  Rmra,
  Iods,
  Mvhd,
  Clip,
  Trak,
  Udta
}

#[derive(PartialEq,Eq,Debug)]
enum MP4Box<'a> {
  Ftyp(FileType<'a>),
  Moov(Vec<MoovBox>),
  Mdat,
  Free,
  Skip,
  Wide,
  Unknown
}

take!(offset 4);
tag!(ftyp    "ftyp".as_bytes());

fn brand_name(input:&[u8]) -> IResult<&[u8],&str> {
  take!(major_brand_bytes 4);
  major_brand_bytes(input).map_res(str::from_utf8)
}
take!(major_brand_version 4);
many0!(compatible_brands<&[u8], &str> brand_name);

fn filetype_parser<'a>(input: &'a[u8]) -> IResult<&'a [u8], FileType<'a> > {
  chaining_parser!(input, ||{FileType{major_brand: m, major_brand_version:v, compatible_brands: c}},
    m: brand_name,
    v: major_brand_version,
    c: compatible_brands,)
}

o!(filetype <&[u8], FileType>  ftyp ~ [ filetype_parser ]);

fn filetype_box(input:&[u8]) -> IResult<&[u8], MP4Box> {
  match filetype(input) {
    Error(a)      => Error(a),
    Incomplete(a) => Incomplete(a),
    Done(i, o)    => {
      Done(i, MP4Box::Ftyp(o))
    }
  }
}

tag!(moov_tag "moov".as_bytes());

tag!(mdra    "mdra".as_bytes());
fn moov_mdra(input:&[u8]) -> IResult<&[u8], MoovBox> {
  mdra(input).map(|o| MoovBox::Mdra)
}

tag!(dref    "dref".as_bytes());
fn moov_dref(input:&[u8]) -> IResult<&[u8], MoovBox> {
  dref(input).map(|o| MoovBox::Dref)
}

tag!(cmov    "cmov".as_bytes());
fn moov_cmov(input:&[u8]) -> IResult<&[u8], MoovBox> {
  cmov(input).map(|o| MoovBox::Cmov)
}

tag!(rmra    "rmra".as_bytes());
fn moov_rmra(input:&[u8]) -> IResult<&[u8], MoovBox> {
  rmra(input).map(|o| MoovBox::Rmra)
}

tag!(iods    "iods".as_bytes());
fn moov_iods(input:&[u8]) -> IResult<&[u8], MoovBox> {
  iods(input).map(|o| MoovBox::Iods)
}

tag!(mvhd    "mvhd".as_bytes());
fn moov_mvhd(input:&[u8]) -> IResult<&[u8], MoovBox> {
  mvhd(input).map(|o| MoovBox::Mvhd)
}

tag!(clip    "clip".as_bytes());
fn moov_clip(input:&[u8]) -> IResult<&[u8], MoovBox> {
  clip(input).map(|o| MoovBox::Clip)
}

tag!(trak    "trak".as_bytes());
fn moov_trak(input:&[u8]) -> IResult<&[u8], MoovBox> {
  trak(input).map(|o| MoovBox::Trak)
}

tag!(udta   "udta".as_bytes());
fn moov_udta(input:&[u8]) -> IResult<&[u8], MoovBox> {
  udta(input).map(|o| MoovBox::Udta)
}

alt!(moov_internal<&[u8], MoovBox>, moov_mdra | moov_dref | moov_cmov |
     moov_rmra | moov_iods | moov_mvhd | moov_clip | moov_trak | moov_udta);

fn moov(input:&[u8]) -> IResult<&[u8], MoovBox> {
  match mp4_box(input) {
    Error(a)      => Error(a),
    Incomplete(a) => Incomplete(a),
    Done(i, o)    => {
      match moov_internal(o) {
        Error(a)      => Error(a),
        Incomplete(a) => Incomplete(a),
        Done(i2, o2)  => {
          Done(i, o2)
        }

      }
    }
  }
}

many0!(moov_many<&[u8],MoovBox> moov);

o!(moov_box_internal <&[u8], Vec<MoovBox> >  moov_tag ~ [ moov_many ]);
fn moov_box(input:&[u8]) -> IResult<&[u8], MP4Box> {
  match moov_box_internal(input) {
    Error(a)      => Error(a),
    Incomplete(a) => Incomplete(a),
    Done(i, o)  => {
      Done(i, MP4Box::Moov(o))
    }
  }
}

tag!(mdat    "mdat".as_bytes());
fn mdat_box(input:&[u8]) -> IResult<&[u8], MP4Box> {
  match mdat(input) {
    Error(a)      => Error(a),
    Incomplete(a) => Incomplete(a),
    Done(i, _)    => {
      Done(i, MP4Box::Mdat)
    }
  }
}
tag!(free    "free".as_bytes());
fn free_box(input:&[u8]) -> IResult<&[u8], MP4Box> {
  match free(input) {
    Error(a)      => Error(a),
    Incomplete(a) => Incomplete(a),
    Done(i, _)    => {
      Done(i, MP4Box::Free)
    }
  }
}

tag!(skip    "skip".as_bytes());
fn skip_box(input:&[u8]) -> IResult<&[u8], MP4Box> {
  match free(input) {
    Error(a)      => Error(a),
    Incomplete(a) => Incomplete(a),
    Done(i, _)    => {
      Done(i, MP4Box::Skip)
    }
  }
}

tag!(wide    "wide".as_bytes());
fn wide_box(input:&[u8]) -> IResult<&[u8], MP4Box> {
  match free(input) {
    Error(a)      => Error(a),
    Incomplete(a) => Incomplete(a),
    Done(i, _)    => {
      Done(i, MP4Box::Wide)
    }
  }
}

fn unknown_box(input:&[u8]) -> IResult<&[u8], MP4Box> {
  println!("calling UNKNOWN");
  Done(input, MP4Box::Unknown)
}

alt!(box_parser_internal<&[u8], MP4Box>, filetype_box | moov_box | mdat_box | free_box | skip_box | wide_box | unknown_box);
fn box_parser(input:&[u8]) -> IResult<&[u8], MP4Box> {
  match mp4_box(input) {
    Error(a)      => Error(a),
    Incomplete(a) => Incomplete(a),
    Done(i, o)    => {
      match box_parser_internal(o) {
        Error(a)      => Error(a),
        Incomplete(a) => Incomplete(a),
        Done(i2, o2)  => {
          Done(i, o2)
        }
      }
    }
  }
}

fn data_interpreter(bytes:&[u8]) -> IResult<&[u8], ()> {
  //println!("bytes:\n{}", bytes.to_hex(8));
  match box_parser(bytes) {
    Done(i, o) => {
      match o {
        MP4Box::Ftyp(f) => println!("-> FTYP: {:?}", f),
        MP4Box::Moov(m) => {println!("-> MOOV: {:?}", m); println!("remaining:\n{}", i.to_hex(8))},
        MP4Box::Mdat    => println!("-> MDAT"),
        MP4Box::Free    => println!("-> FREE"),
        MP4Box::Skip    => println!("-> SKIP"),
        MP4Box::Wide    => println!("-> WIDE"),
        MP4Box::Unknown => println!("-> UNKNOWN")
      }
      //println!("remaining:\n{}", i.to_hex(8));
      Done(i,())
    },
    Error(a) => {
      println!("mp4 parsing error: {:?}", a);
      Error(a)
    },
    Incomplete(a) => {
      //println!("incomplete: {:?}", a);
      Incomplete(a)
    }
  }
}

fn multiple_data_interpreter(bytes:&[u8]) -> IResult<&[u8], ()> {
  match data_interpreter(bytes) {
    Error(a)      => Error(a),
    Incomplete(a) => Incomplete(a),
    Done(i, ())   => {
      println!("NEXT BOX");
      match data_interpreter(i) {
        Error(a)      => Error(a),
        Incomplete(a) => Incomplete(a),
        Done(i2,())   => {
          println!("NEXT BOX 2");
          match data_interpreter(i2) {
            Error(a)      => Error(a),
            Incomplete(a) => Incomplete(a),
            Done(i3,())   => {
              println!("NEXT BOX 3");
              match data_interpreter(i3) {
                Error(a)      => Error(a),
                Incomplete(a) => Incomplete(a),
                Done(i4,())   => {
                  println!("NEXT BOX 4");
                  let res = data_interpreter(i4);
                  println!("res4: {:?}", res);
                  res
                }
              }
            }
          }
        }
      }
    },
  }
}

many0!(full_data_interpreter<&[u8],()> data_interpreter);

fn parse_mp4_file(filename: &str) {
  FileProducer::new(filename, 40000).map(|producer: FileProducer| {
    let mut p = producer;
    match p.produce() {
      ProducerState::Data(bytes) => {
        multiple_data_interpreter(bytes);
      },
      _ => println!("got error")
    }
    /*
    pusher!(ps, full_data_interpreter);
    ps(&mut p);
    */
    //assert!(false);
  });

}
#[test]
fn file_test() {
  parse_mp4_file("small.mp4");
}
#[test]
fn bunny_test() {
  parse_mp4_file("bigbuckbunny.mp4");
}
<|endoftext|>


<commit_before>// Copyright 2013 The Servo Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution.
//
// 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 length::Length;
use size::Size2D;

use std::fmt;
use std::num::Zero;

#[deriving(Clone, Decodable, Encodable, Eq, Hash, PartialEq)]
pub struct Point2D<T> {
    pub x: T,
    pub y: T
}

impl<T: Zero + Clone> Zero for Point2D<T> {
    fn zero() -> Point2D<T> {
        Point2D { x: Zero::zero(), y: Zero::zero() }
    }

    fn is_zero(&self) -> bool {
        self.x.is_zero() && self.y.is_zero()
    }
}

impl<T: fmt::Show> fmt::Show for Point2D<T> {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        write!(f, "({},{})", self.x, self.y)
    }
}

pub fn Point2D<T:Clone>(x: T, y: T) -> Point2D<T> {
    Point2D {x: x, y: y}
}

impl<T:Clone + Add<T,T>> Add<Point2D<T>, Point2D<T>> for Point2D<T> {
    fn add(&self, other: &Point2D<T>) -> Point2D<T> {
        Point2D(self.x + other.x, self.y + other.y)
    }
}

impl<T: Add<T, T>> Point2D<T> {
    pub fn add_size(&self, other: &Size2D<T>) -> Point2D<T> {
        Point2D { x: self.x + other.width, y: self.y + other.height }
    }
}

impl<T:Clone + Sub<T,T>> Sub<Point2D<T>, Point2D<T>> for Point2D<T> {
    fn sub(&self, other: &Point2D<T>) -> Point2D<T> {
        Point2D(self.x - other.x, self.y - other.y)
    }
}

impl <T:Clone + Neg<T>> Neg<Point2D<T>> for Point2D<T> {
    #[inline]
    fn neg(&self) -> Point2D<T> {
        Point2D(-self.x, -self.y)
    }
}

impl<Scale, T0: Mul<Scale, T1>, T1: Clone> Mul<Scale, Point2D<T1>> for Point2D<T0> {
    #[inline]
    fn mul(&self, scale: &Scale) -> Point2D<T1> {
        Point2D(self.x * *scale, self.y * *scale)
    }
}

impl<Scale, T0: Div<Scale, T1>, T1: Clone> Div<Scale, Point2D<T1>> for Point2D<T0> {
    #[inline]
    fn div(&self, scale: &Scale) -> Point2D<T1> {
        Point2D(self.x / *scale, self.y / *scale)
    }
}

// Convenient aliases for Point2D with typed units

pub type TypedPoint2D<Unit, T> = Point2D<Length<Unit, T>>;

pub fn TypedPoint2D<Unit, T: Clone>(x: T, y: T) -> TypedPoint2D<Unit, T> {
    Point2D(Length(x), Length(y))
}

impl<Unit, T: Clone> Point2D<Length<Unit, T>> {
    /// Drop the units, preserving only the numeric value.
    pub fn to_untyped(&self) -> Point2D<T> {
        Point2D(self.x.get(), self.y.get())
    }

    /// Tag a unitless value with units.
    pub fn from_untyped(p: &Point2D<T>) -> TypedPoint2D<Unit, T> {
        Point2D(Length(p.x.clone()), Length(p.y.clone()))
    }
}

impl<Unit, T0: NumCast + Clone, T1: NumCast + Clone> Point2D<Length<Unit, T0>> {
    /// Cast from one numeric representation to another, preserving the units.
    pub fn cast(&self) -> Option<Point2D<Length<Unit, T1>>> {
        match (self.x.cast(), self.y.cast()) {
            (Some(x), Some(y)) => Some(Point2D(x, y)),
            _ => None
        }
    }
}

// Convenience functions for common casts
impl<Unit, T: NumCast + Clone> Point2D<Length<Unit, T>> {
    pub fn as_f32(&self) -> Point2D<Length<Unit, f32>> {
        self.cast().unwrap()
    }

    pub fn as_uint(&self) -> Point2D<Length<Unit, uint>> {
        self.cast().unwrap()
    }
}
<commit_msg>Implement `Point2D + Size2D -> Point2D`, now that we have multi-dispatch<commit_after>// Copyright 2013 The Servo Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution.
//
// 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 length::Length;
use size::Size2D;

use std::fmt;
use std::num::Zero;

#[deriving(Clone, Decodable, Encodable, Eq, Hash, PartialEq)]
pub struct Point2D<T> {
    pub x: T,
    pub y: T
}

impl<T: Zero + Clone> Zero for Point2D<T> {
    fn zero() -> Point2D<T> {
        Point2D { x: Zero::zero(), y: Zero::zero() }
    }

    fn is_zero(&self) -> bool {
        self.x.is_zero() && self.y.is_zero()
    }
}

impl<T: fmt::Show> fmt::Show for Point2D<T> {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        write!(f, "({},{})", self.x, self.y)
    }
}

pub fn Point2D<T:Clone>(x: T, y: T) -> Point2D<T> {
    Point2D {x: x, y: y}
}

impl<T:Clone + Add<T,T>> Add<Point2D<T>, Point2D<T>> for Point2D<T> {
    fn add(&self, other: &Point2D<T>) -> Point2D<T> {
        Point2D(self.x + other.x, self.y + other.y)
    }
}

impl<T:Clone + Add<T,T>> Add<Size2D<T>, Point2D<T>> for Point2D<T> {
    fn add(&self, other: &Size2D<T>) -> Point2D<T> {
        Point2D(self.x + other.width, self.y + other.height)
    }
}

impl<T: Add<T, T>> Point2D<T> {
    pub fn add_size(&self, other: &Size2D<T>) -> Point2D<T> {
        Point2D { x: self.x + other.width, y: self.y + other.height }
    }
}

impl<T:Clone + Sub<T,T>> Sub<Point2D<T>, Point2D<T>> for Point2D<T> {
    fn sub(&self, other: &Point2D<T>) -> Point2D<T> {
        Point2D(self.x - other.x, self.y - other.y)
    }
}

impl <T:Clone + Neg<T>> Neg<Point2D<T>> for Point2D<T> {
    #[inline]
    fn neg(&self) -> Point2D<T> {
        Point2D(-self.x, -self.y)
    }
}

impl<Scale, T0: Mul<Scale, T1>, T1: Clone> Mul<Scale, Point2D<T1>> for Point2D<T0> {
    #[inline]
    fn mul(&self, scale: &Scale) -> Point2D<T1> {
        Point2D(self.x * *scale, self.y * *scale)
    }
}

impl<Scale, T0: Div<Scale, T1>, T1: Clone> Div<Scale, Point2D<T1>> for Point2D<T0> {
    #[inline]
    fn div(&self, scale: &Scale) -> Point2D<T1> {
        Point2D(self.x / *scale, self.y / *scale)
    }
}

// Convenient aliases for Point2D with typed units

pub type TypedPoint2D<Unit, T> = Point2D<Length<Unit, T>>;

pub fn TypedPoint2D<Unit, T: Clone>(x: T, y: T) -> TypedPoint2D<Unit, T> {
    Point2D(Length(x), Length(y))
}

impl<Unit, T: Clone> Point2D<Length<Unit, T>> {
    /// Drop the units, preserving only the numeric value.
    pub fn to_untyped(&self) -> Point2D<T> {
        Point2D(self.x.get(), self.y.get())
    }

    /// Tag a unitless value with units.
    pub fn from_untyped(p: &Point2D<T>) -> TypedPoint2D<Unit, T> {
        Point2D(Length(p.x.clone()), Length(p.y.clone()))
    }
}

impl<Unit, T0: NumCast + Clone, T1: NumCast + Clone> Point2D<Length<Unit, T0>> {
    /// Cast from one numeric representation to another, preserving the units.
    pub fn cast(&self) -> Option<Point2D<Length<Unit, T1>>> {
        match (self.x.cast(), self.y.cast()) {
            (Some(x), Some(y)) => Some(Point2D(x, y)),
            _ => None
        }
    }
}

// Convenience functions for common casts
impl<Unit, T: NumCast + Clone> Point2D<Length<Unit, T>> {
    pub fn as_f32(&self) -> Point2D<Length<Unit, f32>> {
        self.cast().unwrap()
    }

    pub fn as_uint(&self) -> Point2D<Length<Unit, uint>> {
        self.cast().unwrap()
    }
}
<|endoftext|>