<commit_before>extern crate nalgebra;
extern crate num;

use cube::*;
use math::FromDomain;
use num::{One, Zero};

pub struct Cursor {
    origin: Point3,
    width: LogWidth,
    span: Vector3,
}

impl Cursor {
    pub fn at_cube<C: Spatial>(cube: &C) -> Self {
        Cursor {
            origin: cube.partition().origin().clone(),
            width: cube.partition().width(),
            span: Vector3::zero(),
        }
    }

    pub fn at_cube_with_span<C: Spatial>(cube: &C, span: &Vector3) -> Self {
        let mut cursor = Cursor::at_cube(cube);
        cursor.span = span.clone();
        cursor
    }

    pub fn at_point(point: &Point3, width: LogWidth) -> Self {
        let partition = Partition::at_point(point, width);
        Cursor {
            origin: partition.origin().clone(),
            width: partition.width(),
            span: Vector3::zero(),
        }
    }

    pub fn at_point_with_span(point: &Point3, width: LogWidth, span: &Vector3) -> Self {
        let mut cursor = Cursor::at_point(point, width);
        cursor.span = span.clone();
        cursor
    }

    pub fn origin(&self) -> &Point3 {
        &self.origin
    }

    pub fn width(&self) -> LogWidth {
        self.width
    }

    pub fn span(&self) -> &Vector3 {
        &self.span
    }

    pub fn span_mut(&mut self) -> &mut Vector3 {
        &mut self.span
    }

    pub fn extent(&self) -> Vector3 {
        ((self.span + Vector3::one()) * exp(self.width)) - Vector3::one()
    }

    pub fn aabb(&self) -> AABB {
        AABB::new(self.origin, self.extent())
    }
}

#[cfg(test)]
mod tests {
    use super::*;
}
<commit_msg>Remove unneeded import.<commit_after>extern crate nalgebra;
extern crate num;

use cube::*;
use num::{One, Zero};

pub struct Cursor {
    origin: Point3,
    width: LogWidth,
    span: Vector3,
}

impl Cursor {
    pub fn at_cube<C: Spatial>(cube: &C) -> Self {
        Cursor {
            origin: cube.partition().origin().clone(),
            width: cube.partition().width(),
            span: Vector3::zero(),
        }
    }

    pub fn at_cube_with_span<C: Spatial>(cube: &C, span: &Vector3) -> Self {
        let mut cursor = Cursor::at_cube(cube);
        cursor.span = span.clone();
        cursor
    }

    pub fn at_point(point: &Point3, width: LogWidth) -> Self {
        let partition = Partition::at_point(point, width);
        Cursor {
            origin: partition.origin().clone(),
            width: partition.width(),
            span: Vector3::zero(),
        }
    }

    pub fn at_point_with_span(point: &Point3, width: LogWidth, span: &Vector3) -> Self {
        let mut cursor = Cursor::at_point(point, width);
        cursor.span = span.clone();
        cursor
    }

    pub fn origin(&self) -> &Point3 {
        &self.origin
    }

    pub fn width(&self) -> LogWidth {
        self.width
    }

    pub fn span(&self) -> &Vector3 {
        &self.span
    }

    pub fn span_mut(&mut self) -> &mut Vector3 {
        &mut self.span
    }

    pub fn extent(&self) -> Vector3 {
        ((self.span + Vector3::one()) * exp(self.width)) - Vector3::one()
    }

    pub fn aabb(&self) -> AABB {
        AABB::new(self.origin, self.extent())
    }
}

#[cfg(test)]
mod tests {
    use super::*;
}
<|endoftext|>


<commit_before>// -*-  indent-tabs-mode:nil; tab-width:2;  -*-
use std::convert::From;
use std::fmt::Debug;
use std::fmt::Display;
use std::fmt::Error;
use std::fmt::Formatter;
use std::marker::PhantomData;
use std::ops;
use std::rc::Rc;
use super::Buffer;
use super::TensorType;

#[derive(Ord,PartialOrd,Eq,PartialEq,Debug)]
pub enum OpLevel {
  Add,
  Mul,
  Unary,
  Atom,
}

////////////////////////

#[derive(Debug)]
pub struct Expr<T: TensorType> {
  expr: Rc<ExprImpl<T>>,
}

impl<T: TensorType> Display for Expr<T> {
  fn fmt(&self, f: &mut Formatter) -> Result<(), Error> {
    Display::fmt(&self.expr, f)
  }
}

impl<T: TensorType> From<T> for Expr<T> {
  fn from(value: T) -> Self {
    Expr {
      expr: Rc::new(value),
    }
  }
}

////////////////////////

pub trait ExprImpl<T: TensorType>: Display + Debug {
  fn op_level(&self) -> OpLevel;
}

impl<T: TensorType> ExprImpl<T> for T {
  fn op_level(&self) -> OpLevel {
    OpLevel::Atom
  }
}

////////////////////////

macro_rules! impl_bin_op {
  ($name:ident, $fn_name:ident, $op:expr, $op_level:ident, $assoc:expr) => {
    #[derive(Debug)]
    pub struct $name<T: TensorType> {
      left: Expr<T>,
      right: Expr<T>,
    }

    impl<T: TensorType> ops::$name for Expr<T> {
      type Output = Expr<T>;

      fn $fn_name(self, rhs: Expr<T>) -> Expr<T> {
        Expr {
          expr: Rc::new($name {
            left: self,
            right: rhs,
          }),
        }
      }
    }

    impl<T: TensorType> ops::$name<T> for Expr<T> {
      type Output = Expr<T>;

      fn $fn_name(self, rhs: T) -> Expr<T> {
        Expr {
          expr: Rc::new($name {
            left: self,
            right: Expr::from(rhs),
          }),
        }
      }
    }

    impl<T: TensorType> Display for $name<T> {
      fn fmt(&self, f: &mut Formatter) -> Result<(), Error> {
        if self.left.expr.op_level() < OpLevel::$op_level {
          try!(write!(f, "({})", self.left));
        } else {
          try!(write!(f, "{}", self.left));
        }
        try!(write!(f, concat!(" ", $op, " ")));
        let paren = if $assoc {
          self.right.expr.op_level() < OpLevel::$op_level
        } else {
          self.right.expr.op_level() <= OpLevel::$op_level
        };
        if paren {
          write!(f, "({})", self.right)
        } else {
          write!(f, "{}", self.right)
        }
      }
    }

    impl<T: TensorType> ExprImpl<T> for $name<T> {
      fn op_level(&self) -> OpLevel {
        OpLevel::$op_level
      }
    }
  }
}

impl_bin_op!(Add, add, "+", Add, true);
impl_bin_op!(Sub, sub, "-", Add, false);
impl_bin_op!(Mul, mul, "*", Mul, true);
impl_bin_op!(Div, div, "/", Mul, false);
impl_bin_op!(Rem, rem, "%", Mul, false);

////////////////////////

#[derive(Debug)]
pub struct Neg<T: TensorType> {
  expr: Expr<T>,
}

impl<T: TensorType> ops::Neg for Expr<T> {
  type Output = Expr<T>;

  fn neg(self) -> Expr<T> {
    Expr {
      expr: Rc::new(Neg {
        expr: self,
      }),
    }
  }
}

impl<T: TensorType> Display for Neg<T> {
  fn fmt(&self, f: &mut Formatter) -> Result<(), Error> {
    try!(write!(f, "-"));
    if self.expr.expr.op_level() <= OpLevel::Unary {
      write!(f, "({})", self.expr)
    } else {
      write!(f, "{}", self.expr)
    }
  }
}

impl<T: TensorType> ExprImpl<T> for Neg<T> {
  fn op_level(&self) -> OpLevel {
    OpLevel::Unary
  }
}

////////////////////////

#[derive(Debug)]
pub struct Variable<T: TensorType> {
  initial_value: Buffer<T>,
  shape: Vec<u64>,
  name: String,
}

impl<T: TensorType> Variable<T> {
  pub fn new(initial_value: Buffer<T>, shape: &[u64], name: &str) -> Self {
    Variable {
      initial_value: initial_value,
      shape: Vec::from(shape),
      name: name.to_string(),
    }
  }
}

impl<T: TensorType> Display for Variable<T> {
  fn fmt(&self, f: &mut Formatter) -> Result<(), Error> {
    write!(f, "{}", self.name)
  }
}

impl<T: TensorType> ExprImpl<T> for Variable<T> {
  fn op_level(&self) -> OpLevel {
    OpLevel::Atom
  }
}

////////////////////////

#[derive(Debug)]
pub struct Placeholder<T: TensorType> {
  shape: Vec<u64>,
  name: String,
  phantom: PhantomData<T>,
}

impl<T: TensorType> Placeholder<T> {
  pub fn new(shape: &[u64], name: &str) -> Self {
    Placeholder {
      shape: Vec::from(shape),
      name: name.to_string(),
      phantom: PhantomData,
    }
  }
}

impl<T: TensorType> Display for Placeholder<T> {
  fn fmt(&self, f: &mut Formatter) -> Result<(), Error> {
    write!(f, "{}", self.name)
  }
}

impl<T: TensorType> ExprImpl<T> for Placeholder<T> {
  fn op_level(&self) -> OpLevel {
    OpLevel::Atom
  }
}

////////////////////////

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

  #[test]
  fn test_display() {
    assert_eq!("1 + 2 + 3", format!("{}", (Expr::from(1) + 2) + 3));
    assert_eq!("1 + 2 + 3", format!("{}", Expr::from(1) + (Expr::from(2) + 3)));
    assert_eq!("1 + 2 - 3", format!("{}", (Expr::from(1) + 2) - 3));
    assert_eq!("1 - (2 + 3)", format!("{}", Expr::from(1) - (Expr::from(2) + 3)));

    assert_eq!("(1 + 2) * 3", format!("{}", (Expr::from(1) + 2) * 3));
    assert_eq!("1 * (2 + 3)", format!("{}", Expr::from(1) * (Expr::from(2) + 3)));
    assert_eq!("1 * 2 * 3", format!("{}", (Expr::from(1) * 2) * 3));
    assert_eq!("1 * 2 * 3", format!("{}", Expr::from(1) * (Expr::from(2) * 3)));

    assert_eq!("(1 + 2) / 3", format!("{}", (Expr::from(1) + 2) / 3));
    assert_eq!("1 / (2 + 3)", format!("{}", Expr::from(1) / (Expr::from(2) + 3)));
    assert_eq!("1 * 2 / 3", format!("{}", (Expr::from(1) * 2) / 3));
    assert_eq!("1 / (2 * 3)", format!("{}", Expr::from(1) / (Expr::from(2) * 3)));

    assert_eq!("(1 + 2) % 3", format!("{}", (Expr::from(1) + 2) % 3));
    assert_eq!("1 % (2 + 3)", format!("{}", Expr::from(1) % (Expr::from(2) + 3)));
    assert_eq!("1 * 2 % 3", format!("{}", (Expr::from(1) * 2) % 3));
    assert_eq!("1 % (2 * 3)", format!("{}", Expr::from(1) % (Expr::from(2) * 3)));

    assert_eq!("-1", format!("{}", -Expr::from(1)));
    assert_eq!("-(-1)", format!("{}", -(-Expr::from(1))));
    assert_eq!("-(1 + 2)", format!("{}", -(Expr::from(1) + 2)));

    let buf = Buffer::new(6);
    assert_eq!("x", format!("{}", <Variable<f32>>::new(buf, &vec![2, 3], "x")));

    assert_eq!("x", format!("{}", <Placeholder<f32>>::new(&vec![2, 3], "x")));
  }
}
<commit_msg>Add basic docs for expr module<commit_after>// -*-  indent-tabs-mode:nil; tab-width:2;  -*-
//! This module builds computation graphs.
//!
//! This module is unfinished.

use std::convert::From;
use std::fmt::Debug;
use std::fmt::Display;
use std::fmt::Error;
use std::fmt::Formatter;
use std::marker::PhantomData;
use std::ops;
use std::rc::Rc;
use super::Buffer;
use super::TensorType;

