<commit_before>use std::ops::Index;

enum DIM
{
  ONE,
  TWO,
  THREE
}

trait Point
{
  type IndexingType;
  //type DIM;
}

struct Point1D
{
  x: usize,
}

impl Point for Point1D
{
  type IndexingType = usize;
}

mod abs
{
  pub trait Signal
  {
    type valueType;
    type pointType;
    //type DIM;
  }
}

trait Signal<T: abs::Signal> : Index<T::pointType>
{}

struct Signal1D<T>
{
  arr: Box<[T]>,
}

impl <T: Copy> Signal1D<T>
{
  fn new( init_value: T, size: usize) -> Signal1D<T>
  {
    let mut vec: Vec<T> = Vec::with_capacity(size);
    for _ in 0 .. size
    {
      vec.push(init_value);
    };
    Signal1D {arr: vec.into_boxed_slice()}
  }
}

impl <T> abs::Signal for Signal1D<T>
{
  type valueType = T;
  type pointType = Point1D;
  //type DIM = DIM::ONE;
}

impl <T> Signal<Signal1D<T>> for Signal1D<T> {}

impl <T> Index<<Signal1D<T> as abs::Signal>::pointType> for Signal1D<T>
{
  type Output = T;
   fn index<'a>(&'a self, _index: Point1D) -> &'a T
   {
        &self.arr[_index.x]
   }
}

fn main()
{
  let a :Signal1D<i32> = Signal1D::new(0, 10);
  let b = Point1D{x:0};

  println!("{}", a[b]);

}
<commit_msg>Play with traits and macros<commit_after>use std::ops::Index;

//#![feature(macro_rules)]

macro_rules! obvious_signal_impl {
    (impl $type_: ident) => {

      impl <T> Signal<$type_<T>> for $type_<T> {}

      //impl <T> Index<<$type_<T> as abs::Signal>::pointType> for $type_<T> {
      //  type Output = T;
      //  fn index<'a>(&'a self, _index: <$type_<T> as abs::Signal>::pointType) -> &'a T {
      //    &self.arr[_index.x]
      //  }
      //}
    }
}

macro_rules! signal_point_type {
  ($var:ident from $type_:ty) => (
    let mut $var : <$type_ as abs::Signal>::pointType;
  )
}

enum DIM
{
  ONE,
  TWO,
  THREE
}

trait Point
{
  type IndexingType;
  //type DIM;
}

struct Point1D
{
  x: usize,
}

impl Point for Point1D
{
  type IndexingType = usize;
}
impl Point1D
{
  //fn new(x_:usize) -> Point1D
  //{
  //  Point1D{x:x_}
  //}
  fn new() -> Point1D
  {
    Point1D{x:0}
  }
}

mod abs
{
  pub trait Signal
  {
    type valueType;
    type pointType;
    //type DIM;
  }
}

trait Signal<T: abs::Signal> : Index<T::pointType>
{}

struct Signal1D<T>
{
  arr: Box<[T]>,
}

impl <T: Copy> Signal1D<T>
{
  fn new( init_value: T, size: usize) -> Signal1D<T>
  {
    let mut vec: Vec<T> = Vec::with_capacity(size);
    for _ in 0 .. size
    {
      vec.push(init_value);
    };
    Signal1D {arr: vec.into_boxed_slice()}
  }
}

impl <T> abs::Signal for Signal1D<T>
{
  type valueType = T;
  type pointType = Point1D;
}
obvious_signal_impl! {impl Signal1D }

impl <T> Index<Point1D> for Signal1D<T> {
  type Output = T;
  fn index<'a>(&'a self, _index: <Signal1D<T> as abs::Signal>::pointType) -> &'a T {
    &self.arr[_index.x]
  }
}

fn main()
{
  let a :Signal1D<i32> = Signal1D::new(0, 10);
  //let b :<Signal1D<i32> as abs::Signal>::pointType = <Signal1D<i32> as abs::Signal>::pointType::new(0);
  signal_point_type!(b from Signal1D<i32>);

  println!("{}", a[b]);

}
<|endoftext|>


<commit_before>use crate::{
    ast::{InputValue, ToInputValue},
    parser::Spanning,
};
mod object;
mod scalar;

pub use self::object::Object;

pub use self::scalar::{DefaultScalarValue, ParseScalarResult, ParseScalarValue, ScalarValue};

/// Serializable value returned from query and field execution.
///
/// Used by the execution engine and resolvers to build up the response
/// structure. Similar to the `Json` type found in the serialize crate.
///
/// It is also similar to the `InputValue` type, but can not contain enum
/// values or variables. Also, lists and objects do not contain any location
/// information since they are generated by resolving fields and values rather
/// than parsing a source query.
#[derive(Debug, PartialEq, Clone)]
#[allow(missing_docs)]
pub enum Value<S = DefaultScalarValue> {
    Null,
    Scalar(S),
    List(Vec<Value<S>>),
    Object(Object<S>),
}

impl<S> Value<S>
where
    S: ScalarValue,
{
    // CONSTRUCTORS

    /// Construct a null value.
    pub fn null() -> Self {
        Value::Null
    }

    /// Construct an integer value.
    #[deprecated(since = "0.11.0", note = "Use `Value::scalar` instead")]
    pub fn int(i: i32) -> Self {
        Self::scalar(i)
    }

    /// Construct a floating point value.
    #[deprecated(since = "0.11.0", note = "Use `Value::scalar` instead")]
    pub fn float(f: f64) -> Self {
        Self::scalar(f)
    }

    /// Construct a string value.
    #[deprecated(since = "0.11.0", note = "Use `Value::scalar` instead")]
    pub fn string(s: &str) -> Self {
        Self::scalar(s.to_owned())
    }

    /// Construct a boolean value.
    #[deprecated(since = "0.11.0", note = "Use `Value::scalar` instead")]
    pub fn boolean(b: bool) -> Self {
        Self::scalar(b)
    }

    /// Construct a list value.
    pub fn list(l: Vec<Self>) -> Self {
        Value::List(l)
    }

    /// Construct an object value.
    pub fn object(o: Object<S>) -> Self {
        Value::Object(o)
    }

    /// Construct a scalar value
    pub fn scalar<T>(s: T) -> Self
    where
        T: Into<S>,
    {
        Value::Scalar(s.into())
    }

    // DISCRIMINATORS

    /// Does this value represent null?
    pub fn is_null(&self) -> bool {
        match *self {
            Value::Null => true,
            _ => false,
        }
    }

    /// View the underlying scalar value if present
    pub fn as_scalar_value<'a, T>(&'a self) -> Option<&'a T>
    where
        &'a S: Into<Option<&'a T>>,
    {
        match *self {
            Value::Scalar(ref s) => s.into(),
            _ => None,
        }
    }

    /// View the underlying float value, if present.
    pub fn as_float_value(&self) -> Option<f64>
where {
        match self {
            Value::Scalar(ref s) => s.as_float(),
            _ => None,
        }
    }

    /// View the underlying object value, if present.
    pub fn as_object_value(&self) -> Option<&Object<S>> {
        match *self {
            Value::Object(ref o) => Some(o),
            _ => None,
        }
    }

    /// Convert this value into an Object.
    ///
    /// Returns None if value is not an Object.
    pub fn into_object(self) -> Option<Object<S>> {
        match self {
            Value::Object(o) => Some(o),
            _ => None,
        }
    }

    /// Mutable view into the underlying object value, if present.
    pub fn as_mut_object_value(&mut self) -> Option<&mut Object<S>> {
        match *self {
            Value::Object(ref mut o) => Some(o),
            _ => None,
        }
    }

    /// View the underlying list value, if present.
    pub fn as_list_value(&self) -> Option<&Vec<Self>> {
        match *self {
            Value::List(ref l) => Some(l),
            _ => None,
        }
    }

    /// View the underlying scalar value, if present
    pub fn as_scalar(&self) -> Option<&S> {
        match *self {
            Value::Scalar(ref s) => Some(s),
            _ => None,
        }
    }

    /// View the underlying string value, if present.
    pub fn as_string_value<'a>(&'a self) -> Option<&'a str>
    where
        Option<&'a String>: From<&'a S>,
    {
        self.as_scalar_value::<String>().map(|s| s as &str)
    }
}

impl<S: ScalarValue> ToInputValue<S> for Value<S> {
    fn to_input_value(&self) -> InputValue<S> {
        match *self {
            Value::Null => InputValue::Null,
            Value::Scalar(ref s) => InputValue::Scalar(s.clone()),
            Value::List(ref l) => InputValue::List(
                l.iter()
                    .map(|x| Spanning::unlocated(x.to_input_value()))
                    .collect(),
            ),
            Value::Object(ref o) => InputValue::Object(
                o.iter()
                    .map(|&(ref k, ref v)| {
                        (
                            Spanning::unlocated(k.clone()),
                            Spanning::unlocated(v.to_input_value()),
                        )
                    })
                    .collect(),
            ),
        }
    }
}

impl<S, T> From<Option<T>> for Value<S>
where
    S: ScalarValue,
    Value<S>: From<T>,
{
    fn from(v: Option<T>) -> Value<S> {
        match v {
            Some(v) => v.into(),
            None => Value::null(),
        }
    }
}

impl<'a, S> From<&'a str> for Value<S>
where
    S: ScalarValue,
{
    fn from(s: &'a str) -> Self {
        Value::scalar(s.to_owned())
    }
}

impl<S> From<String> for Value<S>
where
    S: ScalarValue,
{
    fn from(s: String) -> Self {
        Value::scalar(s)
    }
}

impl<S> From<i32> for Value<S>
where
    S: ScalarValue,
{
    fn from(i: i32) -> Self {
        Value::scalar(i)
    }
}

impl<S> From<f64> for Value<S>
where
    S: ScalarValue,
{
    fn from(f: f64) -> Self {
        Value::scalar(f)
    }
}

impl<S> From<bool> for Value<S>
where
    S: ScalarValue,
{
    fn from(b: bool) -> Self {
        Value::scalar(b)
    }
}

/// Construct JSON-like values by using JSON syntax
///
/// This macro can be used to create `Value` instances using a JSON syntax.
/// Value objects are used mostly when creating custom errors from fields.
///
/// Here are some examples; the resulting JSON will look just like what you
/// passed in.
/// ```rust
/// extern crate juniper;
/// # use juniper::{Value, DefaultScalarValue, graphql_value};
/// # type V = Value<DefaultScalarValue>;
///
/// # fn main() {
/// # let _: V =
/// graphql_value!(1234);
/// # let _: V =
/// graphql_value!("test");
/// # let _: V =
/// graphql_value!([ 1234, "test", true ]);
/// # let _: V =
/// graphql_value!({ "key": "value", "foo": 1234 });
/// # }
/// ```
#[macro_export]
macro_rules! graphql_value {
    ([ $($arg:tt),* $(,)* ]) => {
        $crate::Value::list(vec![
            $( graphql_value!($arg), )*
        ])
    };
    ({ $($key:tt : $val:tt ),* $(,)* }) => {
        $crate::Value::object(vec![
            $( ($key, graphql_value!($val)), )*
        ].into_iter().collect())
    };
    (None) => ($crate::Value::null());
    ($e:expr) => ($crate::Value::from($e))
}

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

    #[test]
    fn value_macro_string() {
        let s: Value<DefaultScalarValue> = graphql_value!("test");
        assert_eq!(s, Value::scalar("test"));
    }

    #[test]
    fn value_macro_int() {
        let s: Value<DefaultScalarValue> = graphql_value!(123);
        assert_eq!(s, Value::scalar(123));
    }

    #[test]
    fn value_macro_float() {
        let s: Value<DefaultScalarValue> = graphql_value!(123.5);
        assert_eq!(s, Value::scalar(123.5));
    }

    #[test]
    fn value_macro_boolean() {
        let s: Value<DefaultScalarValue> = graphql_value!(false);
        assert_eq!(s, Value::scalar(false));
    }

    #[test]
    fn value_macro_option() {
        let s: Value<DefaultScalarValue> = graphql_value!(Some("test"));
        assert_eq!(s, Value::scalar("test"));
        let s: Value<DefaultScalarValue> = graphql_value!(None);
        assert_eq!(s, Value::null());
    }

    #[test]
    fn value_macro_list() {
        let s: Value<DefaultScalarValue> = graphql_value!([123, "Test", false]);
        assert_eq!(
            s,
            Value::list(vec![
                Value::scalar(123),
                Value::scalar("Test"),
                Value::scalar(false),
            ])
        );
        let s: Value<DefaultScalarValue> = graphql_value!([123, [456], 789]);
        assert_eq!(
            s,
            Value::list(vec![
                Value::scalar(123),
                Value::list(vec![Value::scalar(456)]),
                Value::scalar(789),
            ])
        );
    }

    #[test]
    fn value_macro_object() {
        let s: Value<DefaultScalarValue> = graphql_value!({ "key": 123, "next": true });
        assert_eq!(
            s,
            Value::object(
                vec![("key", Value::scalar(123)), ("next", Value::scalar(true))]
                    .into_iter()
                    .collect(),
            )
        );
    }
}
<commit_msg>Add example of how to construct null in graphql_value<commit_after>use crate::{
    ast::{InputValue, ToInputValue},
    parser::Spanning,
};
mod object;
mod scalar;

