<commit_before>#![allow(clippy::zero_sized_map_values)]

use indoc::indoc;
use serde::de::{Deserialize, SeqAccess, Visitor};
use serde_derive::{Deserialize, Serialize};
use serde_yaml::Deserializer;
use std::collections::BTreeMap;
use std::fmt::{self, Debug};

fn test_error<'de, T>(yaml: &'de str, expected: &str)
where
    T: Deserialize<'de> + Debug,
{
    let result = serde_yaml::from_str::<T>(yaml);
    assert_eq!(expected, result.unwrap_err().to_string());
}

#[test]
fn test_incorrect_type() {
    let yaml = indoc! {"
        ---
        str
    "};
    let expected = "invalid type: string \"str\", expected i16 at line 2 column 1";
    test_error::<i16>(yaml, expected);
}

#[test]
fn test_incorrect_nested_type() {
    #[derive(Deserialize, Debug)]
    struct A {
        #[allow(dead_code)]
        b: Vec<B>,
    }
    #[derive(Deserialize, Debug)]
    enum B {
        C(C),
    }
    #[derive(Deserialize, Debug)]
    struct C {
        #[allow(dead_code)]
        d: bool,
    }
    let yaml = indoc! {"
        b:
          - !C
            d: fase
    "};
    let expected = "b[0].d: invalid type: string \"fase\", expected a boolean at line 3 column 8";
    test_error::<A>(yaml, expected);
}

#[test]
fn test_empty() {
    let expected = "EOF while parsing a value";
    test_error::<String>("", expected);
}

#[test]
fn test_missing_field() {
    #[derive(Deserialize, Debug)]
    struct Basic {
        #[allow(dead_code)]
        v: bool,
        #[allow(dead_code)]
        w: bool,
    }
    let yaml = indoc! {"
        ---
        v: true
    "};
    let expected = "missing field `w` at line 2 column 1";
    test_error::<Basic>(yaml, expected);
}

#[test]
fn test_unknown_anchor() {
    let yaml = indoc! {"
        ---
        *some
    "};
    let expected = "unknown anchor at line 2 column 1";
    test_error::<String>(yaml, expected);
}

#[test]
fn test_ignored_unknown_anchor() {
    #[derive(Deserialize, Debug)]
    struct Wrapper {
        #[allow(dead_code)]
        c: (),
    }
    let yaml = indoc! {"
        b: [*a]
        c: ~
    "};
    let expected = "unknown anchor at line 1 column 5";
    test_error::<Wrapper>(yaml, expected);
}

#[test]
fn test_bytes() {
    let expected = "serialization and deserialization of bytes in YAML is not implemented";
    test_error::<&[u8]>("...", expected);
}

#[test]
fn test_two_documents() {
    let yaml = indoc! {"
        ---
        0
        ---
        1
    "};
    let expected = "deserializing from YAML containing more than one document is not supported";
    test_error::<usize>(yaml, expected);
}

#[test]
fn test_second_document_syntax_error() {
    let yaml = indoc! {"
        ---
        0
        ---
        ]
    "};

    let mut de = Deserializer::from_str(yaml);
    let first_doc = de.next().unwrap();
    let result = <usize as serde::Deserialize>::deserialize(first_doc);
    assert_eq!(0, result.unwrap());

    let second_doc = de.next().unwrap();
    let result = <usize as serde::Deserialize>::deserialize(second_doc);
    let expected = "did not find expected node content at line 4 column 1, while parsing a block node at line 4 column 1";
    assert_eq!(expected, result.unwrap_err().to_string());
}

#[test]
fn test_missing_enum_tag() {
    #[derive(Deserialize, Debug)]
    enum E {
        V(usize),
    }
    let yaml = indoc! {r#"
        "V": 16
        "other": 32
    "#};
    let expected = "invalid type: map, expected a YAML tag starting with '!' at position 0";
    test_error::<E>(yaml, expected);
}

#[test]
fn test_serialize_nested_enum() {
    #[derive(Serialize, Debug)]
    enum Outer {
        Inner(Inner),
    }
    #[derive(Serialize, Debug)]
    enum Inner {
        Newtype(usize),
        Tuple(usize, usize),
        Struct { x: usize },
    }

    let expected = "serializing nested enums in YAML is not supported yet";

    let e = Outer::Inner(Inner::Newtype(0));
    let error = serde_yaml::to_string(&e).unwrap_err();
    assert_eq!(error.to_string(), expected);

    let e = Outer::Inner(Inner::Tuple(0, 0));
    let error = serde_yaml::to_string(&e).unwrap_err();
    assert_eq!(error.to_string(), expected);

    let e = Outer::Inner(Inner::Struct { x: 0 });
    let error = serde_yaml::to_string(&e).unwrap_err();
    assert_eq!(error.to_string(), expected);
}

#[test]
fn test_variant_not_a_seq() {
    #[derive(Deserialize, Debug)]
    enum E {
        V(usize),
    }
    let yaml = indoc! {r#"
        ---
        !V
        value: 0
    "#};
    let expected = "invalid type: map, expected usize at line 2 column 1";
    test_error::<E>(yaml, expected);
}

#[test]
fn test_struct_from_sequence() {
    #[allow(dead_code)]
    #[derive(Deserialize, Debug)]
    struct Struct {
        x: usize,
        y: usize,
    }
    let yaml = indoc! {"
        [0, 0]
    "};
    let expected = "invalid type: sequence, expected struct Struct at position 0";
    test_error::<Struct>(yaml, expected);
}

#[test]
fn test_bad_bool() {
    let yaml = indoc! {"
        ---
        !!bool str
    "};
    let expected = "invalid value: string \"str\", expected a boolean at line 2 column 1";
    test_error::<bool>(yaml, expected);
}

#[test]
fn test_bad_int() {
    let yaml = indoc! {"
        ---
        !!int str
    "};
    let expected = "invalid value: string \"str\", expected an integer at line 2 column 1";
    test_error::<i64>(yaml, expected);
}

#[test]
fn test_bad_float() {
    let yaml = indoc! {"
        ---
        !!float str
    "};
    let expected = "invalid value: string \"str\", expected a float at line 2 column 1";
    test_error::<f64>(yaml, expected);
}

#[test]
fn test_bad_null() {
    let yaml = indoc! {"
        ---
        !!null str
    "};
    let expected = "invalid value: string \"str\", expected null at line 2 column 1";
    test_error::<()>(yaml, expected);
}

#[test]
fn test_short_tuple() {
    let yaml = indoc! {"
        ---
        [0, 0]
    "};
    let expected = "invalid length 2, expected a tuple of size 3 at line 2 column 1";
    test_error::<(u8, u8, u8)>(yaml, expected);
}

#[test]
fn test_long_tuple() {
    let yaml = indoc! {"
        ---
        [0, 0, 0]
    "};
    let expected = "invalid length 3, expected sequence of 2 elements at line 2 column 1";
    test_error::<(u8, u8)>(yaml, expected);
}

#[test]
fn test_invalid_scalar_type() {
    #[derive(Deserialize, Debug)]
    struct S {
        #[allow(dead_code)]
        x: [(); 1],
    }

    let yaml = "x:\n";
    let expected = "x: invalid type: unit value, expected an array of length 1 at line 1 column 3";
    test_error::<S>(yaml, expected);
}

#[cfg(not(miri))]
#[test]
fn test_infinite_recursion_objects() {
    #[derive(Deserialize, Debug)]
    struct S {
        #[allow(dead_code)]
        x: Option<Box<S>>,
    }

    let yaml = "&a {'x': *a}";
    let expected = "recursion limit exceeded at position 0";
    test_error::<S>(yaml, expected);
}

#[cfg(not(miri))]
#[test]
fn test_infinite_recursion_arrays() {
    #[derive(Deserialize, Debug)]
    struct S(usize, Option<Box<S>>);

    let yaml = "&a [0, *a]";
    let expected = "recursion limit exceeded at position 0";
    test_error::<S>(yaml, expected);
}

#[cfg(not(miri))]
#[test]
fn test_infinite_recursion_newtype() {
    #[derive(Deserialize, Debug)]
    struct S(Option<Box<S>>);

    let yaml = "&a [*a]";
    let expected = "recursion limit exceeded at position 0";
    test_error::<S>(yaml, expected);
}

#[cfg(not(miri))]
#[test]
fn test_finite_recursion_objects() {
    #[derive(Deserialize, Debug)]
    struct S {
        #[allow(dead_code)]
        x: Option<Box<S>>,
    }

    let yaml = "{'x':".repeat(1_000) + &"}".repeat(1_000);
    let expected = "recursion limit exceeded at line 1 column 641";
    test_error::<S>(&yaml, expected);
}

#[cfg(not(miri))]
#[test]
fn test_finite_recursion_arrays() {
    #[derive(Deserialize, Debug)]
    struct S(usize, Option<Box<S>>);

    let yaml = "[0, ".repeat(1_000) + &"]".repeat(1_000);
    let expected = "recursion limit exceeded at line 1 column 513";
    test_error::<S>(&yaml, expected);
}

#[cfg(not(miri))]
#[test]
fn test_billion_laughs() {
    #[derive(Debug)]
    struct X;

    impl<'de> Deserialize<'de> for X {
        fn deserialize<D>(deserializer: D) -> Result<X, D::Error>
        where
            D: serde::Deserializer<'de>,
        {
            impl<'de> Visitor<'de> for X {
                type Value = X;

                fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
                    formatter.write_str("exponential blowup")
                }

                fn visit_unit<E>(self) -> Result<X, E> {
                    Ok(X)
                }

                fn visit_seq<S>(self, mut seq: S) -> Result<X, S::Error>
                where
                    S: SeqAccess<'de>,
                {
                    while let Some(X) = seq.next_element()? {}
                    Ok(X)
                }
            }

            deserializer.deserialize_any(X)
        }
    }

    let yaml = indoc! {"
        a: &a ~
        b: &b [*a,*a,*a,*a,*a,*a,*a,*a,*a]
        c: &c [*b,*b,*b,*b,*b,*b,*b,*b,*b]
        d: &d [*c,*c,*c,*c,*c,*c,*c,*c,*c]
        e: &e [*d,*d,*d,*d,*d,*d,*d,*d,*d]
        f: &f [*e,*e,*e,*e,*e,*e,*e,*e,*e]
        g: &g [*f,*f,*f,*f,*f,*f,*f,*f,*f]
        h: &h [*g,*g,*g,*g,*g,*g,*g,*g,*g]
        i: &i [*h,*h,*h,*h,*h,*h,*h,*h,*h]
    "};
    let expected = "repetition limit exceeded";
    test_error::<BTreeMap<String, X>>(yaml, expected);
}
<commit_msg>Add nested enum deserialization error test<commit_after>#![allow(clippy::zero_sized_map_values)]

use indoc::indoc;
use serde::de::{Deserialize, SeqAccess, Visitor};
use serde_derive::{Deserialize, Serialize};
use serde_yaml::Deserializer;
use std::collections::BTreeMap;
use std::fmt::{self, Debug};

fn test_error<'de, T>(yaml: &'de str, expected: &str)
where
    T: Deserialize<'de> + Debug,
{
    let result = serde_yaml::from_str::<T>(yaml);
    assert_eq!(expected, result.unwrap_err().to_string());
}

#[test]
fn test_incorrect_type() {
    let yaml = indoc! {"
        ---
        str
    "};
    let expected = "invalid type: string \"str\", expected i16 at line 2 column 1";
    test_error::<i16>(yaml, expected);
}

#[test]
fn test_incorrect_nested_type() {
    #[derive(Deserialize, Debug)]
    struct A {
        #[allow(dead_code)]
        b: Vec<B>,
    }
    #[derive(Deserialize, Debug)]
    enum B {
        C(C),
    }
    #[derive(Deserialize, Debug)]
    struct C {
        #[allow(dead_code)]
        d: bool,
    }
    let yaml = indoc! {"
        b:
          - !C
            d: fase
    "};
    let expected = "b[0].d: invalid type: string \"fase\", expected a boolean at line 3 column 8";
    test_error::<A>(yaml, expected);
}

#[test]
fn test_empty() {
    let expected = "EOF while parsing a value";
    test_error::<String>("", expected);
}

#[test]
fn test_missing_field() {
    #[derive(Deserialize, Debug)]
    struct Basic {
        #[allow(dead_code)]
        v: bool,
        #[allow(dead_code)]
        w: bool,
    }
    let yaml = indoc! {"
        ---
        v: true
    "};
    let expected = "missing field `w` at line 2 column 1";
    test_error::<Basic>(yaml, expected);
}

#[test]
fn test_unknown_anchor() {
    let yaml = indoc! {"
        ---
        *some
    "};
    let expected = "unknown anchor at line 2 column 1";
    test_error::<String>(yaml, expected);
}

#[test]
fn test_ignored_unknown_anchor() {
    #[derive(Deserialize, Debug)]
    struct Wrapper {
        #[allow(dead_code)]
        c: (),
    }
    let yaml = indoc! {"
        b: [*a]
        c: ~
    "};
    let expected = "unknown anchor at line 1 column 5";
    test_error::<Wrapper>(yaml, expected);
}

#[test]
fn test_bytes() {
    let expected = "serialization and deserialization of bytes in YAML is not implemented";
    test_error::<&[u8]>("...", expected);
}

#[test]
fn test_two_documents() {
    let yaml = indoc! {"
        ---
        0
        ---
        1
    "};
    let expected = "deserializing from YAML containing more than one document is not supported";
    test_error::<usize>(yaml, expected);
}

#[test]
fn test_second_document_syntax_error() {
    let yaml = indoc! {"
        ---
        0
        ---
        ]
    "};

    let mut de = Deserializer::from_str(yaml);
    let first_doc = de.next().unwrap();
    let result = <usize as serde::Deserialize>::deserialize(first_doc);
    assert_eq!(0, result.unwrap());

    let second_doc = de.next().unwrap();
    let result = <usize as serde::Deserialize>::deserialize(second_doc);
    let expected = "did not find expected node content at line 4 column 1, while parsing a block node at line 4 column 1";
    assert_eq!(expected, result.unwrap_err().to_string());
}

#[test]
fn test_missing_enum_tag() {
    #[derive(Deserialize, Debug)]
    enum E {
        V(usize),
    }
    let yaml = indoc! {r#"
        "V": 16
        "other": 32
    "#};
    let expected = "invalid type: map, expected a YAML tag starting with '!' at position 0";
    test_error::<E>(yaml, expected);
}

#[test]
fn test_serialize_nested_enum() {
    #[derive(Serialize, Debug)]
    enum Outer {
        Inner(Inner),
    }
    #[derive(Serialize, Debug)]
    enum Inner {
        Newtype(usize),
        Tuple(usize, usize),
        Struct { x: usize },
    }

    let expected = "serializing nested enums in YAML is not supported yet";

    let e = Outer::Inner(Inner::Newtype(0));
    let error = serde_yaml::to_string(&e).unwrap_err();
    assert_eq!(error.to_string(), expected);

    let e = Outer::Inner(Inner::Tuple(0, 0));
    let error = serde_yaml::to_string(&e).unwrap_err();
    assert_eq!(error.to_string(), expected);

    let e = Outer::Inner(Inner::Struct { x: 0 });
    let error = serde_yaml::to_string(&e).unwrap_err();
    assert_eq!(error.to_string(), expected);
}

#[test]
fn test_deserialize_nested_enum() {
    #[derive(Deserialize, Debug)]
    enum Outer {
        Inner(Inner),
    }
    #[derive(Deserialize, Debug)]
    enum Inner {
        Variant(usize),
    }

    let yaml = "!Inner 0\n";
    let expected = "unknown variant `Inner`, expected `Variant`";
    test_error::<Outer>(yaml, expected);

    let yaml = "!Variant 0\n";
    let expected = "unknown variant `Variant`, expected `Inner`";
    test_error::<Outer>(yaml, expected);

    let yaml = "!Inner !Variant 0\n";
    let expected = "unknown variant `Inner`, expected `Variant`";
    test_error::<Outer>(yaml, expected);
}

#[test]
fn test_variant_not_a_seq() {
    #[derive(Deserialize, Debug)]
    enum E {
        V(usize),
    }
    let yaml = indoc! {r#"
        ---
        !V
        value: 0
    "#};
    let expected = "invalid type: map, expected usize at line 2 column 1";
    test_error::<E>(yaml, expected);
}

#[test]
fn test_struct_from_sequence() {
    #[allow(dead_code)]
    #[derive(Deserialize, Debug)]
    struct Struct {
        x: usize,
        y: usize,
    }
    let yaml = indoc! {"
        [0, 0]
    "};
    let expected = "invalid type: sequence, expected struct Struct at position 0";
    test_error::<Struct>(yaml, expected);
}

#[test]
fn test_bad_bool() {
    let yaml = indoc! {"
        ---
        !!bool str
    "};
    let expected = "invalid value: string \"str\", expected a boolean at line 2 column 1";
    test_error::<bool>(yaml, expected);
}

#[test]
fn test_bad_int() {
    let yaml = indoc! {"
        ---
        !!int str
    "};
    let expected = "invalid value: string \"str\", expected an integer at line 2 column 1";
    test_error::<i64>(yaml, expected);
}

#[test]
fn test_bad_float() {
    let yaml = indoc! {"
        ---
        !!float str
    "};
    let expected = "invalid value: string \"str\", expected a float at line 2 column 1";
    test_error::<f64>(yaml, expected);
}

#[test]
fn test_bad_null() {
    let yaml = indoc! {"
        ---
        !!null str
    "};
    let expected = "invalid value: string \"str\", expected null at line 2 column 1";
    test_error::<()>(yaml, expected);
}

#[test]
fn test_short_tuple() {
    let yaml = indoc! {"
        ---
        [0, 0]
    "};
    let expected = "invalid length 2, expected a tuple of size 3 at line 2 column 1";
    test_error::<(u8, u8, u8)>(yaml, expected);
}

#[test]
fn test_long_tuple() {
    let yaml = indoc! {"
        ---
        [0, 0, 0]
    "};
    let expected = "invalid length 3, expected sequence of 2 elements at line 2 column 1";
    test_error::<(u8, u8)>(yaml, expected);
}

#[test]
fn test_invalid_scalar_type() {
    #[derive(Deserialize, Debug)]
    struct S {
        #[allow(dead_code)]
        x: [(); 1],
    }

    let yaml = "x:\n";
    let expected = "x: invalid type: unit value, expected an array of length 1 at line 1 column 3";
    test_error::<S>(yaml, expected);
}

#[cfg(not(miri))]
#[test]
fn test_infinite_recursion_objects() {
    #[derive(Deserialize, Debug)]
    struct S {
        #[allow(dead_code)]
        x: Option<Box<S>>,
    }

    let yaml = "&a {'x': *a}";
    let expected = "recursion limit exceeded at position 0";
    test_error::<S>(yaml, expected);
}

#[cfg(not(miri))]
#[test]
fn test_infinite_recursion_arrays() {
    #[derive(Deserialize, Debug)]
    struct S(usize, Option<Box<S>>);

    let yaml = "&a [0, *a]";
    let expected = "recursion limit exceeded at position 0";
    test_error::<S>(yaml, expected);
}

#[cfg(not(miri))]
#[test]
fn test_infinite_recursion_newtype() {
    #[derive(Deserialize, Debug)]
    struct S(Option<Box<S>>);

    let yaml = "&a [*a]";
    let expected = "recursion limit exceeded at position 0";
    test_error::<S>(yaml, expected);
}

#[cfg(not(miri))]
#[test]
fn test_finite_recursion_objects() {
    #[derive(Deserialize, Debug)]
    struct S {
        #[allow(dead_code)]
        x: Option<Box<S>>,
    }

    let yaml = "{'x':".repeat(1_000) + &"}".repeat(1_000);
    let expected = "recursion limit exceeded at line 1 column 641";
    test_error::<S>(&yaml, expected);
}

#[cfg(not(miri))]
#[test]
fn test_finite_recursion_arrays() {
    #[derive(Deserialize, Debug)]
    struct S(usize, Option<Box<S>>);

    let yaml = "[0, ".repeat(1_000) + &"]".repeat(1_000);
    let expected = "recursion limit exceeded at line 1 column 513";
    test_error::<S>(&yaml, expected);
}

#[cfg(not(miri))]
#[test]
fn test_billion_laughs() {
    #[derive(Debug)]
    struct X;

    impl<'de> Deserialize<'de> for X {
        fn deserialize<D>(deserializer: D) -> Result<X, D::Error>
        where
            D: serde::Deserializer<'de>,
        {
            impl<'de> Visitor<'de> for X {
                type Value = X;

                fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
                    formatter.write_str("exponential blowup")
                }

                fn visit_unit<E>(self) -> Result<X, E> {
                    Ok(X)
                }

                fn visit_seq<S>(self, mut seq: S) -> Result<X, S::Error>
                where
                    S: SeqAccess<'de>,
                {
                    while let Some(X) = seq.next_element()? {}
                    Ok(X)
                }
            }

            deserializer.deserialize_any(X)
        }
    }

    let yaml = indoc! {"
        a: &a ~
        b: &b [*a,*a,*a,*a,*a,*a,*a,*a,*a]
        c: &c [*b,*b,*b,*b,*b,*b,*b,*b,*b]
        d: &d [*c,*c,*c,*c,*c,*c,*c,*c,*c]
        e: &e [*d,*d,*d,*d,*d,*d,*d,*d,*d]
        f: &f [*e,*e,*e,*e,*e,*e,*e,*e,*e]
        g: &g [*f,*f,*f,*f,*f,*f,*f,*f,*f]
        h: &h [*g,*g,*g,*g,*g,*g,*g,*g,*g]
        i: &i [*h,*h,*h,*h,*h,*h,*h,*h,*h]
    "};
    let expected = "repetition limit exceeded";
    test_error::<BTreeMap<String, X>>(yaml, expected);
}
<|endoftext|>


<commit_before>extern crate num;

#[allow(dead_code)]
pub struct ZeroPaddedSignal<T> {
	values: Vec<T>,
}

impl<T: num::traits::Zero + Clone> ZeroPaddedSignal<T> {
	/**
		Returns the number of initialized values.
	*/
	#[allow(dead_code)]
	pub fn size(&self) -> usize {
		self.values.len()
	}

	/**
		Returns the value at the given index, zero if index
		is negative or uninitialized.
	*/
	#[allow(dead_code)]
	pub fn get(&self, idx: isize) -> T {
		/* Check for negative index: */
		if idx < 0 {
			/* Negative, return zero: */
			T::zero()
		} else {
			/* Not negative, cast to unsigned: */
			let idx = idx as usize;
			/* Check if the index is initialized: */
			if let Some(v) = self.values.get(idx).cloned() {
				/* It is, return the value: */
				v
			} else {
				/* It's not, return zero: */
				T::zero()
			}
		}
	}

	/**
		Returns a vector of signal values, starting with index start,
		ending with index end.
	*/
	#[allow(dead_code)]
	pub fn to_vector(&self, start: isize, end: isize) -> Vec<T> {
		/* Create an empty vector: */
		let mut x: Vec<T> = Vec::new();
		/* Loop through the given range: */
		for i in start..(end+1) {
			/* Add the values to the vector: */
			x.push(self.get(i));
		}
		/* Make the vector immutable: */
		let x = x;
		/* Return the vector: */
		x
	}
}

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

	#[test]
	fn zero_padded_signal() {
		/* Create test signals: */
		let x1 = ZeroPaddedSignal { values: vec![42,7,11] };
		/* Test size method: */
		assert_eq!( 3, x1.size());
		/* Test get method: */
		assert_eq!( 0, x1.get(  -1));
		assert_eq!(42, x1.get(   0));
		assert_eq!( 7, x1.get(   1));
		assert_eq!(11, x1.get(   2));
		assert_eq!( 0, x1.get(   3));
		assert_eq!( 0, x1.get( 100));
		assert_eq!( 0, x1.get(-100));
		/* Test to_vector method: */
		assert_eq!(vec![0,0,0,42,7,11,0], x1.to_vector(-3,3));
	}
}
<commit_msg>linear prediction<commit_after>extern crate num;

use std::ops::Mul;
use std::ops::Add;

#[allow(dead_code)]
pub struct ZeroPaddedSignal<T> {
	values: Vec<T>,
}

impl<T: num::traits::Zero + Clone + Mul<Output = T> + Add> ZeroPaddedSignal<T> {
	/**
		Returns the number of initialized values.
	*/
	#[allow(dead_code)]
	pub fn size(&self) -> usize {
		self.values.len()
	}

	/**
		Returns the value at the given index, zero if index
		is negative or uninitialized.
	*/
	#[allow(dead_code)]
	pub fn get(&self, idx: isize) -> T {
		/* Check for negative index: */
		if idx < 0 {
			/* Negative, return zero: */
			T::zero()
		} else {
			/* Not negative, cast to unsigned: */
			let idx = idx as usize;
			/* Check if the index is initialized: */
			if let Some(v) = self.values.get(idx).cloned() {
				/* It is, return the value: */
				v
			} else {
				/* It's not, return zero: */
				T::zero()
			}
		}
	}

	/**
		Returns a vector of signal values, starting with index start,
		ending with index end.
	*/
	#[allow(dead_code)]
	pub fn to_vector(&self, start: isize, end: isize) -> Vec<T> {
		/* Create an empty vector: */
		let mut x: Vec<T> = Vec::new();
		/* Loop through the given range: */
		for i in start..(end+1) {
			/* Add the values to the vector: */
			x.push(self.get(i));
		}
		/* Make the vector immutable: */
		let x = x;
		/* Return the vector: */
		x
	}

	/**
		Creates a new signal by doing Linear Prediction using
		the given coefficients.
	*/
	#[allow(dead_code)]
	pub fn linear_prediction(&self, a: Vec<T>) -> ZeroPaddedSignal<T> {
		let mut vals: Vec<T> = Vec::new();
		let num: usize = self.size() + a.len();
		for i in 0..num {
			let mut val: T = T::zero();
			for j in 0..a.len() {
				let idx = (i - (j+1)) as isize;
				if let Some(v) = a.get(j).cloned() {
					val = val + v*self.get(idx);
				}
			}
			vals.push(val);
		}
		let x: ZeroPaddedSignal<T> = ZeroPaddedSignal { values: vals };
		x
	}
}

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

	#[test]
	fn zero_padded_signal() {
		/* Create test signals: */
		let x1 = ZeroPaddedSignal { values: vec![42,7,11] };
		/* Test size method: */
		assert_eq!( 3, x1.size());
		/* Test get method: */
		assert_eq!( 0, x1.get(  -1));
		assert_eq!(42, x1.get(   0));
		assert_eq!( 7, x1.get(   1));
		assert_eq!(11, x1.get(   2));
		assert_eq!( 0, x1.get(   3));
		assert_eq!( 0, x1.get( 100));
		assert_eq!( 0, x1.get(-100));
		/* Test to_vector method: */
		assert_eq!(vec![0,0,0,42,7,11,0], x1.to_vector(-3,3));
	}
}
<|endoftext|>


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

use std::collections::HashMap;
use std::rc::{Rc, Weak};
use syntax::ast::{TokenTree, LitInt, UnsuffixedIntLit};
use syntax::codemap::{Span, mk_sp};
use syntax::ext::base::ExtCtxt;
use syntax::parse::{token, ParseSess, lexer, integer_lit};
use syntax::print::pprust;

use node;

pub struct Parser<'a> {
  pub sess: &'a ParseSess,
  reader: Box<lexer::Reader+'a>,
  token: token::Token,
  span: Span,

  last_token: Option<Box<token::Token>>,
  last_span: Span,
}

impl<'a> Parser<'a> {
  pub fn new(cx: &'a ExtCtxt, tts: &[TokenTree]) -> Parser<'a> {
    let sess = cx.parse_sess();
    let ttsvec = tts.iter().map(|x| (*x).clone()).collect();
    let mut reader = Box::new(lexer::new_tt_reader(
        &sess.span_diagnostic, None, None, ttsvec)) as Box<lexer::Reader>;

    let tok0 = reader.next_token();
    let token = tok0.tok;
    let span = tok0.sp;

    Parser {
      sess: sess,
      reader: reader,

      token: token,
      span: span,

      last_token: None,
      last_span: span,
    }
  }

  /// Parse the platform tree from passed in tokens.
  pub fn parse_platformtree(&mut self) -> Option<Rc<node::PlatformTree>> {
    let mut nodes: HashMap<String, Rc<node::Node>> = HashMap::new();
    let mut failed = false;
    loop {
      if self.token == token::Eof {
        break
      }

      let node = match self.parse_node(None) {
        Some(node) => node,
        None => {
          failed = true;
          self.bump();
          continue
        }
      };

      let path = node.path.clone();
      if nodes.contains_key(&path) {
        failed = true;
        self.sess.span_diagnostic.span_err(node.path_span,
            format!("duplicate node definition `{}`", path).as_str());
        let old_node: &Rc<node::Node> = &nodes[&path];
        self.sess.span_diagnostic.span_err(old_node.path_span,
            "previously defined here");
      } else {
        nodes.insert(node.path.clone(), node);
      }
    }

    if failed {
      None
    } else {
      let mut map = HashMap::new();
      if self.collect_node_names(&mut map, &nodes) {
        Some(Rc::new(node::PlatformTree::new(nodes, map)))
      } else {
        None
      }
    }
  }

  fn collect_node_names(&self, map: &mut HashMap<String, Weak<node::Node>>,
      nodes: &HashMap<String, Rc<node::Node>>) -> bool {
    for (_, n) in nodes.iter() {
      let mut strongmap = HashMap::new();
      n.with_subnodes_map(|sub|{
        for (k, weak_node) in sub.iter() {
          let node = weak_node.upgrade().unwrap();
          strongmap.insert(k.clone(), node);
        }
      });

      if !self.collect_node_names(map, &strongmap) {
        return false;
      }

      match n.name {
        Some(ref name) => {
          if map.contains_key(name) {
            self.sess.span_diagnostic.span_err(n.name_span, format!(
                "duplicate `{}` definition", name).as_str());

            self.sess.span_diagnostic.span_warn(
                (*map)[name].upgrade().unwrap().name_span,
                "previously defined here");
            return false;
          } else {
            map.insert(name.clone(), n.downgrade());
          }
        },
        None => (),
      }
    }
    true
  }

  fn parse_node(&mut self, parent: Option<Weak<node::Node>>)
      -> Option<Rc<node::Node>> {
    use syntax::parse::token::Token;
    let name_span: Option<Span>;
    let node_name: Option<String>;

    //  we're here
    // /
    // v
    // NAME @ PATH { ... }
    //      ^-- peeking here
    if self.reader.peek().tok == token::At {
      name_span = Some(self.span);
      node_name = match self.expect_ident() {
        Some(name) => Some(name),
        None => return None,
      };
      if !self.expect(&token::At) {
        return None;
      }
    } else {
      node_name = None;
      name_span = None;
    }

    let node_span: Span;
    let node_path_span: Span;
    let attributes: HashMap<String, Rc<node::Attribute>>;
    let subnodes: node::Subnodes;

    // NAME is resolved, if it was there anyway.
    //    we're here
    //          |
    //          v
    //   NAME @ PATH { ... }
    node_path_span = self.span;
    if node_name == None {
      node_span = self.span;
    } else {
      node_span = mk_sp(name_span.unwrap().lo, self.span.hi);
    }

    let node_path = match self.token {
      Token::Ident(_, _) => {
        pprust::token_to_string(&self.bump())
      },
      Token::Literal(token::Lit::Integer(intname), _) => {
        self.bump();

        let lit = integer_lit(intname.as_str(), None, &self.sess.span_diagnostic, self.span);
        match lit {
          LitInt(i, _) => {
            format!("{}", i)
          },
          _ => {
            self.error(format!("expected unsuffixed integer but found `{}`",
                pprust::token_to_string(&self.token)));
            return None
          }
        }
      }
      ref other => {
        self.error(format!("expected node path but found `{}`",
            pprust::token_to_string(other)));
        return None;
      }
    };

    let node = Rc::new(node::Node::new(
        node_name, node_span, node_path, node_path_span, parent));
    let weak_node = node.downgrade();

    //    we're here
    //             |
    //             v
    // NAME @ PATH { ... }
    // it's either a body, or a semicolon (no body)
    match self.bump() {
      token::OpenDelim(token::Brace) => {
        let (a, s) = match self.parse_node_body(weak_node) {
          Some((attrs, subnodes)) => (attrs, subnodes),
          // TODO(farcaller): eat everything up to '}' and continue if failed
          // we can still parse further nodes.
          None => return None,
        };
        attributes = a;
        subnodes = s;

        if !self.expect(&token::CloseDelim(token::Brace)) {
          return None;
        }
      },
      token::Semi => {
        attributes = HashMap::new();
        subnodes = node::Subnodes::new();
      },
      ref other => {
        self.error(format!("expected `{{` or `;` but found `{}`",
            pprust::token_to_string(other)));
        return None;
      }
    }

    node.attributes.borrow_mut().clone_from(&attributes);
    node.set_subnodes(subnodes);
    Some(node)
  }

  fn parse_node_body(&mut self, weak_node: Weak<node::Node>)
      -> Option<(HashMap<String, Rc<node::Attribute>>, node::Subnodes)> {
    let mut attrs = HashMap::new();
    let mut subnodes = node::Subnodes::new();

    loop {
      // break early if at brace
      if self.token == token::CloseDelim(token::Brace) {
        break;
      }

      // we're here
      // |
      // v
      // ATTR = VAL ;
      // NAME @ PATH
      // PATH { ... }
      // PATH ;
      //      ^-- peeking here
      if self.reader.peek().tok == token::Eq {
        // we're here
        // |
        // v
        // ATTR = VAL ;
        let name_span = self.span;
        let some_name = match self.expect_ident() {
          Some(name) => name,
          None => return None,
        };

        if attrs.contains_key(&some_name) {
          self.error(format!("key `{}` is already defined", some_name));
          return None;
        }

        self.bump(); // bump token::Eq

        // we're here
        //        |
        //        v
        // ATTR = VAL ;
        let attr_value_span = self.span;
        let attr_value = match self.parse_attribute_value() {
          Some(value) => value,
          None => return None,
        };

        //   we're here
        //            |
        //            v
        // ATTR = VAL ;
        if !self.expect(&token::Semi) {
          return None;
        }

        attrs.insert(some_name, Rc::new(node::Attribute::new(
            attr_value, name_span, attr_value_span)));
      } else {
        // this should be a subnode
        let oldsp = self.span;
        let oldtok = self.token.clone();
        let node = match self.parse_node(Some(weak_node.clone())) {
          Some(node) => node,
          None => {
            self.span = oldsp;
            self.error(format!("expected `=` or node but found `{}`",
                pprust::token_to_string(&oldtok)));
            return None;
          },
        };

        let path = node.path.clone();
        if subnodes.as_map().contains_key(&path) {
          self.span = node.path_span;
          self.error(format!("duplicate node definition `{}`",
              path));
          let old_node: Rc<node::Node> = subnodes.as_map()[&path].upgrade().unwrap();
          self.span = old_node.path_span.clone();
          self.error("previously defined here".to_string());
          return None;
        } else {
          subnodes.push(node);
        }
      }
    }

    Some((attrs, subnodes))
  }

  /// Get an Option<AttributeValue> depending on the Token type and value of
  /// self.token
  fn parse_attribute_value(&mut self) -> Option<node::AttributeValue> {
    use syntax::parse::token::{Token, Lit};
    match self.token {
      Token::Literal(Lit::Str_(string_val), _) => {
        self.bump();
        Some(node::StrValue(string_val.as_str().to_string()))
      },
      Token::Literal(Lit::Integer(intname), suffix) => {
        if suffix.is_none() {
          let lit = integer_lit(intname.as_str(), None, &self.sess.span_diagnostic, self.span);
          match lit {
            LitInt(i, UnsuffixedIntLit(_)) => {
              self.bump();
              Some(node::IntValue(i as usize))
            },
            _ => {
              self.error(format!("expected unsuffixed positive integer but found `{}`",
                  pprust::token_to_string(&self.token)));
              None
            }
          }
        } else {
          self.error(format!("expected unsuffixed integer but found `{}`",
              pprust::token_to_string(&self.token)));
          None
        }
      },
      Token::BinOp(token::And) => {
        self.bump();
        let name = match self.expect_ident() {
          Some(name) => name,
          None => return None,
        };
        Some(node::RefValue(name))
      },
      token::Ident(ident, _) => {
        self.bump();
        match &*token::get_ident(ident) {
          "true"  => Some(node::BoolValue(true)),
          "false" => Some(node::BoolValue(false)),
          other   => {
            self.error(format!(
              "expected attribute value but found identifier `{}`",
              other));
            None
          }
        }
      },
      ref other => {
        self.error(format!("expected attribute value but found `{}`",
            pprust::token_to_string(other)));
        None
      }
    }
  }

  fn error(&self, m: String) {
    self.sess.span_diagnostic.span_err(self.span, m.as_str());
  }

  /// Bumps a token.
  ///
  /// This moves current token to last token, pops a new token from backlog or
  /// reader and returns the last token (i.e. the 'current' token at the time of
  /// method call).
  fn bump(&mut self) -> token::Token {
    let tok = self.token.clone();
    self.last_span = self.span;
    self.last_token = Some(Box::new(tok.clone()));

    let next = self.reader.next_token();

    self.span = next.sp;
    self.token = next.tok;

    tok
  }

  /// Expects that the current token is t. Bumps on success.
  fn expect(&mut self, t: &token::Token) -> bool {
    if self.token == *t {
      self.bump();
      true
    } else {
      let token_str = pprust::token_to_string(t);
      let this_token_str = pprust::token_to_string(&self.token);
      self.error(format!("expected `{}` but found `{}`", token_str,
          this_token_str));
      false
    }
  }

  /// Expects that the current token is IDENT, returns its string value. Bumps
  /// on success.
  fn expect_ident(&mut self) -> Option<String> {
    let tok_str = pprust::token_to_string(&self.token);
    match self.token {
      token::Ident(_, _) => {
        self.bump();
        Some(tok_str)
      },
      _ => {
        self.error(format!("expected identifier but found `{}`", tok_str));
        None
      },
    }
  }
}
<commit_msg>Updated parser.rs<commit_after>// Zinc, the bare metal stack for rust.
// Copyright 2014 Vladimir "farcaller" Pouzanov <farcaller@gmail.com>
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

use std::ops::Deref;
use std::collections::HashMap;
use std::rc::{Rc, Weak};
use syntax::ast::{TokenTree, LitInt, UnsuffixedIntLit};
use syntax::codemap::{Span, mk_sp};
use syntax::ext::base::ExtCtxt;
use syntax::parse::{token, ParseSess, lexer, integer_lit};
use syntax::print::pprust;

use node;

pub struct Parser<'a> {
  pub sess: &'a ParseSess,
  reader: Box<lexer::Reader+'a>,
  token: token::Token,
  span: Span,

  last_token: Option<Box<token::Token>>,
  last_span: Span,
}

impl<'a> Parser<'a> {
  pub fn new(cx: &'a ExtCtxt, tts: &[TokenTree]) -> Parser<'a> {
    let sess = cx.parse_sess();
    let ttsvec = tts.iter().map(|x| (*x).clone()).collect();
    let mut reader = Box::new(lexer::new_tt_reader(
        &sess.span_diagnostic, None, None, ttsvec)) as Box<lexer::Reader>;

    let tok0 = reader.next_token();
    let token = tok0.tok;
    let span = tok0.sp;

    Parser {
      sess: sess,
      reader: reader,

      token: token,
      span: span,

      last_token: None,
      last_span: span,
    }
  }

  /// Parse the platform tree from passed in tokens.
  pub fn parse_platformtree(&mut self) -> Option<Rc<node::PlatformTree>> {
    let mut nodes: HashMap<String, Rc<node::Node>> = HashMap::new();
    let mut failed = false;
    loop {
      if self.token == token::Eof {
        break
      }

      let node = match self.parse_node(None) {
        Some(node) => node,
        None => {
          failed = true;
          self.bump();
          continue
        }
      };

      let path = node.path.clone();
      if nodes.contains_key(&path) {
        failed = true;
        self.sess.span_diagnostic.span_err(node.path_span,
            format!("duplicate node definition `{}`", path).as_str());
        let old_node: &Rc<node::Node> = &nodes[&path];
        self.sess.span_diagnostic.span_err(old_node.path_span,
            "previously defined here");
      } else {
        nodes.insert(node.path.clone(), node);
      }
    }

    if failed {
      None
    } else {
      let mut map = HashMap::new();
      if self.collect_node_names(&mut map, &nodes) {
        Some(Rc::new(node::PlatformTree::new(nodes, map)))
      } else {
        None
      }
    }
  }

  fn collect_node_names(&self, map: &mut HashMap<String, Weak<node::Node>>,
      nodes: &HashMap<String, Rc<node::Node>>) -> bool {
    for (_, n) in nodes.iter() {
      let mut strongmap = HashMap::new();
      n.with_subnodes_map(|sub|{
        for (k, weak_node) in sub.iter() {
          let node = weak_node.upgrade().unwrap();
          strongmap.insert(k.clone(), node);
        }
      });

      if !self.collect_node_names(map, &strongmap) {
        return false;
      }

      match n.name {
        Some(ref name) => {
          if map.contains_key(name) {
            self.sess.span_diagnostic.span_err(n.name_span, format!(
                "duplicate `{}` definition", name).as_str());

            self.sess.span_diagnostic.span_warn(
                (*map)[name].upgrade().unwrap().name_span,
                "previously defined here");
            return false;
          } else {
            map.insert(name.clone(), n.downgrade());
          }
        },
        None => (),
      }
    }
    true
  }

  fn parse_node(&mut self, parent: Option<Weak<node::Node>>)
      -> Option<Rc<node::Node>> {
    use syntax::parse::token::Token;
    let name_span: Option<Span>;
    let node_name: Option<String>;

    //  we're here
    // /
    // v
    // NAME @ PATH { ... }
    //      ^-- peeking here
    if self.reader.peek().tok == token::At {
      name_span = Some(self.span);
      node_name = match self.expect_ident() {
        Some(name) => Some(name),
        None => return None,
      };
      if !self.expect(&token::At) {
        return None;
      }
    } else {
      node_name = None;
      name_span = None;
    }

    let node_span: Span;
    let node_path_span: Span;
    let attributes: HashMap<String, Rc<node::Attribute>>;
    let subnodes: node::Subnodes;

    // NAME is resolved, if it was there anyway.
    //    we're here
    //          |
    //          v
    //   NAME @ PATH { ... }
    node_path_span = self.span;
    if node_name == None {
      node_span = self.span;
    } else {
      node_span = mk_sp(name_span.unwrap().lo, self.span.hi);
    }

    let node_path = match self.token {
      Token::Ident(_, _) => {
        pprust::token_to_string(&self.bump())
      },
      Token::Literal(token::Lit::Integer(intname), _) => {
        self.bump();

        let lit = integer_lit(intname.as_str().deref(), None, &self.sess.span_diagnostic, self.span);
        match lit {
          LitInt(i, _) => {
            format!("{}", i)
          },
          _ => {
            self.error(format!("expected unsuffixed integer but found `{}`",
                pprust::token_to_string(&self.token)));
            return None
          }
        }
      }
      ref other => {
        self.error(format!("expected node path but found `{}`",
            pprust::token_to_string(other)));
        return None;
      }
    };

    let node = Rc::new(node::Node::new(
        node_name, node_span, node_path, node_path_span, parent));
    let weak_node = node.downgrade();

    //    we're here
    //             |
    //             v
    // NAME @ PATH { ... }
    // it's either a body, or a semicolon (no body)
    match self.bump() {
      token::OpenDelim(token::Brace) => {
        let (a, s) = match self.parse_node_body(weak_node) {
          Some((attrs, subnodes)) => (attrs, subnodes),
          // TODO(farcaller): eat everything up to '}' and continue if failed
          // we can still parse further nodes.
          None => return None,
        };
        attributes = a;
        subnodes = s;

        if !self.expect(&token::CloseDelim(token::Brace)) {
          return None;
        }
      },
      token::Semi => {
        attributes = HashMap::new();
        subnodes = node::Subnodes::new();
      },
      ref other => {
        self.error(format!("expected `{{` or `;` but found `{}`",
            pprust::token_to_string(other)));
        return None;
      }
    }

    node.attributes.borrow_mut().clone_from(&attributes);
    node.set_subnodes(subnodes);
    Some(node)
  }

  fn parse_node_body(&mut self, weak_node: Weak<node::Node>)
      -> Option<(HashMap<String, Rc<node::Attribute>>, node::Subnodes)> {
    let mut attrs = HashMap::new();
    let mut subnodes = node::Subnodes::new();

    loop {
      // break early if at brace
      if self.token == token::CloseDelim(token::Brace) {
        break;
      }

      // we're here
      // |
      // v
      // ATTR = VAL ;
      // NAME @ PATH
      // PATH { ... }
      // PATH ;
      //      ^-- peeking here
      if self.reader.peek().tok == token::Eq {
        // we're here
        // |
        // v
        // ATTR = VAL ;
        let name_span = self.span;
        let some_name = match self.expect_ident() {
          Some(name) => name,
          None => return None,
        };

        if attrs.contains_key(&some_name) {
          self.error(format!("key `{}` is already defined", some_name));
          return None;
        }

        self.bump(); // bump token::Eq

        // we're here
        //        |
        //        v
        // ATTR = VAL ;
        let attr_value_span = self.span;
        let attr_value = match self.parse_attribute_value() {
          Some(value) => value,
          None => return None,
        };

        //   we're here
        //            |
        //            v
        // ATTR = VAL ;
        if !self.expect(&token::Semi) {
          return None;
        }

        attrs.insert(some_name, Rc::new(node::Attribute::new(
            attr_value, name_span, attr_value_span)));
      } else {
        // this should be a subnode
        let oldsp = self.span;
        let oldtok = self.token.clone();
        let node = match self.parse_node(Some(weak_node.clone())) {
          Some(node) => node,
          None => {
            self.span = oldsp;
            self.error(format!("expected `=` or node but found `{}`",
                pprust::token_to_string(&oldtok)));
            return None;
          },
        };

        let path = node.path.clone();
        if subnodes.as_map().contains_key(&path) {
          self.span = node.path_span;
          self.error(format!("duplicate node definition `{}`",
              path));
          let old_node: Rc<node::Node> = subnodes.as_map()[&path].upgrade().unwrap();
          self.span = old_node.path_span.clone();
          self.error("previously defined here".to_string());
          return None;
        } else {
          subnodes.push(node);
        }
      }
    }

    Some((attrs, subnodes))
  }

  /// Get an Option<AttributeValue> depending on the Token type and value of
  /// self.token
  fn parse_attribute_value(&mut self) -> Option<node::AttributeValue> {
    use syntax::parse::token::{Token, Lit};
    match self.token {
      Token::Literal(Lit::Str_(string_val), _) => {
        self.bump();
        Some(node::StrValue(string_val.as_str().to_string()))
      },
      Token::Literal(Lit::Integer(intname), suffix) => {
        if suffix.is_none() {
          let lit = integer_lit(intname.as_str().deref(), None, &self.sess.span_diagnostic, self.span);
          match lit {
            LitInt(i, UnsuffixedIntLit(_)) => {
              self.bump();
              Some(node::IntValue(i as usize))
            },
            _ => {
              self.error(format!("expected unsuffixed positive integer but found `{}`",
                  pprust::token_to_string(&self.token)));
              None
            }
          }
        } else {
          self.error(format!("expected unsuffixed integer but found `{}`",
              pprust::token_to_string(&self.token)));
          None
        }
      },
      Token::BinOp(token::And) => {
        self.bump();
        let name = match self.expect_ident() {
          Some(name) => name,
          None => return None,
        };
        Some(node::RefValue(name))
      },
      token::Ident(ident, _) => {
        self.bump();
        match &*ident.name.as_str() {
          "true"  => Some(node::BoolValue(true)),
          "false" => Some(node::BoolValue(false)),
          other   => {
            self.error(format!(
              "expected attribute value but found identifier `{}`",
              other));
            None
          }
        }
      },
      ref other => {
        self.error(format!("expected attribute value but found `{}`",
            pprust::token_to_string(other)));
        None
      }
    }
  }

  fn error(&self, m: String) {
    self.sess.span_diagnostic.span_err(self.span, m.as_str());
  }

  /// Bumps a token.
  ///
  /// This moves current token to last token, pops a new token from backlog or
  /// reader and returns the last token (i.e. the 'current' token at the time of
  /// method call).
  fn bump(&mut self) -> token::Token {
    let tok = self.token.clone();
    self.last_span = self.span;
    self.last_token = Some(Box::new(tok.clone()));

    let next = self.reader.next_token();

    self.span = next.sp;
    self.token = next.tok;

    tok
  }

  /// Expects that the current token is t. Bumps on success.
  fn expect(&mut self, t: &token::Token) -> bool {
    if self.token == *t {
      self.bump();
      true
    } else {
      let token_str = pprust::token_to_string(t);
      let this_token_str = pprust::token_to_string(&self.token);
      self.error(format!("expected `{}` but found `{}`", token_str,
          this_token_str));
      false
    }
  }

  /// Expects that the current token is IDENT, returns its string value. Bumps
  /// on success.
  fn expect_ident(&mut self) -> Option<String> {
    let tok_str = pprust::token_to_string(&self.token);
    match self.token {
      token::Ident(_, _) => {
        self.bump();
        Some(tok_str)
      },
      _ => {
        self.error(format!("expected identifier but found `{}`", tok_str));
        None
      },
    }
  }
}
<|endoftext|>


<commit_before>//! Types and traits to handle form processing.
//!
//! In general, you will deal with forms in Rocket via the `form` parameter in
//! routes:
//!
//! ```rust,ignore
//! #[post("/", form = <my_form>)]
//! fn form_submit(my_form: MyType) -> ...
//! ```
//!
//! Form parameter types must implement the [FromForm](trait.FromForm.html)
//! trait, which is automaForwarp derivable. Automatically deriving `FromForm`
//! for a structure requires that all of its fields implement
//! [FromFormValue](trait.FormFormValue.html). See the
//! [codegen](/rocket_codegen/) documentation or the [forms guide](/guide/forms)
//! for more information on forms and on deriving `FromForm`.

mod form_items;
mod from_form;
mod from_form_value;

pub use self::form_items::FormItems;
pub use self::from_form::FromForm;
pub use self::from_form_value::FromFormValue;

use std::marker::PhantomData;
use std::fmt::{self, Debug};
use std::io::Read;

use http::StatusCode;
use request::{Request, FromData, Data, DataOutcome};

// TODO: This works and is safe, but the lifetime appears twice.
/// A `FromData` type for parsing `FromForm` types.
///
/// This type implements the `FromData` trait. It provides a generic means to
/// parse arbitrary structure from incoming form data.
///
/// # Usage
///
/// This type can be used with any type that implements the `FromForm` trait.
/// The trait can be automatically derived; see the
/// [FromForm](trait.FromForm.html) documentation for more information about
/// implementing the trait.
///
/// Because `Form` implement `FromData`, it can be used directly as a target of
/// the `data = "<param>"` route parameter. For instance, if some structure of
/// type `T` implements the `FromForm` trait, an incoming form can be
/// automatically parsed into the `T` structure with the following route and
/// handler:
///
/// ```rust,ignore
/// #[post("/form_submit", data = "<param>")]
/// fn submit(form: Form<T>) ... { ... }
/// ```
///
/// To preserve memory safety, if the underlying structure type contains
/// references into form data, the type can only be borrowed via the
/// [get](#method.get) or [get_mut](#method.get_mut) methods. Otherwise, the
/// parsed structure can be retrieved with the [into_inner](#method.into_inner)
/// method.
///
/// ## With References
///
/// The simplest data structure with a reference into form data looks like this:
///
/// ```rust
/// # #![feature(plugin, custom_derive)]
/// # #![plugin(rocket_codegen)]
/// # extern crate rocket;
/// #[derive(FromForm)]
/// struct UserInput<'f> {
///     value: &'f str
/// }
/// ```
///
/// This corresponds to a form with a single field named `value` that should be
/// a string. A handler for this type can be written as:
///
/// ```rust
/// # #![feature(plugin, custom_derive)]
/// # #![plugin(rocket_codegen)]
/// # extern crate rocket;
/// # use rocket::request::Form;
/// # #[derive(FromForm)]
/// # struct UserInput<'f> {
/// #     value: &'f str
/// # }
/// #[post("/submit", data = "<user_input>")]
/// fn submit_task<'r>(user_input: Form<'r, UserInput<'r>>) -> String {
///     format!("Your value: {}", user_input.get().value)
/// }
/// # fn main() {  }
/// ```
///
/// Note that the ``r` lifetime is used _twice_ in the handler's signature: this
/// is necessary to tie the lifetime of the structure to the lifetime of the
/// request data.
///
/// ## Without References
///
/// The owned analog of the `UserInput` type above is:
///
/// ```rust
/// # #![feature(plugin, custom_derive)]
/// # #![plugin(rocket_codegen)]
/// # extern crate rocket;
/// #[derive(FromForm)]
/// struct OwnedUserInput {
///     value: String
/// }
/// ```
///
/// The handler is written similarly:
///
/// ```rust
/// # #![feature(plugin, custom_derive)]
/// # #![plugin(rocket_codegen)]
/// # extern crate rocket;
/// # use rocket::request::Form;
/// # #[derive(FromForm)]
/// # struct OwnedUserInput {
/// #     value: String
/// # }
/// #[post("/submit", data = "<user_input>")]
/// fn submit_task(user_input: Form<OwnedUserInput>) -> String {
///     let input: OwnedUserInput = user_input.into_inner();
///     format!("Your value: {}", input.value)
/// }
/// # fn main() {  }
/// ```
///
/// Note that no lifetime annotations are required: Rust is able to infer the
/// lifetime as ``static`. Because the lifetime is ``static`, the `into_inner`
/// method can be used to directly retrieve the parsed value.
///
/// ## Performance and Correctness Considerations
///
/// Whether you should use a `str` or `String` in your `FromForm` type depends
/// on your use case. The primary question to answer is: _Can the input contain
/// characters that must be URL encoded?_ Note that this includes commmon
/// characters such as spaces. If so, then you must use `String`, whose
/// `FromFormValue` implementation deserializes the URL encoded string for you.
/// Because the `str` references will refer directly to the underlying form
/// data, they will be raw and URL encoded.
///
/// If your string values will not contain URL encoded characters, using `str`
/// will result in fewer allocation and is thus spreferred.
pub struct Form<'f, T: FromForm<'f> + 'f> {
    object: T,
    form_string: String,
    _phantom: PhantomData<&'f T>,
}

impl<'f, T: FromForm<'f> + 'f> Form<'f, T> {
    /// Immutably borrow the parsed type.
    pub fn get(&'f self) -> &'f T {
        &self.object
    }

    /// Mutably borrow the parsed type.
    pub fn get_mut(&'f mut self) -> &'f mut T {
        &mut self.object
    }

    /// Returns the raw form string that was used to parse the encapsulated
    /// object.
    pub fn raw_form_string(&self) -> &str {
        &self.form_string
    }

    // Alright, so here's what's going on here. We'd like to have form
    // objects have pointers directly to the form string. This means that
    // the form string has to live at least as long as the form object. So,
    // to enforce this, we store the form_string along with the form object.
    //
    // So far so good. Now, this means that the form_string can never be
    // deallocated while the object is alive. That implies that the
    // `form_string` value should never be moved away. We can enforce that
    // easily by 1) not making `form_string` public, and 2) not exposing any
    // `&mut self` methods that could modify `form_string`.
    //
    // Okay, we do all of these things. Now, we still need to give a
    // lifetime to `FromForm`. Which one do we choose? The danger is that
    // references inside `object` may be copied out, and we have to ensure
    // that they don't outlive this structure. So we would really like
    // something like `self` and then to transmute to that. But this doesn't
    // exist. So we do the next best: we use the first lifetime supplied by the
    // caller via `get()` and contrain everything to that lifetime. This is, in
    // reality a little coarser than necessary, but the user can simply move the
    // call to right after the creation of a Form object to get the same effect.
    fn new(form_string: String) -> Result<Self, (String, T::Error)> {
        let long_lived_string: &'f str = unsafe {
            ::std::mem::transmute(form_string.as_str())
        };

        match T::from_form_string(long_lived_string) {
            Ok(obj) => Ok(Form {
                form_string: form_string,
                object: obj,
                _phantom: PhantomData
            }),
            Err(e) => Err((form_string, e))
        }
    }
}

impl<'f, T: FromForm<'f> + 'static> Form<'f, T> {
    /// Consume this object and move out the parsed object.
    pub fn into_inner(self) -> T {
        self.object
    }
}

impl<'f, T: FromForm<'f> + Debug + 'f> Debug for Form<'f, T> {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        write!(f, "{:?} from form string: {:?}", self.object, self.form_string)
    }
}

/// Parses a `Form` from incoming form data.
///
/// If the content type of the request data is not
/// `application/x-www-form-urlencoded`, `Forward`s the request. If the form
/// data cannot be parsed into a `T` or reading the incoming stream failed,
/// returns a `Failure` with the raw form string (if avaialble).
///
/// All relevant warnings and errors are written to the console in Rocket
/// logging format.
impl<'f, T: FromForm<'f>> FromData for Form<'f, T> where T::Error: Debug {
    type Error = Option<String>;

    fn from_data(request: &Request, data: Data) -> DataOutcome<Self, Self::Error> {
        if !request.content_type().is_form() {
            warn_!("Form data does not have form content type.");
            return DataOutcome::forward(data);
        }

        let mut form_string = String::with_capacity(4096);
        let mut stream = data.open().take(32768);
        if let Err(e) = stream.read_to_string(&mut form_string) {
            error_!("IO Error: {:?}", e);
            DataOutcome::failure(StatusCode::InternalServerError, None)
        } else {
            match Form::new(form_string) {
                Ok(form) => DataOutcome::success(form),
                Err((form_string, e)) => {
                    error_!("Failed to parse value from form: {:?}", e);
                    DataOutcome::failure(StatusCode::BadRequest, Some(form_string))
                }
            }
        }
    }
}

#[cfg(test)]
mod test {
    use super::Form;
    use ::request::FromForm;

    struct Simple<'s> {
        value: &'s str
    }

    struct Other {
        value: String
    }

    impl<'s> FromForm<'s> for Simple<'s> {
        type Error = &'s str;

        fn from_form_string(fs: &'s str) -> Result<Simple<'s>, &'s str> {
            Ok(Simple { value: fs })
        }
    }

    impl<'s> FromForm<'s> for Other {
        type Error = &'s str;

        fn from_form_string(fs: &'s str) -> Result<Other, &'s str> {
            Ok(Other { value: fs.to_string() })
        }
    }

    #[test]
    fn test_lifetime() {
        let form_string = "hello=world".to_string();
        let form: Form<Simple> = Form::new(form_string).unwrap();

        let string: &str = form.get().value;
        assert_eq!(string, "hello=world");
    }

    #[test]
    fn test_lifetime_2() {
        let form_string = "hello=world".to_string();
        let mut _y = "hi";
        let _form: Form<Simple> = Form::new(form_string).unwrap();
        // _y = form.get().value;

        // fn should_not_compile<'f>(form: Form<'f, &'f str>) -> &'f str {
        //     form.get()
        // }

        // fn should_not_compile_2<'f>(form: Form<'f, Simple<'f>>) -> &'f str {
        //     form.into_inner().value
        // }

        // assert_eq!(should_not_compile(form), "hello=world");
    }

    #[test]
    fn test_lifetime_3() {
        let form_string = "hello=world".to_string();
        let form: Form<Other> = Form::new(form_string).unwrap();

        // Not bad.
        fn should_compile(form: Form<Other>) -> String {
            form.into_inner().value
        }

        assert_eq!(should_compile(form), "hello=world".to_string());
    }

    #[test]
    fn test_lifetime_4() {
        let form_string = "hello=world".to_string();
        let form: Form<Simple> = Form::new(form_string).unwrap();

        fn should_compile<'f>(_form: Form<'f, Simple<'f>>) {  }

        should_compile(form)
        // assert_eq!(should_not_compile(form), "hello=world");
    }
}

<commit_msg>Properly escape ticks for markdown in Form docs.<commit_after>//! Types and traits to handle form processing.
//!
//! In general, you will deal with forms in Rocket via the `form` parameter in
//! routes:
//!
//! ```rust,ignore
//! #[post("/", form = <my_form>)]
//! fn form_submit(my_form: MyType) -> ...
//! ```
//!
//! Form parameter types must implement the [FromForm](trait.FromForm.html)
//! trait, which is automaForwarp derivable. Automatically deriving `FromForm`
//! for a structure requires that all of its fields implement
//! [FromFormValue](trait.FormFormValue.html). See the
//! [codegen](/rocket_codegen/) documentation or the [forms guide](/guide/forms)
//! for more information on forms and on deriving `FromForm`.

mod form_items;
mod from_form;
mod from_form_value;

pub use self::form_items::FormItems;
pub use self::from_form::FromForm;
pub use self::from_form_value::FromFormValue;

use std::marker::PhantomData;
use std::fmt::{self, Debug};
use std::io::Read;

use http::StatusCode;
use request::{Request, FromData, Data, DataOutcome};

// TODO: This works and is safe, but the lifetime appears twice.
/// A `FromData` type for parsing `FromForm` types.
///
/// This type implements the `FromData` trait. It provides a generic means to
/// parse arbitrary structure from incoming form data.
///
/// # Usage
///
/// This type can be used with any type that implements the `FromForm` trait.
/// The trait can be automatically derived; see the
/// [FromForm](trait.FromForm.html) documentation for more information about
/// implementing the trait.
///
/// Because `Form` implement `FromData`, it can be used directly as a target of
/// the `data = "<param>"` route parameter. For instance, if some structure of
/// type `T` implements the `FromForm` trait, an incoming form can be
/// automatically parsed into the `T` structure with the following route and
/// handler:
///
/// ```rust,ignore
/// #[post("/form_submit", data = "<param>")]
/// fn submit(form: Form<T>) ... { ... }
/// ```
///
/// To preserve memory safety, if the underlying structure type contains
/// references into form data, the type can only be borrowed via the
/// [get](#method.get) or [get_mut](#method.get_mut) methods. Otherwise, the
/// parsed structure can be retrieved with the [into_inner](#method.into_inner)
/// method.
///
/// ## With References
///
/// The simplest data structure with a reference into form data looks like this:
///
/// ```rust
/// # #![feature(plugin, custom_derive)]
/// # #![plugin(rocket_codegen)]
/// # extern crate rocket;
/// #[derive(FromForm)]
/// struct UserInput<'f> {
///     value: &'f str
/// }
/// ```
///
/// This corresponds to a form with a single field named `value` that should be
/// a string. A handler for this type can be written as:
///
/// ```rust
/// # #![feature(plugin, custom_derive)]
/// # #![plugin(rocket_codegen)]
/// # extern crate rocket;
/// # use rocket::request::Form;
/// # #[derive(FromForm)]
/// # struct UserInput<'f> {
/// #     value: &'f str
/// # }
/// #[post("/submit", data = "<user_input>")]
/// fn submit_task<'r>(user_input: Form<'r, UserInput<'r>>) -> String {
///     format!("Your value: {}", user_input.get().value)
/// }
/// # fn main() {  }
/// ```
///
/// Note that the `` `r`` lifetime is used _twice_ in the handler's signature:
/// this is necessary to tie the lifetime of the structure to the lifetime of
/// the request data.
///
/// ## Without References
///
/// The owned analog of the `UserInput` type above is:
///
/// ```rust
/// # #![feature(plugin, custom_derive)]
/// # #![plugin(rocket_codegen)]
/// # extern crate rocket;
/// #[derive(FromForm)]
/// struct OwnedUserInput {
///     value: String
/// }
/// ```
///
/// The handler is written similarly:
///
/// ```rust
/// # #![feature(plugin, custom_derive)]
/// # #![plugin(rocket_codegen)]
/// # extern crate rocket;
/// # use rocket::request::Form;
/// # #[derive(FromForm)]
/// # struct OwnedUserInput {
/// #     value: String
/// # }
/// #[post("/submit", data = "<user_input>")]
/// fn submit_task(user_input: Form<OwnedUserInput>) -> String {
///     let input: OwnedUserInput = user_input.into_inner();
///     format!("Your value: {}", input.value)
/// }
/// # fn main() {  }
/// ```
///
/// Note that no lifetime annotations are required: Rust is able to infer the
/// lifetime as `` `static``. Because the lifetime is `` `static``, the
/// `into_inner` method can be used to directly retrieve the parsed value.
///
/// ## Performance and Correctness Considerations
///
/// Whether you should use a `str` or `String` in your `FromForm` type depends
/// on your use case. The primary question to answer is: _Can the input contain
/// characters that must be URL encoded?_ Note that this includes commmon
/// characters such as spaces. If so, then you must use `String`, whose
/// `FromFormValue` implementation deserializes the URL encoded string for you.
/// Because the `str` references will refer directly to the underlying form
/// data, they will be raw and URL encoded.
///
/// If your string values will not contain URL encoded characters, using `str`
/// will result in fewer allocation and is thus spreferred.
pub struct Form<'f, T: FromForm<'f> + 'f> {
    object: T,
    form_string: String,
    _phantom: PhantomData<&'f T>,
}

impl<'f, T: FromForm<'f> + 'f> Form<'f, T> {
    /// Immutably borrow the parsed type.
    pub fn get(&'f self) -> &'f T {
        &self.object
    }

    /// Mutably borrow the parsed type.
    pub fn get_mut(&'f mut self) -> &'f mut T {
        &mut self.object
    }

    /// Returns the raw form string that was used to parse the encapsulated
    /// object.
    pub fn raw_form_string(&self) -> &str {
        &self.form_string
    }

    // Alright, so here's what's going on here. We'd like to have form
    // objects have pointers directly to the form string. This means that
    // the form string has to live at least as long as the form object. So,
    // to enforce this, we store the form_string along with the form object.
    //
    // So far so good. Now, this means that the form_string can never be
    // deallocated while the object is alive. That implies that the
    // `form_string` value should never be moved away. We can enforce that
    // easily by 1) not making `form_string` public, and 2) not exposing any
    // `&mut self` methods that could modify `form_string`.
    //
    // Okay, we do all of these things. Now, we still need to give a
    // lifetime to `FromForm`. Which one do we choose? The danger is that
    // references inside `object` may be copied out, and we have to ensure
    // that they don't outlive this structure. So we would really like
    // something like `self` and then to transmute to that. But this doesn't
    // exist. So we do the next best: we use the first lifetime supplied by the
    // caller via `get()` and contrain everything to that lifetime. This is, in
    // reality a little coarser than necessary, but the user can simply move the
    // call to right after the creation of a Form object to get the same effect.
    fn new(form_string: String) -> Result<Self, (String, T::Error)> {
        let long_lived_string: &'f str = unsafe {
            ::std::mem::transmute(form_string.as_str())
        };

        match T::from_form_string(long_lived_string) {
            Ok(obj) => Ok(Form {
                form_string: form_string,
                object: obj,
                _phantom: PhantomData
            }),
            Err(e) => Err((form_string, e))
        }
    }
}

impl<'f, T: FromForm<'f> + 'static> Form<'f, T> {
    /// Consume this object and move out the parsed object.
    pub fn into_inner(self) -> T {
        self.object
    }
}

impl<'f, T: FromForm<'f> + Debug + 'f> Debug for Form<'f, T> {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        write!(f, "{:?} from form string: {:?}", self.object, self.form_string)
    }
}

/// Parses a `Form` from incoming form data.
///
/// If the content type of the request data is not
/// `application/x-www-form-urlencoded`, `Forward`s the request. If the form
/// data cannot be parsed into a `T` or reading the incoming stream failed,
/// returns a `Failure` with the raw form string (if avaialble).
///
/// All relevant warnings and errors are written to the console in Rocket
/// logging format.
impl<'f, T: FromForm<'f>> FromData for Form<'f, T> where T::Error: Debug {
    type Error = Option<String>;

    fn from_data(request: &Request, data: Data) -> DataOutcome<Self, Self::Error> {
        if !request.content_type().is_form() {
            warn_!("Form data does not have form content type.");
            return DataOutcome::forward(data);
        }

        let mut form_string = String::with_capacity(4096);
        let mut stream = data.open().take(32768);
        if let Err(e) = stream.read_to_string(&mut form_string) {
            error_!("IO Error: {:?}", e);
            DataOutcome::failure(StatusCode::InternalServerError, None)
        } else {
            match Form::new(form_string) {
                Ok(form) => DataOutcome::success(form),
                Err((form_string, e)) => {
                    error_!("Failed to parse value from form: {:?}", e);
                    DataOutcome::failure(StatusCode::BadRequest, Some(form_string))
                }
            }
        }
    }
}

#[cfg(test)]
mod test {
    use super::Form;
    use ::request::FromForm;

    struct Simple<'s> {
        value: &'s str
    }

    struct Other {
        value: String
    }

    impl<'s> FromForm<'s> for Simple<'s> {
        type Error = &'s str;

        fn from_form_string(fs: &'s str) -> Result<Simple<'s>, &'s str> {
            Ok(Simple { value: fs })
        }
    }

    impl<'s> FromForm<'s> for Other {
        type Error = &'s str;

        fn from_form_string(fs: &'s str) -> Result<Other, &'s str> {
            Ok(Other { value: fs.to_string() })
        }
    }

    #[test]
    fn test_lifetime() {
        let form_string = "hello=world".to_string();
        let form: Form<Simple> = Form::new(form_string).unwrap();

        let string: &str = form.get().value;
        assert_eq!(string, "hello=world");
    }

    #[test]
    fn test_lifetime_2() {
        let form_string = "hello=world".to_string();
        let mut _y = "hi";
        let _form: Form<Simple> = Form::new(form_string).unwrap();
        // _y = form.get().value;

        // fn should_not_compile<'f>(form: Form<'f, &'f str>) -> &'f str {
        //     form.get()
        // }

        // fn should_not_compile_2<'f>(form: Form<'f, Simple<'f>>) -> &'f str {
        //     form.into_inner().value
        // }

        // assert_eq!(should_not_compile(form), "hello=world");
    }

    #[test]
    fn test_lifetime_3() {
        let form_string = "hello=world".to_string();
        let form: Form<Other> = Form::new(form_string).unwrap();

        // Not bad.
        fn should_compile(form: Form<Other>) -> String {
            form.into_inner().value
        }

        assert_eq!(should_compile(form), "hello=world".to_string());
    }

    #[test]
    fn test_lifetime_4() {
        let form_string = "hello=world".to_string();
        let form: Form<Simple> = Form::new(form_string).unwrap();

        fn should_compile<'f>(_form: Form<'f, Simple<'f>>) {  }

        should_compile(form)
        // assert_eq!(should_not_compile(form), "hello=world");
    }
}

<|endoftext|>


<commit_before>use color::PuyoColor;
use small_int_set::SmallIntSet;
use std;

const MAX_SIZE: usize = 8;

pub struct ColumnPuyoList {
    size: [usize; 6],
    puyo: [[PuyoColor; MAX_SIZE]; 6],
    place_holders: [SmallIntSet; 6],
}

impl ColumnPuyoList {
    pub fn new() -> ColumnPuyoList {
        ColumnPuyoList {
            size: [0; 6],
            puyo: [[PuyoColor::EMPTY; MAX_SIZE]; 6],
            place_holders: [SmallIntSet::new(); 6],
        }
    }

    fn is_place_holder(c: PuyoColor) -> bool {
        c == PuyoColor::IRON
    }

    pub fn size_on(&self, x: usize) -> usize {
        self.size[x - 1]
    }

    pub fn is_empty(&self) -> bool {
        self.size() == 0
    }

    pub fn size(&self) -> usize {
        self.size[0] + self.size[1] + self.size[2] +
        self.size[3] + self.size[4] + self.size[5]
    }

    pub fn top(&self, x: usize) -> Option<PuyoColor> {
        if self.size_on(x) == 0 {
            None
        } else {
            Some(self.puyo[x - 1][self.size_on(x) - 1])
        }
    }

    pub fn get(&self, x: usize, i: usize) -> PuyoColor {
        debug_assert!(i < self.size_on(x));
        self.puyo[x - 1][i]
    }

    pub fn has_place_holder(&self) -> bool {
        for i in 0..6 {
            if !self.place_holders[i].is_empty() {
                return true;
            }
        }

        false
    }

    /// Adds PuyoColor `c` on column `x`.
    /// Returns true if succeeded. Returns false otherwise.
    /// When failed, the `self` won't be changed.
    pub fn add(&mut self, x: usize, c: PuyoColor) -> bool {
        if MAX_SIZE <= self.size[x - 1] {
            return false;
        }
        if ColumnPuyoList::is_place_holder(c) {
            self.place_holders[x - 1].set(self.size[x - 1]);
        }
        self.puyo[x - 1][self.size[x - 1]] = c;
        self.size[x - 1] += 1;
        true
    }

    /// Adds `n` PuyoColor `c` on column `x`.
    /// Returns true if succeeded. Returns false otherwise.
    /// When failed, the `self` won't be changed.
    pub fn add_multi(&mut self, x: usize, c: PuyoColor, n: usize) -> bool {
        if MAX_SIZE < self.size_on(x) + n {
            return false;
        }
        for i in 0..n {
            if ColumnPuyoList::is_place_holder(c) {
                self.place_holders[x - 1].set(self.size[x - 1] + i);
            }
            self.puyo[x - 1][self.size[x - 1] + i] = c;
        }
        self.size[x - 1] += n;
        true
    }

    /// Removes top puyo from column x.
    pub fn remove_top(&mut self, x: usize) {
        if self.size_on(x) == 0 {
            return;
        }
        let c = self.puyo[x - 1][self.size[x - 1] - 1];
        if ColumnPuyoList::is_place_holder(c) {
            self.place_holders[x - 1].unset(self.size[x - 1] - 1);
        }
        self.size[x - 1] -= 1;
    }

    pub fn merge(&mut self, cpl: &ColumnPuyoList) -> bool {
        for i in 0..6 {
            if cpl.size[i] >= self.place_holders[i].size() && MAX_SIZE < self.size[i] + (cpl.size[i] - self.place_holders[i].size()) {
                return false;
            }
        }

        for i in 0..6 {
            if cpl.size[i] < self.place_holders[i].size() {
                let discard = self.place_holders[i].size() - cpl.size[i];
                for _ in 0..discard {
                    self.place_holders[i].remove_smallest();
                }
                for j in 0..cpl.size[i] {
                    let k = self.place_holders[i].smallest();
                    self.place_holders[i].remove_smallest();
                    self.puyo[i][k] = cpl.puyo[i][j];
                }
            } else {
                let mut j = 0;
                while !self.place_holders[i].is_empty() {
                    let k = self.place_holders[i].smallest();
                    self.place_holders[i].remove_smallest();
                    self.puyo[i][k] = cpl.puyo[i][j];
                    j += 1;
                }

                while j < cpl.size[i] {
                    self.puyo[i][self.size[i]] = cpl.puyo[i][j];
                    self.size[i] += 1;
                    j += 1;
                }
            }

            let mut new_place_holder = SmallIntSet::new();
            for j in 0..self.size[i] {
                if ColumnPuyoList::is_place_holder(cpl.puyo[i][j]) {
                    new_place_holder.set(j);
                }
            }
            self.place_holders[i] = new_place_holder;
        }

        true
    }
}

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

    #[test]
    fn test_constructor() {
        let cpl = ColumnPuyoList::new();
        assert_eq!(cpl.size(), 0);
        assert!(cpl.is_empty());
    }

    #[test]
    fn test_add() {
        let mut cpl = ColumnPuyoList::new();
        cpl.add(1, PuyoColor::RED);
        cpl.add(1, PuyoColor::BLUE);
        cpl.add(2, PuyoColor::YELLOW);

        assert_eq!(cpl.size_on(1), 2);
        assert_eq!(cpl.size_on(2), 1);
        assert_eq!(cpl.size_on(3), 0);
        assert_eq!(cpl.size_on(4), 0);
        assert_eq!(cpl.size_on(5), 0);
        assert_eq!(cpl.size_on(6), 0);

        assert_eq!(cpl.top(1), Some(PuyoColor::BLUE));
        assert_eq!(cpl.top(2), Some(PuyoColor::YELLOW));
        assert_eq!(cpl.top(3), None);
    }

    #[test]
    fn test_place_holder() {
        let mut cpl = ColumnPuyoList::new();
        assert!(!cpl.has_place_holder());

        cpl.add(1, PuyoColor::RED);
        assert!(!cpl.has_place_holder());

        cpl.add(1, PuyoColor::IRON);
        assert!(cpl.has_place_holder());

        cpl.remove_top(1);
        assert!(!cpl.has_place_holder());
    }

    #[test]
    fn test_merge() {
        let mut cpl = ColumnPuyoList::new();
        let mut cpl1 = ColumnPuyoList::new();
        assert!(cpl1.add_multi(3, PuyoColor::RED, 2));
        let mut cpl2 = ColumnPuyoList::new();
        assert!(cpl2.add_multi(3, PuyoColor::BLUE, 2));
        let mut cpl3 = ColumnPuyoList::new();
        assert!(cpl3.add_multi(3, PuyoColor::BLUE, 8));

        assert!(cpl.merge(&cpl1));
        assert!(cpl.merge(&cpl2));
        assert_eq!(4, cpl.size());

        assert!(!cpl.merge(&cpl3));
        assert_eq!(4, cpl.size());
    }

    #[test]
    fn test_merge_with_place_holders_1() {
        let mut cpl1 = ColumnPuyoList::new();
        assert!(cpl1.add(3, PuyoColor::IRON));
        assert!(cpl1.add(3, PuyoColor::IRON));
        assert!(cpl1.add(3, PuyoColor::IRON));
        assert!(cpl1.add(3, PuyoColor::RED));
        assert!(cpl1.add(3, PuyoColor::RED));
        assert!(cpl1.add(3, PuyoColor::RED));

        let mut cpl2 = ColumnPuyoList::new();
        assert!(cpl2.add(3, PuyoColor::IRON));
        assert!(cpl2.add(3, PuyoColor::IRON));
        assert!(cpl2.add(3, PuyoColor::YELLOW));
        assert!(cpl2.add(3, PuyoColor::YELLOW));

        assert!(cpl1.merge(&cpl2));

        assert_eq!(7, cpl1.size());
        assert_eq!(7, cpl1.size_on(3));
        assert_eq!(PuyoColor::IRON, cpl1.get(3, 0));
        assert_eq!(PuyoColor::IRON, cpl1.get(3, 1));
        assert_eq!(PuyoColor::YELLOW, cpl1.get(3, 2));
        assert_eq!(PuyoColor::RED, cpl1.get(3, 3));
        assert_eq!(PuyoColor::RED, cpl1.get(3, 4));
        assert_eq!(PuyoColor::RED, cpl1.get(3, 5));
        assert_eq!(PuyoColor::YELLOW, cpl1.get(3, 6));
    }

    #[test]
    fn test_merge_with_place_holders_2() {
        let mut cpl1 = ColumnPuyoList::new();
        assert!(cpl1.add(3, PuyoColor::IRON));
        assert!(cpl1.add(3, PuyoColor::IRON));
        assert!(cpl1.add(3, PuyoColor::IRON));
        assert!(cpl1.add(3, PuyoColor::RED));
        assert!(cpl1.add(3, PuyoColor::RED));
        assert!(cpl1.add(3, PuyoColor::RED));

        let mut cpl2 = ColumnPuyoList::new();
        assert!(cpl2.add(3, PuyoColor::YELLOW));
        assert!(cpl2.add(3, PuyoColor::YELLOW));

        assert!(cpl1.merge(&cpl2));

        assert_eq!(6, cpl1.size());
        assert_eq!(6, cpl1.size_on(3));
        assert_eq!(PuyoColor::IRON, cpl1.get(3, 0));
        assert_eq!(PuyoColor::YELLOW, cpl1.get(3, 1));
        assert_eq!(PuyoColor::YELLOW, cpl1.get(3, 2));
        assert_eq!(PuyoColor::RED, cpl1.get(3, 3));
        assert_eq!(PuyoColor::RED, cpl1.get(3, 4));
        assert_eq!(PuyoColor::RED, cpl1.get(3, 5));
    }

    #[test]
    fn test_merge_with_place_holders_3() {
        let mut cpl1 = ColumnPuyoList::new();
        assert!(cpl1.add(3, PuyoColor::IRON));
        assert!(cpl1.add(3, PuyoColor::IRON));
        assert!(cpl1.add(3, PuyoColor::IRON));
        assert!(cpl1.add(3, PuyoColor::RED));
        assert!(cpl1.add(3, PuyoColor::RED));
        assert!(cpl1.add(3, PuyoColor::RED));
        assert!(cpl1.add(3, PuyoColor::RED));
        assert!(cpl1.add(3, PuyoColor::RED));

        let mut cpl2 = ColumnPuyoList::new();
        assert!(cpl2.add(3, PuyoColor::YELLOW));
        assert!(cpl2.add(3, PuyoColor::YELLOW));
        assert!(cpl2.add(3, PuyoColor::YELLOW));
        assert!(cpl2.add(3, PuyoColor::YELLOW));

        assert!(!cpl1.merge(&cpl2));
    }
}
<commit_msg>:shirt: Remove unused 'use std' from column_puyo_list<commit_after>use color::PuyoColor;
use small_int_set::SmallIntSet;

const MAX_SIZE: usize = 8;

pub struct ColumnPuyoList {
    size: [usize; 6],
    puyo: [[PuyoColor; MAX_SIZE]; 6],
    place_holders: [SmallIntSet; 6],
}

impl ColumnPuyoList {
    pub fn new() -> ColumnPuyoList {
        ColumnPuyoList {
            size: [0; 6],
            puyo: [[PuyoColor::EMPTY; MAX_SIZE]; 6],
            place_holders: [SmallIntSet::new(); 6],
        }
    }

    fn is_place_holder(c: PuyoColor) -> bool {
        c == PuyoColor::IRON
    }

    pub fn size_on(&self, x: usize) -> usize {
        self.size[x - 1]
    }

    pub fn is_empty(&self) -> bool {
        self.size() == 0
    }

    pub fn size(&self) -> usize {
        self.size[0] + self.size[1] + self.size[2] +
        self.size[3] + self.size[4] + self.size[5]
    }

    pub fn top(&self, x: usize) -> Option<PuyoColor> {
        if self.size_on(x) == 0 {
            None
        } else {
            Some(self.puyo[x - 1][self.size_on(x) - 1])
        }
    }

    pub fn get(&self, x: usize, i: usize) -> PuyoColor {
        debug_assert!(i < self.size_on(x));
        self.puyo[x - 1][i]
    }

    pub fn has_place_holder(&self) -> bool {
        for i in 0..6 {
            if !self.place_holders[i].is_empty() {
                return true;
            }
        }

        false
    }

    /// Adds PuyoColor `c` on column `x`.
    /// Returns true if succeeded. Returns false otherwise.
    /// When failed, the `self` won't be changed.
    pub fn add(&mut self, x: usize, c: PuyoColor) -> bool {
        if MAX_SIZE <= self.size[x - 1] {
            return false;
        }
        if ColumnPuyoList::is_place_holder(c) {
            self.place_holders[x - 1].set(self.size[x - 1]);
        }
        self.puyo[x - 1][self.size[x - 1]] = c;
        self.size[x - 1] += 1;
        true
    }

    /// Adds `n` PuyoColor `c` on column `x`.
    /// Returns true if succeeded. Returns false otherwise.
    /// When failed, the `self` won't be changed.
    pub fn add_multi(&mut self, x: usize, c: PuyoColor, n: usize) -> bool {
        if MAX_SIZE < self.size_on(x) + n {
            return false;
        }
        for i in 0..n {
            if ColumnPuyoList::is_place_holder(c) {
                self.place_holders[x - 1].set(self.size[x - 1] + i);
            }
            self.puyo[x - 1][self.size[x - 1] + i] = c;
        }
        self.size[x - 1] += n;
        true
    }

    /// Removes top puyo from column x.
    pub fn remove_top(&mut self, x: usize) {
        if self.size_on(x) == 0 {
            return;
        }
        let c = self.puyo[x - 1][self.size[x - 1] - 1];
        if ColumnPuyoList::is_place_holder(c) {
            self.place_holders[x - 1].unset(self.size[x - 1] - 1);
        }
        self.size[x - 1] -= 1;
    }

    pub fn merge(&mut self, cpl: &ColumnPuyoList) -> bool {
        for i in 0..6 {
            if cpl.size[i] >= self.place_holders[i].size() && MAX_SIZE < self.size[i] + (cpl.size[i] - self.place_holders[i].size()) {
                return false;
            }
        }

        for i in 0..6 {
            if cpl.size[i] < self.place_holders[i].size() {
                let discard = self.place_holders[i].size() - cpl.size[i];
                for _ in 0..discard {
                    self.place_holders[i].remove_smallest();
                }
                for j in 0..cpl.size[i] {
                    let k = self.place_holders[i].smallest();
                    self.place_holders[i].remove_smallest();
                    self.puyo[i][k] = cpl.puyo[i][j];
                }
            } else {
                let mut j = 0;
                while !self.place_holders[i].is_empty() {
                    let k = self.place_holders[i].smallest();
                    self.place_holders[i].remove_smallest();
                    self.puyo[i][k] = cpl.puyo[i][j];
                    j += 1;
                }

                while j < cpl.size[i] {
                    self.puyo[i][self.size[i]] = cpl.puyo[i][j];
                    self.size[i] += 1;
                    j += 1;
                }
            }

            let mut new_place_holder = SmallIntSet::new();
            for j in 0..self.size[i] {
                if ColumnPuyoList::is_place_holder(cpl.puyo[i][j]) {
                    new_place_holder.set(j);
                }
            }
            self.place_holders[i] = new_place_holder;
        }

        true
    }
}

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

    #[test]
    fn test_constructor() {
        let cpl = ColumnPuyoList::new();
        assert_eq!(cpl.size(), 0);
        assert!(cpl.is_empty());
    }

    #[test]
    fn test_add() {
        let mut cpl = ColumnPuyoList::new();
        cpl.add(1, PuyoColor::RED);
        cpl.add(1, PuyoColor::BLUE);
        cpl.add(2, PuyoColor::YELLOW);

        assert_eq!(cpl.size_on(1), 2);
        assert_eq!(cpl.size_on(2), 1);
        assert_eq!(cpl.size_on(3), 0);
        assert_eq!(cpl.size_on(4), 0);
        assert_eq!(cpl.size_on(5), 0);
        assert_eq!(cpl.size_on(6), 0);

        assert_eq!(cpl.top(1), Some(PuyoColor::BLUE));
        assert_eq!(cpl.top(2), Some(PuyoColor::YELLOW));
        assert_eq!(cpl.top(3), None);
    }

    #[test]
    fn test_place_holder() {
        let mut cpl = ColumnPuyoList::new();
        assert!(!cpl.has_place_holder());

        cpl.add(1, PuyoColor::RED);
        assert!(!cpl.has_place_holder());

        cpl.add(1, PuyoColor::IRON);
        assert!(cpl.has_place_holder());

        cpl.remove_top(1);
        assert!(!cpl.has_place_holder());
    }

    #[test]
    fn test_merge() {
        let mut cpl = ColumnPuyoList::new();
        let mut cpl1 = ColumnPuyoList::new();
        assert!(cpl1.add_multi(3, PuyoColor::RED, 2));
        let mut cpl2 = ColumnPuyoList::new();
        assert!(cpl2.add_multi(3, PuyoColor::BLUE, 2));
        let mut cpl3 = ColumnPuyoList::new();
        assert!(cpl3.add_multi(3, PuyoColor::BLUE, 8));

        assert!(cpl.merge(&cpl1));
        assert!(cpl.merge(&cpl2));
        assert_eq!(4, cpl.size());

        assert!(!cpl.merge(&cpl3));
        assert_eq!(4, cpl.size());
    }

    #[test]
    fn test_merge_with_place_holders_1() {
        let mut cpl1 = ColumnPuyoList::new();
        assert!(cpl1.add(3, PuyoColor::IRON));
        assert!(cpl1.add(3, PuyoColor::IRON));
        assert!(cpl1.add(3, PuyoColor::IRON));
        assert!(cpl1.add(3, PuyoColor::RED));
        assert!(cpl1.add(3, PuyoColor::RED));
        assert!(cpl1.add(3, PuyoColor::RED));

        let mut cpl2 = ColumnPuyoList::new();
        assert!(cpl2.add(3, PuyoColor::IRON));
        assert!(cpl2.add(3, PuyoColor::IRON));
        assert!(cpl2.add(3, PuyoColor::YELLOW));
        assert!(cpl2.add(3, PuyoColor::YELLOW));

        assert!(cpl1.merge(&cpl2));

        assert_eq!(7, cpl1.size());
        assert_eq!(7, cpl1.size_on(3));
        assert_eq!(PuyoColor::IRON, cpl1.get(3, 0));
        assert_eq!(PuyoColor::IRON, cpl1.get(3, 1));
        assert_eq!(PuyoColor::YELLOW, cpl1.get(3, 2));
        assert_eq!(PuyoColor::RED, cpl1.get(3, 3));
        assert_eq!(PuyoColor::RED, cpl1.get(3, 4));
        assert_eq!(PuyoColor::RED, cpl1.get(3, 5));
        assert_eq!(PuyoColor::YELLOW, cpl1.get(3, 6));
    }

    #[test]
    fn test_merge_with_place_holders_2() {
        let mut cpl1 = ColumnPuyoList::new();
        assert!(cpl1.add(3, PuyoColor::IRON));
        assert!(cpl1.add(3, PuyoColor::IRON));
        assert!(cpl1.add(3, PuyoColor::IRON));
        assert!(cpl1.add(3, PuyoColor::RED));
        assert!(cpl1.add(3, PuyoColor::RED));
        assert!(cpl1.add(3, PuyoColor::RED));

        let mut cpl2 = ColumnPuyoList::new();
        assert!(cpl2.add(3, PuyoColor::YELLOW));
        assert!(cpl2.add(3, PuyoColor::YELLOW));

        assert!(cpl1.merge(&cpl2));

        assert_eq!(6, cpl1.size());
        assert_eq!(6, cpl1.size_on(3));
        assert_eq!(PuyoColor::IRON, cpl1.get(3, 0));
        assert_eq!(PuyoColor::YELLOW, cpl1.get(3, 1));
        assert_eq!(PuyoColor::YELLOW, cpl1.get(3, 2));
        assert_eq!(PuyoColor::RED, cpl1.get(3, 3));
        assert_eq!(PuyoColor::RED, cpl1.get(3, 4));
        assert_eq!(PuyoColor::RED, cpl1.get(3, 5));
    }

    #[test]
    fn test_merge_with_place_holders_3() {
        let mut cpl1 = ColumnPuyoList::new();
        assert!(cpl1.add(3, PuyoColor::IRON));
        assert!(cpl1.add(3, PuyoColor::IRON));
        assert!(cpl1.add(3, PuyoColor::IRON));
        assert!(cpl1.add(3, PuyoColor::RED));
        assert!(cpl1.add(3, PuyoColor::RED));
        assert!(cpl1.add(3, PuyoColor::RED));
        assert!(cpl1.add(3, PuyoColor::RED));
        assert!(cpl1.add(3, PuyoColor::RED));

        let mut cpl2 = ColumnPuyoList::new();
        assert!(cpl2.add(3, PuyoColor::YELLOW));
        assert!(cpl2.add(3, PuyoColor::YELLOW));
        assert!(cpl2.add(3, PuyoColor::YELLOW));
        assert!(cpl2.add(3, PuyoColor::YELLOW));

        assert!(!cpl1.merge(&cpl2));
    }
}
<|endoftext|>