/// Denotes operator precedence.
/// Used for displaying expressions as strings.
#[derive(Ord,PartialOrd,Eq,PartialEq,Debug)]
pub enum OpLevel {
  Add,
  Mul,
  Unary,
  Atom,
}

////////////////////////

/// A node in an expression tree, which is a thin wrapper around an ExprImpl.
///
/// This is separate from ExprImpl because we want expressions to be wrapped in an Rc,
/// and we can't directly implement std::ops::Add, etc., for Rc<E: ExprImpl<T>>.
#[derive(Debug)]
pub struct Expr<T: TensorType> {
  expr: Rc<ExprImpl<T>>,
}

impl<T: TensorType> Display for Expr<T> {
  fn fmt(&self, f: &mut Formatter) -> Result<(), Error> {
    Display::fmt(&self.expr, f)
  }
}

impl<T: TensorType> From<T> for Expr<T> {
  fn from(value: T) -> Self {
    Expr {
      expr: Rc::new(value),
    }
  }
}

////////////////////////

/// Trait implemented by all expression types.
/// Most users will want to store an Expr instead.
pub trait ExprImpl<T: TensorType>: Display + Debug {
  /// Returns the precedence level for this operator.
  fn op_level(&self) -> OpLevel;
}

impl<T: TensorType> ExprImpl<T> for T {
  fn op_level(&self) -> OpLevel {
    OpLevel::Atom
  }
}

////////////////////////

macro_rules! impl_bin_op {
  ($name:ident, $fn_name:ident, $op:expr, $op_level:ident, $assoc:expr, $doc:expr) => {
    #[doc = $doc]
    #[derive(Debug)]
    pub struct $name<T: TensorType> {
      left: Expr<T>,
      right: Expr<T>,
    }

    impl<T: TensorType> ops::$name for Expr<T> {
      type Output = Expr<T>;

      fn $fn_name(self, rhs: Expr<T>) -> Expr<T> {
        Expr {
          expr: Rc::new($name {
            left: self,
            right: rhs,
          }),
        }
      }
    }

    impl<T: TensorType> ops::$name<T> for Expr<T> {
      type Output = Expr<T>;

      fn $fn_name(self, rhs: T) -> Expr<T> {
        Expr {
          expr: Rc::new($name {
            left: self,
            right: Expr::from(rhs),
          }),
        }
      }
    }

    impl<T: TensorType> Display for $name<T> {
      fn fmt(&self, f: &mut Formatter) -> Result<(), Error> {
        if self.left.expr.op_level() < OpLevel::$op_level {
          try!(write!(f, "({})", self.left));
        } else {
          try!(write!(f, "{}", self.left));
        }
        try!(write!(f, concat!(" ", $op, " ")));
        let paren = if $assoc {
          self.right.expr.op_level() < OpLevel::$op_level
        } else {
          self.right.expr.op_level() <= OpLevel::$op_level
        };
        if paren {
          write!(f, "({})", self.right)
        } else {
          write!(f, "{}", self.right)
        }
      }
    }

    impl<T: TensorType> ExprImpl<T> for $name<T> {
      fn op_level(&self) -> OpLevel {
        OpLevel::$op_level
      }
    }
  }
}

impl_bin_op!(Add, add, "+", Add, true, "Expression resulting from adding two subexpressions.");
impl_bin_op!(Sub, sub, "-", Add, false, "Expression resulting from subtracting two subexpressions.");
impl_bin_op!(Mul, mul, "*", Mul, true, "Expression resulting from multiplying two subexpressions.");
impl_bin_op!(Div, div, "/", Mul, false, "Expression resulting from dividing two subexpressions.");
impl_bin_op!(Rem, rem, "%", Mul, false, "Expression resulting from taking a modulus.");

////////////////////////

/// Expression resulting from negation of an expression.
#[derive(Debug)]
pub struct Neg<T: TensorType> {
  expr: Expr<T>,
}

impl<T: TensorType> ops::Neg for Expr<T> {
  type Output = Expr<T>;

  fn neg(self) -> Expr<T> {
    Expr {
      expr: Rc::new(Neg {
        expr: self,
      }),
    }
  }
}

impl<T: TensorType> Display for Neg<T> {
  fn fmt(&self, f: &mut Formatter) -> Result<(), Error> {
    try!(write!(f, "-"));
    if self.expr.expr.op_level() <= OpLevel::Unary {
      write!(f, "({})", self.expr)
    } else {
      write!(f, "{}", self.expr)
    }
  }
}

impl<T: TensorType> ExprImpl<T> for Neg<T> {
  fn op_level(&self) -> OpLevel {
    OpLevel::Unary
  }
}

////////////////////////

/// Expression for a variable.
#[derive(Debug)]
pub struct Variable<T: TensorType> {
  initial_value: Buffer<T>,
  shape: Vec<u64>,
  name: String,
}

impl<T: TensorType> Variable<T> {
  pub fn new(initial_value: Buffer<T>, shape: &[u64], name: &str) -> Self {
    Variable {
      initial_value: initial_value,
      shape: Vec::from(shape),
      name: name.to_string(),
    }
  }
}

impl<T: TensorType> Display for Variable<T> {
  fn fmt(&self, f: &mut Formatter) -> Result<(), Error> {
    write!(f, "{}", self.name)
  }
}

impl<T: TensorType> ExprImpl<T> for Variable<T> {
  fn op_level(&self) -> OpLevel {
    OpLevel::Atom
  }
}

////////////////////////

/// Expression for a placeholder.
#[derive(Debug)]
pub struct Placeholder<T: TensorType> {
  shape: Vec<u64>,
  name: String,
  phantom: PhantomData<T>,
}

impl<T: TensorType> Placeholder<T> {
  pub fn new(shape: &[u64], name: &str) -> Self {
    Placeholder {
      shape: Vec::from(shape),
      name: name.to_string(),
      phantom: PhantomData,
    }
  }
}

impl<T: TensorType> Display for Placeholder<T> {
  fn fmt(&self, f: &mut Formatter) -> Result<(), Error> {
    write!(f, "{}", self.name)
  }
}

impl<T: TensorType> ExprImpl<T> for Placeholder<T> {
  fn op_level(&self) -> OpLevel {
    OpLevel::Atom
  }
}

////////////////////////

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

  #[test]
  fn test_display() {
    assert_eq!("1 + 2 + 3", format!("{}", (Expr::from(1) + 2) + 3));
    assert_eq!("1 + 2 + 3", format!("{}", Expr::from(1) + (Expr::from(2) + 3)));
    assert_eq!("1 + 2 - 3", format!("{}", (Expr::from(1) + 2) - 3));
    assert_eq!("1 - (2 + 3)", format!("{}", Expr::from(1) - (Expr::from(2) + 3)));

    assert_eq!("(1 + 2) * 3", format!("{}", (Expr::from(1) + 2) * 3));
    assert_eq!("1 * (2 + 3)", format!("{}", Expr::from(1) * (Expr::from(2) + 3)));
    assert_eq!("1 * 2 * 3", format!("{}", (Expr::from(1) * 2) * 3));
    assert_eq!("1 * 2 * 3", format!("{}", Expr::from(1) * (Expr::from(2) * 3)));

    assert_eq!("(1 + 2) / 3", format!("{}", (Expr::from(1) + 2) / 3));
    assert_eq!("1 / (2 + 3)", format!("{}", Expr::from(1) / (Expr::from(2) + 3)));
    assert_eq!("1 * 2 / 3", format!("{}", (Expr::from(1) * 2) / 3));
    assert_eq!("1 / (2 * 3)", format!("{}", Expr::from(1) / (Expr::from(2) * 3)));

    assert_eq!("(1 + 2) % 3", format!("{}", (Expr::from(1) + 2) % 3));
    assert_eq!("1 % (2 + 3)", format!("{}", Expr::from(1) % (Expr::from(2) + 3)));
    assert_eq!("1 * 2 % 3", format!("{}", (Expr::from(1) * 2) % 3));
    assert_eq!("1 % (2 * 3)", format!("{}", Expr::from(1) % (Expr::from(2) * 3)));

    assert_eq!("-1", format!("{}", -Expr::from(1)));
    assert_eq!("-(-1)", format!("{}", -(-Expr::from(1))));
    assert_eq!("-(1 + 2)", format!("{}", -(Expr::from(1) + 2)));

    let buf = Buffer::new(6);
    assert_eq!("x", format!("{}", <Variable<f32>>::new(buf, &vec![2, 3], "x")));

    assert_eq!("x", format!("{}", <Placeholder<f32>>::new(&vec![2, 3], "x")));
  }
}
<|endoftext|>


<commit_before>use super::*;

ast_struct! {
    /// A complete file of Rust source code.
    ///
    /// *This type is available only if Syn is built with the `"full"` feature.*
    ///
    /// # Example
    ///
    /// Parse a Rust source file into a `syn::File` and print out a debug
    /// representation of the syntax tree.
    ///
    /// ```
    /// use std::env;
    /// use std::fs::File;
    /// use std::io::Read;
    /// use std::process;
    ///
    /// fn main() {
    /// # }
    /// #
    /// # fn fake_main() {
    ///     let mut args = env::args();
    ///     let _ = args.next(); // executable name
    ///
    ///     let filename = match (args.next(), args.next()) {
    ///         (Some(filename), None) => filename,
    ///         _ => {
    ///             eprintln!("Usage: dump-syntax path/to/filename.rs");
    ///             process::exit(1);
    ///         }
    ///     };
    ///
    ///     let mut file = File::open(&filename).expect("Unable to open file");
    ///
    ///     let mut src = String::new();
    ///     file.read_to_string(&mut src).expect("Unable to read file");
    ///
    ///     let syntax = syn::parse_file(&src).expect("Unable to parse file");
    ///
    ///     // Debug impl is available if Syn is built with "extra-traits" feature.
    ///     println!("{:#?}", syntax);
    /// }
    /// ```
    ///
    /// Running with its own source code as input, this program prints output
    /// that begins with:
    ///
    /// ```text
    /// File {
    ///     shebang: None,
    ///     attrs: [],
    ///     items: [
    ///         ExternCrate(
    ///             ItemExternCrate {
    ///                 attrs: [],
    ///                 vis: Inherited,
    ///                 extern_token: Extern,
    ///                 crate_token: Crate,
    ///                 ident: Ident {
    ///                     term: Term(
    ///                         "syn"
    ///                     ),
    ///                     span: Span
    ///                 },
    ///                 rename: None,
    ///                 semi_token: Semi
    ///             }
    ///         ),
    /// ...
    /// ```
    #[cfg_attr(doc_cfg, doc(cfg(feature = "full")))]
    pub struct File {
        pub shebang: Option<String>,
        pub attrs: Vec<Attribute>,
        pub items: Vec<Item>,
    }
}

#[cfg(feature = "parsing")]
pub mod parsing {
    use super::*;
    use crate::parse::{Parse, ParseStream, Result};

    #[cfg_attr(doc_cfg, doc(cfg(feature = "parsing")))]
    impl Parse for File {
        fn parse(input: ParseStream) -> Result<Self> {
            Ok(File {
                shebang: None,
                attrs: input.call(Attribute::parse_inner)?,
                items: {
                    let mut items = Vec::new();
                    while !input.is_empty() {
                        items.push(input.parse()?);
                    }
                    items
                },
            })
        }
    }
}

#[cfg(feature = "printing")]
mod printing {
    use super::*;
    use crate::attr::FilterAttrs;
    use proc_macro2::TokenStream;
    use quote::{ToTokens, TokenStreamExt};

    #[cfg_attr(doc_cfg, doc(cfg(feature = "printing")))]
    impl ToTokens for File {
        fn to_tokens(&self, tokens: &mut TokenStream) {
            tokens.append_all(self.attrs.inner());
            tokens.append_all(&self.items);
        }
    }
}
<commit_msg>update `File` example program output<commit_after>use super::*;