pub use self::object::Object;

pub use self::scalar::{DefaultScalarValue, ParseScalarResult, ParseScalarValue, ScalarValue};

/// Serializable value returned from query and field execution.
///
/// Used by the execution engine and resolvers to build up the response
/// structure. Similar to the `Json` type found in the serialize crate.
///
/// It is also similar to the `InputValue` type, but can not contain enum
/// values or variables. Also, lists and objects do not contain any location
/// information since they are generated by resolving fields and values rather
/// than parsing a source query.
#[derive(Debug, PartialEq, Clone)]
#[allow(missing_docs)]
pub enum Value<S = DefaultScalarValue> {
    Null,
    Scalar(S),
    List(Vec<Value<S>>),
    Object(Object<S>),
}

impl<S> Value<S>
where
    S: ScalarValue,
{
    // CONSTRUCTORS

    /// Construct a null value.
    pub fn null() -> Self {
        Value::Null
    }

    /// Construct an integer value.
    #[deprecated(since = "0.11.0", note = "Use `Value::scalar` instead")]
    pub fn int(i: i32) -> Self {
        Self::scalar(i)
    }

    /// Construct a floating point value.
    #[deprecated(since = "0.11.0", note = "Use `Value::scalar` instead")]
    pub fn float(f: f64) -> Self {
        Self::scalar(f)
    }

    /// Construct a string value.
    #[deprecated(since = "0.11.0", note = "Use `Value::scalar` instead")]
    pub fn string(s: &str) -> Self {
        Self::scalar(s.to_owned())
    }

    /// Construct a boolean value.
    #[deprecated(since = "0.11.0", note = "Use `Value::scalar` instead")]
    pub fn boolean(b: bool) -> Self {
        Self::scalar(b)
    }

    /// Construct a list value.
    pub fn list(l: Vec<Self>) -> Self {
        Value::List(l)
    }

    /// Construct an object value.
    pub fn object(o: Object<S>) -> Self {
        Value::Object(o)
    }

    /// Construct a scalar value
    pub fn scalar<T>(s: T) -> Self
    where
        T: Into<S>,
    {
        Value::Scalar(s.into())
    }

    // DISCRIMINATORS

    /// Does this value represent null?
    pub fn is_null(&self) -> bool {
        match *self {
            Value::Null => true,
            _ => false,
        }
    }

    /// View the underlying scalar value if present
    pub fn as_scalar_value<'a, T>(&'a self) -> Option<&'a T>
    where
        &'a S: Into<Option<&'a T>>,
    {
        match *self {
            Value::Scalar(ref s) => s.into(),
            _ => None,
        }
    }

    /// View the underlying float value, if present.
    pub fn as_float_value(&self) -> Option<f64>
where {
        match self {
            Value::Scalar(ref s) => s.as_float(),
            _ => None,
        }
    }

    /// View the underlying object value, if present.
    pub fn as_object_value(&self) -> Option<&Object<S>> {
        match *self {
            Value::Object(ref o) => Some(o),
            _ => None,
        }
    }

    /// Convert this value into an Object.
    ///
    /// Returns None if value is not an Object.
    pub fn into_object(self) -> Option<Object<S>> {
        match self {
            Value::Object(o) => Some(o),
            _ => None,
        }
    }

    /// Mutable view into the underlying object value, if present.
    pub fn as_mut_object_value(&mut self) -> Option<&mut Object<S>> {
        match *self {
            Value::Object(ref mut o) => Some(o),
            _ => None,
        }
    }

    /// View the underlying list value, if present.
    pub fn as_list_value(&self) -> Option<&Vec<Self>> {
        match *self {
            Value::List(ref l) => Some(l),
            _ => None,
        }
    }

    /// View the underlying scalar value, if present
    pub fn as_scalar(&self) -> Option<&S> {
        match *self {
            Value::Scalar(ref s) => Some(s),
            _ => None,
        }
    }

    /// View the underlying string value, if present.
    pub fn as_string_value<'a>(&'a self) -> Option<&'a str>
    where
        Option<&'a String>: From<&'a S>,
    {
        self.as_scalar_value::<String>().map(|s| s as &str)
    }
}

impl<S: ScalarValue> ToInputValue<S> for Value<S> {
    fn to_input_value(&self) -> InputValue<S> {
        match *self {
            Value::Null => InputValue::Null,
            Value::Scalar(ref s) => InputValue::Scalar(s.clone()),
            Value::List(ref l) => InputValue::List(
                l.iter()
                    .map(|x| Spanning::unlocated(x.to_input_value()))
                    .collect(),
            ),
            Value::Object(ref o) => InputValue::Object(
                o.iter()
                    .map(|&(ref k, ref v)| {
                        (
                            Spanning::unlocated(k.clone()),
                            Spanning::unlocated(v.to_input_value()),
                        )
                    })
                    .collect(),
            ),
        }
    }
}

impl<S, T> From<Option<T>> for Value<S>
where
    S: ScalarValue,
    Value<S>: From<T>,
{
    fn from(v: Option<T>) -> Value<S> {
        match v {
            Some(v) => v.into(),
            None => Value::null(),
        }
    }
}

impl<'a, S> From<&'a str> for Value<S>
where
    S: ScalarValue,
{
    fn from(s: &'a str) -> Self {
        Value::scalar(s.to_owned())
    }
}

impl<S> From<String> for Value<S>
where
    S: ScalarValue,
{
    fn from(s: String) -> Self {
        Value::scalar(s)
    }
}

impl<S> From<i32> for Value<S>
where
    S: ScalarValue,
{
    fn from(i: i32) -> Self {
        Value::scalar(i)
    }
}

impl<S> From<f64> for Value<S>
where
    S: ScalarValue,
{
    fn from(f: f64) -> Self {
        Value::scalar(f)
    }
}

impl<S> From<bool> for Value<S>
where
    S: ScalarValue,
{
    fn from(b: bool) -> Self {
        Value::scalar(b)
    }
}

/// Construct JSON-like values by using JSON syntax
///
/// This macro can be used to create `Value` instances using a JSON syntax.
/// Value objects are used mostly when creating custom errors from fields.
///
/// Here are some examples; the resulting JSON will look just like what you
/// passed in.
/// ```rust
/// extern crate juniper;
/// # use juniper::{Value, DefaultScalarValue, graphql_value};
/// # type V = Value<DefaultScalarValue>;
///
/// # fn main() {
/// # let _: V =
/// graphql_value!(None);
/// # let _: V =
/// graphql_value!(1234);
/// # let _: V =
/// graphql_value!("test");
/// # let _: V =
/// graphql_value!([ 1234, "test", true ]);
/// # let _: V =
/// graphql_value!({ "key": "value", "foo": 1234 });
/// # }
/// ```
#[macro_export]
macro_rules! graphql_value {
    ([ $($arg:tt),* $(,)* ]) => {
        $crate::Value::list(vec![
            $( graphql_value!($arg), )*
        ])
    };
    ({ $($key:tt : $val:tt ),* $(,)* }) => {
        $crate::Value::object(vec![
            $( ($key, graphql_value!($val)), )*
        ].into_iter().collect())
    };
    (None) => ($crate::Value::null());
    ($e:expr) => ($crate::Value::from($e))
}

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

    #[test]
    fn value_macro_string() {
        let s: Value<DefaultScalarValue> = graphql_value!("test");
        assert_eq!(s, Value::scalar("test"));
    }

    #[test]
    fn value_macro_int() {
        let s: Value<DefaultScalarValue> = graphql_value!(123);
        assert_eq!(s, Value::scalar(123));
    }

    #[test]
    fn value_macro_float() {
        let s: Value<DefaultScalarValue> = graphql_value!(123.5);
        assert_eq!(s, Value::scalar(123.5));
    }

    #[test]
    fn value_macro_boolean() {
        let s: Value<DefaultScalarValue> = graphql_value!(false);
        assert_eq!(s, Value::scalar(false));
    }

    #[test]
    fn value_macro_option() {
        let s: Value<DefaultScalarValue> = graphql_value!(Some("test"));
        assert_eq!(s, Value::scalar("test"));
        let s: Value<DefaultScalarValue> = graphql_value!(None);
        assert_eq!(s, Value::null());
    }

    #[test]
    fn value_macro_list() {
        let s: Value<DefaultScalarValue> = graphql_value!([123, "Test", false]);
        assert_eq!(
            s,
            Value::list(vec![
                Value::scalar(123),
                Value::scalar("Test"),
                Value::scalar(false),
            ])
        );
        let s: Value<DefaultScalarValue> = graphql_value!([123, [456], 789]);
        assert_eq!(
            s,
            Value::list(vec![
                Value::scalar(123),
                Value::list(vec![Value::scalar(456)]),
                Value::scalar(789),
            ])
        );
    }

    #[test]
    fn value_macro_object() {
        let s: Value<DefaultScalarValue> = graphql_value!({ "key": 123, "next": true });
        assert_eq!(
            s,
            Value::object(
                vec![("key", Value::scalar(123)), ("next", Value::scalar(true))]
                    .into_iter()
                    .collect(),
            )
        );
    }
}
<|endoftext|>


<commit_before>use crate::spec::{LinkArgs, LinkerFlavor, TargetOptions};
use std::default::Default;

pub fn opts() -> TargetOptions {
    let mut args = LinkArgs::new();
    args.insert(LinkerFlavor::Msvc,
                vec!["/NOLOGO".to_string(),
                     "/NXCOMPAT".to_string()]);

    TargetOptions {
        function_sections: true,
        dynamic_linking: true,
        executables: true,
        dll_prefix: String::new(),
        dll_suffix: ".dll".to_string(),
        exe_suffix: ".exe".to_string(),
        staticlib_prefix: String::new(),
        staticlib_suffix: ".lib".to_string(),
        target_family: Some("windows".to_string()),
        is_like_windows: true,
        is_like_msvc: true,
        link_env: vec![("VSLANG".to_string(), "1033".to_string())],
        pre_link_args: args,
        crt_static_allows_dylibs: true,
        crt_static_respected: true,
        abi_return_struct_as_int: true,
        emit_debug_gdb_scripts: false,
        requires_uwtable: true,

        .. Default::default()
    }
}
<commit_msg>Added comment description.<commit_after>use crate::spec::{LinkArgs, LinkerFlavor, TargetOptions};
use std::default::Default;

pub fn opts() -> TargetOptions {
    let mut args = LinkArgs::new();
    args.insert(LinkerFlavor::Msvc,
                vec!["/NOLOGO".to_string(),
                     "/NXCOMPAT".to_string()]);

    TargetOptions {
        function_sections: true,
        dynamic_linking: true,
        executables: true,
        dll_prefix: String::new(),
        dll_suffix: ".dll".to_string(),
        exe_suffix: ".exe".to_string(),
        staticlib_prefix: String::new(),
        staticlib_suffix: ".lib".to_string(),
        target_family: Some("windows".to_string()),
        is_like_windows: true,
        is_like_msvc: true,
        // set VSLANG to 1033 can prevent link.exe from using
        // language packs, and avoid generating Non-UTF-8 error
        // messages if a link error occurred.
        link_env: vec![("VSLANG".to_string(), "1033".to_string())],
        pre_link_args: args,
        crt_static_allows_dylibs: true,
        crt_static_respected: true,
        abi_return_struct_as_int: true,
        emit_debug_gdb_scripts: false,
        requires_uwtable: true,

        .. Default::default()
    }
}
<|endoftext|>


<commit_before>// Copyright 2016 The Rust Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution and at
// http://rust-lang.org/COPYRIGHT.
//
// 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.

#![allow(unused)]

fn main() {
    let x = 0;
    macro_rules! foo { () => {
        assert_eq!(x, 0);
    } }

    let x = 1;
    foo!();

    g();
}

fn g() {
    let x = 0;
    macro_rules! m { ($x:ident) => {
        macro_rules! m2 { () => { ($x, x) } }
        let x = 1;
        macro_rules! m3 { () => { ($x, x) } }
    } }

    let x = 2;
    m!(x);

    let x = 3;
    assert_eq!(m2!(), (2, 0));
    assert_eq!(m3!(), (2, 1));

    let x = 4;
    m!(x);
    assert_eq!(m2!(), (4, 0));
    assert_eq!(m3!(), (4, 1));
}
<commit_msg>More hygiene tests<commit_after>// Copyright 2016 The Rust Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution and at
// http://rust-lang.org/COPYRIGHT.
//
// 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.

#![allow(unused)]

fn f() {
    let x = 0;
    macro_rules! foo { () => {
        assert_eq!(x, 0);
    } }

    let x = 1;
    foo!();
}

fn g() {
    let x = 0;
    macro_rules! m { ($x:ident) => {
        macro_rules! m2 { () => { ($x, x) } }
        let x = 1;
        macro_rules! m3 { () => { ($x, x) } }
    } }

    let x = 2;
    m!(x);

    let x = 3;
    assert_eq!(m2!(), (2, 0));
    assert_eq!(m3!(), (2, 1));

    let x = 4;
    m!(x);
    assert_eq!(m2!(), (4, 0));
    assert_eq!(m3!(), (4, 1));
}

mod foo {
    macro_rules! m {
        ($f:ident : |$x:ident| $e:expr) => {
            pub fn $f() -> (i32, i32) {
                let x = 0;
                let $x = 1;
                (x, $e)
            }
        }
    }

    m!(f: |x| x + 10);
}

fn interpolated_pattern() {
    let x = 0;
    macro_rules! m {
        ($p:pat, $e:expr) => {
            let $p = 1;
            assert_eq!((x, $e), (0, 1));
        }
    }

    m!(x, x);
}

fn patterns_in_macro_generated_macros() {
    let x = 0;
    macro_rules! m {
        ($a:expr, $b:expr) => {
            assert_eq!(x, 0);
            let x = $a;
            macro_rules! n {
                () => {
                    (x, $b)
                }
            }
        }
    }

    let x = 1;
    m!(2, x);

    let x = 3;
    assert_eq!(n!(), (2, 1));
}

fn match_hygiene() {
    let x = 0;

    macro_rules! m {
        ($p:pat, $e:expr) => {
            for result in &[Ok(1), Err(1)] {
                match *result {
                    $p => { assert_eq!(($e, x), (1, 0)); }
                    Err(x) => { assert_eq!(($e, x), (2, 1)); }
                }
            }
        }
    }

    let x = 2;
    m!(Ok(x), x);
}

fn main() {
    f();
    g();
    assert_eq!(foo::f(), (0, 11));
    interpolated_pattern();
    patterns_in_macro_generated_macros();
    match_hygiene();
}
<|endoftext|>


<commit_before>
use std::io;

use parser::*;
use scope::*;
use processing::*;
use output::*;

impl ElementOpsStreamWriter for DefaultOutputWriterJs {

    fn write_op_element_open<PropIter, EventIter, BindingIter>(&mut self, w: &mut io::Write, ctx: &mut Context, bindings: &BindingContext, element_tag: &str, element_key: &str, is_void: bool, _props: PropIter, _events: EventIter, _binding: BindingIter) -> Result
        where PropIter : IntoIterator<Item = Prop>, EventIter: IntoIterator<Item = EventHandler>, BindingIter: IntoIterator<Item = ElementValueBinding>
    {
        if !is_void {
            write!(w, "IncrementalDOM.elementOpen(\"{}\", ", element_tag)?;
        } else {
            write!(w, "IncrementalDOM.elementVoid(\"{}\", ", element_tag)?;
        };

        let path_expr = ctx.join_path_as_expr_with(Some("."), element_key);
        self.write_expr(w, ctx, bindings, &path_expr)?;
        // write_js_func_params(scope, w)?;
        writeln!(w, ");")?;

        Ok(())
    }

    fn write_op_element_close(&mut self, w: &mut io::Write, __ctx: &mut Context, _bindings: &BindingContext, element_tag: &str) -> Result {
        writeln!(w, "IncrementalDOM.elementClose(\"{}\");", element_tag)?;
        Ok(())
    }

    fn write_op_element_start_block<PropIter: IntoIterator<Item = Prop>>(&mut self, _w: &mut io::Write, __ctx: &mut Context, _bindings: &BindingContext, _block_id: &str, _props: PropIter) -> Result {
        Ok(())
    }

    fn write_op_element_end_block(&mut self, _w: &mut io::Write, __ctx: &mut Context, _bindings: &BindingContext, _block_id: &str) -> Result {
        Ok(())
    }

    fn write_op_element_map_collection_to_block(&mut self, w: &mut io::Write, __ctx: &mut Context, _bindings: &BindingContext, _coll_expr: &ExprValue, block_id: &str) -> Result {
        write!(w, "(")?;
        // let binding = BindingType::LoopIndexBinding;
        writeln!(w, ").forEach(__{});", block_id)?;
        Ok(())
    }

    fn write_op_element_instance_component<'a, PropIter, EventIter, BindingIter, OpsIter>(&mut self, w: &mut io::Write, doc: &Document, ctx: &mut Context, bindings: &BindingContext, element_tag: &str, element_key: &str, _is_void: bool, _props: PropIter, _events: EventIter, _binding: BindingIter, ops: OpsIter) -> Result
        where PropIter : IntoIterator<Item = Prop>, EventIter: IntoIterator<Item = EventHandler>, BindingIter: IntoIterator<Item = ElementValueBinding>, OpsIter: IntoIterator<Item = &'a ElementOp>
    {
        let instance_key = ctx.join_path_as_expr_with(Some("_"), element_key);

        write!(w, "component_{}(", element_tag)?;
        self.write_expr(w, ctx, bindings, &instance_key)?;
        write!(w, ", {{")?;
        writeln!(w, "}});")?;
        Ok(())
    }

    fn write_op_element_value(&mut self, w: &mut io::Write, ctx: &mut Context, bindings: &BindingContext, expr: &ExprValue, _element_key: &str) -> Result {
        write!(w, "IncrementalDOM.text(")?;
        self.write_expr(w, ctx, bindings, expr)?;
        writeln!(w, ");")?;
        Ok(())
    }
}

#[cfg(test)]
mod tests {
    use super::*;
    use std::str;
    use std::iter::empty;
    use scope::context::*;
    use scope::bindings::*;
    use output::writers::*;