ast_struct! {
    /// A complete file of Rust source code.
    ///
    /// *This type is available only if Syn is built with the `"full"` feature.*
    ///
    /// # Example
    ///
    /// Parse a Rust source file into a `syn::File` and print out a debug
    /// representation of the syntax tree.
    ///
    /// ```
    /// use std::env;
    /// use std::fs::File;
    /// use std::io::Read;
    /// use std::process;
    ///
    /// fn main() {
    /// # }
    /// #
    /// # fn fake_main() {
    ///     let mut args = env::args();
    ///     let _ = args.next(); // executable name
    ///
    ///     let filename = match (args.next(), args.next()) {
    ///         (Some(filename), None) => filename,
    ///         _ => {
    ///             eprintln!("Usage: dump-syntax path/to/filename.rs");
    ///             process::exit(1);
    ///         }
    ///     };
    ///
    ///     let mut file = File::open(&filename).expect("Unable to open file");
    ///
    ///     let mut src = String::new();
    ///     file.read_to_string(&mut src).expect("Unable to read file");
    ///
    ///     let syntax = syn::parse_file(&src).expect("Unable to parse file");
    ///
    ///     // Debug impl is available if Syn is built with "extra-traits" feature.
    ///     println!("{:#?}", syntax);
    /// }
    /// ```
    ///
    /// Running with its own source code as input, this program prints output
    /// that begins with:
    ///
    /// ```text
    /// File {
    ///     shebang: None,
    ///     attrs: [],
    ///     items: [
    ///         Use(
    ///             ItemUse {
    ///                 attrs: [],
    ///                 vis: Inherited,
    ///                 use_token: Use,
    ///                 leading_colon: None,
    ///                 tree: Path(
    ///                     UsePath {
    ///                         ident: Ident(
    ///                             std,
    ///                         ),
    ///                         colon2_token: Colon2,
    ///                         tree: Name(
    ///                             UseName {
    ///                                 ident: Ident(
    ///                                     env,
    ///                                 ),
    ///                             },
    ///                         ),
    ///                     },
    ///                 ),
    ///                 semi_token: Semi,
    ///             },
    ///         ),
    /// ...
    /// ```
    #[cfg_attr(doc_cfg, doc(cfg(feature = "full")))]
    pub struct File {
        pub shebang: Option<String>,
        pub attrs: Vec<Attribute>,
        pub items: Vec<Item>,
    }
}

#[cfg(feature = "parsing")]
pub mod parsing {
    use super::*;
    use crate::parse::{Parse, ParseStream, Result};

    #[cfg_attr(doc_cfg, doc(cfg(feature = "parsing")))]
    impl Parse for File {
        fn parse(input: ParseStream) -> Result<Self> {
            Ok(File {
                shebang: None,
                attrs: input.call(Attribute::parse_inner)?,
                items: {
                    let mut items = Vec::new();
                    while !input.is_empty() {
                        items.push(input.parse()?);
                    }
                    items
                },
            })
        }
    }
}

#[cfg(feature = "printing")]
mod printing {
    use super::*;
    use crate::attr::FilterAttrs;
    use proc_macro2::TokenStream;
    use quote::{ToTokens, TokenStreamExt};

    #[cfg_attr(doc_cfg, doc(cfg(feature = "printing")))]
    impl ToTokens for File {
        fn to_tokens(&self, tokens: &mut TokenStream) {
            tokens.append_all(self.attrs.inner());
            tokens.append_all(&self.items);
        }
    }
}
<|endoftext|>


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

use super::signature_sets::{Error as SignatureSetError, Result as SignatureSetResult, *};
use crate::common::get_indexed_attestation;
use crate::per_block_processing::errors::{AttestationInvalid, BlockOperationError};
use bls::{verify_signature_sets, PublicKey, SignatureSet};
use rayon::prelude::*;
use std::borrow::Cow;
use types::{
    BeaconState, BeaconStateError, ChainSpec, EthSpec, Hash256, IndexedAttestation,
    SignedBeaconBlock,
};

pub type Result<T> = std::result::Result<T, Error>;

#[derive(Debug, PartialEq)]
pub enum Error {
    /// All public keys were found but signature verification failed. The block is invalid.
    SignatureInvalid,
    /// An attestation in the block was invalid. The block is invalid.
    AttestationValidationError(BlockOperationError<AttestationInvalid>),
    /// There was an error attempting to read from a `BeaconState`. Block
    /// validity was not determined.
    BeaconStateError(BeaconStateError),
    /// The `BeaconBlock` has a `proposer_index` that does not match the index we computed locally.
    ///
    /// The block is invalid.
    IncorrectBlockProposer { block: u64, local_shuffling: u64 },
    /// Failed to load a signature set. The block may be invalid or we failed to process it.
    SignatureSetError(SignatureSetError),
}

impl From<BeaconStateError> for Error {
    fn from(e: BeaconStateError) -> Error {
        Error::BeaconStateError(e)
    }
}

impl From<SignatureSetError> for Error {
    fn from(e: SignatureSetError) -> Error {
        match e {
            // Make a special distinction for `IncorrectBlockProposer` since it indicates an
            // invalid block, not an internal error.
            SignatureSetError::IncorrectBlockProposer {
                block,
                local_shuffling,
            } => Error::IncorrectBlockProposer {
                block,
                local_shuffling,
            },
            e => Error::SignatureSetError(e),
        }
    }
}

impl From<BlockOperationError<AttestationInvalid>> for Error {
    fn from(e: BlockOperationError<AttestationInvalid>) -> Error {
        Error::AttestationValidationError(e)
    }
}

/// Reads the BLS signatures and keys from a `SignedBeaconBlock`, storing them as a `Vec<SignatureSet>`.
///
/// This allows for optimizations related to batch BLS operations (see the
/// `Self::verify_entire_block(..)` function).
pub struct BlockSignatureVerifier<'a, T, F>
where
    T: EthSpec,
    F: Fn(usize) -> Option<Cow<'a, PublicKey>> + Clone,
{
    get_pubkey: F,
    state: &'a BeaconState<T>,
    spec: &'a ChainSpec,
    sets: Vec<SignatureSet<'a>>,
}

impl<'a, T, F> BlockSignatureVerifier<'a, T, F>
where
    T: EthSpec,
    F: Fn(usize) -> Option<Cow<'a, PublicKey>> + Clone,
{
    /// Create a new verifier without any included signatures. See the `include...` functions to
    /// add signatures, and the `verify`
    pub fn new(state: &'a BeaconState<T>, get_pubkey: F, spec: &'a ChainSpec) -> Self {
        Self {
            get_pubkey,
            state,
            spec,
            sets: vec![],
        }
    }

    /// Verify all* the signatures in the given `SignedBeaconBlock`, returning `Ok(())` if the signatures
    /// are valid.
    ///
    /// * : _Does not verify any signatures in `block.body.deposits`. A block is still valid if it
    /// contains invalid signatures on deposits._
    ///
    /// See `Self::verify` for more detail.
    pub fn verify_entire_block(
        state: &'a BeaconState<T>,
        get_pubkey: F,
        block: &'a SignedBeaconBlock<T>,
        block_root: Option<Hash256>,
        spec: &'a ChainSpec,
    ) -> Result<()> {
        let mut verifier = Self::new(state, get_pubkey, spec);
        verifier.include_all_signatures(block, block_root)?;
        verifier.verify()
    }

    /// Verify all* the signatures that have been included in `self`, returning `Ok(())` if the
    /// signatures are all valid.
    ///
    /// ## Notes
    ///
    /// Signature validation will take place in accordance to the [Faster verification of multiple
    /// BLS signatures](https://ethresear.ch/t/fast-verification-of-multiple-bls-signatures/5407)
    /// optimization proposed by Vitalik Buterin.
    ///
    /// It is not possible to know exactly _which_ signature is invalid here, just that
    /// _at least one_ was invalid.
    ///
    /// Uses `rayon` to do a map-reduce of Vitalik's method across multiple cores.
    pub fn verify(self) -> Result<()> {
        let num_sets = self.sets.len();
        let num_chunks = std::cmp::max(1, num_sets / rayon::current_num_threads());
        let result: bool = self
            .sets
            .into_par_iter()
            .chunks(num_chunks)
            .map(|chunk| verify_signature_sets(chunk.iter()))
            .reduce(|| true, |current, this| current && this);

        if result {
            Ok(())
        } else {
            Err(Error::SignatureInvalid)
        }
    }

    /// Includes all signatures on the block (except the deposit signatures) for verification.
    pub fn include_all_signatures(
        &mut self,
        block: &'a SignedBeaconBlock<T>,
        block_root: Option<Hash256>,
    ) -> Result<()> {
        self.include_block_proposal(block, block_root)?;
        self.include_randao_reveal(block)?;
        self.include_proposer_slashings(block)?;
        self.include_attester_slashings(block)?;
        self.include_attestations(block)?;
        // Deposits are not included because they can legally have invalid signatures.
        self.include_exits(block)?;

        Ok(())
    }

    /// Includes all signatures on the block (except the deposit signatures and the proposal
    /// signature) for verification.
    pub fn include_all_signatures_except_proposal(
        &mut self,
        block: &'a SignedBeaconBlock<T>,
    ) -> Result<()> {
        self.include_randao_reveal(block)?;
        self.include_proposer_slashings(block)?;
        self.include_attester_slashings(block)?;
        self.include_attestations(block)?;
        // Deposits are not included because they can legally have invalid signatures.
        self.include_exits(block)?;

        Ok(())
    }

    /// Includes the block signature for `self.block` for verification.
    pub fn include_block_proposal(
        &mut self,
        block: &'a SignedBeaconBlock<T>,
        block_root: Option<Hash256>,
    ) -> Result<()> {
        let set = block_proposal_signature_set(
            self.state,
            self.get_pubkey.clone(),
            block,
            block_root,
            self.spec,
        )?;
        self.sets.push(set);
        Ok(())
    }

    /// Includes the randao signature for `self.block` for verification.
    pub fn include_randao_reveal(&mut self, block: &'a SignedBeaconBlock<T>) -> Result<()> {
        let set = randao_signature_set(
            self.state,
            self.get_pubkey.clone(),
            &block.message,
            self.spec,
        )?;
        self.sets.push(set);
        Ok(())
    }

    /// Includes all signatures in `self.block.body.proposer_slashings` for verification.
    pub fn include_proposer_slashings(&mut self, block: &'a SignedBeaconBlock<T>) -> Result<()> {
        let mut sets: Vec<SignatureSet> = block
            .message
            .body
            .proposer_slashings
            .iter()
            .map(|proposer_slashing| {
                let (set_1, set_2) = proposer_slashing_signature_set(
                    self.state,
                    self.get_pubkey.clone(),
                    proposer_slashing,
                    self.spec,
                )?;
                Ok(vec![set_1, set_2])
            })
            .collect::<SignatureSetResult<Vec<Vec<SignatureSet>>>>()?
            .into_iter()
            .flatten()
            .collect();

        self.sets.append(&mut sets);
        Ok(())
    }

    /// Includes all signatures in `self.block.body.attester_slashings` for verification.
    pub fn include_attester_slashings(&mut self, block: &'a SignedBeaconBlock<T>) -> Result<()> {
        block
            .message
            .body
            .attester_slashings
            .iter()
            .try_for_each(|attester_slashing| {
                let (set_1, set_2) = attester_slashing_signature_sets(
                    &self.state,
                    self.get_pubkey.clone(),
                    attester_slashing,
                    &self.spec,
                )?;

                self.sets.push(set_1);
                self.sets.push(set_2);

                Ok(())
            })
    }

    /// Includes all signatures in `self.block.body.attestations` for verification.
    pub fn include_attestations(
        &mut self,
        block: &'a SignedBeaconBlock<T>,
    ) -> Result<Vec<IndexedAttestation<T>>> {
        block
            .message
            .body
            .attestations
            .iter()
            .map(|attestation| {
                let committee = self
                    .state
                    .get_beacon_committee(attestation.data.slot, attestation.data.index)?;
                let indexed_attestation =
                    get_indexed_attestation(committee.committee, attestation)?;

                self.sets.push(indexed_attestation_signature_set(
                    &self.state,
                    self.get_pubkey.clone(),
                    &attestation.signature,
                    &indexed_attestation,
                    &self.spec,
                )?);

                Ok(indexed_attestation)
            })
            .collect::<Result<_>>()
            .map_err(Into::into)
    }

    /// Includes all signatures in `self.block.body.voluntary_exits` for verification.
    pub fn include_exits(&mut self, block: &'a SignedBeaconBlock<T>) -> Result<()> {
        let mut sets = block
            .message
            .body
            .voluntary_exits
            .iter()
            .map(|exit| exit_signature_set(&self.state, self.get_pubkey.clone(), exit, &self.spec))
            .collect::<SignatureSetResult<_>>()?;

        self.sets.append(&mut sets);

        Ok(())
    }
}
<commit_msg>Avoid some allocations in BlockSignatureVerifier (#1922)<commit_after>#![allow(clippy::integer_arithmetic)]

use super::signature_sets::{Error as SignatureSetError, *};
use crate::common::get_indexed_attestation;
use crate::per_block_processing::errors::{AttestationInvalid, BlockOperationError};
use bls::{verify_signature_sets, PublicKey, SignatureSet};
use rayon::prelude::*;
use std::borrow::Cow;
use types::{
    BeaconState, BeaconStateError, ChainSpec, EthSpec, Hash256, IndexedAttestation,
    SignedBeaconBlock,
};

pub type Result<T> = std::result::Result<T, Error>;

#[derive(Debug, PartialEq)]
pub enum Error {
    /// All public keys were found but signature verification failed. The block is invalid.
    SignatureInvalid,
    /// An attestation in the block was invalid. The block is invalid.
    AttestationValidationError(BlockOperationError<AttestationInvalid>),
    /// There was an error attempting to read from a `BeaconState`. Block
    /// validity was not determined.
    BeaconStateError(BeaconStateError),
    /// The `BeaconBlock` has a `proposer_index` that does not match the index we computed locally.
    ///
    /// The block is invalid.
    IncorrectBlockProposer { block: u64, local_shuffling: u64 },
    /// Failed to load a signature set. The block may be invalid or we failed to process it.
    SignatureSetError(SignatureSetError),
}

impl From<BeaconStateError> for Error {
    fn from(e: BeaconStateError) -> Error {
        Error::BeaconStateError(e)
    }
}

impl From<SignatureSetError> for Error {
    fn from(e: SignatureSetError) -> Error {
        match e {
            // Make a special distinction for `IncorrectBlockProposer` since it indicates an
            // invalid block, not an internal error.
            SignatureSetError::IncorrectBlockProposer {
                block,
                local_shuffling,
            } => Error::IncorrectBlockProposer {
                block,
                local_shuffling,
            },
            e => Error::SignatureSetError(e),
        }
    }
}

impl From<BlockOperationError<AttestationInvalid>> for Error {
    fn from(e: BlockOperationError<AttestationInvalid>) -> Error {
        Error::AttestationValidationError(e)
    }
}

/// Reads the BLS signatures and keys from a `SignedBeaconBlock`, storing them as a `Vec<SignatureSet>`.
///
/// This allows for optimizations related to batch BLS operations (see the
/// `Self::verify_entire_block(..)` function).
pub struct BlockSignatureVerifier<'a, T, F>
where
    T: EthSpec,
    F: Fn(usize) -> Option<Cow<'a, PublicKey>> + Clone,
{
    get_pubkey: F,
    state: &'a BeaconState<T>,
    spec: &'a ChainSpec,
    sets: Vec<SignatureSet<'a>>,
}

impl<'a, T, F> BlockSignatureVerifier<'a, T, F>
where
    T: EthSpec,
    F: Fn(usize) -> Option<Cow<'a, PublicKey>> + Clone,
{
    /// Create a new verifier without any included signatures. See the `include...` functions to
    /// add signatures, and the `verify`
    pub fn new(state: &'a BeaconState<T>, get_pubkey: F, spec: &'a ChainSpec) -> Self {
        Self {
            get_pubkey,
            state,
            spec,
            sets: vec![],
        }
    }

    /// Verify all* the signatures in the given `SignedBeaconBlock`, returning `Ok(())` if the signatures
    /// are valid.
    ///
    /// * : _Does not verify any signatures in `block.body.deposits`. A block is still valid if it
    /// contains invalid signatures on deposits._
    ///
    /// See `Self::verify` for more detail.
    pub fn verify_entire_block(
        state: &'a BeaconState<T>,
        get_pubkey: F,
        block: &'a SignedBeaconBlock<T>,
        block_root: Option<Hash256>,
        spec: &'a ChainSpec,
    ) -> Result<()> {
        let mut verifier = Self::new(state, get_pubkey, spec);
        verifier.include_all_signatures(block, block_root)?;
        verifier.verify()
    }

    /// Verify all* the signatures that have been included in `self`, returning `Ok(())` if the
    /// signatures are all valid.
    ///
    /// ## Notes
    ///
    /// Signature validation will take place in accordance to the [Faster verification of multiple
    /// BLS signatures](https://ethresear.ch/t/fast-verification-of-multiple-bls-signatures/5407)
    /// optimization proposed by Vitalik Buterin.
    ///
    /// It is not possible to know exactly _which_ signature is invalid here, just that
    /// _at least one_ was invalid.
    ///
    /// Uses `rayon` to do a map-reduce of Vitalik's method across multiple cores.
    pub fn verify(self) -> Result<()> {
        let num_sets = self.sets.len();
        let num_chunks = std::cmp::max(1, num_sets / rayon::current_num_threads());
        let result: bool = self
            .sets
            .into_par_iter()
            .chunks(num_chunks)
            .map(|chunk| verify_signature_sets(chunk.iter()))
            .reduce(|| true, |current, this| current && this);

        if result {
            Ok(())
        } else {
            Err(Error::SignatureInvalid)
        }
    }

    /// Includes all signatures on the block (except the deposit signatures) for verification.
    pub fn include_all_signatures(
        &mut self,
        block: &'a SignedBeaconBlock<T>,
        block_root: Option<Hash256>,
    ) -> Result<()> {
        self.include_block_proposal(block, block_root)?;
        self.include_randao_reveal(block)?;
        self.include_proposer_slashings(block)?;
        self.include_attester_slashings(block)?;
        self.include_attestations(block)?;
        // Deposits are not included because they can legally have invalid signatures.
        self.include_exits(block)?;

        Ok(())
    }

    /// Includes all signatures on the block (except the deposit signatures and the proposal
    /// signature) for verification.
    pub fn include_all_signatures_except_proposal(
        &mut self,
        block: &'a SignedBeaconBlock<T>,
    ) -> Result<()> {
        self.include_randao_reveal(block)?;
        self.include_proposer_slashings(block)?;
        self.include_attester_slashings(block)?;
        self.include_attestations(block)?;
        // Deposits are not included because they can legally have invalid signatures.
        self.include_exits(block)?;

        Ok(())
    }

    /// Includes the block signature for `self.block` for verification.
    pub fn include_block_proposal(
        &mut self,
        block: &'a SignedBeaconBlock<T>,
        block_root: Option<Hash256>,
    ) -> Result<()> {
        let set = block_proposal_signature_set(
            self.state,
            self.get_pubkey.clone(),
            block,
            block_root,
            self.spec,
        )?;
        self.sets.push(set);
        Ok(())
    }

    /// Includes the randao signature for `self.block` for verification.
    pub fn include_randao_reveal(&mut self, block: &'a SignedBeaconBlock<T>) -> Result<()> {
        let set = randao_signature_set(
            self.state,
            self.get_pubkey.clone(),
            &block.message,
            self.spec,
        )?;
        self.sets.push(set);
        Ok(())
    }

    /// Includes all signatures in `self.block.body.proposer_slashings` for verification.
    pub fn include_proposer_slashings(&mut self, block: &'a SignedBeaconBlock<T>) -> Result<()> {
        self.sets
            .reserve(block.message.body.proposer_slashings.len() * 2);

        block
            .message
            .body
            .proposer_slashings
            .iter()
            .try_for_each(|proposer_slashing| {
                let (set_1, set_2) = proposer_slashing_signature_set(
                    self.state,
                    self.get_pubkey.clone(),
                    proposer_slashing,
                    self.spec,
                )?;

                self.sets.push(set_1);
                self.sets.push(set_2);

                Ok(())
            })
    }

    /// Includes all signatures in `self.block.body.attester_slashings` for verification.
    pub fn include_attester_slashings(&mut self, block: &'a SignedBeaconBlock<T>) -> Result<()> {
        self.sets
            .reserve(block.message.body.attester_slashings.len() * 2);

        block
            .message
            .body
            .attester_slashings
            .iter()
            .try_for_each(|attester_slashing| {
                let (set_1, set_2) = attester_slashing_signature_sets(
                    &self.state,
                    self.get_pubkey.clone(),
                    attester_slashing,
                    &self.spec,
                )?;

                self.sets.push(set_1);
                self.sets.push(set_2);

                Ok(())
            })
    }

    /// Includes all signatures in `self.block.body.attestations` for verification.
    pub fn include_attestations(
        &mut self,
        block: &'a SignedBeaconBlock<T>,
    ) -> Result<Vec<IndexedAttestation<T>>> {
        self.sets.reserve(block.message.body.attestations.len());

        block
            .message
            .body
            .attestations
            .iter()
            .try_fold(
                Vec::with_capacity(block.message.body.attestations.len()),
                |mut vec, attestation| {
                    let committee = self
                        .state
                        .get_beacon_committee(attestation.data.slot, attestation.data.index)?;
                    let indexed_attestation =
                        get_indexed_attestation(committee.committee, attestation)?;

                    self.sets.push(indexed_attestation_signature_set(
                        &self.state,
                        self.get_pubkey.clone(),
                        &attestation.signature,
                        &indexed_attestation,
                        &self.spec,
                    )?);

                    vec.push(indexed_attestation);

                    Ok(vec)
                },
            )
            .map_err(Error::into)
    }

    /// Includes all signatures in `self.block.body.voluntary_exits` for verification.
    pub fn include_exits(&mut self, block: &'a SignedBeaconBlock<T>) -> Result<()> {
        self.sets.reserve(block.message.body.voluntary_exits.len());

        block
            .message
            .body
            .voluntary_exits
            .iter()
            .try_for_each(|exit| {
                let exit =
                    exit_signature_set(&self.state, self.get_pubkey.clone(), exit, &self.spec)?;

                self.sets.push(exit);

                Ok(())
            })
    }
}
<|endoftext|>


<commit_before>use mul_reader::MulReader;
use color::{Color16, Color};
use std::io::{Result, Error, ErrorKind, Cursor, SeekFrom, Seek, Write, Read};
use std::fs::File;
use byteorder::{LittleEndian, ReadBytesExt};
use std::path::Path;
use image::{Rgba, RgbaImage};

#[derive(Clone, Copy)]
pub struct GumpPair {
    color: Color16,
    count: u16
}

#[derive(Clone)]
pub struct Gump {
    width: u16,
    height: u16,
    data: Vec<Vec<GumpPair>>
}

impl Gump {

    // TODO: This should be a Result as it can overflow
    pub fn to_image(&self) -> RgbaImage {
        let mut buffer = RgbaImage::new(self.width as u32, self.height as u32);
        for (y, row) in self.data.iter().enumerate() {
            let mut x = 0;
            for run_pair in row {
                let (r, g, b, a) = run_pair.color.to_rgba();
                if (r != 0 || g != 0 || b != 0) {
                    for _i in 0..run_pair.count {
                        buffer.put_pixel(x, y as u32, Rgba([r, g, b, a]));
                    }
                    x += 1;
                } else {
                    x += run_pair.count as u32;
                }
            }
        };
        buffer
    }
}

pub struct GumpReader<T: Read + Seek> {
    mul_reader: MulReader<T>
}

impl GumpReader<File> {

    pub fn new(index_path: &Path, mul_path: &Path) -> Result<GumpReader<File>> {
        let mul_reader = try!(MulReader::new(index_path, mul_path));
        Ok(GumpReader {
            mul_reader: mul_reader
        })
    }
}

impl<T: Read + Seek> GumpReader<T> {

    pub fn from_mul(reader: MulReader<T>) -> GumpReader<T> {
        GumpReader {
            mul_reader: reader
        }
    }

    pub fn read_gump(&mut self, index: u32) -> Result<Gump> {
        let raw = try!(self.mul_reader.read(index));
        let mut output = vec![];
        let len = raw.data.len();
        assert!(len % 4 == 0);
        let mut reader = Cursor::new(raw.data);
        let mut row_offsets = vec![];
        // Load all of our offsets
        for _i in 0..raw.opt1 {
            row_offsets.push(try!(reader.read_u32::<LittleEndian>()));
        }
        // Unsure if the offset is from start of file, or start of data

        // FIXME: The RLE stuff in here and in art should probably be abstracted
        for (row_idx, offset) in row_offsets.iter().enumerate() {
            let row_length = if row_idx == row_offsets.len() - 1 {
                (len / 4) as u32 - offset
            } else {
                let next_row = row_offsets[row_idx + 1];
                next_row - offset
            };
            try!(reader.seek(SeekFrom::Start((*offset as u64) * 4)));
            let mut row = vec![];
            for _i in 0..row_length {
                let color = try!(reader.read_u16::<LittleEndian>());
                let count = try!(reader.read_u16::<LittleEndian>());
                row.push(GumpPair {
                    color: color,
                    count: count
                });
            };
            output.push(row);
        }
        Ok(Gump {
            height: raw.opt1,
            width: raw.opt2,
            data: output
        })
    }
}
<commit_msg>Corrected GUMP logic<commit_after>use mul_reader::MulReader;
use color::{Color16, Color};
use std::io::{Result, Error, ErrorKind, Cursor, SeekFrom, Seek, Write, Read};
use std::fs::File;
use byteorder::{LittleEndian, ReadBytesExt};
use std::path::Path;
use image::{Rgba, RgbaImage};

#[derive(Clone, Copy)]
pub struct GumpPair {
    color: Color16,
    count: u16
}

#[derive(Clone)]
pub struct Gump {
    width: u16,
    height: u16,
    data: Vec<Vec<GumpPair>>
}

impl Gump {

    // TODO: This should be a Result as it can overflow
    pub fn to_image(&self) -> RgbaImage {
        let mut buffer = RgbaImage::new(self.width as u32, self.height as u32);
        for (y, row) in self.data.iter().enumerate() {
            let mut x = 0;
            for run_pair in row {
                let (r, g, b, a) = run_pair.color.to_rgba();
                for i in 0..run_pair.count {
                    buffer.put_pixel(x + i as u32, y as u32, Rgba([r, g, b, a]));
                }
                x += run_pair.count as u32;
            }
        };
        buffer
    }
}

pub struct GumpReader<T: Read + Seek> {
    mul_reader: MulReader<T>
}

impl GumpReader<File> {

    pub fn new(index_path: &Path, mul_path: &Path) -> Result<GumpReader<File>> {
        let mul_reader = try!(MulReader::new(index_path, mul_path));
        Ok(GumpReader {
            mul_reader: mul_reader
        })
    }
}

impl<T: Read + Seek> GumpReader<T> {

    pub fn from_mul(reader: MulReader<T>) -> GumpReader<T> {
        GumpReader {
            mul_reader: reader
        }
    }

    pub fn read_gump(&mut self, index: u32) -> Result<Gump> {
        let raw = try!(self.mul_reader.read(index));
        let mut output = vec![];
        let len = raw.data.len();
        assert!(len % 4 == 0);
        let mut reader = Cursor::new(raw.data);
        let mut row_offsets = vec![];
        // Load all of our offsets
        for _i in 0..raw.opt1 {
            row_offsets.push(try!(reader.read_u32::<LittleEndian>()));
        }
        // Unsure if the offset is from start of file, or start of data

        // FIXME: The RLE stuff in here and in art should probably be abstracted
        for (row_idx, offset) in row_offsets.iter().enumerate() {
            let row_length = if row_idx == row_offsets.len() - 1 {
                (len / 4) as u32 - offset
            } else {
                let next_row = row_offsets[row_idx + 1];
                next_row - offset
            };
            try!(reader.seek(SeekFrom::Start((*offset as u64) * 4)));
            let mut row = vec![];
            for _i in 0..row_length {
                let color = try!(reader.read_u16::<LittleEndian>());
                let count = try!(reader.read_u16::<LittleEndian>());
                row.push(GumpPair {
                    color: color,
                    count: count
                });
            };
            output.push(row);
        }
        Ok(Gump {
            height: raw.opt1,
            width: raw.opt2,
            data: output
        })
    }
}
<|endoftext|>


<commit_before>extern crate rust_sodium;
use rust_sodium::crypto::box_::curve25519xsalsa20poly1305 as crypto_box;

pub struct PublicKey {
    pub crypto_box_key: crypto_box::PublicKey,
}
impl PublicKey {
    pub fn new(bytes: &[u8; crypto_box::PUBLICKEYBYTES]) -> PublicKey {
        PublicKey { crypto_box_key: crypto_box::PublicKey::from_slice(bytes).unwrap(), }
    }

    pub fn bytes(&self) -> &[u8; crypto_box::PUBLICKEYBYTES] {
        &self.crypto_box_key.0
    }
}

pub struct SecretKey {
    pub crypto_box_key: crypto_box::SecretKey,
}
impl SecretKey {
    pub fn new(bytes: &[u8; crypto_box::SECRETKEYBYTES]) -> SecretKey {
        SecretKey { crypto_box_key: crypto_box::SecretKey::from_slice(bytes).unwrap(), }
    }

    pub fn bytes(&self) -> &[u8; crypto_box::SECRETKEYBYTES] {
        &self.crypto_box_key.0
    }
}

pub fn gen_keypair() -> (PublicKey, SecretKey) {
    let (cb_pk, cb_sk) = crypto_box::gen_keypair();
    (PublicKey { crypto_box_key: cb_pk }, SecretKey { crypto_box_key: cb_sk })
}
<commit_msg>Add Base32 decoder for loading public keys.<commit_after>extern crate rust_sodium;
use rust_sodium::crypto::box_::curve25519xsalsa20poly1305 as crypto_box;

pub const PUBLIC_KEY_BYTES: usize = crypto_box::PUBLICKEYBYTES;
pub const SECRET_KEY_BYTES: usize = crypto_box::SECRETKEYBYTES;

// DNSCurve's Base32 decoding table
const BASE32_DECODING_TABLE: [u8; 128] = [
        99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,
        99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,
        99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,
         0, 1, 2, 3, 4, 5, 6, 7, 8, 9,99,99,99,99,99,99,
        99,99,10,11,12,99,13,14,15,99,16,17,18,19,20,99,
        21,22,23,24,25,26,27,28,29,30,31,99,99,99,99,99,
        99,99,10,11,12,99,13,14,15,99,16,17,18,19,20,99,
        21,22,23,24,25,26,27,28,29,30,31,99,99,99,99,99
        ];
// decode a base32-encoded byte array into an u32.
// Panics if the array is too large.
// Returns Err(c) if a character c is not valid in a Base32 string.
fn decode_base32(encoded: &[u8]) -> Result<Vec<u8>, u8> {
    println!("{:?}", encoded.len()*5);
    let mut res = Vec::with_capacity(encoded.len()*5/8);
    let mut last_word_length = 0;
    let mut last_word = 0u16;
    for c in encoded.iter() {
        let c = c.clone();
        if c >= 128 {
            return Err(c);
        }
        let bits = BASE32_DECODING_TABLE[c as usize];
        if bits == 99 {
            return Err(c);
        }

        // Add the new bits at the left of the current word
        last_word += (bits as u16) << last_word_length;
        last_word_length += 5;

        // If the right byte of the current word is full, push the on the vector
        // and shift the current word to remove the right byte.
        if last_word_length >= 8 {
            last_word_length -= 8;
            res.push((last_word & 0b11111111) as u8);
            last_word >>= 8;
        }
    }
    if last_word > 0 {
        res.push(last_word as u8);
    }
    Ok(res)
}

#[test]
fn test_decode_base32() {
    assert_eq!(decode_base32(b"4321"), Ok(vec![0x64, 0x88]));
    decode_base32(b"2j1xz5k5y1xwz7kcczc4565jurhp8bbz1lqfu9kljw36p3nmb050");
}

/// Represents a CryptoAuth public key.
///
/// # Example
///
/// ```
/// # use fcp_cryptoauth::keys::*;
/// PublicKey::new_from_base32(b"2j1xz5k5y1xwz7kcczc4565jurhp8bbz1lqfu9kljw36p3nmb050.k");
/// ```
pub struct PublicKey {
    pub crypto_box_key: crypto_box::PublicKey,
}
impl PublicKey {
    pub fn new_from_bytes(bytes: &[u8; PUBLIC_KEY_BYTES]) -> PublicKey {
        PublicKey { crypto_box_key: crypto_box::PublicKey::from_slice(bytes).unwrap(), }
    }
    /// Returns a Public key from its Base32 representation.
    ///
    /// TODO: better errors
    pub fn new_from_base32(characters: &[u8]) -> Option<PublicKey> {
        assert_eq!(characters[characters.len()-2..], b".k".to_owned());
        if let Ok(bytes) = decode_base32(characters) {
            if let Some(key) = crypto_box::PublicKey::from_slice(&bytes) {
                Some(PublicKey { crypto_box_key: key })
            }
            else {
                None
            }
        }
        else {
            None
        }
    }

    pub fn bytes(&self) -> &[u8; PUBLIC_KEY_BYTES] {
        &self.crypto_box_key.0
    }
}

pub struct SecretKey {
    pub crypto_box_key: crypto_box::SecretKey,
}
impl SecretKey {
    pub fn new(bytes: &[u8; SECRET_KEY_BYTES]) -> SecretKey {
        SecretKey { crypto_box_key: crypto_box::SecretKey::from_slice(bytes).unwrap(), }
    }

    pub fn bytes(&self) -> &[u8; SECRET_KEY_BYTES] {
        &self.crypto_box_key.0
    }
}

pub fn gen_keypair() -> (PublicKey, SecretKey) {
    let (cb_pk, cb_sk) = crypto_box::gen_keypair();
    (PublicKey { crypto_box_key: cb_pk }, SecretKey { crypto_box_key: cb_sk })
}
<|endoftext|>


<commit_before>/* This file is part of rpds.
 *
 * rpds 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, either version 3 of the License, or
 * (at your option) any later version.
 *
 * rpds 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 rpds.  If not, see <http://www.gnu.org/licenses/>.
 */

use std::sync::Arc;
use std::fmt::Display;
use std::borrow::Borrow;

/// A persistent list with structural sharing.  This data structure supports fast get head,
/// get tail, and append.
///
/// # Complexity
///
/// Let *n* be the number of elements in the list.
///
/// ## Temporal complexity
///
/// | Operation         | Best case | Average | Worst case  |
/// |:----------------- | ---------:| -------:| -----------:|
/// | new               |      Θ(1) |    Θ(1) |        Θ(1) |
/// | cons              |      Θ(1) |    Θ(1) |        Θ(1) |
/// | tail              |      Θ(1) |    Θ(1) |        Θ(1) |
/// | clone             |      Θ(1) |    Θ(1) |        Θ(1) |
/// | iterator creation |      Θ(1) |    Θ(1) |        Θ(1) |
/// | iterator step     |      Θ(1) |    Θ(1) |        Θ(1) |
/// | iterator full     |      Θ(n) |    Θ(n) |        Θ(n) |
///
/// ## Space complexity
///
/// The space complexity is *Θ(n)*.
#[derive(Debug)]
pub struct List<T> {
    node: Arc<Node<T>>,
}

#[derive(Debug)]
enum Node<T> {
    Cons(T, Arc<Node<T>>),
    Nil,
}

impl<T> List<T> {
    pub fn new() -> List<T> {
        List {
            node: Arc::new(Node::Nil)
        }
    }

    pub fn head(&self) -> Option<&T> {
        match *self.node {
            Node::Cons(ref h, _) => Some(h),
            Node::Nil            => None,
        }
    }

    pub fn tail(&self) -> Option<List<T>> {
        match *self.node {
            Node::Cons(_, ref t) => Some(List { node: t.clone() }),
            Node::Nil            => None,
        }
    }

    pub fn cons(&self, v: T) -> List<T> {
        List {
            node: Arc::new(Node::Cons(v, self.node.clone()))
        }
    }

    pub fn iter(&self) -> Iter<T> {
        Iter::new(self)
    }
}

impl<T> Clone for List<T> {
    fn clone(&self) -> List<T> {
        List {
            node: self.node.clone()
        }
    }
}

impl<T> Display for List<T>
    where T: Display {
    fn fmt(&self, fmt: &mut ::std::fmt::Formatter) -> ::std::fmt::Result {
        fmt.write_str("[")?;

        let mut first = true;

        for v in self.iter() {
            if !first {
                fmt.write_str(", ")?;
            }
            v.fmt(fmt)?;
            first = false;
        }

        fmt.write_str("]")
    }
}

impl<'a, T> IntoIterator for &'a List<T> {
    type Item = &'a T;
    type IntoIter = Iter<'a, T>;

    fn into_iter(self) -> Iter<'a, T> {
        self.iter()
    }
}