    #[test]
    pub fn test_output_stream_writers_js_ops1() {
        let mut ctx = Context::default();
        ctx.append_path_str("prefix");
        let bindings = BindingContext::default();

        let mut writer = DefaultOutputWriterJs::default();

        let mut s: Vec<u8> = Default::default();
        let key = "key".to_owned();
        assert!(
            writer.write_op_element_open(&mut s, &mut ctx, &bindings, "span", &key, false, empty(), empty(), empty()).is_ok() &&
            writer.write_op_element_close(&mut s, &mut ctx, &bindings, "span").is_ok()
        );
        // assert_eq!(str::from_utf8(&s), Ok("IncrementalDOM.elementOpen(\"span\", [\"prefix\", \"key\"].join(\".\"));\nIncrementalDOM.elementClose(\"span\");\n".into()));
        assert_eq!(str::from_utf8(&s), Ok(indoc![r#"
            IncrementalDOM.elementOpen("span", ["prefix", "key"].join("."));
            IncrementalDOM.elementClose("span");
        "#]));
    }
}<commit_msg>Output attributes on elements<commit_after>
use std::io;

use parser::*;
use scope::*;
use processing::*;
use output::*;

impl ElementOpsStreamWriter for DefaultOutputWriterJs {

    fn write_op_element_open<PropIter, EventIter, BindingIter>(&mut self, w: &mut io::Write, ctx: &mut Context, bindings: &BindingContext, element_tag: &str, element_key: &str, is_void: bool, props: PropIter, _events: EventIter, _binding: BindingIter) -> Result
        where PropIter : IntoIterator<Item = Prop>, EventIter: IntoIterator<Item = EventHandler>, BindingIter: IntoIterator<Item = ElementValueBinding>
    {
        if !is_void {
            write!(w, "IncrementalDOM.elementOpen(\"{}\", ", element_tag)?;
        } else {
            write!(w, "IncrementalDOM.elementVoid(\"{}\", ", element_tag)?;
        };

        let path_expr = ctx.join_path_as_expr_with(Some("."), element_key);
        self.write_expr(w, ctx, bindings, &path_expr)?;
        write!(w, ", [")?;

        let mut first_item = true;
        for ref prop in props {
            if let Some(ref expr) = prop.1 {
                if !first_item { write!(w, ", ")?; }
                first_item = false;
                write!(w, "\"{}\", ", &prop.0)?;
                self.write_expr(w, ctx, bindings, &expr)?;
            };
        }

        writeln!(w, "]);")?;

        Ok(())
    }

    fn write_op_element_close(&mut self, w: &mut io::Write, __ctx: &mut Context, _bindings: &BindingContext, element_tag: &str) -> Result {
        writeln!(w, "IncrementalDOM.elementClose(\"{}\");", element_tag)?;
        Ok(())
    }

    fn write_op_element_start_block<PropIter: IntoIterator<Item = Prop>>(&mut self, _w: &mut io::Write, __ctx: &mut Context, _bindings: &BindingContext, _block_id: &str, _props: PropIter) -> Result {
        Ok(())
    }

    fn write_op_element_end_block(&mut self, _w: &mut io::Write, __ctx: &mut Context, _bindings: &BindingContext, _block_id: &str) -> Result {
        Ok(())
    }

    fn write_op_element_map_collection_to_block(&mut self, w: &mut io::Write, __ctx: &mut Context, _bindings: &BindingContext, _coll_expr: &ExprValue, block_id: &str) -> Result {
        write!(w, "(")?;
        // let binding = BindingType::LoopIndexBinding;
        writeln!(w, ").forEach(__{});", block_id)?;
        Ok(())
    }

    fn write_op_element_instance_component<'a, PropIter, EventIter, BindingIter, OpsIter>(&mut self, w: &mut io::Write, doc: &Document, ctx: &mut Context, bindings: &BindingContext, element_tag: &str, element_key: &str, _is_void: bool, _props: PropIter, _events: EventIter, _binding: BindingIter, ops: OpsIter) -> Result
        where PropIter : IntoIterator<Item = Prop>, EventIter: IntoIterator<Item = EventHandler>, BindingIter: IntoIterator<Item = ElementValueBinding>, OpsIter: IntoIterator<Item = &'a ElementOp>
    {
        let instance_key = ctx.join_path_as_expr_with(Some("_"), element_key);

        write!(w, "component_{}(", element_tag)?;
        self.write_expr(w, ctx, bindings, &instance_key)?;
        write!(w, ", {{")?;
        writeln!(w, "}});")?;
        Ok(())
    }

    fn write_op_element_value(&mut self, w: &mut io::Write, ctx: &mut Context, bindings: &BindingContext, expr: &ExprValue, _element_key: &str) -> Result {
        write!(w, "IncrementalDOM.text(")?;
        self.write_expr(w, ctx, bindings, expr)?;
        writeln!(w, ");")?;
        Ok(())
    }
}

#[cfg(test)]
mod tests {
    use super::*;
    use std::str;
    use std::iter::empty;
    use scope::context::*;
    use scope::bindings::*;
    use output::writers::*;

    #[test]
    pub fn test_output_stream_writers_js_ops1() {
        let mut ctx = Context::default();
        ctx.append_path_str("prefix");
        let bindings = BindingContext::default();

        let mut writer = DefaultOutputWriterJs::default();

        let mut s: Vec<u8> = Default::default();
        let key = "key".to_owned();
        assert!(
            writer.write_op_element_open(&mut s, &mut ctx, &bindings, "span", &key, false, empty(), empty(), empty()).is_ok() &&
            writer.write_op_element_close(&mut s, &mut ctx, &bindings, "span").is_ok()
        );
        // assert_eq!(str::from_utf8(&s), Ok("IncrementalDOM.elementOpen(\"span\", [\"prefix\", \"key\"].join(\".\"));\nIncrementalDOM.elementClose(\"span\");\n".into()));
        assert_eq!(str::from_utf8(&s), Ok(indoc![r#"
            IncrementalDOM.elementOpen("span", ["prefix", "key"].join("."));
            IncrementalDOM.elementClose("span");
        "#]));
    }
}<|endoftext|>


<commit_before>//
// imag - the personal information management suite for the commandline
// Copyright (C) 2015, 2016 Matthias Beyer <mail@beyermatthias.de> and contributors
//
// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public
// License as published by the Free Software Foundation; version
// 2.1 of the License.
//
// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
// Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public
// License along with this library; if not, write to the Free Software
// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
//

use chrono::naive::datetime::NaiveDateTime;
use toml_query::delete::TomlValueDeleteExt;
use toml_query::insert::TomlValueInsertExt;
use toml_query::read::TomlValueReadExt;
use toml::Value;

use libimagstore::store::Entry;
use libimagerror::into::IntoError;

use error::DateErrorKind as DEK;
use error::*;
use result::Result;

pub trait EntryDate {

    fn delete_date(&mut self) -> Result<()>;
    fn read_date(&self) -> Result<NaiveDateTime>;
    fn set_date(&mut self, d: NaiveDateTime) -> Result<Option<Result<NaiveDateTime>>>;

}

lazy_static! {
    static ref DATE_HEADER_LOCATION : String = String::from("date.value");
    static ref DATE_FMT : &'static str       = "%Y-%m-%d %H:%M:%S";
}

impl EntryDate for Entry {

    fn delete_date(&mut self) -> Result<()> {
        self.get_header_mut()
            .delete(&DATE_HEADER_LOCATION)
            .map(|_| ())
            .map_err_into(DEK::StoreWriteError)
    }

    fn read_date(&self) -> Result<NaiveDateTime> {
        self.get_header()
            .read(&DATE_HEADER_LOCATION)
            .map_err_into(DEK::StoreReadError)
            .and_then(|v| {
                match v {
                    &Value::String(ref s) => s.parse::<NaiveDateTime>()
                        .map_err_into(DEK::DateTimeParsingError),
                    _ => Err(DEK::DateHeaderFieldTypeError.into_error()),
                }
            })
    }

    /// Set a Date for this entry
    ///
    /// # Return value
    ///
    /// This function returns funny things, I know. But I find it more attractive to be explicit
    /// what failed when here, instead of beeing nice to the user here.
    ///
    /// So here's a list how things are returned:
    ///
    /// - Err(_) if the inserting failed
    /// - Ok(None) if the inserting succeeded and _did not replace an existing value_.
    /// - Ok(Some(Ok(_))) if the inserting succeeded, but replaced an existing value which then got
    /// parsed into a NaiveDateTime object
    /// - Ok(Some(Err(_))) if the inserting succeeded, but replaced an existing value which then
    /// got parsed into a NaiveDateTime object, where the parsing failed for some reason.
    ///
    fn set_date(&mut self, d: NaiveDateTime) -> Result<Option<Result<NaiveDateTime>>> {
        let date = d.format(&DATE_FMT).to_string();

        self.get_header_mut()
            .insert(&DATE_HEADER_LOCATION, Value::String(date))
            .map(|opt| opt.map(|stri| {
                match stri {
                    Value::String(ref s) => s.parse::<NaiveDateTime>()
                                             .map_err_into(DEK::DateTimeParsingError),
                    _ => Err(DEK::DateHeaderFieldTypeError.into_error()),
                }
            }))
            .map_err_into(DEK::StoreWriteError)
    }

}

<commit_msg>Add range support<commit_after>//
// imag - the personal information management suite for the commandline
// Copyright (C) 2015, 2016 Matthias Beyer <mail@beyermatthias.de> and contributors
//
// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public
// License as published by the Free Software Foundation; version
// 2.1 of the License.
//
// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
// Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public
// License along with this library; if not, write to the Free Software
// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
//

use chrono::naive::datetime::NaiveDateTime;
use toml_query::delete::TomlValueDeleteExt;
use toml_query::insert::TomlValueInsertExt;
use toml_query::read::TomlValueReadExt;
use toml::Value;

use libimagstore::store::Entry;
use libimagerror::into::IntoError;

use error::DateErrorKind as DEK;
use error::*;
use result::Result;

#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
pub struct DateRange(NaiveDateTime, NaiveDateTime);

pub trait EntryDate {

    fn delete_date(&mut self) -> Result<()>;
    fn read_date(&self) -> Result<NaiveDateTime>;
    fn set_date(&mut self, d: NaiveDateTime) -> Result<Option<Result<NaiveDateTime>>>;

    fn delete_date_range(&mut self) -> Result<()>;
    fn read_date_range(&self) -> Result<DateRange>;
    fn set_date_range(&mut self, start: NaiveDateTime, end: NaiveDateTime) -> Result<Option<Result<DateRange>>>;

}

lazy_static! {
    static ref DATE_HEADER_LOCATION : String             = String::from("date.value");
    static ref DATE_RANGE_START_HEADER_LOCATION : String = String::from("date.range.start");
    static ref DATE_RANGE_END_HEADER_LOCATION : String   = String::from("date.range.end");
    static ref DATE_FMT : &'static str                   = "%Y-%m-%d %H:%M:%S";
}

impl EntryDate for Entry {

    fn delete_date(&mut self) -> Result<()> {
        self.get_header_mut()
            .delete(&DATE_HEADER_LOCATION)
            .map(|_| ())
            .map_err_into(DEK::StoreWriteError)
    }

    fn read_date(&self) -> Result<NaiveDateTime> {
        self.get_header()
            .read(&DATE_HEADER_LOCATION)
            .map_err_into(DEK::StoreReadError)
            .and_then(|v| {
                match v {
                    &Value::String(ref s) => s.parse::<NaiveDateTime>()
                        .map_err_into(DEK::DateTimeParsingError),
                    _ => Err(DEK::DateHeaderFieldTypeError.into_error()),
                }
            })
    }

    /// Set a Date for this entry
    ///
    /// # Return value
    ///
    /// This function returns funny things, I know. But I find it more attractive to be explicit
    /// what failed when here, instead of beeing nice to the user here.
    ///
    /// So here's a list how things are returned:
    ///
    /// - Err(_) if the inserting failed
    /// - Ok(None) if the inserting succeeded and _did not replace an existing value_.
    /// - Ok(Some(Ok(_))) if the inserting succeeded, but replaced an existing value which then got
    /// parsed into a NaiveDateTime object
    /// - Ok(Some(Err(_))) if the inserting succeeded, but replaced an existing value which then
    /// got parsed into a NaiveDateTime object, where the parsing failed for some reason.
    ///
    fn set_date(&mut self, d: NaiveDateTime) -> Result<Option<Result<NaiveDateTime>>> {
        let date = d.format(&DATE_FMT).to_string();

        self.get_header_mut()
            .insert(&DATE_HEADER_LOCATION, Value::String(date))
            .map(|opt| opt.map(|stri| {
                match stri {
                    Value::String(ref s) => s.parse::<NaiveDateTime>()
                                             .map_err_into(DEK::DateTimeParsingError),
                    _ => Err(DEK::DateHeaderFieldTypeError.into_error()),
                }
            }))
            .map_err_into(DEK::StoreWriteError)
    }

    /// Deletes the date range
    ///
    /// # Warning
    ///
    /// First deletes the start, then the end. If the first operation fails, this might leave the
    /// header in an inconsistent state.
    ///
    fn delete_date_range(&mut self) -> Result<()> {
        let _ = try!(self
             .get_header_mut()
            .delete(&DATE_RANGE_START_HEADER_LOCATION)
            .map(|_| ())
            .map_err_into(DEK::StoreWriteError));

        self.get_header_mut()
            .delete(&DATE_RANGE_END_HEADER_LOCATION)
            .map(|_| ())
            .map_err_into(DEK::StoreWriteError)
    }

    fn read_date_range(&self) -> Result<DateRange> {
        let start = try!(self
            .get_header()
            .read(&DATE_RANGE_START_HEADER_LOCATION)
            .map_err_into(DEK::StoreReadError)
            .and_then(|v| {
                match v {
                    &Value::String(ref s) => s.parse::<NaiveDateTime>()
                        .map_err_into(DEK::DateTimeParsingError),
                    _ => Err(DEK::DateHeaderFieldTypeError.into_error()),
                }
            }));

        let end = try!(self
            .get_header()
            .read(&DATE_RANGE_START_HEADER_LOCATION)
            .map_err_into(DEK::StoreReadError)
            .and_then(|v| {
                match v {
                    &Value::String(ref s) => s.parse::<NaiveDateTime>()
                        .map_err_into(DEK::DateTimeParsingError),
                    _ => Err(DEK::DateHeaderFieldTypeError.into_error()),
                }
            }));

        Ok(DateRange(start, end))
    }

    /// Set the date range
    ///
    /// # Warning
    ///
    /// This first sets the start, then the end. If the first operation fails, this might leave the
    /// header in an inconsistent state.
    ///
    fn set_date_range(&mut self, start: NaiveDateTime, end: NaiveDateTime)
        -> Result<Option<Result<DateRange>>>
    {
        let start = start.format(&DATE_FMT).to_string();
        let end   = end.format(&DATE_FMT).to_string();

        let opt_old_start = try!(self
            .get_header_mut()
            .insert(&DATE_RANGE_START_HEADER_LOCATION, Value::String(start))
            .map(|opt| opt.map(|stri| {
                match stri {
                    Value::String(ref s) => s.parse::<NaiveDateTime>()
                                             .map_err_into(DEK::DateTimeParsingError),
                    _ => Err(DEK::DateHeaderFieldTypeError.into_error()),
                }
            }))
            .map_err_into(DEK::StoreWriteError));

        let opt_old_end = try!(self
            .get_header_mut()
            .insert(&DATE_RANGE_END_HEADER_LOCATION, Value::String(end))
            .map(|opt| opt.map(|stri| {
                match stri {
                    Value::String(ref s) => s.parse::<NaiveDateTime>()
                                             .map_err_into(DEK::DateTimeParsingError),
                    _ => Err(DEK::DateHeaderFieldTypeError.into_error()),
                }
            }))
            .map_err_into(DEK::StoreWriteError));

        match (opt_old_start, opt_old_end) {
            (Some(Ok(old_start)), Some(Ok(old_end))) => Ok(Some(Ok(DateRange(old_start, old_end)))),

            (Some(Err(e)), _) => Err(e),
            (_, Some(Err(e))) => Err(e),
            _ => {
                Ok(None)
            },
        }
    }

}

<|endoftext|>


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

// Marauder is grid-less turn-based strategy game.

extern mod glfw;
extern mod gl;
extern mod cgmath;

use gl::types::{
  GLenum,
  GLuint,
  GLint,
  GLchar,
  GLfloat,
  GLsizeiptr,
  GLboolean
};
use cgmath::matrix::{Matrix, Mat4, Mat3, ToMat4};
use cgmath::projection;
use cgmath::angle;
use cgmath::vector::{Vec3, Vec2};

#[link(name = "glfw")]
#[link(name = "m")]
extern {}

/// usage: let s = mvp_matrix; println(type_of(&s));
fn type_of<T>(_: &T) -> &'static str {
  unsafe {
    (*std::unstable::intrinsics::get_tydesc::<T>()).name
  }
}

fn print_mat4(name: &str, mat: Mat4<f32>) {
  println!("{}:", name);
  for i in range(0u, 4) {
    for j in range(0u, 4) {
      print!("{} ", *mat.cr(i, j));
    }
    println("");
  }
  println("");
}

static mut MOUSE_POS: Vec2<f32> = Vec2{x: 0.0f32, y: 0.0};
static mut CAMERA_POS: Vec3<f32> = Vec3{x: 0.0f32, y: 0.0, z: 0.0};

static WIN_SIZE: Vec2<uint> = Vec2{x: 640, y: 480};
static VERTICES_COUNT: i32 = 3 * 2;

static VERTEX_DATA: [GLfloat, ..VERTICES_COUNT * 3] = [
   0.0,  1.0, 0.0,
   2.0, -1.0, 0.0,
  -2.0, -1.0, 0.0,

  0.0,  1.0,  0.0,
  0.0, -1.0,  2.0,
  0.0, -1.0, -2.0
];

static VERTEX_SHADER_SRC: &'static str = "
  #version 130
  in vec3 position;
  uniform mat4 model_view_proj_matrix;
  void main() {
    vec4 v = vec4(position, 1);
    gl_Position = model_view_proj_matrix * v;
  }
";

static FRAGMENT_SHADER_SRC: &'static str = "
  #version 130
  out vec4 out_color;
  void main() {
    out_color = vec4(1.0, 1.0, 1.0, 1.0);
  }
";

fn compile_shader(src: &str, ty: GLenum) -> GLuint {
  let shader = gl::CreateShader(ty);
  unsafe {
    // Attempt to compile the shader
    gl::ShaderSource(shader, 1, &src.to_c_str().unwrap(), std::ptr::null());
    gl::CompileShader(shader);

    // Get the compile status
    let mut status = gl::FALSE as GLint;
    gl::GetShaderiv(shader, gl::COMPILE_STATUS, &mut status);

    // Fail on error
    if status != (gl::TRUE as GLint) {
      let mut len = 0;
      gl::GetShaderiv(shader, gl::INFO_LOG_LENGTH, &mut len);
      // subtract 1 to skip the trailing null character
      let mut buf = std::vec::from_elem(len as uint - 1, 0u8);
      gl::GetShaderInfoLog(shader, len, std::ptr::mut_null(),
        std::vec::raw::to_mut_ptr(buf) as *mut GLchar
      );
      fail!("compile_shader(): " + std::str::raw::from_utf8(buf));
    }
  }
  shader
}

fn link_program(vertex_shader: GLuint, fragment_shader: GLuint) -> GLuint {
  let program = gl::CreateProgram();
  gl::AttachShader(program, vertex_shader);
  gl::AttachShader(program, fragment_shader);
  gl::LinkProgram(program);
  unsafe {
    // Get the link status
    let mut status = gl::FALSE as GLint;
    gl::GetProgramiv(program, gl::LINK_STATUS, &mut status);

    // Fail on error
    if status != (gl::TRUE as GLint) {
      let mut len: GLint = 0;
      gl::GetProgramiv(program, gl::INFO_LOG_LENGTH, &mut len);
      // subtract 1 to skip the trailing null character
      let mut buf = std::vec::from_elem(len as uint - 1, 0u8);
      gl::GetProgramInfoLog(program, len, std::ptr::mut_null(),
        std::vec::raw::to_mut_ptr(buf) as *mut GLchar
      );
      fail!("link_program(): " + std::str::raw::from_utf8(buf));
    }
  }
  program
}

fn tr(m: Mat4<f32>, v: Vec3<f32>) -> Mat4<f32> {
  let mut t = Mat4::<f32>::identity();
  *t.mut_cr(3, 0) = v.x;
  *t.mut_cr(3, 1) = v.y;
  *t.mut_cr(3, 2) = v.z;
  m.mul_m(&t)
}

fn rot_x(m: Mat4<f32>, angle: f32) -> Mat4<f32> {
  let r = Mat3::from_angle_x(angle::rad(angle)).to_mat4();
  m.mul_m(&r)
}

fn rot_y(m: Mat4<f32>, angle: f32) -> Mat4<f32> {
  let r = Mat3::from_angle_y(angle::rad(angle)).to_mat4();
  m.mul_m(&r)
}

fn update_matrices(programId: GLuint) {
  let fov = angle::deg(45.0f32);
  let ratio = 4.0 / 3.0;
  let display_range_min = 0.1;
  let display_range_max = 100.0;
  let projection_matrix = projection::perspective(
    fov, ratio, display_range_min, display_range_max
  );

  let mut mvp_matrix = projection_matrix;
  unsafe {
    mvp_matrix = tr(mvp_matrix, Vec3{x: 0.0f32, y: 0.0, z: -10.0f32});
    mvp_matrix = rot_x(mvp_matrix, MOUSE_POS.y / 100.0);
    mvp_matrix = rot_y(mvp_matrix, MOUSE_POS.x / 100.0);
    mvp_matrix = tr(mvp_matrix, CAMERA_POS);
  }

  unsafe {
    // Get a handle for our "model_view_proj_matrix" uniform.
    // Only at initialisation time.
    let matrixId = gl::GetUniformLocation(
      programId, "model_view_proj_matrix".to_c_str().unwrap());

    // Send our transformation to the currently bound shader,
    // in the "model_view_proj_matrix" uniform.
    // For each model you render, since the model_view_proj_matrix
    // will be different (at least the M part).
    gl::UniformMatrix4fv(matrixId, 1, gl::FALSE, mvp_matrix.cr(0, 0));
  }
}

struct Win {
  vertex_shader: GLuint,
  fragment_shader: GLuint,
  program: GLuint,
  vertex_array_obj: GLuint,
  vertex_buffer_obj: GLuint,
  window: glfw::Window
}

impl Win {
  fn new() -> Win {
    // TODO: Move to opengl_init method
    // glfw::window_hint::context_version(3, 2);

    let mut win =  Win{
      vertex_shader: 0,
      fragment_shader: 0,
      program: 0,
      vertex_array_obj: 0,
      vertex_buffer_obj: 0,
      window: glfw::Window::create(
        WIN_SIZE.x,
        WIN_SIZE.y,
        "OpenGL",
        glfw::Windowed
      ).unwrap()
    };

    win.window.make_context_current();
    win.window.set_cursor_pos_callback(~CursorPosContext);
    win.window.set_key_callback(~KeyContext);

    // Load the OpenGL function pointers
    gl::load_with(glfw::get_proc_address);

    // Create GLSL shaders
    win.vertex_shader = compile_shader(
      VERTEX_SHADER_SRC, gl::VERTEX_SHADER);
    win.fragment_shader = compile_shader(
      FRAGMENT_SHADER_SRC, gl::FRAGMENT_SHADER);
    win.program = link_program(win.vertex_shader, win.fragment_shader);

    unsafe {
      // Create Vertex Array Object
      gl::GenVertexArrays(1, &mut win.vertex_array_obj);
      gl::BindVertexArray(win.vertex_array_obj);

      // Create a Vertex Buffer Object and copy the vertex data to it
      gl::GenBuffers(1, &mut win.vertex_buffer_obj);
      gl::BindBuffer(gl::ARRAY_BUFFER, win.vertex_buffer_obj);
      let float_size = std::mem::size_of::<GLfloat>();
      let vertices_ptr = (VERTEX_DATA.len() * float_size) as GLsizeiptr;
      gl::BufferData(
        gl::ARRAY_BUFFER,
        vertices_ptr,
        std::cast::transmute(&VERTEX_DATA[0]),
        gl::STATIC_DRAW
      );

      gl::UseProgram(win.program);
      gl::BindFragDataLocation(win.program, 0, "out_color".to_c_str().unwrap());

      // Specify the layout of the vertex data
      let pos_attr = gl::GetAttribLocation(
        win.program, "position".to_c_str().unwrap()) as GLuint;
      gl::EnableVertexAttribArray(pos_attr);
      let size = 3;
      let normalized = gl::FALSE as GLboolean;
      let stride = 0;
      gl::VertexAttribPointer(
        pos_attr,
        size,
        gl::FLOAT,
        normalized,
        stride,
        std::ptr::null()
      );
    }

    win
  }

  fn cleanup(&self) {
    // Cleanup
    gl::DeleteProgram(self.program);
    gl::DeleteShader(self.fragment_shader);
    gl::DeleteShader(self.vertex_shader);
    unsafe {
      gl::DeleteBuffers(1, &self.vertex_buffer_obj);
      gl::DeleteVertexArrays(1, &self.vertex_array_obj);
    }
  }

  fn draw(&self) {
    update_matrices(self.program);

    // Clear the screen to black
    gl::ClearColor(0.3, 0.3, 0.3, 1.0);
    gl::Clear(gl::COLOR_BUFFER_BIT);

    // Draw a triangle from the 3 vertices
    gl::DrawArrays(gl::TRIANGLES, 0, VERTICES_COUNT);

    self.window.swap_buffers();
  }

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

  fn process_events(&self) {
    glfw::poll_events();
  }
}

struct CursorPosContext;
impl glfw::CursorPosCallback for CursorPosContext {
  fn call(&self, w: &glfw::Window, xpos: f64, ypos: f64) {
    if w.get_mouse_button(glfw::MouseButtonRight) == glfw::Press {
      // println!("Cursor position: ({}, {})", xpos, ypos);
      unsafe {
        MOUSE_POS.x = xpos as f32;
        MOUSE_POS.y = ypos as f32;
      }
    }
  }
}

struct ErrorContext;
impl glfw::ErrorCallback for ErrorContext {
  fn call(&self, _: glfw::Error, description: ~str) {
    println!("GLFW Error: {:s}", description);
  }
}

struct KeyContext;
impl glfw::KeyCallback for KeyContext {
  fn call(
    &self,
    window: &glfw::Window,
    key:    glfw::Key,
    _:      std::libc::c_int,
    action: glfw::Action,
    _:      glfw::Modifiers
  ) {
    match (action, key) {
      (glfw::Press, glfw::KeyEscape) => {
        window.set_should_close(true)
      }
      (glfw::Press, glfw::KeySpace) => {
        println!("space")
      }
      (glfw::Press, glfw::KeyUp) => unsafe { CAMERA_POS.y -= 1.0f32 },
      (glfw::Press, glfw::KeyDown) => unsafe { CAMERA_POS.y += 1.0f32 },
      (glfw::Press, glfw::KeyRight) => unsafe { CAMERA_POS.x -= 1.0f32 },
      (glfw::Press, glfw::KeyLeft) => unsafe { CAMERA_POS.x += 1.0f32 },
      _ => {}
    }
  }
}

fn main() {
  glfw::set_error_callback(~ErrorContext);
  do glfw::start {
    let win =  Win::new();
    while win.is_running() {
      win.process_events();
      win.draw();
    }
    win.cleanup();
  }
}

#[start]
fn start(argc: int, argv: **u8) -> int {
  std::rt::start_on_main_thread(argc, argv, main)
}

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

// Marauder is grid-less turn-based strategy game.

extern mod glfw;
extern mod gl;
extern mod cgmath;

use gl::types::{
  GLenum,
  GLuint,
  GLint,
  GLchar,
  GLfloat,
  GLsizeiptr,
  GLboolean
};
use cgmath::matrix::{Matrix, Mat4, Mat3, ToMat4};
use cgmath::projection;
use cgmath::angle;
use cgmath::vector::{Vec3, Vec2};

#[link(name = "glfw")]
#[link(name = "m")]
extern {}

/// usage: let s = mvp_matrix; println(type_of(&s));
fn type_of<T>(_: &T) -> &'static str {
  unsafe {
    (*std::unstable::intrinsics::get_tydesc::<T>()).name
  }
}

fn print_mat4(name: &str, mat: Mat4<f32>) {
  println!("{}:", name);
  for i in range(0u, 4) {
    for j in range(0u, 4) {
      print!("{} ", *mat.cr(i, j));
    }
    println("");
  }
  println("");
}

static mut MOUSE_POS: Vec2<f32> = Vec2{x: 0.0f32, y: 0.0};
static mut CAMERA_POS: Vec3<f32> = Vec3{x: 0.0f32, y: 0.0, z: 0.0};

static WIN_SIZE: Vec2<uint> = Vec2{x: 640, y: 480};
static VERTICES_COUNT: i32 = 3 * 2;

static VERTEX_DATA: [GLfloat, ..VERTICES_COUNT * 3] = [
   0.0,  1.0, 0.0,
   2.0, -1.0, 0.0,
  -2.0, -1.0, 0.0,

  0.0,  1.0,  0.0,
  0.0, -1.0,  2.0,
  0.0, -1.0, -2.0
];

static VERTEX_SHADER_SRC: &'static str = "
  #version 130
  in vec3 position;
  uniform mat4 model_view_proj_matrix;
  void main() {
    vec4 v = vec4(position, 1);
    gl_Position = model_view_proj_matrix * v;
  }
";

static FRAGMENT_SHADER_SRC: &'static str = "
  #version 130
  out vec4 out_color;
  void main() {
    out_color = vec4(1.0, 1.0, 1.0, 1.0);
  }
";

fn compile_shader(src: &str, ty: GLenum) -> GLuint {
  let shader = gl::CreateShader(ty);
  unsafe {
    // Attempt to compile the shader
    gl::ShaderSource(shader, 1, &src.to_c_str().unwrap(), std::ptr::null());
    gl::CompileShader(shader);

    // Get the compile status
    let mut status = gl::FALSE as GLint;
    gl::GetShaderiv(shader, gl::COMPILE_STATUS, &mut status);

    // Fail on error
    if status != (gl::TRUE as GLint) {
      let mut len = 0;
      gl::GetShaderiv(shader, gl::INFO_LOG_LENGTH, &mut len);
      // subtract 1 to skip the trailing null character
      let mut buf = std::vec::from_elem(len as uint - 1, 0u8);
      gl::GetShaderInfoLog(shader, len, std::ptr::mut_null(),
        std::vec::raw::to_mut_ptr(buf) as *mut GLchar
      );
      fail!("compile_shader(): " + std::str::raw::from_utf8(buf));
    }
  }
  shader
}

fn link_program(vertex_shader: GLuint, fragment_shader: GLuint) -> GLuint {
  let program = gl::CreateProgram();
  gl::AttachShader(program, vertex_shader);
  gl::AttachShader(program, fragment_shader);
  gl::LinkProgram(program);
  unsafe {
    // Get the link status
    let mut status = gl::FALSE as GLint;
    gl::GetProgramiv(program, gl::LINK_STATUS, &mut status);

    // Fail on error
    if status != (gl::TRUE as GLint) {
      let mut len: GLint = 0;
      gl::GetProgramiv(program, gl::INFO_LOG_LENGTH, &mut len);
      // subtract 1 to skip the trailing null character
      let mut buf = std::vec::from_elem(len as uint - 1, 0u8);
      gl::GetProgramInfoLog(program, len, std::ptr::mut_null(),
        std::vec::raw::to_mut_ptr(buf) as *mut GLchar
      );
      fail!("link_program(): " + std::str::raw::from_utf8(buf));
    }
  }
  program
}

fn tr(m: Mat4<f32>, v: Vec3<f32>) -> Mat4<f32> {
  let mut t = Mat4::<f32>::identity();
  *t.mut_cr(3, 0) = v.x;
  *t.mut_cr(3, 1) = v.y;
  *t.mut_cr(3, 2) = v.z;
  m.mul_m(&t)
}

fn rot_x(m: Mat4<f32>, angle: f32) -> Mat4<f32> {
  let r = Mat3::from_angle_x(angle::rad(angle)).to_mat4();
  m.mul_m(&r)
}

fn rot_y(m: Mat4<f32>, angle: f32) -> Mat4<f32> {
  let r = Mat3::from_angle_y(angle::rad(angle)).to_mat4();
  m.mul_m(&r)
}

struct Win {
  vertex_shader: GLuint,
  fragment_shader: GLuint,
  program: GLuint,
  vertex_array_obj: GLuint,
  vertex_buffer_obj: GLuint,
  matrixId: GLint, // TODO: _id
  window: glfw::Window
}

impl Win {
  fn new() -> Win {
    // TODO: Move to opengl_init method
    // glfw::window_hint::context_version(3, 2);

    let mut win =  Win{
      vertex_shader: 0,
      fragment_shader: 0,
      program: 0,
      vertex_array_obj: 0,
      vertex_buffer_obj: 0,
      matrixId: 0,
      window: glfw::Window::create(
        WIN_SIZE.x,
        WIN_SIZE.y,
        "OpenGL",
        glfw::Windowed
      ).unwrap()
    };

    win.window.make_context_current();
    win.window.set_cursor_pos_callback(~CursorPosContext);
    win.window.set_key_callback(~KeyContext);

    // Load the OpenGL function pointers
    gl::load_with(glfw::get_proc_address);

    // Create GLSL shaders
    win.vertex_shader = compile_shader(
      VERTEX_SHADER_SRC, gl::VERTEX_SHADER);
    win.fragment_shader = compile_shader(
      FRAGMENT_SHADER_SRC, gl::FRAGMENT_SHADER);
    win.program = link_program(win.vertex_shader, win.fragment_shader);

    unsafe {
      // Create Vertex Array Object
      gl::GenVertexArrays(1, &mut win.vertex_array_obj);
      gl::BindVertexArray(win.vertex_array_obj);

      // Create a Vertex Buffer Object and copy the vertex data to it
      gl::GenBuffers(1, &mut win.vertex_buffer_obj);
      gl::BindBuffer(gl::ARRAY_BUFFER, win.vertex_buffer_obj);
      let float_size = std::mem::size_of::<GLfloat>();
      let vertices_ptr = (VERTEX_DATA.len() * float_size) as GLsizeiptr;
      gl::BufferData(
        gl::ARRAY_BUFFER,
        vertices_ptr,
        std::cast::transmute(&VERTEX_DATA[0]),
        gl::STATIC_DRAW
      );

      gl::UseProgram(win.program);
      gl::BindFragDataLocation(win.program, 0, "out_color".to_c_str().unwrap());

      // Specify the layout of the vertex data
      let pos_attr = gl::GetAttribLocation(
        win.program, "position".to_c_str().unwrap()) as GLuint;
      gl::EnableVertexAttribArray(pos_attr);
      let size = 3;
      let normalized = gl::FALSE as GLboolean;
      let stride = 0;
      gl::VertexAttribPointer(
        pos_attr,
        size,
        gl::FLOAT,
        normalized,
        stride,
        std::ptr::null()
      );

      // Get a handle for our "model_view_proj_matrix" uniform.
      // Only at initialisation time.
      win.matrixId = gl::GetUniformLocation(
        win.program, "model_view_proj_matrix".to_c_str().unwrap()
      );
    }

    win
  }

  fn cleanup(&self) {
    // Cleanup
    gl::DeleteProgram(self.program);
    gl::DeleteShader(self.fragment_shader);
    gl::DeleteShader(self.vertex_shader);
    unsafe {
      gl::DeleteBuffers(1, &self.vertex_buffer_obj);
      gl::DeleteVertexArrays(1, &self.vertex_array_obj);
    }
  }

  fn update_matrices(&self) {
    let fov = angle::deg(45.0f32);
    let ratio = 4.0 / 3.0;
    let display_range_min = 0.1;
    let display_range_max = 100.0;
    let projection_matrix = projection::perspective(
      fov, ratio, display_range_min, display_range_max
    );

    let mut mvp_matrix = projection_matrix;
    unsafe {
      mvp_matrix = tr(mvp_matrix, Vec3{x: 0.0f32, y: 0.0, z: -10.0f32});
      mvp_matrix = rot_x(mvp_matrix, MOUSE_POS.y / 100.0);
      mvp_matrix = rot_y(mvp_matrix, MOUSE_POS.x / 100.0);
      mvp_matrix = tr(mvp_matrix, CAMERA_POS);
    }

    unsafe {
      // Send our transformation to the currently bound shader,
      // in the "model_view_proj_matrix" uniform.
      // For each model you render, since the model_view_proj_matrix
      // will be different (at least the M part).
      gl::UniformMatrix4fv(self.matrixId, 1, gl::FALSE, mvp_matrix.cr(0, 0));
    }
  }

  fn draw(&self) {
    self.update_matrices();

    // Clear the screen to black
    gl::ClearColor(0.3, 0.3, 0.3, 1.0);
    gl::Clear(gl::COLOR_BUFFER_BIT);

    // Draw a triangle from the 3 vertices
    gl::DrawArrays(gl::TRIANGLES, 0, VERTICES_COUNT);

    self.window.swap_buffers();
  }

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

  fn process_events(&self) {
    glfw::poll_events();
  }
}

struct CursorPosContext;
impl glfw::CursorPosCallback for CursorPosContext {
  fn call(&self, w: &glfw::Window, xpos: f64, ypos: f64) {
    if w.get_mouse_button(glfw::MouseButtonRight) == glfw::Press {
      // println!("Cursor position: ({}, {})", xpos, ypos);
      unsafe {
        MOUSE_POS.x = xpos as f32;
        MOUSE_POS.y = ypos as f32;
      }
    }
  }
}

struct ErrorContext;
impl glfw::ErrorCallback for ErrorContext {
  fn call(&self, _: glfw::Error, description: ~str) {
    println!("GLFW Error: {:s}", description);
  }
}

struct KeyContext;
impl glfw::KeyCallback for KeyContext {
  fn call(
    &self,
    window: &glfw::Window,
    key:    glfw::Key,
    _:      std::libc::c_int,
    action: glfw::Action,
    _:      glfw::Modifiers
  ) {
    match (action, key) {
      (glfw::Press, glfw::KeyEscape) => {
        window.set_should_close(true)
      }
      (glfw::Press, glfw::KeySpace) => {
        println!("space")
      }
      (glfw::Press, glfw::KeyUp) => unsafe { CAMERA_POS.y -= 1.0f32 },
      (glfw::Press, glfw::KeyDown) => unsafe { CAMERA_POS.y += 1.0f32 },
      (glfw::Press, glfw::KeyRight) => unsafe { CAMERA_POS.x -= 1.0f32 },
      (glfw::Press, glfw::KeyLeft) => unsafe { CAMERA_POS.x += 1.0f32 },
      _ => {}
    }
  }
}

fn main() {
  glfw::set_error_callback(~ErrorContext);
  do glfw::start {
    let win =  Win::new();
    while win.is_running() {
      win.process_events();
      win.draw();
    }
    win.cleanup();
  }
}

#[start]
fn start(argc: int, argv: **u8) -> int {
  std::rt::start_on_main_thread(argc, argv, main)
}

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


<commit_before>use std::io::Timer;
use grid_builder::build_from_file_contents;

use std::io::Reader;
use std::io::{File, result};
use std::io::buffered::BufferedReader;
use std::path::Path;
use std::os;
mod grid_builder;
mod grid;

fn main() {
  let args = os::args();
  assert_eq!(2, args.len());

  let arg_vec = args.iter()
    .skip(1)  // Skip program's name.
    .take(1)
    .to_owned_vec(); // I don't know if this is the best way in rust.

  let filename = arg_vec.head(); // It won't let me chain head() (idk why YET!)
  println!("Opening file {:s}", filename.as_slice());

  let path = &Path::new(filename.as_slice());
  let mut reader = BufferedReader::new(File::open(path));
  let line = reader.read_line();

  // todo: understand why to_owned() is necessary here
  // also, is it really smart that lines() returns newlines? why?
  let lines: ~[~str] = reader.lines()
      .map(|x| x.trim().to_owned())
      .collect();

  let grid_from_file = grid_builder::build_from_file_contents(lines);
  grid_from_file.print();

  let mut next = grid_from_file;
  let mut timer = Timer::new().unwrap();

  loop {
    timer.sleep(1000);
    next = grid_builder::build_from_grid(&next);
    println!("");
    next.print();
    println!("");
  }
}
<commit_msg>Handled error to create timer.<commit_after>use std::io::Timer;
use grid_builder::build_from_file_contents;

use std::io::Reader;
use std::io::{File, result};
use std::io::buffered::BufferedReader;
use std::path::Path;
use std::os;
mod grid_builder;
mod grid;

fn main() {
  let args = os::args();
  assert_eq!(2, args.len());

  let arg_vec = args.iter()
    .skip(1)  // Skip program's name.
    .take(1)
    .to_owned_vec(); // I don't know if this is the best way in rust.

  let filename = arg_vec.head(); // It won't let me chain head() (idk why YET!)
  println!("Opening file {:s}", filename.as_slice());

  let path = &Path::new(filename.as_slice());
  let mut reader = BufferedReader::new(File::open(path));
  let line = reader.read_line();

  // todo: understand why to_owned() is necessary here
  // also, is it really smart that lines() returns newlines? why?
  let lines: ~[~str] = reader.lines()
      .map(|x| x.trim().to_owned())
      .collect();

  let grid_from_file = grid_builder::build_from_file_contents(lines);
  grid_from_file.print();

  let mut timer = match Timer::new() {
    Some(t) => t,
    None() => fail!("Error creating timer.")
  };
  let mut next = grid_from_file;

  loop {
    timer.sleep(1000);
    next = grid_builder::build_from_grid(&next);
    println!("");
    next.print();
    println!("");
  }
}
<|endoftext|>


<commit_before>/*
 * Geometry minization of a molecule of water
 */
extern crate cymbalum;
use cymbalum::*;

fn main() {
    Logger::stdout();
    let mut universe = Universe::new();

    let alpha = units::from(50.0, "deg").unwrap();

    universe.add_particle(Particle::new("O"));
    universe[0].set_position(Vector3D::new(0.0, 0.0, 0.0));
    universe.add_particle(Particle::new("H"));
    universe[1].set_position(Vector3D::new(1.2*f64::cos(alpha), 1.2*f64::sin(alpha), 0.0));
    universe.add_particle(Particle::new("H"));
    universe[2].set_position(Vector3D::new(1.2*f64::cos(-alpha), 1.2*f64::sin(-alpha), 0.0));

    {
        let topology = universe.topology_mut();
        topology.add_bond(0, 1);
        topology.add_bond(0, 2);
    }

    universe.add_pair_interaction("O", "H", NullPotential);
    universe.add_pair_interaction("O", "O", NullPotential);
    universe.add_pair_interaction("H", "H", NullPotential);

    universe.add_bond_interaction("O", "H", Harmonic{
        x0: units::from(1.1, "A").unwrap(),
        k: units::from(100.0, "kJ/mol/A^2").unwrap(),
    });
    universe.add_angle_interaction("H", "O", "H", Harmonic{
        x0: units::from(109.0, "deg").unwrap(),
        k: units::from(30.0, "kJ/mol/deg").unwrap(),
    });

    let mut simulation = Simulation::new(GradientDescent::new());
    simulation.add_output(EnergyOutput::new("energy.dat").unwrap());
    simulation.run(&mut universe, 500);
}
<commit_msg>Use the Universe::add_bond function in example<commit_after>/*
 * Geometry minization of a molecule of water
 */
extern crate cymbalum;
use cymbalum::*;

fn main() {
    Logger::stdout();
    let mut universe = Universe::new();

    let alpha = units::from(50.0, "deg").unwrap();

    universe.add_particle(Particle::new("O"));
    universe[0].set_position(Vector3D::new(0.0, 0.0, 0.0));
    universe.add_particle(Particle::new("H"));
    universe[1].set_position(Vector3D::new(1.2*f64::cos(alpha), 1.2*f64::sin(alpha), 0.0));
    universe.add_particle(Particle::new("H"));
    universe[2].set_position(Vector3D::new(1.2*f64::cos(-alpha), 1.2*f64::sin(-alpha), 0.0));

    universe.add_bond(0, 1);
    universe.add_bond(0, 2);

    universe.add_pair_interaction("O", "H", NullPotential);
    universe.add_pair_interaction("O", "O", NullPotential);
    universe.add_pair_interaction("H", "H", NullPotential);

    universe.add_bond_interaction("O", "H", Harmonic{
        x0: units::from(1.1, "A").unwrap(),
        k: units::from(100.0, "kJ/mol/A^2").unwrap(),
    });
    universe.add_angle_interaction("H", "O", "H", Harmonic{
        x0: units::from(109.0, "deg").unwrap(),
        k: units::from(30.0, "kJ/mol/deg").unwrap(),
    });

    let mut simulation = Simulation::new(GradientDescent::new());
    simulation.add_output(EnergyOutput::new("energy.dat").unwrap());
    simulation.run(&mut universe, 500);
}
<|endoftext|>


<commit_before>//! Least squares

use crate::{error::*, layout::MatrixLayout};
use cauchy::*;
use num_traits::Zero;

/// Result of LeastSquares
pub struct LeastSquaresOutput<A: Scalar> {
    /// singular values
    pub singular_values: Vec<A::Real>,
    /// The rank of the input matrix A
    pub rank: i32,
}

/// Wraps `*gelsd`
pub trait LeastSquaresSvdDivideConquer_: Scalar {
    unsafe fn least_squares(
        a_layout: MatrixLayout,
        a: &mut [Self],
        b: &mut [Self],
    ) -> Result<LeastSquaresOutput<Self>>;

    unsafe fn least_squares_nrhs(
        a_layout: MatrixLayout,
        a: &mut [Self],
        b_layout: MatrixLayout,
        b: &mut [Self],
    ) -> Result<LeastSquaresOutput<Self>>;
}

macro_rules! impl_least_squares {
    ($scalar:ty, $gelsd:path) => {
        impl LeastSquaresSvdDivideConquer_ for $scalar {
            unsafe fn least_squares(
                a_layout: MatrixLayout,
                a: &mut [Self],
                b: &mut [Self],
            ) -> Result<LeastSquaresOutput<Self>> {
                let (m, n) = a_layout.size();
                if (m as usize) > b.len() || (n as usize) > b.len() {
                    return Err(Error::InvalidShape);
                }
                let k = ::std::cmp::min(m, n);
                let nrhs = 1;
                let rcond: Self::Real = -1.;
                let mut singular_values: Vec<Self::Real> = vec![Self::Real::zero(); k as usize];
                let mut rank: i32 = 0;

                $gelsd(
                    a_layout.lapacke_layout(),
                    m,
                    n,
                    nrhs,
                    a,
                    a_layout.lda(),
                    b,
                    // this is the 'leading dimension of b', in the case where
                    // b is a single vector, this is 1
                    nrhs,
                    &mut singular_values,
                    rcond,
                    &mut rank,
                )
                .as_lapack_result()?;

                Ok(LeastSquaresOutput {
                    singular_values,
                    rank,
                })
            }

            unsafe fn least_squares_nrhs(
                a_layout: MatrixLayout,
                a: &mut [Self],
                b_layout: MatrixLayout,
                b: &mut [Self],
            ) -> Result<LeastSquaresOutput<Self>> {
                let (m, n) = a_layout.size();
                if (m as usize) > b.len()
                    || (n as usize) > b.len()
                    || a_layout.lapacke_layout() != b_layout.lapacke_layout()
                {
                    return Err(Error::InvalidShape);
                }
                let k = ::std::cmp::min(m, n);
                let nrhs = b_layout.size().1;
                let rcond: Self::Real = -1.;
                let mut singular_values: Vec<Self::Real> = vec![Self::Real::zero(); k as usize];
                let mut rank: i32 = 0;

                $gelsd(
                    a_layout.lapacke_layout(),
                    m,
                    n,
                    nrhs,
                    a,
                    a_layout.lda(),
                    b,
                    b_layout.lda(),
                    &mut singular_values,
                    rcond,
                    &mut rank,
                )
                .as_lapack_result()?;
                Ok(LeastSquaresOutput {
                    singular_values,
                    rank,
                })
            }
        }
    };
}

impl_least_squares!(f64, lapacke::dgelsd);
impl_least_squares!(f32, lapacke::sgelsd);
impl_least_squares!(c64, lapacke::zgelsd);
impl_least_squares!(c32, lapacke::cgelsd);
<commit_msg>Fix F-contiguous case<commit_after>//! Least squares

use crate::{error::*, layout::MatrixLayout};
use cauchy::*;
use num_traits::Zero;

/// Result of LeastSquares
pub struct LeastSquaresOutput<A: Scalar> {
    /// singular values
    pub singular_values: Vec<A::Real>,
    /// The rank of the input matrix A
    pub rank: i32,
}

/// Wraps `*gelsd`
pub trait LeastSquaresSvdDivideConquer_: Scalar {
    unsafe fn least_squares(
        a_layout: MatrixLayout,
        a: &mut [Self],
        b: &mut [Self],
    ) -> Result<LeastSquaresOutput<Self>>;

    unsafe fn least_squares_nrhs(
        a_layout: MatrixLayout,
        a: &mut [Self],
        b_layout: MatrixLayout,
        b: &mut [Self],
    ) -> Result<LeastSquaresOutput<Self>>;
}

macro_rules! impl_least_squares {
    ($scalar:ty, $gelsd:path) => {
        impl LeastSquaresSvdDivideConquer_ for $scalar {
            unsafe fn least_squares(
                a_layout: MatrixLayout,
                a: &mut [Self],
                b: &mut [Self],
            ) -> Result<LeastSquaresOutput<Self>> {
                let (m, n) = a_layout.size();
                if (m as usize) > b.len() || (n as usize) > b.len() {
                    return Err(Error::InvalidShape);
                }
                let k = ::std::cmp::min(m, n);
                let nrhs = 1;
                let ldb = match a_layout {
                    MatrixLayout::F { .. } => m.max(n),
                    MatrixLayout::C { .. } => 1,
                };
                let rcond: Self::Real = -1.;
                let mut singular_values: Vec<Self::Real> = vec![Self::Real::zero(); k as usize];
                let mut rank: i32 = 0;

                $gelsd(
                    a_layout.lapacke_layout(),
                    m,
                    n,
                    nrhs,
                    a,
                    a_layout.lda(),
                    b,
                    ldb,
                    &mut singular_values,
                    rcond,
                    &mut rank,
                )
                .as_lapack_result()?;

                Ok(LeastSquaresOutput {
                    singular_values,
                    rank,
                })
            }

            unsafe fn least_squares_nrhs(
                a_layout: MatrixLayout,
                a: &mut [Self],
                b_layout: MatrixLayout,
                b: &mut [Self],
            ) -> Result<LeastSquaresOutput<Self>> {
                let (m, n) = a_layout.size();
                if (m as usize) > b.len()
                    || (n as usize) > b.len()
                    || a_layout.lapacke_layout() != b_layout.lapacke_layout()
                {
                    return Err(Error::InvalidShape);
                }
                let k = ::std::cmp::min(m, n);
                let nrhs = b_layout.size().1;
                let rcond: Self::Real = -1.;
                let mut singular_values: Vec<Self::Real> = vec![Self::Real::zero(); k as usize];
                let mut rank: i32 = 0;

                $gelsd(
                    a_layout.lapacke_layout(),
                    m,
                    n,
                    nrhs,
                    a,
                    a_layout.lda(),
                    b,
                    b_layout.lda(),
                    &mut singular_values,
                    rcond,
                    &mut rank,
                )
                .as_lapack_result()?;
                Ok(LeastSquaresOutput {
                    singular_values,
                    rank,
                })
            }
        }
    };
}

impl_least_squares!(f64, lapacke::dgelsd);
impl_least_squares!(f32, lapacke::sgelsd);
impl_least_squares!(c64, lapacke::zgelsd);
impl_least_squares!(c32, lapacke::cgelsd);
<|endoftext|>


<commit_before>//! Test runner.
//!
//! This module implements the `TestRunner` struct which manages executing tests as well as
//! scanning directories for tests.

use std::ffi::OsStr;
use std::path::{Path, PathBuf};
use std::error::Error;
use std::mem;
use std::borrow::{Borrow, Cow};
use std::panic::catch_unwind;
use std::time;
use CommandResult;
use utils::read_to_string;
use cton_reader::parse_test;
use cretonne::ir::Function;
use cretonne::verify_function;
use filetest::subtest::{self, SubTest, Context};

type TestResult = Result<time::Duration, String>;

#[derive(PartialEq, Eq, Debug)]
enum QueueEntry {
    New(PathBuf),
    Running,
    Done(PathBuf, TestResult),
}

pub struct TestRunner {
    // Directories that have not yet been scanned.
    dir_stack: Vec<PathBuf>,

    // Filenames of tests to run.
    tests: Vec<QueueEntry>,

    // Pointer into `tests` where the `New` entries begin.
    new_tests: usize,

    // Number of contiguous finished tests at the front of `tests`.
    finished_tests: usize,

    errors: usize,
}

impl TestRunner {
    /// Create a new blank TrstRunner.
    pub fn new() -> TestRunner {
        TestRunner {
            dir_stack: Vec::new(),
            tests: Vec::new(),
            new_tests: 0,
            finished_tests: 0,
            errors: 0,
        }
    }

    /// Add a directory path to be scanned later.
    ///
    /// If `dir` turns out to be a regular file, it is silently ignored.
    /// Otherwise, any problems reading the directory are reported.
    pub fn push_dir<P: Into<PathBuf>>(&mut self, dir: P) {
        self.dir_stack.push(dir.into());
    }

    /// Add a test to be executed later.
    ///
    /// Any problems reading `file` as a test case file will be reported as a test failure.
    pub fn push_test<P: Into<PathBuf>>(&mut self, file: P) {
        self.tests.push(QueueEntry::New(file.into()));
    }

    /// Take a new test for running as a job.
    /// Leaves the queue entry marked as `Runnning`.
    fn take_job(&mut self) -> Option<Job> {
        let index = self.new_tests;
        if index == self.tests.len() {
            return None;
        }
        self.new_tests += 1;

        let entry = mem::replace(&mut self.tests[index], QueueEntry::Running);
        if let QueueEntry::New(path) = entry {
            Some(Job::new(index, path))
        } else {
            // Oh, sorry about that. Put the entry back.
            self.tests[index] = entry;
            None
        }
    }

    /// Report the end of a job.
    fn finish_job(&mut self, job: Job, result: TestResult) {
        assert_eq!(self.tests[job.index], QueueEntry::Running);
        if let Err(ref e) = result {
            self.job_error(&job.path, e);
        }
        self.tests[job.index] = QueueEntry::Done(job.path, result);
        if job.index == self.finished_tests {
            while let Some(&QueueEntry::Done(_, _)) = self.tests.get(self.finished_tests) {
                self.finished_tests += 1;
            }
        }
    }

    /// Scan any directories pushed so far.
    /// Push any potential test cases found.
    pub fn scan_dirs(&mut self) {
        // This recursive search tries to minimize statting in a directory hierarchy containing
        // mostly test cases.
        //
        // - Directory entries with a "cton" extension are presumed to be test case files.
        // - Directory entries with no extension are presumed to be subdirectories.
        // - Anything else is ignored.
        //
        while let Some(dir) = self.dir_stack.pop() {
            match dir.read_dir() {
                Err(err) => {
                    // Fail silently if `dir` was actually a regular file.
                    // This lets us skip spurious extensionless files without statting everything
                    // needlessly.
                    if !dir.is_file() {
                        self.path_error(dir, err);
                    }
                }
                Ok(entries) => {
                    // Read all directory entries. Avoid statting.
                    for entry_result in entries {
                        match entry_result {
                            Err(err) => {
                                // Not sure why this would happen. `read_dir` succeeds, but there's
                                // a problem with an entry. I/O error during a getdirentries
                                // syscall seems to be the reason. The implementation in
                                // libstd/sys/unix/fs.rs seems to suggest that breaking now would
                                // be a good idea, or the iterator could keep returning the same
                                // error forever.
                                self.path_error(dir, err);
                                break;
                            }
                            Ok(entry) => {
                                let path = entry.path();
                                // Recognize directories and tests by extension.
                                // Yes, this means we ignore directories with '.' in their name.
                                match path.extension().and_then(OsStr::to_str) {
                                    Some("cton") => self.push_test(path),
                                    Some(_) => {}
                                    None => self.push_dir(path),
                                }
                            }
                        }
                    }
                }
            }
            // Get the new jobs running before moving on to the next directory.
            self.schedule_jobs();
        }
    }

    /// Report an error related to a path.
    fn path_error<E: Error>(&mut self, path: PathBuf, err: E) {
        self.errors += 1;
        println!("{}: {}", path.to_string_lossy(), err);
    }

    /// Report an error related to a job.
    fn job_error(&mut self, path: &Path, err: &str) {
        self.errors += 1;
        println!("FAIL {}: {}", path.to_string_lossy(), err);
    }

    /// Schedule and new jobs to run.
    fn schedule_jobs(&mut self) {
        while let Some(job) = self.take_job() {
            let result = job.run();
            self.finish_job(job, result);
        }
    }

    /// Scan pushed directories for tests and run them.
    pub fn run(&mut self) -> CommandResult {
        self.scan_dirs();
        self.schedule_jobs();
        match self.errors {
            0 => Ok(()),
            1 => Err("1 failure".to_string()),
            n => Err(format!("{} failures", n)),
        }
    }
}

/// A test file waiting to be run.
struct Job {
    index: usize,
    path: PathBuf,
}

impl Job {
    pub fn new(index: usize, path: PathBuf) -> Job {
        Job {
            index: index,
            path: path,
        }
    }

    pub fn run(&self) -> TestResult {
        match catch_unwind(|| self.run_or_panic()) {
            Err(msg) => Err(format!("panic: {:?}", msg)),
            Ok(result) => result,
        }
    }

    fn run_or_panic(&self) -> TestResult {
        let started = time::Instant::now();
        let buffer = try!(read_to_string(&self.path).map_err(|e| e.to_string()));
        let testfile = try!(parse_test(&buffer).map_err(|e| e.to_string()));
        if testfile.functions.is_empty() {
            return Err("no functions found".to_string());
        }
        // Parse the test commands.
        let mut tests =
            try!(testfile.commands.iter().map(subtest::new).collect::<subtest::Result<Vec<_>>>());

        // Sort the tests so the mutators are at the end, and those that
        // don't need the verifier are at the front
        tests.sort_by_key(|st| (st.is_mutating(), st.needs_verifier()));

        // Isolate the last test in the hope that this is the only mutating test.
        // If so, we can completely avoid cloning functions.
        let last_test = match tests.pop() {
            None => return Err("no test commands found".to_string()),
            Some(t) => t,
        };

        for (func, details) in testfile.functions {
            let mut context = subtest::Context {
                details: details,
                verified: false,
            };

            for test in &tests {
                try!(self.run_one_test(test.borrow(), Cow::Borrowed(&func), &mut context));
            }
            // Run the last test with an owned function which means it won't need to clone it
            // before mutating.
            try!(self.run_one_test(last_test.borrow(), Cow::Owned(func), &mut context));
        }

        // TODO: Actually run the tests.
        Ok(started.elapsed())
    }

    fn run_one_test(&self,
                    test: &SubTest,
                    func: Cow<Function>,
                    context: &mut Context)
                    -> subtest::Result<()> {
        let name = format!("{}({})", test.name(), func.name);

        // Should we run the verifier before this test?
        if !context.verified && test.needs_verifier() {
            try!(verify_function(&func));
            context.verified = true;
        }

        test.run(func, context).map_err(|e| format!("{}: {}", name, e))
    }
}
<commit_msg>Print the number of tests run.<commit_after>//! Test runner.
//!
//! This module implements the `TestRunner` struct which manages executing tests as well as
//! scanning directories for tests.

use std::ffi::OsStr;
use std::path::{Path, PathBuf};
use std::error::Error;
use std::mem;
use std::borrow::{Borrow, Cow};
use std::panic::catch_unwind;
use std::time;
use CommandResult;
use utils::read_to_string;
use cton_reader::parse_test;
use cretonne::ir::Function;
use cretonne::verify_function;
use filetest::subtest::{self, SubTest, Context};

type TestResult = Result<time::Duration, String>;

#[derive(PartialEq, Eq, Debug)]
enum QueueEntry {
    New(PathBuf),
    Running,
    Done(PathBuf, TestResult),
}

pub struct TestRunner {
    // Directories that have not yet been scanned.
    dir_stack: Vec<PathBuf>,

    // Filenames of tests to run.
    tests: Vec<QueueEntry>,

    // Pointer into `tests` where the `New` entries begin.
    new_tests: usize,

    // Number of contiguous finished tests at the front of `tests`.
    finished_tests: usize,

    errors: usize,
}

impl TestRunner {
    /// Create a new blank TrstRunner.
    pub fn new() -> TestRunner {
        TestRunner {
            dir_stack: Vec::new(),
            tests: Vec::new(),
            new_tests: 0,
            finished_tests: 0,
            errors: 0,
        }
    }

    /// Add a directory path to be scanned later.
    ///
    /// If `dir` turns out to be a regular file, it is silently ignored.
    /// Otherwise, any problems reading the directory are reported.
    pub fn push_dir<P: Into<PathBuf>>(&mut self, dir: P) {
        self.dir_stack.push(dir.into());
    }

    /// Add a test to be executed later.
    ///
    /// Any problems reading `file` as a test case file will be reported as a test failure.
    pub fn push_test<P: Into<PathBuf>>(&mut self, file: P) {
        self.tests.push(QueueEntry::New(file.into()));
    }

    /// Take a new test for running as a job.
    /// Leaves the queue entry marked as `Runnning`.
    fn take_job(&mut self) -> Option<Job> {
        let index = self.new_tests;
        if index == self.tests.len() {
            return None;
        }
        self.new_tests += 1;

        let entry = mem::replace(&mut self.tests[index], QueueEntry::Running);
        if let QueueEntry::New(path) = entry {
            Some(Job::new(index, path))
        } else {
            // Oh, sorry about that. Put the entry back.
            self.tests[index] = entry;
            None
        }
    }

    /// Report the end of a job.
    fn finish_job(&mut self, job: Job, result: TestResult) {
        assert_eq!(self.tests[job.index], QueueEntry::Running);
        if let Err(ref e) = result {
            self.job_error(&job.path, e);
        }
        self.tests[job.index] = QueueEntry::Done(job.path, result);
        if job.index == self.finished_tests {
            while let Some(&QueueEntry::Done(_, _)) = self.tests.get(self.finished_tests) {
                self.finished_tests += 1;
            }
        }
    }

    /// Scan any directories pushed so far.
    /// Push any potential test cases found.
    pub fn scan_dirs(&mut self) {
        // This recursive search tries to minimize statting in a directory hierarchy containing
        // mostly test cases.
        //
        // - Directory entries with a "cton" extension are presumed to be test case files.
        // - Directory entries with no extension are presumed to be subdirectories.
        // - Anything else is ignored.
        //
        while let Some(dir) = self.dir_stack.pop() {
            match dir.read_dir() {
                Err(err) => {
                    // Fail silently if `dir` was actually a regular file.
                    // This lets us skip spurious extensionless files without statting everything
                    // needlessly.
                    if !dir.is_file() {
                        self.path_error(dir, err);
                    }
                }
                Ok(entries) => {
                    // Read all directory entries. Avoid statting.
                    for entry_result in entries {
                        match entry_result {
                            Err(err) => {
                                // Not sure why this would happen. `read_dir` succeeds, but there's
                                // a problem with an entry. I/O error during a getdirentries
                                // syscall seems to be the reason. The implementation in
                                // libstd/sys/unix/fs.rs seems to suggest that breaking now would
                                // be a good idea, or the iterator could keep returning the same
                                // error forever.
                                self.path_error(dir, err);
                                break;
                            }
                            Ok(entry) => {
                                let path = entry.path();
                                // Recognize directories and tests by extension.
                                // Yes, this means we ignore directories with '.' in their name.
                                match path.extension().and_then(OsStr::to_str) {
                                    Some("cton") => self.push_test(path),
                                    Some(_) => {}
                                    None => self.push_dir(path),
                                }
                            }
                        }
                    }
                }
            }
            // Get the new jobs running before moving on to the next directory.
            self.schedule_jobs();
        }
    }

    /// Report an error related to a path.
    fn path_error<E: Error>(&mut self, path: PathBuf, err: E) {
        self.errors += 1;
        println!("{}: {}", path.to_string_lossy(), err);
    }

    /// Report an error related to a job.
    fn job_error(&mut self, path: &Path, err: &str) {
        self.errors += 1;
        println!("FAIL {}: {}", path.to_string_lossy(), err);
    }

    /// Schedule and new jobs to run.
    fn schedule_jobs(&mut self) {
        while let Some(job) = self.take_job() {
            let result = job.run();
            self.finish_job(job, result);
        }
    }

    /// Scan pushed directories for tests and run them.
    pub fn run(&mut self) -> CommandResult {
        self.scan_dirs();
        self.schedule_jobs();
        println!("{} tests", self.tests.len());
        match self.errors {
            0 => Ok(()),
            1 => Err("1 failure".to_string()),
            n => Err(format!("{} failures", n)),
        }
    }
}

/// A test file waiting to be run.
struct Job {
    index: usize,
    path: PathBuf,
}

impl Job {
    pub fn new(index: usize, path: PathBuf) -> Job {
        Job {
            index: index,
            path: path,
        }
    }

    pub fn run(&self) -> TestResult {
        match catch_unwind(|| self.run_or_panic()) {
            Err(msg) => Err(format!("panic: {:?}", msg)),
            Ok(result) => result,
        }
    }

    fn run_or_panic(&self) -> TestResult {
        let started = time::Instant::now();
        let buffer = try!(read_to_string(&self.path).map_err(|e| e.to_string()));
        let testfile = try!(parse_test(&buffer).map_err(|e| e.to_string()));
        if testfile.functions.is_empty() {
            return Err("no functions found".to_string());
        }
        // Parse the test commands.
        let mut tests =
            try!(testfile.commands.iter().map(subtest::new).collect::<subtest::Result<Vec<_>>>());

        // Sort the tests so the mutators are at the end, and those that
        // don't need the verifier are at the front
        tests.sort_by_key(|st| (st.is_mutating(), st.needs_verifier()));

        // Isolate the last test in the hope that this is the only mutating test.
        // If so, we can completely avoid cloning functions.
        let last_test = match tests.pop() {
            None => return Err("no test commands found".to_string()),
            Some(t) => t,
        };

        for (func, details) in testfile.functions {
            let mut context = subtest::Context {
                details: details,
                verified: false,
            };

            for test in &tests {
                try!(self.run_one_test(test.borrow(), Cow::Borrowed(&func), &mut context));
            }
            // Run the last test with an owned function which means it won't need to clone it
            // before mutating.
            try!(self.run_one_test(last_test.borrow(), Cow::Owned(func), &mut context));
        }

        // TODO: Actually run the tests.
        Ok(started.elapsed())
    }

    fn run_one_test(&self,
                    test: &SubTest,
                    func: Cow<Function>,
                    context: &mut Context)
                    -> subtest::Result<()> {
        let name = format!("{}({})", test.name(), func.name);

        // Should we run the verifier before this test?
        if !context.verified && test.needs_verifier() {
            try!(verify_function(&func));
            context.verified = true;
        }

        test.run(func, context).map_err(|e| format!("{}: {}", name, e))
    }
}
<|endoftext|>