#[derive(Debug)]
pub struct Iter<'a, T: 'a> {
    next: &'a Node<T>
}

impl<'a, T> Iter<'a, T> {
    fn new(list: &List<T>) -> Iter<T> {
        Iter {
            next: list.node.borrow()
        }
    }
}

impl<'a, T> Iterator for Iter<'a, T> {
    type Item = &'a T;

    fn next(&mut self) -> Option<&'a T> {
        match *self.next {
            Node::Cons(ref v, ref t) => {
                self.next = t;
                Some(v)
            },
            Node::Nil => None
        }
    }
}

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

    #[test]
    fn test_new() -> () {
        let empty_list: List<i32> = List::new();

        match *empty_list.node {
            Node::Nil => (),
            _         => panic!("should be nil"),
        }
    }

    #[test]
    fn test_head() -> () {
        let empty_list: List<i32> = List::new();
        let singleton_list = List::new()
            .cons("hello");
        let list = List::new()
            .cons(3)
            .cons(2)
            .cons(1)
            .cons(0);

        assert_eq!(empty_list.head(), None);
        assert_eq!(singleton_list.head(), Some(&"hello"));
        assert_eq!(list.head(), Some(&0));
    }

    #[test]
    fn test_tail() -> () {
        let empty_list: List<i32> = List::new();
        let singleton_list = List::new()
            .cons("hello");
        let list = List::new()
            .cons(3)
            .cons(2)
            .cons(1)
            .cons(0);

        assert!(empty_list.tail().is_none());
        assert_eq!(singleton_list.tail().unwrap().head(), None);
        assert_eq!(list.tail().unwrap().head(), Some(&1));
    }

    #[test]
    fn test_display() -> () {
        let empty_list: List<i32> = List::new();
        let singleton_list = List::new()
            .cons("hello");
        let list = List::new()
            .cons(3)
            .cons(2)
            .cons(1)
            .cons(0);

        assert_eq!(format!("{}", empty_list), "[]");
        assert_eq!(format!("{}", singleton_list), "[hello]");
        assert_eq!(format!("{}", list), "[0, 1, 2, 3]");
    }

    #[test]
    fn test_iter() -> () {
        let limit = 1024;
        let mut list = List::new();
        let mut left = limit;

        for i in 0..limit {
            list = list.cons(i);
        }

        for v in list.iter() {
            left -= 1;
            assert_eq!(*v, left);
        }

        assert!(left == 0);
    }

    #[test]
    fn test_into_iterator() -> () {
        let list = List::new()
            .cons(3)
            .cons(2)
            .cons(1)
            .cons(0);
        let mut expected = 0;
        let mut left = 4;

        for n in &list {
            left -= 1;

            assert!(left >= 0);
            assert_eq!(*n, expected);

            expected += 1;
        }

        assert!(left == 0);
    }

    #[test]
    fn test_clone() -> () {
        let list = List::new()
            .cons("there")
            .cons("hello");
        let clone = list.clone();

        assert!(clone.iter().eq(list.iter()));
    }
}

/* TODO
 *
 * Implement traits:
 *
 *  - impl<T> Sync for List<T> where T: Sync
 *  - impl<T> Send for List<T> where T: Send
 *  - impl<T> IntoIterator for List<T>
 *  - impl<T> FromIterator<T>
 *  - impl<T> Ord for List<T> where T: Ord
 *  - impl<T> Eq for List<T> where T: Eq
 *  - impl<T> PartialEq<List<T>> for List<T> where T: PartialEq<T>
 *  - impl<T> PartialOrd<List<T>> for List<T> where T: PartialOrd<T>
 *  - impl<T> Hash for List<T> where T: Hash
 *  - impl<T> Default for List<T>
 *
 * Done:
 *  - impl<T> Clone for List<T> where T: Clone
 *  - impl<T> Debug for List<T> where T: Debug
 *  - impl<T> Display for List<T> where T: Display
 */
<commit_msg>Implemented a bunch of traits for `List`.<commit_after>/* This file is part of rpds.
 *
 * rpds 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, either version 3 of the License, or
 * (at your option) any later version.
 *
 * rpds 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 rpds.  If not, see <http://www.gnu.org/licenses/>.
 */

use std::sync::Arc;
use std::fmt::Display;
use std::cmp::Ordering;
use std::hash::{Hasher, Hash};
use std::borrow::Borrow;

/// A persistent list with structural sharing.  This data structure supports fast get head,
/// get tail, and cons.
///
/// # Complexity
///
/// Let *n* be the number of elements in the list.
///
/// ## Temporal complexity
///
/// | Operation         | Best case | Average | Worst case  |
/// |:----------------- | ---------:| -------:| -----------:|
/// | new               |      Θ(1) |    Θ(1) |        Θ(1) |
/// | cons              |      Θ(1) |    Θ(1) |        Θ(1) |
/// | tail              |      Θ(1) |    Θ(1) |        Θ(1) |
/// | clone             |      Θ(1) |    Θ(1) |        Θ(1) |
/// | iterator creation |      Θ(1) |    Θ(1) |        Θ(1) |
/// | iterator step     |      Θ(1) |    Θ(1) |        Θ(1) |
/// | iterator full     |      Θ(n) |    Θ(n) |        Θ(n) |
///
/// ## Space complexity
///
/// The space complexity is *Θ(n)*.
#[derive(Debug)]
pub struct List<T> {
    node: Arc<Node<T>>,
}

#[derive(Debug)]
enum Node<T> {
    Cons(T, Arc<Node<T>>),
    Nil,
}

impl<T> List<T> {
    pub fn new() -> List<T> {
        List {
            node: Arc::new(Node::Nil)
        }
    }

    pub fn head(&self) -> Option<&T> {
        match *self.node {
            Node::Cons(ref h, _) => Some(h),
            Node::Nil            => None,
        }
    }

    pub fn tail(&self) -> Option<List<T>> {
        match *self.node {
            Node::Cons(_, ref t) => Some(List { node: t.clone() }),
            Node::Nil            => None,
        }
    }

    pub fn cons(&self, v: T) -> List<T> {
        List {
            node: Arc::new(Node::Cons(v, self.node.clone()))
        }
    }

    pub fn iter(&self) -> Iter<T> {
        Iter::new(self)
    }
}

impl<T> Default for List<T> {
    fn default() -> List<T> {
        List::new()
    }
}

impl<T: PartialEq<T>> PartialEq<List<T>> for List<T> {
    fn eq(&self, other: &List<T>) -> bool {
        self.iter().eq(other.iter())
    }
}

impl<T: Eq> Eq for List<T> {}

impl<T: PartialOrd<T>> PartialOrd<List<T>> for List<T>  {
    fn partial_cmp(&self, other: &List<T>) -> Option<Ordering> {
        self.iter().partial_cmp(other.iter())
    }
}

impl<T: Ord> Ord for List<T> {
    fn cmp(&self, other: &List<T>) -> Ordering {
        self.iter().cmp(other.iter())
    }
}

impl<T: Hash> Hash for List<T> {
    fn hash<H: Hasher>(&self, state: &mut H) -> () {
        for e in self {
            e.hash(state);
        }
    }
}

impl<T> Clone for List<T> {
    fn clone(&self) -> List<T> {
        List {
            node: self.node.clone()
        }
    }
}

impl<T: Display> Display for List<T> {
    fn fmt(&self, fmt: &mut ::std::fmt::Formatter) -> ::std::fmt::Result {
        let mut first = true;

        fmt.write_str("[")?;

        for v in self.iter() {
            if !first {
                fmt.write_str(", ")?;
            }
            v.fmt(fmt)?;
            first = false;
        }

        fmt.write_str("]")
    }
}

impl<'a, T> IntoIterator for &'a List<T> {
    type Item = &'a T;
    type IntoIter = Iter<'a, T>;

    fn into_iter(self) -> Iter<'a, T> {
        self.iter()
    }
}

#[derive(Debug)]
pub struct Iter<'a, T: 'a> {
    next: &'a Node<T>
}

impl<'a, T> Iter<'a, T> {
    fn new(list: &List<T>) -> Iter<T> {
        Iter {
            next: list.node.borrow()
        }
    }
}

impl<'a, T> Iterator for Iter<'a, T> {
    type Item = &'a T;

    fn next(&mut self) -> Option<&'a T> {
        match *self.next {
            Node::Cons(ref v, ref t) => {
                self.next = t;
                Some(v)
            },
            Node::Nil => None
        }
    }
}

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

    #[test]
    fn test_new() -> () {
        let empty_list: List<i32> = List::new();

        match *empty_list.node {
            Node::Nil => (),
            _         => panic!("should be nil"),
        }
    }

    #[test]
    fn test_head() -> () {
        let empty_list: List<i32> = List::new();
        let singleton_list = List::new()
            .cons("hello");
        let list = List::new()
            .cons(3)
            .cons(2)
            .cons(1)
            .cons(0);

        assert_eq!(empty_list.head(), None);
        assert_eq!(singleton_list.head(), Some(&"hello"));
        assert_eq!(list.head(), Some(&0));
    }

    #[test]
    fn test_tail() -> () {
        let empty_list: List<i32> = List::new();
        let singleton_list = List::new()
            .cons("hello");
        let list = List::new()
            .cons(3)
            .cons(2)
            .cons(1)
            .cons(0);

        assert!(empty_list.tail().is_none());
        assert_eq!(singleton_list.tail().unwrap().head(), None);
        assert_eq!(list.tail().unwrap().head(), Some(&1));
    }

    #[test]
    fn test_default() -> () {
        let list: List<i32> = List::default();

        assert_eq!(list.head(), None);
    }

    #[test]
    fn test_display() -> () {
        let empty_list: List<i32> = List::new();
        let singleton_list = List::new()
            .cons("hello");
        let list = List::new()
            .cons(3)
            .cons(2)
            .cons(1)
            .cons(0);

        assert_eq!(format!("{}", empty_list), "[]");
        assert_eq!(format!("{}", singleton_list), "[hello]");
        assert_eq!(format!("{}", list), "[0, 1, 2, 3]");
    }

    #[test]
    fn test_iter() -> () {
        let limit = 1024;
        let mut list = List::new();
        let mut left = limit;

        for i in 0..limit {
            list = list.cons(i);
        }

        for v in list.iter() {
            left -= 1;
            assert_eq!(*v, left);
        }

        assert!(left == 0);
    }

    #[test]
    fn test_into_iterator() -> () {
        let list = List::new()
            .cons(3)
            .cons(2)
            .cons(1)
            .cons(0);
        let mut expected = 0;
        let mut left = 4;

        for n in &list {
            left -= 1;

            assert!(left >= 0);
            assert_eq!(*n, expected);

            expected += 1;
        }

        assert!(left == 0);
    }

    #[test]
    fn test_eq() -> () {
        let list_1 = List::new()
            .cons("a")
            .cons("a");
        let list_1_prime = List::new()
            .cons("a")
            .cons("a");
        let list_2 = List::new()
            .cons("b")
            .cons("a");

        assert_ne!(list_1, list_2);
        assert_eq!(list_1, list_1);
        assert_eq!(list_1, list_1_prime);
        assert_eq!(list_2, list_2);
    }

    #[test]
    fn test_partial_ord() -> () {
        let list_1 = List::new()
            .cons("a");
        let list_1_prime = List::new()
            .cons("a");
        let list_2 = List::new()
            .cons("b");
        let list_3 = List::new()
            .cons(0.0);
        let list_4 = List::new()
            .cons(::std::f32::NAN);

        assert!(list_1.partial_cmp(&list_1_prime) == Some(Ordering::Equal));
        assert!(list_1.partial_cmp(&list_2) == Some(Ordering::Less));
        assert!(list_2.partial_cmp(&list_1) == Some(Ordering::Greater));
        assert!(list_3.partial_cmp(&list_4) == None);
    }

    #[test]
    fn test_ord() -> () {
        let list_1 = List::new()
            .cons("a");
        let list_1_prime = List::new()
            .cons("a");
        let list_2 = List::new()
            .cons("b");

        assert!(list_1.cmp(&list_1_prime) == Ordering::Equal);
        assert!(list_1.cmp(&list_2) == Ordering::Less);
        assert!(list_2.cmp(&list_1) == Ordering::Greater);
    }

    fn hash<T: Hash>(list: &List<T>) -> u64 {
        let mut hasher = ::std::collections::hash_map::DefaultHasher::new();

        list.hash(&mut hasher);

        hasher.finish()
    }

    #[test]
    fn test_hash() -> () {
        let list_1 = List::new()
            .cons("a");
        let list_1_prime = List::new()
            .cons("a");
        let list_2 = List::new()
            .cons("b")
            .cons("a");

        assert_eq!(hash(&list_1), hash(&list_1));
        assert_eq!(hash(&list_1), hash(&list_1_prime));
        assert_ne!(hash(&list_1), hash(&list_2));
    }

    #[test]
    fn test_clone() -> () {
        let list = List::new()
            .cons("there")
            .cons("hello");
        let clone = list.clone();

        assert!(clone.iter().eq(list.iter()));
    }
}

/* TODO
 *
 * Implement traits:
 *
 *  - impl<T> Sync for List<T> where T: Sync
 *  - impl<T> Send for List<T> where T: Send
 *  - impl<T> IntoIterator for List<T>
 *  - impl<T> FromIterator<T>
 *  - impl<'a, T> From<&'a [T]> for List<T>
 *  - impl<'a, T> From<&'a Vec<T>> for List<T>
 *  - impl<'a, T> From<&'a Vector<T>> for List<T>
 *
 * Done:
 *
 *  - impl<T> Clone for List<T> where T: Clone
 *  - impl<T> Debug for List<T> where T: Debug
 *  - impl<T> Display for List<T> where T: Display
 *  - impl<T> Hash for List<T> where T: Hash
 *  - impl<T> Default for List<T>
 *  - impl<T> Ord for List<T> where T: Ord
 *  - impl<T> PartialOrd<List<T>> for List<T> where T: PartialOrd<T>
 *  - impl<T> Eq for List<T> where T: Eq
 *  - impl<T> PartialEq<List<T>> for List<T> where T: PartialEq<T>
 */
<|endoftext|>


<commit_before>#![feature(path_ext, file_path, exit_status)]

extern crate time;

use std::fs::{File, create_dir, OpenOptions, remove_file};
use std::io::{Seek, SeekFrom, BufReader, BufRead, Lines, Write};
use std::io;
use std::path::{Path, PathBuf};
use std::fs::PathExt;
use std::env::{args, home_dir, set_exit_status};
use std::fmt;
use time::{Duration, now_utc, Tm, empty_tm, strptime};

fn main() {
    let result = match args().nth(1) {
        None => Err(PunchClockError::NoCommandGiven),
        Some(command) => {
            let mut time_clock = TimeClock::new().unwrap();
            match &command[..] {
                "in" => time_clock.punch_in(),
                "out" => time_clock.punch_out(),
                "status" => time_clock.status(),
                "report" => time_clock.report_daily_hours(),
                _ => Err(PunchClockError::UnknownCommand)
            }
        }
    };

    if let Err(e) = result {
        println!("Error: {}", e);
        set_exit_status(1);
    }
}

#[derive(Debug)]
enum PunchClockError {
    NoCommandGiven,
    UnknownCommand,
    AlreadyPunchedIn,
    AlreadyPunchedOut,
    CorruptedTimeSheet,
    IoError(io::Error),
}

impl fmt::Display for PunchClockError {
    fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
        use PunchClockError::*;
        fmt.write_str(
            match *self {
                NoCommandGiven => "No command given",
                UnknownCommand => "Unknown command",
                AlreadyPunchedIn => "You are already punched in",
                AlreadyPunchedOut => "You're not currently punched in",
                CorruptedTimeSheet => "Bad data in timesheet",
                IoError(_) => "IO error"
            }
        )
    }
}

impl From<io::Error> for PunchClockError {
    fn from(err: io::Error) -> PunchClockError {
        PunchClockError::IoError(err)
    }
}
type PunchClockResult<T> = Result<T, PunchClockError>;

struct TimeClock {
    now: Tm,
    timesheet: File,
    currently_working: bool,
    state_path: PathBuf
}

impl TimeClock {
    fn new() -> PunchClockResult<TimeClock> {
        let now = now_utc();
        let home = home_dir().unwrap();
        let base_dir = home.join(Path::new(".punch"));
        let timesheet_path = base_dir.join("timesheet");
        let working_state_path = base_dir.join("state");
        if !base_dir.exists() {
            try!(create_dir(&base_dir));
        }
        let timesheet = try!(OpenOptions::new().write(true).append(true)
                            .open(&timesheet_path));
        Ok(TimeClock {
            timesheet: timesheet,
            currently_working: working_state_path.exists(),
            state_path: working_state_path,
            now: now
        })
    }

    // commands

    fn punch_in(&mut self) -> PunchClockResult<()> {
        if self.currently_working {
            return Err(PunchClockError::AlreadyPunchedIn);
        }
        try!(self.timesheet.seek(SeekFrom::End(0)));
        writeln!(&mut self.timesheet, "in: {}", self.now.rfc822()).unwrap();
        self.set_current_working_state(true);
        Ok(())
    }

    fn punch_out(&mut self) -> PunchClockResult<()> {
        if !self.currently_working {
            return Err(PunchClockError::AlreadyPunchedOut);
        }
        try!(self.timesheet.seek(SeekFrom::End(0)));
        try!(writeln!(&mut self.timesheet, "out: {}", self.now.rfc822()));
        self.set_current_working_state(false);
        Ok(())
    }

    fn status(&self) -> PunchClockResult<()> {
        if self.currently_working {
            println!("You're punched in");
        } else {
            println!("You're punched out");
        }
        Ok(())
    }

    fn report_daily_hours(&mut self) -> PunchClockResult<()> {
        try!(self.timesheet.seek(SeekFrom::Start(0)));
        let buf = BufReader::new(try!(File::open(self.timesheet.path().unwrap())));
        let mut current_day = empty_tm();
        let mut time_worked_today = Duration::zero();

        for interval in IntervalIter::from_lines(buf.lines()) {
            let (start, end) = try!(interval);
            if !same_day(&start, &current_day) {
                if !time_worked_today.is_zero() {
                    print_time_worked(&time_worked_today, &current_day);
                }
                current_day = start;
                time_worked_today = Duration::zero();
            }
            time_worked_today =
                time_worked_today + (end.to_timespec() - start.to_timespec());
        }

        if !time_worked_today.is_zero() {
            print_time_worked(&time_worked_today, &current_day);
        }
        Ok(())
    }

    // aux. methods

    fn set_current_working_state(&mut self, currently_working: bool) {
        self.currently_working = currently_working;
        if currently_working {
            File::create(&self.state_path).unwrap();
        } else {
            remove_file(&self.state_path).unwrap();
        }
    }
}

struct IntervalIter {
    lines: Lines<BufReader<File>>
}

impl IntervalIter {
    fn from_lines(lines: Lines<BufReader<File>>) -> IntervalIter {
        IntervalIter {lines: lines}
    }
}

impl Iterator for IntervalIter {
    type Item = PunchClockResult<(Tm, Tm)>;
    fn next(&mut self) -> Option<PunchClockResult<(Tm, Tm)>> {

        // helper function to make error handling a bit nicer
        fn inner_unwrap<T>(x: Option<io::Result<T>>)
                -> PunchClockResult<Option<T>> {
            match x {
                None => Ok(None),
                Some(Ok(inner)) => Ok(Some(inner)),
                Some(Err(e)) => Err(PunchClockError::IoError(e))
            }
        }

        let line_1 = match inner_unwrap(self.lines.next()) {
            Ok(l) => l,
            Err(e) => return Some(Err(e))
        };
        let line_2 = match inner_unwrap(self.lines.next()) {
            Ok(l) => l,
            Err(e) => return Some(Err(e))
        };

        match (line_1, line_2) {
            (None, None) => None,
            (Some(start_line), o_end_line) => {
                if !start_line.starts_with("in: ") {
                    return Some(Err(PunchClockError::CorruptedTimeSheet));
                }
                let start = parse_time(&start_line[4..]);
                let end = match o_end_line {
                    None => now_utc(),
                    Some(end_line) => {
                        if !end_line.starts_with("out: ") {
                            return Some(Err(PunchClockError::CorruptedTimeSheet));
                        }
                        parse_time(&end_line[5..])
                    },
                };
                Some(Ok((start, end)))
            },
            _ => unreachable!() // (None, Some(l)) should not happen
        }
    }

    fn size_hint(&self) -> (usize, Option<usize>) {
        (0, None)
    }
}

fn parse_time(s: &str) -> Tm {
    strptime(&s[..s.len() - 1], "%a, %d %b %Y %T %Z").unwrap()
}

fn same_day(t1: &Tm, t2: &Tm) -> bool {
    t1.tm_year == t2.tm_year &&
    t1.tm_mon == t2.tm_mon &&
    t1.tm_mday == t2.tm_mday
}

fn print_time_worked(t: &Duration, day: &Tm) {
    println!("{}: {:>2}:{:02}",
        day.strftime("%a, %d %b %Y").unwrap(),
        t.num_hours() ,
        t.num_minutes() % 60
    );
}
<commit_msg>Get rid of file_path feature<commit_after>#![feature(path_ext, exit_status)]

extern crate time;

use std::fs::{File, create_dir, OpenOptions, remove_file};
use std::io::{Seek, SeekFrom, BufReader, BufRead, Lines, Write};
use std::io;
use std::path::{Path, PathBuf};
use std::fs::PathExt;
use std::env::{args, home_dir, set_exit_status};
use std::fmt;
use time::{Duration, now_utc, Tm, empty_tm, strptime};

fn main() {
    let result = match args().nth(1) {
        None => Err(PunchClockError::NoCommandGiven),
        Some(command) => {
            let mut time_clock = TimeClock::new().unwrap();
            match &command[..] {
                "in" => time_clock.punch_in(),
                "out" => time_clock.punch_out(),
                "status" => time_clock.status(),
                "report" => time_clock.report_daily_hours(),
                _ => Err(PunchClockError::UnknownCommand)
            }
        }
    };

    if let Err(e) = result {
        println!("Error: {}", e);
        set_exit_status(1);
    }
}

#[derive(Debug)]
enum PunchClockError {
    NoCommandGiven,
    UnknownCommand,
    AlreadyPunchedIn,
    AlreadyPunchedOut,
    CorruptedTimeSheet,
    IoError(io::Error),
}

impl fmt::Display for PunchClockError {
    fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
        use PunchClockError::*;
        fmt.write_str(
            match *self {
                NoCommandGiven => "No command given",
                UnknownCommand => "Unknown command",
                AlreadyPunchedIn => "You are already punched in",
                AlreadyPunchedOut => "You're not currently punched in",
                CorruptedTimeSheet => "Bad data in timesheet",
                IoError(_) => "IO error"
            }
        )
    }
}

impl From<io::Error> for PunchClockError {
    fn from(err: io::Error) -> PunchClockError {
        PunchClockError::IoError(err)
    }
}
type PunchClockResult<T> = Result<T, PunchClockError>;

struct TimeClock {
    now: Tm,
    timesheet: File,
    timesheet_path: PathBuf,
    currently_working: bool,
    state_path: PathBuf
}

impl TimeClock {
    fn new() -> PunchClockResult<TimeClock> {
        let now = now_utc();
        let home = home_dir().unwrap();
        let base_dir = home.join(Path::new(".punch"));
        let timesheet_path = base_dir.join("timesheet");
        let working_state_path = base_dir.join("state");
        if !base_dir.exists() {
            try!(create_dir(&base_dir));
        }
        let timesheet = try!(OpenOptions::new().write(true).append(true)
                            .open(&timesheet_path));
        Ok(TimeClock {
            timesheet: timesheet,
            timesheet_path: timesheet_path,
            currently_working: working_state_path.exists(),
            state_path: working_state_path,
            now: now
        })
    }

    // commands

    fn punch_in(&mut self) -> PunchClockResult<()> {
        if self.currently_working {
            return Err(PunchClockError::AlreadyPunchedIn);
        }
        try!(self.timesheet.seek(SeekFrom::End(0)));
        writeln!(&mut self.timesheet, "in: {}", self.now.rfc822()).unwrap();
        self.set_current_working_state(true);
        Ok(())
    }

    fn punch_out(&mut self) -> PunchClockResult<()> {
        if !self.currently_working {
            return Err(PunchClockError::AlreadyPunchedOut);
        }
        try!(self.timesheet.seek(SeekFrom::End(0)));
        try!(writeln!(&mut self.timesheet, "out: {}", self.now.rfc822()));
        self.set_current_working_state(false);
        Ok(())
    }

    fn status(&self) -> PunchClockResult<()> {
        if self.currently_working {
            println!("You're punched in");
        } else {
            println!("You're punched out");
        }
        Ok(())
    }

    fn report_daily_hours(&mut self) -> PunchClockResult<()> {
        try!(self.timesheet.seek(SeekFrom::Start(0)));
        let buf = BufReader::new(try!(File::open(&self.timesheet_path)));
        let mut current_day = empty_tm();
        let mut time_worked_today = Duration::zero();

        for interval in IntervalIter::from_lines(buf.lines()) {
            let (start, end) = try!(interval);
            if !same_day(&start, &current_day) {
                if !time_worked_today.is_zero() {
                    print_time_worked(&time_worked_today, &current_day);
                }
                current_day = start;
                time_worked_today = Duration::zero();
            }
            time_worked_today =
                time_worked_today + (end.to_timespec() - start.to_timespec());
        }

        if !time_worked_today.is_zero() {
            print_time_worked(&time_worked_today, &current_day);
        }
        Ok(())
    }

    // aux. methods

    fn set_current_working_state(&mut self, currently_working: bool) {
        self.currently_working = currently_working;
        if currently_working {
            File::create(&self.state_path).unwrap();
        } else {
            remove_file(&self.state_path).unwrap();
        }
    }
}

struct IntervalIter {
    lines: Lines<BufReader<File>>
}

impl IntervalIter {
    fn from_lines(lines: Lines<BufReader<File>>) -> IntervalIter {
        IntervalIter {lines: lines}
    }
}

impl Iterator for IntervalIter {
    type Item = PunchClockResult<(Tm, Tm)>;
    fn next(&mut self) -> Option<PunchClockResult<(Tm, Tm)>> {

        // helper function to make error handling a bit nicer
        fn inner_unwrap<T>(x: Option<io::Result<T>>)
                -> PunchClockResult<Option<T>> {
            match x {
                None => Ok(None),
                Some(Ok(inner)) => Ok(Some(inner)),
                Some(Err(e)) => Err(PunchClockError::IoError(e))
            }
        }

        let line_1 = match inner_unwrap(self.lines.next()) {
            Ok(l) => l,
            Err(e) => return Some(Err(e))
        };
        let line_2 = match inner_unwrap(self.lines.next()) {
            Ok(l) => l,
            Err(e) => return Some(Err(e))
        };

        match (line_1, line_2) {
            (None, None) => None,
            (Some(start_line), o_end_line) => {
                if !start_line.starts_with("in: ") {
                    return Some(Err(PunchClockError::CorruptedTimeSheet));
                }
                let start = parse_time(&start_line[4..]);
                let end = match o_end_line {
                    None => now_utc(),
                    Some(end_line) => {
                        if !end_line.starts_with("out: ") {
                            return Some(Err(PunchClockError::CorruptedTimeSheet));
                        }
                        parse_time(&end_line[5..])
                    },
                };
                Some(Ok((start, end)))
            },
            _ => unreachable!() // (None, Some(l)) should not happen
        }
    }

    fn size_hint(&self) -> (usize, Option<usize>) {
        (0, None)
    }
}

fn parse_time(s: &str) -> Tm {
    strptime(&s[..s.len() - 1], "%a, %d %b %Y %T %Z").unwrap()
}

fn same_day(t1: &Tm, t2: &Tm) -> bool {
    t1.tm_year == t2.tm_year &&
    t1.tm_mon == t2.tm_mon &&
    t1.tm_mday == t2.tm_mday
}

fn print_time_worked(t: &Duration, day: &Tm) {
    println!("{}: {:>2}:{:02}",
        day.strftime("%a, %d %b %Y").unwrap(),
        t.num_hours() ,
        t.num_minutes() % 60
    );
}
<|endoftext|>


<commit_before>use macroquad::prelude::*;

use grid::Grid;
use graph::Graph;

mod colour;
mod grid;
mod graph;

#[macroquad::main("BasicShapes")]
async fn main() {
    let grid = Grid::generate(8);
    let mut graph = Graph::create(&grid);

    loop {
        clear_background(RED);

        draw_line(40.0, 40.0, 100.0, 200.0, 15.0, BLUE);
        draw_rectangle(screen_width() / 2.0 - 60.0, 100.0, 120.0, 60.0, GREEN);
        draw_circle(screen_width() - 30.0, screen_height() - 30.0, 15.0, YELLOW);
        draw_text("HELLO", 20.0, 20.0, 20.0, DARKGRAY);

        next_frame().await
    }
}
<commit_msg>Use black background<commit_after>use macroquad::prelude::*;

use grid::Grid;
use graph::Graph;

mod colour;
mod grid;
mod graph;

#[macroquad::main("BasicShapes")]
async fn main() {
    let grid = Grid::generate(8);
    let mut graph = Graph::create(&grid);

    loop {
        clear_background(BLACK);

        draw_line(40.0, 40.0, 100.0, 200.0, 15.0, BLUE);
        draw_rectangle(screen_width() / 2.0 - 60.0, 100.0, 120.0, 60.0, GREEN);
        draw_circle(screen_width() - 30.0, screen_height() - 30.0, 15.0, YELLOW);
        draw_text("HELLO", 20.0, 20.0, 20.0, DARKGRAY);

        next_frame().await
    }
}
<|endoftext|>


<commit_before>extern crate rand;
use rand::{Rand, Rng};
use std::collections::HashMap;
use std::thread::sleep_ms;

#[derive(Debug, PartialEq, Clone)]
enum CellState{
    Alive,
    Dead
}

type WSize = i8;
type Point = (WSize, WSize);

impl Rand for CellState {
    #[inline]
    fn rand<R:Rng>(rng: &mut R) -> CellState {
        let x: bool = rand::random();
        match x {
            true => CellState::Alive,
            false => CellState::Dead
        }
    }
}
#[derive(Debug, Clone)]
struct World {
    width: WSize,
    height: WSize,
    cells: HashMap<Point, CellState>
}

impl World {
    fn new(width: WSize, height: WSize)  -> World {
        let mut world = World{width: width, height: height, cells: HashMap::new()};
        for y in 0..height { for x in 0..width {
            world.cells.insert((x, y), CellState::Dead);
        }}
        world
    }
    fn evolve(&self) -> World {
        let mut new_world = self.clone();
        for y in 0..self.height { for x in 0..self.width {
            new_world.set_state(x, y, self.decide_fate(x, y))
        }}
        new_world

    }

    fn decide_fate(&self, x: WSize, y: WSize) -> CellState {
        rand::random()
    }

    fn is_alive(&self, x: WSize, y: WSize) -> bool {
        let key = (x, y);
        self.cells.get(&key) == Some(&CellState::Alive)
    }

    fn set_state(&mut self, x: WSize, y: WSize, value: CellState) {
        self.cells.insert((x, y), value);
    }

    fn randomize(&mut self) {
        for y in 0..self.height { for x in 0..self.width {
            self.set_state(x, y, rand::random());
        }}

    }
}

fn clear_screen() {
    print!("\x1b[2J\n");
}

fn draw(ref world: &World) {
    clear_screen();
    for y in 0..world.height {
        print!("\n");
        for x in 0..world.width {
            if world.is_alive(x,y) {
                print!("□");
            } else {
                print!(" ");
            }

        }
    }
    print!("\n");
}

fn main() {
    println!("Hello");
    let mut world:World = World::new(30, 20);
    world.randomize();
    loop {
        world = world.evolve();
        draw(&world);
        std::thread::sleep_ms(50);
    }
}

<commit_msg>power of mod<commit_after>extern crate rand;
use rand::{Rand, Rng};
use std::collections::HashMap;
use std::thread::sleep_ms;

type Point = (u8, u8);

#[derive(Debug, PartialEq, Clone)]
enum CellState{
    Alive,
    Dead
}

impl Rand for CellState {
    #[inline]
    fn rand<R:Rng>(rng: &mut R) -> CellState {
        match rand::random() {
            true => CellState::Alive,
            false => CellState::Dead
        }
    }
}

trait Measurable {

}

#[derive(Debug, Clone)]
struct World {
    width: u8,
    height: u8,
    cells: HashMap<Point, CellState>
}

impl World {
    fn new(width: u8, height: u8)  -> World {
        let mut world = World{width: width, height: height, cells: HashMap::new()};
        for y in 0..height { for x in 0..width {
            world.cells.insert((x, y), CellState::Dead);
        }}
        world
    }
    fn evolve(&self) -> World {
        let mut new_world = self.clone();
        for y in 0..self.height { for x in 0..self.width {
            new_world.set_state(x, y, self.decide_fate(x, y))
        }}
        new_world

    }

    fn decide_fate(&self, x: u8, y: u8) -> CellState {
        rand::random()
    }

    fn is_alive(&self, x: u8, y: u8) -> bool {
        let key = (x, y);
        self.cells.get(&key) == Some(&CellState::Alive)
    }

    fn set_state(&mut self, x: u8, y: u8, value: CellState) {
        self.cells.insert((x, y), value);
    }

    fn randomize(&mut self) {
        for y in 0..self.height { for x in 0..self.width {
            self.set_state(x, y, rand::random());
        }}

    }
}

impl display::Drawable for World {
    fn should_draw(&self, x: u8, y: u8) -> bool {
        self.is_alive(x, y)
    }
    fn get_height(&self) -> u8 {
        self.height
    }
    fn get_width(&self) -> u8 {
        self.width
    }
}

mod display {
    fn clear_screen() {
        print!("\x1b[2J\n");
    }

    pub trait Drawable {
        fn should_draw(&self, x: u8, y: u8) -> bool;
        fn get_height(&self) -> u8;
        fn get_width(&self) -> u8;
    }

    pub fn draw<T: Drawable>(ref world: &T) {
        clear_screen();
        for y in 0..world.get_height() {
            print!("\n");
            for x in 0..world.get_width() {
                if world.should_draw(x,y) {
                    print!("□");
                } else {
                    print!(" ");
                }

            }
        }
        print!("\n");
    }
}

fn main() {
    println!("Hello");
    let mut world:World = World::new(30, 20);
    world.randomize();
    loop {
        world = world.evolve();
        display::draw(&world);
        std::thread::sleep_ms(50);
    }
}

<|endoftext|>