<commit_before>//! This module provides an oct-tree of cubes. Each leaf cube describes a
//! spatial partition, its properties, and a deformable geometry.

extern crate nalgebra;

use ::nalgebra::Origin;
use ::std::error;
use ::std::error::Error;
use ::std::fmt;
use ::std::mem;
use ::std::ops;

use resource::ResourceId;

pub const MAX_WIDTH: RootWidth = 31;
pub const MIN_WIDTH: RootWidth = 4;

pub type Point = nalgebra::Point3<u32>;
pub type Vector = nalgebra::Vector3<u32>;
pub type RootWidth = u8; // TODO: https://github.com/rust-lang/rfcs/issues/671

pub trait Clamp<T>
    where T: PartialOrd
{
    fn clamp(&self, min: T, max: T) -> Self;
}

impl Clamp<RootWidth> for RootWidth {
    fn clamp(&self, min: RootWidth, max: RootWidth) -> Self {
        nalgebra::clamp(*self, min, max)
    }
}

impl<T> Clamp<T> for nalgebra::Point3<T>
    where T: Copy,
          T: PartialOrd
{
    fn clamp(&self, min: T, max: T) -> Self {
        nalgebra::Point3::new(nalgebra::clamp(self.x, min, max),
                              nalgebra::clamp(self.y, min, max),
                              nalgebra::clamp(self.z, min, max))
    }
}

pub trait Mask<T>
    where T: ops::BitAnd<Output = T>
{
    fn mask(&self, value: T) -> Self;
}

impl<T> Mask<T> for nalgebra::Point3<T>
    where T: Copy,
          T: ops::BitAnd<Output = T>
{
    fn mask(&self, value: T) -> Self {
        nalgebra::Point3::new(self.x & value, self.y & value, self.z & value)
    }
}

#[derive(Clone)]
pub struct Partition {
    origin: Point,
    width: RootWidth,
}

impl Partition {
    fn new(point: &Point, width: RootWidth) -> Self {
        Partition {
            origin: point.mask(!0u32 << width),
            width: width,
        }
    }

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

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

pub trait Traversal: ops::Deref<Target = Cube> {
    fn partition(&self) -> &Partition;

    fn depth(&self) -> u8;
}

pub trait TraversalMut: Traversal + ops::DerefMut {}

#[derive(Clone)]
pub struct Cursor<'a> {
    cube: &'a Cube,
    root: &'a Partition,
    partition: Partition,
}

impl<'a> Cursor<'a> {
    fn new(cube: &'a Cube, root: &'a Partition, partition: Partition) -> Self {
        Cursor {
            cube: cube,
            root: root,
            partition: partition,
        }
    }

    pub fn resolve(&self, point: &Point, width: RootWidth) -> Self {
        let mut cube = self.cube;
        let mut depth = self.partition.width();

        // Clamp the inputs.
        let point = point.clamp(0, (1u32 << self.root.width()) - 1);
        let width = 1u32 << width.clamp(MIN_WIDTH, depth);

        while (width >> depth) == 0 {
            match *cube {
                Cube::Branch(ref branch) => {
                    depth = depth - 1;
                    cube = &branch.cubes[cube_index_at_point(&point, depth)]
                }
                _ => break,
            }
        }

        Cursor::new(cube, self.root, Partition::new(&point, depth))
    }
}

impl<'a> Traversal for Cursor<'a> {
    fn partition(&self) -> &Partition {
        &self.partition
    }

    fn depth(&self) -> u8 {
        self.root.width() - self.partition.width()
    }
}

impl<'a> ops::Deref for Cursor<'a> {
    type Target = Cube;

    fn deref(&self) -> &Self::Target {
        self.cube
    }
}

#[derive(Debug)]
pub enum JoinError {
    LeafJoined,
}

impl fmt::Display for JoinError {
    fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
        write!(formatter, "{}", self.description())
    }
}

impl error::Error for JoinError {
    fn description(&self) -> &str {
        match *self {
            JoinError::LeafJoined => "attempted to join leaf",
        }
    }
}

#[derive(Debug)]
pub enum SubdivideError {
    LimitExceeded,
    BranchSubdivided,
}

impl fmt::Display for SubdivideError {
    fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
        write!(formatter, "{}", self.description())
    }
}

impl error::Error for SubdivideError {
    fn description(&self) -> &str {
        match *self {
            SubdivideError::LimitExceeded => "minimum width limit exceeded",
            SubdivideError::BranchSubdivided => "attempted to subdivide branch",
        }
    }
}

pub struct CursorMut<'a> {
    cube: &'a mut Cube,
    root: &'a Partition,
    partition: Partition,
}

impl<'a> CursorMut<'a> {
    fn new(cube: &'a mut Cube, root: &'a Partition, partition: Partition) -> Self {
        CursorMut {
            cube: cube,
            root: root,
            partition: partition,
        }
    }

    pub fn resolve(&'a mut self, point: &Point, width: RootWidth) -> Self {
        let mut cube: Option<&mut Cube> = Some(self.cube);
        let mut depth = self.partition.width();

        let point = point.clamp(0, (1u32 << self.root.width()) - 1);
        let width = 1u32 << width.clamp(MIN_WIDTH, depth);

        while (width >> depth) == 0 {
            let inner = cube.take().unwrap();
            match *inner {
                Cube::Branch(ref mut branch) => {
                    depth = depth - 1;
                    cube = Some(&mut branch.cubes[cube_index_at_point(&point, depth)]);
                }
                _ => {
                    cube = Some(inner);
                    break;
                }
            }
        }

        CursorMut::new(cube.take().unwrap(),
                       self.root,
                       Partition::new(&point, depth))
    }

    pub fn join(&mut self) -> Result<&mut Self, JoinError> {
        try!(self.cube.join());
        Ok(self)
    }

    pub fn subdivide(&mut self) -> Result<&mut Self, SubdivideError> {
        if self.partition.width() > MIN_WIDTH {
            try!(self.cube.subdivide());
            Ok(self)
        } else {
            Err(SubdivideError::LimitExceeded)
        }
    }
}

impl<'a> Traversal for CursorMut<'a> {
    fn partition(&self) -> &Partition {
        &self.partition
    }

    fn depth(&self) -> u8 {
        self.root.width() - self.partition.width()
    }
}

impl<'a> TraversalMut for CursorMut<'a> {}

impl<'a> ops::Deref for CursorMut<'a> {
    type Target = Cube;

    fn deref(&self) -> &Self::Target {
        self.cube
    }
}

impl<'a> ops::DerefMut for CursorMut<'a> {
    fn deref_mut(&mut self) -> &mut Self::Target {
        self.cube
    }
}

pub struct Tree {
    cube: Cube,
    partition: Partition,
}

impl Tree {
    pub fn new(width: RootWidth) -> Self {
        Tree {
            cube: Cube::new(),
            partition: Partition::new(&Point::origin(), width),
        }
    }

    pub fn cursor(&self) -> Cursor {
        Cursor::new(&self.cube, &self.partition, self.partition.clone())
    }

    pub fn cursor_mut(&mut self) -> CursorMut {
        CursorMut::new(&mut self.cube, &self.partition, self.partition.clone())
    }
}

impl Traversal for Tree {
    fn partition(&self) -> &Partition {
        &self.partition
    }

    fn depth(&self) -> u8 {
        0
    }
}

impl TraversalMut for Tree {}

impl ops::Deref for Tree {
    type Target = Cube;

    fn deref(&self) -> &Self::Target {
        &self.cube
    }
}

impl ops::DerefMut for Tree {
    fn deref_mut(&mut self) -> &mut Self::Target {
        &mut self.cube
    }
}

#[derive(Clone)]
pub enum Cube {
    Leaf(LeafNode),
    Branch(BranchNode),
}

impl Cube {
    fn new() -> Self {
        Cube::Leaf(LeafNode::new())
    }

    fn join(&mut self) -> Result<&mut Self, JoinError> {
        let cube = mem::replace(self, Cube::default());
        match cube {
            Cube::Branch(branch) => {
                *self = branch.join().into();
                Ok(self)
            }
            _ => {
                *self = cube;
                Err(JoinError::LeafJoined)
            }
        }
    }

    fn subdivide(&mut self) -> Result<&mut Self, SubdivideError> {
        let cube = mem::replace(self, Cube::default());
        match cube {
            Cube::Leaf(leaf) => {
                *self = leaf.subdivide().into();
                Ok(self)
            }
            _ => {
                *self = cube;
                Err(SubdivideError::BranchSubdivided)
            }
        }
    }
}

impl Default for Cube {
    fn default() -> Self {
        Cube::new()
    }
}

impl From<LeafNode> for Cube {
    fn from(leaf: LeafNode) -> Self {
        Cube::Leaf(leaf)
    }
}

impl From<BranchNode> for Cube {
    fn from(branch: BranchNode) -> Self {
        Cube::Branch(branch)
    }
}

#[derive(Clone, Copy)]
pub struct LeafNode {
    pub geometry: [u32; 3],
    pub material: ResourceId,
}

impl LeafNode {
    fn new() -> Self {
        LeafNode {
            geometry: Geometry::full(),
            material: 0,
        }
    }

    fn subdivide(self) -> BranchNode {
        // TODO: Transform the geometry of the parent into the children.
        let cube: Cube = self.into();
        BranchNode {
            cubes: Box::new([cube.clone(),
                             cube.clone(),
                             cube.clone(),
                             cube.clone(),
                             cube.clone(),
                             cube.clone(),
                             cube.clone(),
                             cube]),
        }
    }
}

pub struct BranchNode {
    cubes: Box<[Cube; 8]>,
}

impl BranchNode {
    pub fn join(self) -> LeafNode {
        // TODO: Copy data from one of the original leaves.
        LeafNode::new()
    }
}

impl Clone for BranchNode {
    fn clone(&self) -> Self {
        BranchNode {
            cubes: Box::new([self.cubes[0].clone(),
                             self.cubes[1].clone(),
                             self.cubes[2].clone(),
                             self.cubes[3].clone(),
                             self.cubes[4].clone(),
                             self.cubes[5].clone(),
                             self.cubes[6].clone(),
                             self.cubes[7].clone()]),
        }
    }
}

trait Geometry {
    fn full() -> Self;
    fn empty() -> Self;
}

impl Geometry for [u32; 3] {
    fn full() -> Self {
        [0x0F0F0F0F; 3]
    }

    fn empty() -> Self {
        [0x00000000; 3]
    }
}

trait Subdivision {}

impl Subdivision for [Cube; 8] {}

trait Storage {}

impl Storage for Box<[Cube; 8]> {}

#[cfg_attr(rustfmt, rustfmt_skip)]
fn cube_index_at_point(point: &Point, width: RootWidth) -> usize {
    ((((point.x >> width) & 1u32) << 0) |
     (((point.y >> width) & 1u32) << 1) |
     (((point.z >> width) & 1u32) << 2)) as usize
}

#[cfg(test)]
mod tests {
    use super::*;
}
<commit_msg>Implement iterator for `Cursor`.<commit_after>//! This module provides an oct-tree of cubes. Each leaf cube describes a
//! spatial partition, its properties, and a deformable geometry.

extern crate nalgebra;

use ::nalgebra::Origin;
use ::std::error;
use ::std::error::Error;
use ::std::fmt;
use ::std::mem;
use ::std::ops;
use ::std::ops::Deref;

use resource::ResourceId;

pub const MAX_WIDTH: RootWidth = 31;
pub const MIN_WIDTH: RootWidth = 4;

pub type Point = nalgebra::Point3<u32>;
pub type Vector = nalgebra::Vector3<u32>;
pub type RootWidth = u8; // TODO: https://github.com/rust-lang/rfcs/issues/671

pub trait Clamp<T>
    where T: PartialOrd
{
    fn clamp(&self, min: T, max: T) -> Self;
}

impl Clamp<RootWidth> for RootWidth {
    fn clamp(&self, min: RootWidth, max: RootWidth) -> Self {
        nalgebra::clamp(*self, min, max)
    }
}

impl<T> Clamp<T> for nalgebra::Point3<T>
    where T: Copy,
          T: PartialOrd
{
    fn clamp(&self, min: T, max: T) -> Self {
        nalgebra::Point3::new(nalgebra::clamp(self.x, min, max),
                              nalgebra::clamp(self.y, min, max),
                              nalgebra::clamp(self.z, min, max))
    }
}

pub trait Mask<T>
    where T: ops::BitAnd<Output = T>
{
    fn mask(&self, value: T) -> Self;
}

impl<T> Mask<T> for nalgebra::Point3<T>
    where T: Copy,
          T: ops::BitAnd<Output = T>
{
    fn mask(&self, value: T) -> Self {
        nalgebra::Point3::new(self.x & value, self.y & value, self.z & value)
    }
}

#[derive(Clone)]
pub struct Partition {
    origin: Point,
    width: RootWidth,
}

impl Partition {
    fn at_point(point: &Point, width: RootWidth) -> Self {
        Partition {
            origin: point.mask(!0u32 << width),
            width: width,
        }
    }

    fn at_index(&self, index: usize) -> Option<Self> {
        assert!(index < 8);
        if self.width > MIN_WIDTH {
            let index = index as u32;
            let width = self.width - 1;
            let exp = 1u32 << width;
            Some(Partition {
                origin: self.origin + Vector::new(
                    ((index >> 0) & 1u32) * exp,
                    ((index >> 1) & 1u32) * exp,
                    ((index >> 2) & 1u32) * exp),
                width: width,
            })
        }
        else {
            None
        }
    }

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

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

pub trait Traversal: ops::Deref<Target = Cube> {
    fn partition(&self) -> &Partition;

    fn depth(&self) -> u8;
}

pub trait TraversalMut: Traversal + ops::DerefMut {}

#[derive(Clone)]
pub struct Cursor<'a> {
    cube: &'a Cube,
    root: &'a Partition,
    partition: Partition,
}

impl<'a> Cursor<'a> {
    fn new(cube: &'a Cube, root: &'a Partition, partition: Partition) -> Self {
        Cursor {
            cube: cube,
            root: root,
            partition: partition,
        }
    }

    pub fn iter(&self) -> CursorIter {
        CursorIter::new(self.clone())
    }

    pub fn resolve(&self, point: &Point, width: RootWidth) -> Self {
        let mut cube = self.cube;
        let mut depth = self.partition.width();

        // Clamp the inputs.
        let point = point.clamp(0, (1u32 << self.root.width()) - 1);
        let width = 1u32 << width.clamp(MIN_WIDTH, depth);

        while (width >> depth) == 0 {
            match *cube {
                Cube::Branch(ref branch) => {
                    depth = depth - 1;
                    cube = &branch.cubes[index_at_point(&point, depth)]
                }
                _ => break,
            }
        }

        Cursor::new(cube, self.root, Partition::at_point(&point, depth))
    }
}

impl<'a> Traversal for Cursor<'a> {
    fn partition(&self) -> &Partition {
        &self.partition
    }

    fn depth(&self) -> u8 {
        self.root.width() - self.partition.width()
    }
}

impl<'a> ops::Deref for Cursor<'a> {
    type Target = Cube;

    fn deref(&self) -> &Self::Target {
        self.cube
    }
}

pub struct CursorIter<'a> {
    cursors: Vec<Cursor<'a>>,
}

impl<'a> CursorIter<'a> {
    fn new(cursor: Cursor<'a>) -> Self {
        CursorIter {
            cursors: vec![cursor],
        }
    }
}

impl<'a> Iterator for CursorIter<'a> {
    type Item = Cursor<'a>;

    fn next(&mut self) -> Option<Self::Item> {
        if let Some(cursor) = self.cursors.pop() {
            match *cursor.cube {
                Cube::Branch(ref branch) => {
                    for (index, cube) in branch.iter().enumerate() {
                        self.cursors.push(Cursor::new(
                            cube,
                            cursor.root,
                            cursor.partition().at_index(index).unwrap()));
                    }
                },
                _ => {},
            }
            Some(cursor)
        }
        else {
            None
        }
    }
}

#[derive(Debug)]
pub enum JoinError {
    LeafJoined,
}

impl fmt::Display for JoinError {
    fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
        write!(formatter, "{}", self.description())
    }
}

impl error::Error for JoinError {
    fn description(&self) -> &str {
        match *self {
            JoinError::LeafJoined => "attempted to join leaf",
        }
    }
}

#[derive(Debug)]
pub enum SubdivideError {
    LimitExceeded,
    BranchSubdivided,
}

impl fmt::Display for SubdivideError {
    fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
        write!(formatter, "{}", self.description())
    }
}

impl error::Error for SubdivideError {
    fn description(&self) -> &str {
        match *self {
            SubdivideError::LimitExceeded => "minimum width limit exceeded",
            SubdivideError::BranchSubdivided => "attempted to subdivide branch",
        }
    }
}

pub struct CursorMut<'a> {
    cube: &'a mut Cube,
    root: &'a Partition,
    partition: Partition,
}

impl<'a> CursorMut<'a> {
    fn new(cube: &'a mut Cube, root: &'a Partition, partition: Partition) -> Self {
        CursorMut {
            cube: cube,
            root: root,
            partition: partition,
        }
    }

    pub fn resolve(&'a mut self, point: &Point, width: RootWidth) -> Self {
        let mut cube: Option<&mut Cube> = Some(self.cube);
        let mut depth = self.partition.width();

        let point = point.clamp(0, (1u32 << self.root.width()) - 1);
        let width = 1u32 << width.clamp(MIN_WIDTH, depth);

        while (width >> depth) == 0 {
            let inner = cube.take().unwrap();
            match *inner {
                Cube::Branch(ref mut branch) => {
                    depth = depth - 1;
                    cube = Some(&mut branch.cubes[index_at_point(&point, depth)]);
                }
                _ => {
                    cube = Some(inner);
                    break;
                }
            }
        }

        CursorMut::new(cube.take().unwrap(),
                       self.root,
                       Partition::at_point(&point, depth))
    }

    pub fn join(&mut self) -> Result<&mut Self, JoinError> {
        try!(self.cube.join());
        Ok(self)
    }

    pub fn subdivide(&mut self) -> Result<&mut Self, SubdivideError> {
        if self.partition.width() > MIN_WIDTH {
            try!(self.cube.subdivide());
            Ok(self)
        } else {
            Err(SubdivideError::LimitExceeded)
        }
    }
}

impl<'a> Traversal for CursorMut<'a> {
    fn partition(&self) -> &Partition {
        &self.partition
    }

    fn depth(&self) -> u8 {
        self.root.width() - self.partition.width()
    }
}

impl<'a> TraversalMut for CursorMut<'a> {}

impl<'a> ops::Deref for CursorMut<'a> {
    type Target = Cube;

    fn deref(&self) -> &Self::Target {
        self.cube
    }
}

impl<'a> ops::DerefMut for CursorMut<'a> {
    fn deref_mut(&mut self) -> &mut Self::Target {
        self.cube
    }
}

pub struct Tree {
    cube: Cube,
    partition: Partition,
}

impl Tree {
    pub fn new(width: RootWidth) -> Self {
        Tree {
            cube: Cube::new(),
            partition: Partition::at_point(&Point::origin(), width),
        }
    }

    pub fn cursor(&self) -> Cursor {
        Cursor::new(&self.cube, &self.partition, self.partition.clone())
    }

    pub fn cursor_mut(&mut self) -> CursorMut {
        CursorMut::new(&mut self.cube, &self.partition, self.partition.clone())
    }
}

impl Traversal for Tree {
    fn partition(&self) -> &Partition {
        &self.partition
    }

    fn depth(&self) -> u8 {
        0
    }
}

impl TraversalMut for Tree {}

impl ops::Deref for Tree {
    type Target = Cube;

    fn deref(&self) -> &Self::Target {
        &self.cube
    }
}

impl ops::DerefMut for Tree {
    fn deref_mut(&mut self) -> &mut Self::Target {
        &mut self.cube
    }
}

#[derive(Clone)]
pub enum Cube {
    Leaf(LeafNode),
    Branch(BranchNode),
}

impl Cube {
    fn new() -> Self {
        Cube::Leaf(LeafNode::new())
    }

    fn join(&mut self) -> Result<&mut Self, JoinError> {
        let cube = mem::replace(self, Cube::default());
        match cube {
            Cube::Branch(branch) => {
                *self = branch.join().into();
                Ok(self)
            }
            _ => {
                *self = cube;
                Err(JoinError::LeafJoined)
            }
        }
    }

    fn subdivide(&mut self) -> Result<&mut Self, SubdivideError> {
        let cube = mem::replace(self, Cube::default());
        match cube {
            Cube::Leaf(leaf) => {
                *self = leaf.subdivide().into();
                Ok(self)
            }
            _ => {
                *self = cube;
                Err(SubdivideError::BranchSubdivided)
            }
        }
    }

    pub fn is_leaf(&self) -> bool {
        match *self {
            Cube::Leaf(_) => true,
            _ => false,
        }
    }
}

impl Default for Cube {
    fn default() -> Self {
        Cube::new()
    }
}

impl From<LeafNode> for Cube {
    fn from(leaf: LeafNode) -> Self {
        Cube::Leaf(leaf)
    }
}

impl From<BranchNode> for Cube {
    fn from(branch: BranchNode) -> Self {
        Cube::Branch(branch)
    }
}

#[derive(Clone, Copy)]
pub struct LeafNode {
    pub geometry: [u32; 3],
    pub material: ResourceId,
}

impl LeafNode {
    fn new() -> Self {
        LeafNode {
            geometry: Geometry::full(),
            material: 0,
        }
    }

    fn subdivide(self) -> BranchNode {
        // TODO: Transform the geometry of the parent into the children.
        let cube: Cube = self.into();
        BranchNode {
            cubes: Box::new([cube.clone(),
                             cube.clone(),
                             cube.clone(),
                             cube.clone(),
                             cube.clone(),
                             cube.clone(),
                             cube.clone(),
                             cube]),
        }
    }
}

pub struct BranchNode {
    cubes: Box<[Cube; 8]>,
}

impl BranchNode {
    pub fn join(self) -> LeafNode {
        // TODO: Copy data from one of the original leaves.
        LeafNode::new()
    }
}

impl Clone for BranchNode {
    fn clone(&self) -> Self {
        BranchNode {
            cubes: Box::new([self.cubes[0].clone(),
                             self.cubes[1].clone(),
                             self.cubes[2].clone(),
                             self.cubes[3].clone(),
                             self.cubes[4].clone(),
                             self.cubes[5].clone(),
                             self.cubes[6].clone(),
                             self.cubes[7].clone()]),
        }
    }
}

impl ops::Deref for BranchNode {
    type Target = [Cube];

    fn deref(&self) -> &Self::Target {
        &*self.cubes
    }
}

trait Geometry {
    fn full() -> Self;
    fn empty() -> Self;
}

impl Geometry for [u32; 3] {
    fn full() -> Self {
        [0x0F0F0F0F; 3]
    }

    fn empty() -> Self {
        [0x00000000; 3]
    }
}

trait Subdivision {}

impl Subdivision for [Cube; 8] {}

trait Storage {}

impl Storage for Box<[Cube; 8]> {}

#[cfg_attr(rustfmt, rustfmt_skip)]
fn index_at_point(point: &Point, width: RootWidth) -> usize {
    ((((point.x >> width) & 1u32) << 0) |
     (((point.y >> width) & 1u32) << 1) |
     (((point.z >> width) & 1u32) << 2)) as usize
}

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


<commit_before>//! Graph traits for associated data and graph construction.

use Graph;
#[cfg(feature = "stable_graph")]
use stable_graph::StableGraph;
use ::{
    EdgeType,
};
use graph::IndexType;
#[cfg(feature = "graphmap")]
use graphmap::{GraphMap, NodeTrait};
use visit::{
    Data,
    NodeCount,
    NodeIndexable,
    Reversed,
};

trait_template!{
    /// Access node and edge weights (associated data).
pub trait DataMap : Data {
    @section self_ref
    fn node_weight(&self, id: Self::NodeId) -> Option<&Self::NodeWeight>;
    fn edge_weight(&self, id: Self::EdgeId) -> Option<&Self::EdgeWeight>;
}
}

macro_rules! access0 {
    ($e:expr) => ($e.0);
}

DataMap!{delegate_impl []}
DataMap!{delegate_impl [['a, G], G, &'a mut G, deref_twice]}
DataMap!{delegate_impl [[G], G, Reversed<G>, access0]}

trait_template! {
    /// Access node and edge weights mutably.
pub trait DataMapMut : DataMap {
    @section self_mut
    fn node_weight_mut(&mut self, id: Self::NodeId) -> Option<&mut Self::NodeWeight>;
    fn edge_weight_mut(&mut self, id: Self::EdgeId) -> Option<&mut Self::EdgeWeight>;
}
}

DataMapMut!{delegate_impl [['a, G], G, &'a mut G, deref_twice]}
DataMapMut!{delegate_impl [[G], G, Reversed<G>, access0]}

/// A graph that can be extended with further nodes and edges
pub trait Build : Data + NodeCount {
    fn add_node(&mut self, weight: Self::NodeWeight) -> Self::NodeId;
    /// Add a new edge. If parallel edges (duplicate) are not allowed and
    /// the edge already exists, return `None`.
    fn add_edge(&mut self,
                a: Self::NodeId,
                b: Self::NodeId,
                weight: Self::EdgeWeight) -> Option<Self::EdgeId> {
        Some(self.update_edge(a, b, weight))
    }
    /// Add or update the edge from `a` to `b`. Return the id of the affected
    /// edge.
    fn update_edge(&mut self,
                   a: Self::NodeId,
                   b: Self::NodeId,
                   weight: Self::EdgeWeight) -> Self::EdgeId;
}

/// A graph that can be created
pub trait Create : Build + Default {
    fn with_capacity(nodes: usize, edges: usize) -> Self;
}

impl<N, E, Ty, Ix> Data for Graph<N, E, Ty, Ix>
    where Ix: IndexType
{
    type NodeWeight = N;
    type EdgeWeight = E;
}

impl<N, E, Ty, Ix> DataMap for Graph<N, E, Ty, Ix>
    where Ty: EdgeType,
          Ix: IndexType
{
    fn node_weight(&self, id: Self::NodeId) -> Option<&Self::NodeWeight> {
        self.node_weight(id)
    }
    fn edge_weight(&self, id: Self::EdgeId) -> Option<&Self::EdgeWeight> {
        self.edge_weight(id)
    }
}

impl<N, E, Ty, Ix> DataMapMut for Graph<N, E, Ty, Ix>
    where Ty: EdgeType,
          Ix: IndexType
{
    fn node_weight_mut(&mut self, id: Self::NodeId) -> Option<&mut Self::NodeWeight> {
        self.node_weight_mut(id)
    }
    fn edge_weight_mut(&mut self, id: Self::EdgeId) -> Option<&mut Self::EdgeWeight> {
        self.edge_weight_mut(id)
    }
}

#[cfg(feature = "stable_graph")]
impl<N, E, Ty, Ix> DataMap for StableGraph<N, E, Ty, Ix>
    where Ty: EdgeType,
          Ix: IndexType
{
    fn node_weight(&self, id: Self::NodeId) -> Option<&Self::NodeWeight> {
        self.node_weight(id)
    }
    fn edge_weight(&self, id: Self::EdgeId) -> Option<&Self::EdgeWeight> {
        self.edge_weight(id)
    }
}

#[cfg(feature = "stable_graph")]
impl<N, E, Ty, Ix> DataMapMut for StableGraph<N, E, Ty, Ix>
    where Ty: EdgeType,
          Ix: IndexType
{
    fn node_weight_mut(&mut self, id: Self::NodeId) -> Option<&mut Self::NodeWeight> {
        self.node_weight_mut(id)
    }
    fn edge_weight_mut(&mut self, id: Self::EdgeId) -> Option<&mut Self::EdgeWeight> {
        self.edge_weight_mut(id)
    }
}

impl<N, E, Ty, Ix> Build for Graph<N, E, Ty, Ix>
    where Ty: EdgeType,
          Ix: IndexType,
{
    fn add_node(&mut self, weight: Self::NodeWeight) -> Self::NodeId {
        self.add_node(weight)
    }
    fn add_edge(&mut self,
                a: Self::NodeId,
                b: Self::NodeId,
                weight: Self::EdgeWeight) -> Option<Self::EdgeId>
    {
        Some(self.add_edge(a, b, weight))
    }
    fn update_edge(&mut self,
                   a: Self::NodeId,
                   b: Self::NodeId,
                   weight: Self::EdgeWeight) -> Self::EdgeId
    {
        self.update_edge(a, b, weight)
    }
}

#[cfg(feature = "stable_graph")]
impl<N, E, Ty, Ix> Build for StableGraph<N, E, Ty, Ix>
    where Ty: EdgeType,
          Ix: IndexType,
{
    fn add_node(&mut self, weight: Self::NodeWeight) -> Self::NodeId {
        self.add_node(weight)
    }
    fn add_edge(&mut self,
                a: Self::NodeId,
                b: Self::NodeId,
                weight: Self::EdgeWeight) -> Option<Self::EdgeId>
    {
        Some(self.add_edge(a, b, weight))
    }
    fn update_edge(&mut self,
                   a: Self::NodeId,
                   b: Self::NodeId,
                   weight: Self::EdgeWeight) -> Self::EdgeId
    {
        self.update_edge(a, b, weight)
    }
}

#[cfg(feature = "graphmap")]
impl<N, E, Ty> Build for GraphMap<N, E, Ty>
    where Ty: EdgeType,
          N: NodeTrait,
{
    fn add_node(&mut self, weight: Self::NodeWeight) -> Self::NodeId {
        self.add_node(weight)
    }
    fn add_edge(&mut self,
                a: Self::NodeId,
                b: Self::NodeId,
                weight: Self::EdgeWeight) -> Option<Self::EdgeId>
    {
        if self.contains_edge(a, b) {
            None
        } else {
            let r = self.add_edge(a, b, weight);
            debug_assert!(r.is_none());
            Some((a, b))
        }
    }
    fn update_edge(&mut self,
                   a: Self::NodeId,
                   b: Self::NodeId,
                   weight: Self::EdgeWeight) -> Self::EdgeId
    {
        self.add_edge(a, b, weight);
        (a, b)
    }
}

impl<N, E, Ty, Ix> Create for Graph<N, E, Ty, Ix>
    where Ty: EdgeType,
          Ix: IndexType,
{
    fn with_capacity(nodes: usize, edges: usize) -> Self {
        Self::with_capacity(nodes, edges)
    }
}

#[cfg(feature = "stable_graph")]
impl<N, E, Ty, Ix> Create for StableGraph<N, E, Ty, Ix>
    where Ty: EdgeType,
          Ix: IndexType,
{
    fn with_capacity(nodes: usize, edges: usize) -> Self {
        Self::with_capacity(nodes, edges)
    }
}

#[cfg(feature = "graphmap")]
impl<N, E, Ty> Create for GraphMap<N, E, Ty>
    where Ty: EdgeType,
          N: NodeTrait,
{
    fn with_capacity(nodes: usize, edges: usize) -> Self {
        Self::with_capacity(nodes, edges)
    }
}

/// A graph element.
///
/// A sequence of Elements, for example an iterator, is laid out as follows:
/// Nodes are implicitly given the index of their appearance in the sequence.
/// The edges’ source and target fields refer to these indices.
#[derive(Clone, Debug, PartialEq, Eq)]
pub enum Element<N, E> {
    /// A graph node.
    Node {
        weight: N,
    },
    /// A graph edge.
    Edge {
        source: usize,
        target: usize,
        weight: E,
    }
}

/// Create a graph from an iterator of elements.
pub trait FromElements : Create {
    fn from_elements<I>(iterable: I) -> Self
        where Self: Sized,
              I: IntoIterator<Item=Element<Self::NodeWeight, Self::EdgeWeight>>,
    {
        let mut gr = Self::with_capacity(0, 0);
        // usize -> NodeId map
        let mut map = Vec::new();
        for element in iterable {
            match element {
                Element::Node { weight } => {
                    map.push(gr.add_node(weight));
                }
                Element::Edge { source, target, weight } => {
                    gr.add_edge(map[source], map[target], weight);
                }
            }
        }
        gr
    }

}

fn from_elements_indexable<G, I>(iterable: I) -> G
    where G: Create + NodeIndexable,
          I: IntoIterator<Item=Element<G::NodeWeight, G::EdgeWeight>>,
{
    let mut gr = G::with_capacity(0, 0);
    let map = |gr: &G, i| gr.from_index(i);
    for element in iterable {
        match element {
            Element::Node { weight } => {
                gr.add_node(weight);
            }
            Element::Edge { source, target, weight } => {
                let from = map(&gr, source);
                let to = map(&gr, target);
                gr.add_edge(from, to, weight);
            }
        }
    }
    gr
}

impl<N, E, Ty, Ix> FromElements for Graph<N, E, Ty, Ix>
    where Ty: EdgeType,
          Ix: IndexType,
{
    fn from_elements<I>(iterable: I) -> Self
        where Self: Sized,
              I: IntoIterator<Item=Element<Self::NodeWeight, Self::EdgeWeight>>,
    {
        from_elements_indexable(iterable)
    }
}

#[cfg(feature = "stable_graph")]
impl<N, E, Ty, Ix> FromElements for StableGraph<N, E, Ty, Ix>
    where Ty: EdgeType,
          Ix: IndexType,
{
    fn from_elements<I>(iterable: I) -> Self
        where Self: Sized,
              I: IntoIterator<Item=Element<Self::NodeWeight, Self::EdgeWeight>>,
    {
        from_elements_indexable(iterable)
    }
}

#[cfg(feature = "graphmap")]
impl<N, E, Ty> FromElements for GraphMap<N, E, Ty>
    where Ty: EdgeType,
          N: NodeTrait,
{
    fn from_elements<I>(iterable: I) -> Self
        where Self: Sized,
              I: IntoIterator<Item=Element<Self::NodeWeight, Self::EdgeWeight>>,
    {
        from_elements_indexable(iterable)
    }
}

/// Iterator adaptors for iterators of `Element`.
pub trait ElementIterator<N, E> : Iterator<Item=Element<N, E>> {
    /// Create an iterator adaptor that filters graph elements.
    ///
    /// The function `f` is called with each element and if its return value
    /// is `true` the element is accepted and if `false` it is removed.
    ///
    /// `f` is called with mutable references to the node and edge weights,
    /// so that they can be mutated (but the edge endpoints can not).
    ///
    /// This filter adapts the edge source, target numbers in the
    /// stream so that they are correct after the removals.
    fn filter_elements<F>(self, f: F) -> FilterElements<Self, F>
        where Self: Sized,
              F: FnMut(Element<&mut N, &mut E>) -> bool,
    {
        FilterElements {
            iter: self,
            node_index: 0,
            map: Vec::new(),
            f: f,
        }
    }
}

impl<N, E, I: ?Sized> ElementIterator<N, E> for I
    where I: Iterator<Item=Element<N, E>> { }

/// An iterator that filters graph elements.
///
/// See [`.filter_elements()`][1] for more information.
///
/// [1]: trait.ElementIterator.html#method.filter_elements
pub struct FilterElements<I, F> {
    iter: I,
    node_index: usize,
    map: Vec<usize>,
    f: F,
}

impl<I, F, N, E> Iterator for FilterElements<I, F>
    where I: Iterator<Item=Element<N, E>>,
          F: FnMut(Element<&mut N, &mut E>) -> bool,
{
    type Item = Element<N, E>;

    fn next(&mut self) -> Option<Self::Item> {
        loop {
            let mut elt = match self.iter.next() {
                None => return None,
                Some(elt) => elt,
            };
            let keep = (self.f)(match elt {
                Element::Node { ref mut weight } => Element::Node { weight: weight },
                Element::Edge { source, target, ref mut weight }
                    => Element::Edge { source: source, target: target, weight: weight },
            });
            let is_node = if let Element::Node { .. } = elt { true } else { false };
            if !keep && is_node {
                self.map.push(self.node_index);
            }
            if is_node {
                self.node_index += 1;
            }
            if !keep {
                continue;
            }

            // map edge parts
            match elt {
                Element::Edge {
                    ref mut source,
                    ref mut target,
                    ..
                } => {
                    // Find the node indices in the map of removed ones.
                    // If a node was removed, the edge is as well.
                    // Otherwise the counts are adjusted by the number of nodes
                    // removed.
                    // Example: map: [1, 3, 4, 6]
                    // binary search for 2, result is Err(1). One node has been
                    // removed before 2.
                    match self.map.binary_search(source) {
                        Ok(_) => continue,
                        Err(i) => *source -= i,
                    }
                    match self.map.binary_search(target) {
                        Ok(_) => continue,
                        Err(i) => *target -= i,
                    }
                }
                Element::Node { .. } => { }
            }
            return Some(elt);
        }
    }
}
<commit_msg>filter_eleents: Update doc<commit_after>//! Graph traits for associated data and graph construction.

use Graph;
#[cfg(feature = "stable_graph")]
use stable_graph::StableGraph;
use ::{
    EdgeType,
};
use graph::IndexType;
#[cfg(feature = "graphmap")]
use graphmap::{GraphMap, NodeTrait};
use visit::{
    Data,
    NodeCount,
    NodeIndexable,
    Reversed,
};

trait_template!{
    /// Access node and edge weights (associated data).
pub trait DataMap : Data {
    @section self_ref
    fn node_weight(&self, id: Self::NodeId) -> Option<&Self::NodeWeight>;
    fn edge_weight(&self, id: Self::EdgeId) -> Option<&Self::EdgeWeight>;
}
}

macro_rules! access0 {
    ($e:expr) => ($e.0);
}

DataMap!{delegate_impl []}
DataMap!{delegate_impl [['a, G], G, &'a mut G, deref_twice]}
DataMap!{delegate_impl [[G], G, Reversed<G>, access0]}

trait_template! {
    /// Access node and edge weights mutably.
pub trait DataMapMut : DataMap {
    @section self_mut
    fn node_weight_mut(&mut self, id: Self::NodeId) -> Option<&mut Self::NodeWeight>;
    fn edge_weight_mut(&mut self, id: Self::EdgeId) -> Option<&mut Self::EdgeWeight>;
}
}

DataMapMut!{delegate_impl [['a, G], G, &'a mut G, deref_twice]}
DataMapMut!{delegate_impl [[G], G, Reversed<G>, access0]}

/// A graph that can be extended with further nodes and edges
pub trait Build : Data + NodeCount {
    fn add_node(&mut self, weight: Self::NodeWeight) -> Self::NodeId;
    /// Add a new edge. If parallel edges (duplicate) are not allowed and
    /// the edge already exists, return `None`.
    fn add_edge(&mut self,
                a: Self::NodeId,
                b: Self::NodeId,
                weight: Self::EdgeWeight) -> Option<Self::EdgeId> {
        Some(self.update_edge(a, b, weight))
    }
    /// Add or update the edge from `a` to `b`. Return the id of the affected
    /// edge.
    fn update_edge(&mut self,
                   a: Self::NodeId,
                   b: Self::NodeId,
                   weight: Self::EdgeWeight) -> Self::EdgeId;
}

/// A graph that can be created
pub trait Create : Build + Default {
    fn with_capacity(nodes: usize, edges: usize) -> Self;
}

impl<N, E, Ty, Ix> Data for Graph<N, E, Ty, Ix>
    where Ix: IndexType
{
    type NodeWeight = N;
    type EdgeWeight = E;
}

impl<N, E, Ty, Ix> DataMap for Graph<N, E, Ty, Ix>
    where Ty: EdgeType,
          Ix: IndexType
{
    fn node_weight(&self, id: Self::NodeId) -> Option<&Self::NodeWeight> {
        self.node_weight(id)
    }
    fn edge_weight(&self, id: Self::EdgeId) -> Option<&Self::EdgeWeight> {
        self.edge_weight(id)
    }
}

impl<N, E, Ty, Ix> DataMapMut for Graph<N, E, Ty, Ix>
    where Ty: EdgeType,
          Ix: IndexType
{
    fn node_weight_mut(&mut self, id: Self::NodeId) -> Option<&mut Self::NodeWeight> {
        self.node_weight_mut(id)
    }
    fn edge_weight_mut(&mut self, id: Self::EdgeId) -> Option<&mut Self::EdgeWeight> {
        self.edge_weight_mut(id)
    }
}

#[cfg(feature = "stable_graph")]
impl<N, E, Ty, Ix> DataMap for StableGraph<N, E, Ty, Ix>
    where Ty: EdgeType,
          Ix: IndexType
{
    fn node_weight(&self, id: Self::NodeId) -> Option<&Self::NodeWeight> {
        self.node_weight(id)
    }
    fn edge_weight(&self, id: Self::EdgeId) -> Option<&Self::EdgeWeight> {
        self.edge_weight(id)
    }
}

#[cfg(feature = "stable_graph")]
impl<N, E, Ty, Ix> DataMapMut for StableGraph<N, E, Ty, Ix>
    where Ty: EdgeType,
          Ix: IndexType
{
    fn node_weight_mut(&mut self, id: Self::NodeId) -> Option<&mut Self::NodeWeight> {
        self.node_weight_mut(id)
    }
    fn edge_weight_mut(&mut self, id: Self::EdgeId) -> Option<&mut Self::EdgeWeight> {
        self.edge_weight_mut(id)
    }
}

impl<N, E, Ty, Ix> Build for Graph<N, E, Ty, Ix>
    where Ty: EdgeType,
          Ix: IndexType,
{
    fn add_node(&mut self, weight: Self::NodeWeight) -> Self::NodeId {
        self.add_node(weight)
    }
    fn add_edge(&mut self,
                a: Self::NodeId,
                b: Self::NodeId,
                weight: Self::EdgeWeight) -> Option<Self::EdgeId>
    {
        Some(self.add_edge(a, b, weight))
    }
    fn update_edge(&mut self,
                   a: Self::NodeId,
                   b: Self::NodeId,
                   weight: Self::EdgeWeight) -> Self::EdgeId
    {
        self.update_edge(a, b, weight)
    }
}

#[cfg(feature = "stable_graph")]
impl<N, E, Ty, Ix> Build for StableGraph<N, E, Ty, Ix>
    where Ty: EdgeType,
          Ix: IndexType,
{
    fn add_node(&mut self, weight: Self::NodeWeight) -> Self::NodeId {
        self.add_node(weight)
    }
    fn add_edge(&mut self,
                a: Self::NodeId,
                b: Self::NodeId,
                weight: Self::EdgeWeight) -> Option<Self::EdgeId>
    {
        Some(self.add_edge(a, b, weight))
    }
    fn update_edge(&mut self,
                   a: Self::NodeId,
                   b: Self::NodeId,
                   weight: Self::EdgeWeight) -> Self::EdgeId
    {
        self.update_edge(a, b, weight)
    }
}

#[cfg(feature = "graphmap")]
impl<N, E, Ty> Build for GraphMap<N, E, Ty>
    where Ty: EdgeType,
          N: NodeTrait,
{
    fn add_node(&mut self, weight: Self::NodeWeight) -> Self::NodeId {
        self.add_node(weight)
    }
    fn add_edge(&mut self,
                a: Self::NodeId,
                b: Self::NodeId,
                weight: Self::EdgeWeight) -> Option<Self::EdgeId>
    {
        if self.contains_edge(a, b) {
            None
        } else {
            let r = self.add_edge(a, b, weight);
            debug_assert!(r.is_none());
            Some((a, b))
        }
    }
    fn update_edge(&mut self,
                   a: Self::NodeId,
                   b: Self::NodeId,
                   weight: Self::EdgeWeight) -> Self::EdgeId
    {
        self.add_edge(a, b, weight);
        (a, b)
    }
}

impl<N, E, Ty, Ix> Create for Graph<N, E, Ty, Ix>
    where Ty: EdgeType,
          Ix: IndexType,
{
    fn with_capacity(nodes: usize, edges: usize) -> Self {
        Self::with_capacity(nodes, edges)
    }
}

#[cfg(feature = "stable_graph")]
impl<N, E, Ty, Ix> Create for StableGraph<N, E, Ty, Ix>
    where Ty: EdgeType,
          Ix: IndexType,
{
    fn with_capacity(nodes: usize, edges: usize) -> Self {
        Self::with_capacity(nodes, edges)
    }
}

#[cfg(feature = "graphmap")]
impl<N, E, Ty> Create for GraphMap<N, E, Ty>
    where Ty: EdgeType,
          N: NodeTrait,
{
    fn with_capacity(nodes: usize, edges: usize) -> Self {
        Self::with_capacity(nodes, edges)
    }
}

/// A graph element.
///
/// A sequence of Elements, for example an iterator, is laid out as follows:
/// Nodes are implicitly given the index of their appearance in the sequence.
/// The edges’ source and target fields refer to these indices.
#[derive(Clone, Debug, PartialEq, Eq)]
pub enum Element<N, E> {
    /// A graph node.
    Node {
        weight: N,
    },
    /// A graph edge.
    Edge {
        source: usize,
        target: usize,
        weight: E,
    }
}

/// Create a graph from an iterator of elements.
pub trait FromElements : Create {
    fn from_elements<I>(iterable: I) -> Self
        where Self: Sized,
              I: IntoIterator<Item=Element<Self::NodeWeight, Self::EdgeWeight>>,
    {
        let mut gr = Self::with_capacity(0, 0);
        // usize -> NodeId map
        let mut map = Vec::new();
        for element in iterable {
            match element {
                Element::Node { weight } => {
                    map.push(gr.add_node(weight));
                }
                Element::Edge { source, target, weight } => {
                    gr.add_edge(map[source], map[target], weight);
                }
            }
        }
        gr
    }

}

fn from_elements_indexable<G, I>(iterable: I) -> G
    where G: Create + NodeIndexable,
          I: IntoIterator<Item=Element<G::NodeWeight, G::EdgeWeight>>,
{
    let mut gr = G::with_capacity(0, 0);
    let map = |gr: &G, i| gr.from_index(i);
    for element in iterable {
        match element {
            Element::Node { weight } => {
                gr.add_node(weight);
            }
            Element::Edge { source, target, weight } => {
                let from = map(&gr, source);
                let to = map(&gr, target);
                gr.add_edge(from, to, weight);
            }
        }
    }
    gr
}

impl<N, E, Ty, Ix> FromElements for Graph<N, E, Ty, Ix>
    where Ty: EdgeType,
          Ix: IndexType,
{
    fn from_elements<I>(iterable: I) -> Self
        where Self: Sized,
              I: IntoIterator<Item=Element<Self::NodeWeight, Self::EdgeWeight>>,
    {
        from_elements_indexable(iterable)
    }
}

#[cfg(feature = "stable_graph")]
impl<N, E, Ty, Ix> FromElements for StableGraph<N, E, Ty, Ix>
    where Ty: EdgeType,
          Ix: IndexType,
{
    fn from_elements<I>(iterable: I) -> Self
        where Self: Sized,
              I: IntoIterator<Item=Element<Self::NodeWeight, Self::EdgeWeight>>,
    {
        from_elements_indexable(iterable)
    }
}

#[cfg(feature = "graphmap")]
impl<N, E, Ty> FromElements for GraphMap<N, E, Ty>
    where Ty: EdgeType,
          N: NodeTrait,
{
    fn from_elements<I>(iterable: I) -> Self
        where Self: Sized,
              I: IntoIterator<Item=Element<Self::NodeWeight, Self::EdgeWeight>>,
    {
        from_elements_indexable(iterable)
    }
}

/// Iterator adaptors for iterators of `Element`.
pub trait ElementIterator<N, E> : Iterator<Item=Element<N, E>> {
    /// Create an iterator adaptor that filters graph elements.
    ///
    /// The function `f` is called with each element and if its return value
    /// is `true` the element is accepted and if `false` it is removed.
    /// `f` is called with mutable references to the node and edge weights,
    /// so that they can be mutated (but the edge endpoints can not).
    ///
    /// This filter adapts the edge source and target indices in the
    /// stream so that they are correct after the removals.
    fn filter_elements<F>(self, f: F) -> FilterElements<Self, F>
        where Self: Sized,
              F: FnMut(Element<&mut N, &mut E>) -> bool,
    {
        FilterElements {
            iter: self,
            node_index: 0,
            map: Vec::new(),
            f: f,
        }
    }
}

impl<N, E, I: ?Sized> ElementIterator<N, E> for I
    where I: Iterator<Item=Element<N, E>> { }

/// An iterator that filters graph elements.
///
/// See [`.filter_elements()`][1] for more information.
///
/// [1]: trait.ElementIterator.html#method.filter_elements
pub struct FilterElements<I, F> {
    iter: I,
    node_index: usize,
    map: Vec<usize>,
    f: F,
}

impl<I, F, N, E> Iterator for FilterElements<I, F>
    where I: Iterator<Item=Element<N, E>>,
          F: FnMut(Element<&mut N, &mut E>) -> bool,
{
    type Item = Element<N, E>;

    fn next(&mut self) -> Option<Self::Item> {
        loop {
            let mut elt = match self.iter.next() {
                None => return None,
                Some(elt) => elt,
            };
            let keep = (self.f)(match elt {
                Element::Node { ref mut weight } => Element::Node { weight: weight },
                Element::Edge { source, target, ref mut weight }
                    => Element::Edge { source: source, target: target, weight: weight },
            });
            let is_node = if let Element::Node { .. } = elt { true } else { false };
            if !keep && is_node {
                self.map.push(self.node_index);
            }
            if is_node {
                self.node_index += 1;
            }
            if !keep {
                continue;
            }

            // map edge parts
            match elt {
                Element::Edge {
                    ref mut source,
                    ref mut target,
                    ..
                } => {
                    // Find the node indices in the map of removed ones.
                    // If a node was removed, the edge is as well.
                    // Otherwise the counts are adjusted by the number of nodes
                    // removed.
                    // Example: map: [1, 3, 4, 6]
                    // binary search for 2, result is Err(1). One node has been
                    // removed before 2.
                    match self.map.binary_search(source) {
                        Ok(_) => continue,
                        Err(i) => *source -= i,
                    }
                    match self.map.binary_search(target) {
                        Ok(_) => continue,
                        Err(i) => *target -= i,
                    }
                }
                Element::Node { .. } => { }
            }
            return Some(elt);
        }
    }
}
<|endoftext|>


<commit_before>// This is a part of rust-chrono.
// Copyright (c) 2014, Kang Seonghoon.
// See README.md and LICENSE.txt for details.

/*!
 * ISO 8601 calendar date with timezone.
 */

use std::{fmt, hash};

use {Weekday, Datelike};
use duration::Duration;
use offset::{Offset, UTC};
use naive;
use naive::date::NaiveDate;
use naive::time::NaiveTime;
use datetime::DateTime;
use format::DelayedFormat;

/// ISO 8601 calendar date with timezone.
#[deriving(Clone)]
pub struct Date<Off> {
    date: NaiveDate,
    offset: Off,
}

/// The minimum possible `Date`.
pub const MIN: Date<UTC> = Date { date: naive::date::MIN, offset: UTC };
/// The maximum possible `Date`.
pub const MAX: Date<UTC> = Date { date: naive::date::MAX, offset: UTC };

impl<Off:Offset> Date<Off> {
    /// Makes a new `Date` with given *UTC* date and offset.
    /// The local date should be constructed via the `Offset` trait.
    #[inline]
    pub fn from_utc(date: NaiveDate, offset: Off) -> Date<Off> {
        Date { date: date, offset: offset }
    }

    /// Makes a new `DateTime` from the current date and given `NaiveTime`.
    /// The offset in the current date is preserved.
    ///
    /// Fails on invalid datetime.
    #[inline]
    pub fn and_time(&self, time: NaiveTime) -> Option<DateTime<Off>> {
        self.offset.from_local_datetime(&self.date.and_time(time)).single()
    }

    /// Makes a new `DateTime` from the current date, hour, minute and second.
    /// The offset in the current date is preserved.
    ///
    /// Fails on invalid hour, minute and/or second.
    #[inline]
    pub fn and_hms(&self, hour: u32, min: u32, sec: u32) -> DateTime<Off> {
        self.and_hms_opt(hour, min, sec).expect("invalid time")
    }

    /// Makes a new `DateTime` from the current date, hour, minute and second.
    /// The offset in the current date is preserved.
    ///
    /// Returns `None` on invalid hour, minute and/or second.
    #[inline]
    pub fn and_hms_opt(&self, hour: u32, min: u32, sec: u32) -> Option<DateTime<Off>> {
        NaiveTime::from_hms_opt(hour, min, sec).and_then(|time| self.and_time(time))
    }

    /// Makes a new `DateTime` from the current date, hour, minute, second and millisecond.
    /// The millisecond part can exceed 1,000 in order to represent the leap second.
    /// The offset in the current date is preserved.
    ///
    /// Fails on invalid hour, minute, second and/or millisecond.
    #[inline]
    pub fn and_hms_milli(&self, hour: u32, min: u32, sec: u32, milli: u32) -> DateTime<Off> {
        self.and_hms_milli_opt(hour, min, sec, milli).expect("invalid time")
    }

    /// Makes a new `DateTime` from the current date, hour, minute, second and millisecond.
    /// The millisecond part can exceed 1,000 in order to represent the leap second.
    /// The offset in the current date is preserved.
    ///
    /// Returns `None` on invalid hour, minute, second and/or millisecond.
    #[inline]
    pub fn and_hms_milli_opt(&self, hour: u32, min: u32, sec: u32,
                             milli: u32) -> Option<DateTime<Off>> {
        NaiveTime::from_hms_milli_opt(hour, min, sec, milli).and_then(|time| self.and_time(time))
    }

    /// Makes a new `DateTime` from the current date, hour, minute, second and microsecond.
    /// The microsecond part can exceed 1,000,000 in order to represent the leap second.
    /// The offset in the current date is preserved.
    ///
    /// Fails on invalid hour, minute, second and/or microsecond.
    #[inline]
    pub fn and_hms_micro(&self, hour: u32, min: u32, sec: u32, micro: u32) -> DateTime<Off> {
        self.and_hms_micro_opt(hour, min, sec, micro).expect("invalid time")
    }

    /// Makes a new `DateTime` from the current date, hour, minute, second and microsecond.
    /// The microsecond part can exceed 1,000,000 in order to represent the leap second.
    /// The offset in the current date is preserved.
    ///
    /// Returns `None` on invalid hour, minute, second and/or microsecond.
    #[inline]
    pub fn and_hms_micro_opt(&self, hour: u32, min: u32, sec: u32,
                             micro: u32) -> Option<DateTime<Off>> {
        NaiveTime::from_hms_micro_opt(hour, min, sec, micro).and_then(|time| self.and_time(time))
    }

    /// Makes a new `DateTime` from the current date, hour, minute, second and nanosecond.
    /// The nanosecond part can exceed 1,000,000,000 in order to represent the leap second.
    /// The offset in the current date is preserved.
    ///
    /// Fails on invalid hour, minute, second and/or nanosecond.
    #[inline]
    pub fn and_hms_nano(&self, hour: u32, min: u32, sec: u32, nano: u32) -> DateTime<Off> {
        self.and_hms_nano_opt(hour, min, sec, nano).expect("invalid time")
    }

    /// Makes a new `DateTime` from the current date, hour, minute, second and nanosecond.
    /// The nanosecond part can exceed 1,000,000,000 in order to represent the leap second.
    /// The offset in the current date is preserved.
    ///
    /// Returns `None` on invalid hour, minute, second and/or nanosecond.
    #[inline]
    pub fn and_hms_nano_opt(&self, hour: u32, min: u32, sec: u32,
                            nano: u32) -> Option<DateTime<Off>> {
        NaiveTime::from_hms_nano_opt(hour, min, sec, nano).and_then(|time| self.and_time(time))
    }

    /// Makes a new `Date` for the next date.
    ///
    /// Fails when `self` is the last representable date.
    #[inline]
    pub fn succ(&self) -> Date<Off> {
        self.succ_opt().expect("out of bound")
    }

    /// Makes a new `Date` for the next date.
    ///
    /// Returns `None` when `self` is the last representable date.
    #[inline]
    pub fn succ_opt(&self) -> Option<Date<Off>> {
        self.date.succ_opt().map(|date| Date::from_utc(date, self.offset.clone()))
    }

    /// Makes a new `Date` for the prior date.
    ///
    /// Fails when `self` is the first representable date.
    #[inline]
    pub fn pred(&self) -> Date<Off> {
        self.pred_opt().expect("out of bound")
    }

    /// Makes a new `Date` for the prior date.
    ///
    /// Returns `None` when `self` is the first representable date.
    #[inline]
    pub fn pred_opt(&self) -> Option<Date<Off>> {
        self.date.pred_opt().map(|date| Date::from_utc(date, self.offset.clone()))
    }

    /// Retrieves an associated offset.
    #[inline]
    pub fn offset<'a>(&'a self) -> &'a Off {
        &self.offset
    }

    /// Changes the associated offset.
    /// This does not change the actual `Date` (but will change the string representation).
    #[inline]
    pub fn with_offset<Off2:Offset>(&self, offset: Off2) -> Date<Off2> {
        Date::from_utc(self.date, offset)
    }

    /// Formats the date in the specified format string.
    /// See the `format` module on the supported escape sequences.
    #[inline]
    pub fn format<'a>(&'a self, fmt: &'a str) -> DelayedFormat<'a> {
        DelayedFormat::new_with_offset(Some(self.local()), None, &self.offset, fmt)
    }

    /// Returns a view to the local date.
    fn local(&self) -> NaiveDate {
        self.offset.to_local_date(&self.date)
    }
}

impl<Off:Offset> Datelike for Date<Off> {
    #[inline] fn year(&self) -> i32 { self.local().year() }
    #[inline] fn month(&self) -> u32 { self.local().month() }
    #[inline] fn month0(&self) -> u32 { self.local().month0() }
    #[inline] fn day(&self) -> u32 { self.local().day() }
    #[inline] fn day0(&self) -> u32 { self.local().day0() }
    #[inline] fn ordinal(&self) -> u32 { self.local().ordinal() }
    #[inline] fn ordinal0(&self) -> u32 { self.local().ordinal0() }
    #[inline] fn weekday(&self) -> Weekday { self.local().weekday() }
    #[inline] fn isoweekdate(&self) -> (i32, u32, Weekday) { self.local().isoweekdate() }

    #[inline]
    fn with_year(&self, year: i32) -> Option<Date<Off>> {
        self.local().with_year(year)
            .and_then(|date| self.offset.from_local_date(&date).single())
    }

    #[inline]
    fn with_month(&self, month: u32) -> Option<Date<Off>> {
        self.local().with_month(month)
            .and_then(|date| self.offset.from_local_date(&date).single())
    }

    #[inline]
    fn with_month0(&self, month0: u32) -> Option<Date<Off>> {
        self.local().with_month0(month0)
            .and_then(|date| self.offset.from_local_date(&date).single())
    }

    #[inline]
    fn with_day(&self, day: u32) -> Option<Date<Off>> {
        self.local().with_day(day)
            .and_then(|date| self.offset.from_local_date(&date).single())
    }

    #[inline]
    fn with_day0(&self, day0: u32) -> Option<Date<Off>> {
        self.local().with_day0(day0)
            .and_then(|date| self.offset.from_local_date(&date).single())
    }

    #[inline]
    fn with_ordinal(&self, ordinal: u32) -> Option<Date<Off>> {
        self.local().with_ordinal(ordinal)
            .and_then(|date| self.offset.from_local_date(&date).single())
    }

    #[inline]
    fn with_ordinal0(&self, ordinal0: u32) -> Option<Date<Off>> {
        self.local().with_ordinal0(ordinal0)
            .and_then(|date| self.offset.from_local_date(&date).single())
    }
}

impl<Off:Offset, Off2:Offset> PartialEq<Date<Off2>> for Date<Off> {
    fn eq(&self, other: &Date<Off2>) -> bool { self.date == other.date }
}

impl<Off:Offset, Off2:Offset> Eq<Date<Off2>> for Date<Off> {
}

impl<Off:Offset> PartialOrd for Date<Off> {
    fn partial_cmp(&self, other: &Date<Off>) -> Option<Ordering> {
        self.date.partial_cmp(&other.date)
    }
}

impl<Off:Offset> Ord for Date<Off> {
    fn cmp(&self, other: &Date<Off>) -> Ordering { self.date.cmp(&other.date) }
}

impl<Off:Offset> hash::Hash for Date<Off> {
    fn hash(&self, state: &mut hash::sip::SipState) { self.date.hash(state) }
}

impl<Off:Offset> Add<Duration,Date<Off>> for Date<Off> {
    fn add(&self, rhs: &Duration) -> Date<Off> {
        Date { date: self.date + *rhs, offset: self.offset.clone() }
    }
}

impl<Off:Offset> Add<Date<Off>,Date<Off>> for Duration {
    #[inline]
    fn add(&self, rhs: &Date<Off>) -> Date<Off> { rhs.add(self) }
}

impl<Off:Offset, Off2:Offset> Sub<Date<Off2>,Duration> for Date<Off> {
    fn sub(&self, rhs: &Date<Off2>) -> Duration {
        self.date - rhs.date
    }
}

impl<Off:Offset> Sub<Duration,Date<Off>> for Date<Off> {
    #[inline]
    fn sub(&self, rhs: &Duration) -> Date<Off> { self.add(&-*rhs) }
}

impl<Off:Offset> fmt::Show for Date<Off> {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        write!(f, "{}{}", self.local(), self.offset)
    }
}

<commit_msg>fixed an edge case with date-changing offsets.<commit_after>// This is a part of rust-chrono.
// Copyright (c) 2014, Kang Seonghoon.
// See README.md and LICENSE.txt for details.

/*!
 * ISO 8601 calendar date with timezone.
 */

use std::{fmt, hash};

use {Weekday, Datelike};
use duration::Duration;
use offset::{Offset, UTC};
use naive;
use naive::date::NaiveDate;
use naive::time::NaiveTime;
use datetime::DateTime;
use format::DelayedFormat;

/// ISO 8601 calendar date with timezone.
#[deriving(Clone)]
pub struct Date<Off> {
    date: NaiveDate,
    offset: Off,
}

/// The minimum possible `Date`.
pub const MIN: Date<UTC> = Date { date: naive::date::MIN, offset: UTC };
/// The maximum possible `Date`.
pub const MAX: Date<UTC> = Date { date: naive::date::MAX, offset: UTC };

impl<Off:Offset> Date<Off> {
    /// Makes a new `Date` with given *UTC* date and offset.
    /// The local date should be constructed via the `Offset` trait.
    #[inline]
    pub fn from_utc(date: NaiveDate, offset: Off) -> Date<Off> {
        Date { date: date, offset: offset }
    }

    /// Makes a new `DateTime` from the current date and given `NaiveTime`.
    /// The offset in the current date is preserved.
    ///
    /// Fails on invalid datetime.
    #[inline]
    pub fn and_time(&self, time: NaiveTime) -> Option<DateTime<Off>> {
        let localdt = self.offset.to_local_date(&self.date).and_time(time);
        self.offset.from_local_datetime(&localdt).single()
    }

    /// Makes a new `DateTime` from the current date, hour, minute and second.
    /// The offset in the current date is preserved.
    ///
    /// Fails on invalid hour, minute and/or second.
    #[inline]
    pub fn and_hms(&self, hour: u32, min: u32, sec: u32) -> DateTime<Off> {
        self.and_hms_opt(hour, min, sec).expect("invalid time")
    }

    /// Makes a new `DateTime` from the current date, hour, minute and second.
    /// The offset in the current date is preserved.
    ///
    /// Returns `None` on invalid hour, minute and/or second.
    #[inline]
    pub fn and_hms_opt(&self, hour: u32, min: u32, sec: u32) -> Option<DateTime<Off>> {
        NaiveTime::from_hms_opt(hour, min, sec).and_then(|time| self.and_time(time))
    }

    /// Makes a new `DateTime` from the current date, hour, minute, second and millisecond.
    /// The millisecond part can exceed 1,000 in order to represent the leap second.
    /// The offset in the current date is preserved.
    ///
    /// Fails on invalid hour, minute, second and/or millisecond.
    #[inline]
    pub fn and_hms_milli(&self, hour: u32, min: u32, sec: u32, milli: u32) -> DateTime<Off> {
        self.and_hms_milli_opt(hour, min, sec, milli).expect("invalid time")
    }

    /// Makes a new `DateTime` from the current date, hour, minute, second and millisecond.
    /// The millisecond part can exceed 1,000 in order to represent the leap second.
    /// The offset in the current date is preserved.
    ///
    /// Returns `None` on invalid hour, minute, second and/or millisecond.
    #[inline]
    pub fn and_hms_milli_opt(&self, hour: u32, min: u32, sec: u32,
                             milli: u32) -> Option<DateTime<Off>> {
        NaiveTime::from_hms_milli_opt(hour, min, sec, milli).and_then(|time| self.and_time(time))
    }

    /// Makes a new `DateTime` from the current date, hour, minute, second and microsecond.
    /// The microsecond part can exceed 1,000,000 in order to represent the leap second.
    /// The offset in the current date is preserved.
    ///
    /// Fails on invalid hour, minute, second and/or microsecond.
    #[inline]
    pub fn and_hms_micro(&self, hour: u32, min: u32, sec: u32, micro: u32) -> DateTime<Off> {
        self.and_hms_micro_opt(hour, min, sec, micro).expect("invalid time")
    }

    /// Makes a new `DateTime` from the current date, hour, minute, second and microsecond.
    /// The microsecond part can exceed 1,000,000 in order to represent the leap second.
    /// The offset in the current date is preserved.
    ///
    /// Returns `None` on invalid hour, minute, second and/or microsecond.
    #[inline]
    pub fn and_hms_micro_opt(&self, hour: u32, min: u32, sec: u32,
                             micro: u32) -> Option<DateTime<Off>> {
        NaiveTime::from_hms_micro_opt(hour, min, sec, micro).and_then(|time| self.and_time(time))
    }

    /// Makes a new `DateTime` from the current date, hour, minute, second and nanosecond.
    /// The nanosecond part can exceed 1,000,000,000 in order to represent the leap second.
    /// The offset in the current date is preserved.
    ///
    /// Fails on invalid hour, minute, second and/or nanosecond.
    #[inline]
    pub fn and_hms_nano(&self, hour: u32, min: u32, sec: u32, nano: u32) -> DateTime<Off> {
        self.and_hms_nano_opt(hour, min, sec, nano).expect("invalid time")
    }

    /// Makes a new `DateTime` from the current date, hour, minute, second and nanosecond.
    /// The nanosecond part can exceed 1,000,000,000 in order to represent the leap second.
    /// The offset in the current date is preserved.
    ///
    /// Returns `None` on invalid hour, minute, second and/or nanosecond.
    #[inline]
    pub fn and_hms_nano_opt(&self, hour: u32, min: u32, sec: u32,
                            nano: u32) -> Option<DateTime<Off>> {
        NaiveTime::from_hms_nano_opt(hour, min, sec, nano).and_then(|time| self.and_time(time))
    }

    /// Makes a new `Date` for the next date.
    ///
    /// Fails when `self` is the last representable date.
    #[inline]
    pub fn succ(&self) -> Date<Off> {
        self.succ_opt().expect("out of bound")
    }

    /// Makes a new `Date` for the next date.
    ///
    /// Returns `None` when `self` is the last representable date.
    #[inline]
    pub fn succ_opt(&self) -> Option<Date<Off>> {
        self.date.succ_opt().map(|date| Date::from_utc(date, self.offset.clone()))
    }

    /// Makes a new `Date` for the prior date.
    ///
    /// Fails when `self` is the first representable date.
    #[inline]
    pub fn pred(&self) -> Date<Off> {
        self.pred_opt().expect("out of bound")
    }

    /// Makes a new `Date` for the prior date.
    ///
    /// Returns `None` when `self` is the first representable date.
    #[inline]
    pub fn pred_opt(&self) -> Option<Date<Off>> {
        self.date.pred_opt().map(|date| Date::from_utc(date, self.offset.clone()))
    }

    /// Retrieves an associated offset.
    #[inline]
    pub fn offset<'a>(&'a self) -> &'a Off {
        &self.offset
    }

    /// Changes the associated offset.
    /// This does not change the actual `Date` (but will change the string representation).
    #[inline]
    pub fn with_offset<Off2:Offset>(&self, offset: Off2) -> Date<Off2> {
        Date::from_utc(self.date, offset)
    }

    /// Formats the date in the specified format string.
    /// See the `format` module on the supported escape sequences.
    #[inline]
    pub fn format<'a>(&'a self, fmt: &'a str) -> DelayedFormat<'a> {
        DelayedFormat::new_with_offset(Some(self.local()), None, &self.offset, fmt)
    }

    /// Returns a view to the local date.
    fn local(&self) -> NaiveDate {
        self.offset.to_local_date(&self.date)
    }
}

impl<Off:Offset> Datelike for Date<Off> {
    #[inline] fn year(&self) -> i32 { self.local().year() }
    #[inline] fn month(&self) -> u32 { self.local().month() }
    #[inline] fn month0(&self) -> u32 { self.local().month0() }
    #[inline] fn day(&self) -> u32 { self.local().day() }
    #[inline] fn day0(&self) -> u32 { self.local().day0() }
    #[inline] fn ordinal(&self) -> u32 { self.local().ordinal() }
    #[inline] fn ordinal0(&self) -> u32 { self.local().ordinal0() }
    #[inline] fn weekday(&self) -> Weekday { self.local().weekday() }
    #[inline] fn isoweekdate(&self) -> (i32, u32, Weekday) { self.local().isoweekdate() }

    #[inline]
    fn with_year(&self, year: i32) -> Option<Date<Off>> {
        self.local().with_year(year)
            .and_then(|date| self.offset.from_local_date(&date).single())
    }

    #[inline]
    fn with_month(&self, month: u32) -> Option<Date<Off>> {
        self.local().with_month(month)
            .and_then(|date| self.offset.from_local_date(&date).single())
    }

    #[inline]
    fn with_month0(&self, month0: u32) -> Option<Date<Off>> {
        self.local().with_month0(month0)
            .and_then(|date| self.offset.from_local_date(&date).single())
    }

    #[inline]
    fn with_day(&self, day: u32) -> Option<Date<Off>> {
        self.local().with_day(day)
            .and_then(|date| self.offset.from_local_date(&date).single())
    }

    #[inline]
    fn with_day0(&self, day0: u32) -> Option<Date<Off>> {
        self.local().with_day0(day0)
            .and_then(|date| self.offset.from_local_date(&date).single())
    }

    #[inline]
    fn with_ordinal(&self, ordinal: u32) -> Option<Date<Off>> {
        self.local().with_ordinal(ordinal)
            .and_then(|date| self.offset.from_local_date(&date).single())
    }

    #[inline]
    fn with_ordinal0(&self, ordinal0: u32) -> Option<Date<Off>> {
        self.local().with_ordinal0(ordinal0)
            .and_then(|date| self.offset.from_local_date(&date).single())
    }
}

impl<Off:Offset, Off2:Offset> PartialEq<Date<Off2>> for Date<Off> {
    fn eq(&self, other: &Date<Off2>) -> bool { self.date == other.date }
}

impl<Off:Offset, Off2:Offset> Eq<Date<Off2>> for Date<Off> {
}

impl<Off:Offset> PartialOrd for Date<Off> {
    fn partial_cmp(&self, other: &Date<Off>) -> Option<Ordering> {
        self.date.partial_cmp(&other.date)
    }
}

impl<Off:Offset> Ord for Date<Off> {
    fn cmp(&self, other: &Date<Off>) -> Ordering { self.date.cmp(&other.date) }
}

impl<Off:Offset> hash::Hash for Date<Off> {
    fn hash(&self, state: &mut hash::sip::SipState) { self.date.hash(state) }
}

impl<Off:Offset> Add<Duration,Date<Off>> for Date<Off> {
    fn add(&self, rhs: &Duration) -> Date<Off> {
        Date { date: self.date + *rhs, offset: self.offset.clone() }
    }
}

impl<Off:Offset> Add<Date<Off>,Date<Off>> for Duration {
    #[inline]
    fn add(&self, rhs: &Date<Off>) -> Date<Off> { rhs.add(self) }
}

impl<Off:Offset, Off2:Offset> Sub<Date<Off2>,Duration> for Date<Off> {
    fn sub(&self, rhs: &Date<Off2>) -> Duration {
        self.date - rhs.date
    }
}

impl<Off:Offset> Sub<Duration,Date<Off>> for Date<Off> {
    #[inline]
    fn sub(&self, rhs: &Duration) -> Date<Off> { self.add(&-*rhs) }
}

impl<Off:Offset> fmt::Show for Date<Off> {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        write!(f, "{}{}", self.local(), self.offset)
    }
}

#[cfg(test)]
mod tests {
    use std::fmt;
    use std::str::SendStr;

    use duration::Duration;
    use naive::date::NaiveDate;
    use naive::time::NaiveTime;
    use naive::datetime::NaiveDateTime;
    use super::Date;
    use time::Time;
    use datetime::DateTime;
    use offset::{Offset, LocalResult};

    #[deriving(Copy, Clone, PartialEq, Eq)]
    struct UTC1y; // same to UTC but with an offset of 365 days

    impl Offset for UTC1y {
        fn name(&self) -> SendStr { "UTC+8760".into_cow() } // yes, no kidding
        fn local_minus_utc(&self) -> Duration { Duration::zero() }

        fn from_local_date(&self, local: &NaiveDate) -> LocalResult<Date<UTC1y>> {
            LocalResult::Single(Date::from_utc(*local - Duration::days(365), UTC1y))
        }
        fn from_local_time(&self, local: &NaiveTime) -> LocalResult<Time<UTC1y>> {
            LocalResult::Single(Time::from_utc(local.clone(), UTC1y))
        }
        fn from_local_datetime(&self, local: &NaiveDateTime) -> LocalResult<DateTime<UTC1y>> {
            LocalResult::Single(DateTime::from_utc(*local - Duration::days(365), UTC1y))
        }

        fn to_local_date(&self, utc: &NaiveDate) -> NaiveDate { *utc + Duration::days(365) }
        fn to_local_time(&self, utc: &NaiveTime) -> NaiveTime { utc.clone() }
        fn to_local_datetime(&self, utc: &NaiveDateTime) -> NaiveDateTime {
            *utc + Duration::days(365)
        }
    }

    impl fmt::Show for UTC1y {
        fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { write!(f, "+8760:00") }
    }

    #[test]
    fn test_date_weird_offset() {
        assert_eq!(UTC1y.ymd(2012, 2, 29).to_string(),
                   "2012-02-29+8760:00".to_string());
        assert_eq!(UTC1y.ymd(2012, 2, 29).and_hms(5, 6, 7).to_string(),
                   "2012-02-29T05:06:07+8760:00".to_string());
        assert_eq!(UTC1y.ymd(2012, 3, 4).to_string(),
                   "2012-03-04+8760:00".to_string());
        assert_eq!(UTC1y.ymd(2012, 3, 4).and_hms(5, 6, 7).to_string(),
                   "2012-03-04T05:06:07+8760:00".to_string());
    }
}

<|endoftext|>


<commit_before>use std::path::{Path, PathBuf};

use xdg;
use rustc_version;

fn xdg_dir() -> xdg::BaseDirectories {
    let prefix = Path::new("afl.rs")
        .join(rustc_version::version().unwrap().to_string())
        .join(pkg_version());
    xdg::BaseDirectories::with_prefix(prefix).unwrap()
}

fn pkg_version() -> &'static str {
    let version = env!("CARGO_PKG_VERSION");
    assert!(!version.is_empty());
    version
}

pub fn afl() -> PathBuf {
    xdg_dir().create_data_directory("afl").unwrap()
}

pub fn afl_llvm_rt() -> PathBuf {
    xdg_dir().create_data_directory("afl-llvm-rt").unwrap()
}
<commit_msg>Prefix more things.<commit_after>use std::path::{Path, PathBuf};

use xdg;
use rustc_version;

fn xdg_dir() -> xdg::BaseDirectories {
    let prefix = Path::new("afl.rs")
        .join(rustc_version())
        .join(pkg_version());
    xdg::BaseDirectories::with_prefix(prefix).unwrap()
}

fn rustc_version() -> String {
    let mut ret = String::from("rustc-");
    ret.push_str(&rustc_version::version().unwrap().to_string());
    ret
}

fn pkg_version() -> String {
    let mut ret = String::from("afl.rs-");

    let version = env!("CARGO_PKG_VERSION");
    assert!(!version.is_empty());

    ret.push_str(version);
    ret
}

pub fn afl() -> PathBuf {
    xdg_dir().create_data_directory("afl").unwrap()
}

pub fn afl_llvm_rt() -> PathBuf {
    xdg_dir().create_data_directory("afl-llvm-rt").unwrap()
}
<|endoftext|>


<commit_before>//! Eigenvalue decomposition for Hermite matrices

use ndarray::*;

use crate::diagonal::*;
use crate::error::*;
use crate::layout::*;
use crate::operator::LinearOperator;
use crate::types::*;
use crate::UPLO;
use std::iter::FromIterator;

/// Eigenvalue decomposition of Hermite matrix reference
pub trait Eigh {
    type EigVal;
    type EigVec;
    fn eigh(&self, uplo: UPLO) -> Result<(Self::EigVal, Self::EigVec)>;
}

/// Eigenvalue decomposition of mutable reference of Hermite matrix
pub trait EighInplace {
    type EigVal;
    fn eigh_inplace(&mut self, uplo: UPLO) -> Result<(Self::EigVal, &mut Self)>;
}

/// Eigenvalue decomposition of Hermite matrix
pub trait EighInto: Sized {
    type EigVal;
    fn eigh_into(self, uplo: UPLO) -> Result<(Self::EigVal, Self)>;
}

impl<A, S> EighInto for ArrayBase<S, Ix2>
where
    A: Scalar + Lapack,
    S: DataMut<Elem = A>,
{
    type EigVal = Array1<A::Real>;

    fn eigh_into(mut self, uplo: UPLO) -> Result<(Self::EigVal, Self)> {
        let (val, _) = self.eigh_inplace(uplo)?;
        Ok((val, self))
    }
}

impl<A, S> EighInto for (ArrayBase<S, Ix2>, ArrayBase<S, Ix2>)
where
    A: Scalar + Lapack,
    S: DataMut<Elem = A>,
{
    type EigVal = Array1<A::Real>;

    fn eigh_into(mut self, uplo: UPLO) -> Result<(Self::EigVal, Self)> {
        let (val, _) = self.eigh_inplace(uplo)?;
        Ok((val, self))
    }
}

impl<A, S> Eigh for ArrayBase<S, Ix2>
where
    A: Scalar + Lapack,
    S: Data<Elem = A>,
{
    type EigVal = Array1<A::Real>;
    type EigVec = Array2<A>;

    fn eigh(&self, uplo: UPLO) -> Result<(Self::EigVal, Self::EigVec)> {
        let a = self.to_owned();
        a.eigh_into(uplo)
    }
}

impl<A, S> Eigh for (ArrayBase<S, Ix2>, ArrayBase<S, Ix2>)
where
    A: Scalar + Lapack,
    S: Data<Elem = A>,
{
    type EigVal = Array1<A::Real>;
    type EigVec = (Array2<A>, Array2<A>);

    fn eigh(&self, uplo: UPLO) -> Result<(Self::EigVal, Self::EigVec)> {
        let (a,b) = (self.0.to_owned(), self.1.to_owned());
        (a,b).eigh_into(uplo)
    }
}

impl<A, S> EighInplace for ArrayBase<S, Ix2>
where
    A: Scalar + Lapack,
    S: DataMut<Elem = A>,
{
    type EigVal = Array1<A::Real>;

    fn eigh_inplace(&mut self, uplo: UPLO) -> Result<(Self::EigVal, &mut Self)> {
        let layout = self.square_layout()?;
        // XXX Force layout to be Fortran (see #146)
        match layout {
            MatrixLayout::C(_) => self.swap_axes(0, 1),
            MatrixLayout::F(_) => {}
        }
        let s = unsafe { A::eigh(true, self.square_layout()?, uplo, self.as_allocated_mut()?)? };
        Ok((ArrayBase::from(s), self))
    }
}

impl<A, S> EighInplace for (ArrayBase<S, Ix2>, ArrayBase<S, Ix2>)
where
    A: Scalar + Lapack,
    S: DataMut<Elem = A>,
{
    type EigVal = Array1<A::Real>;

    fn eigh_inplace(&mut self, uplo: UPLO) -> Result<(Self::EigVal, &mut Self)> {
        let layout = self.0.square_layout()?;
        // XXX Force layout to be Fortran (see #146)
        match layout {
            MatrixLayout::C(_) => self.0.swap_axes(0, 1),
            MatrixLayout::F(_) => {}
        }

        let layout = self.1.square_layout()?;
        match layout {
            MatrixLayout::C(_) => self.1.swap_axes(0, 1),
            MatrixLayout::F(_) => {}
        }

        let s = unsafe { A::eigh_generalized(true, self.0.square_layout()?, uplo, self.0.as_allocated_mut()?, self.1.as_allocated_mut()?)? };

        Ok((ArrayBase::from(s), self))
    }
}

/// Calculate eigenvalues without eigenvectors
pub trait EigValsh {
    type EigVal;
    fn eigvalsh(&self, uplo: UPLO) -> Result<Self::EigVal>;
}

/// Calculate eigenvalues without eigenvectors
pub trait EigValshInto {
    type EigVal;
    fn eigvalsh_into(self, uplo: UPLO) -> Result<Self::EigVal>;
}

/// Calculate eigenvalues without eigenvectors
pub trait EigValshInplace {
    type EigVal;
    fn eigvalsh_inplace(&mut self, uplo: UPLO) -> Result<Self::EigVal>;
}

impl<A, S> EigValshInto for ArrayBase<S, Ix2>
where
    A: Scalar + Lapack,
    S: DataMut<Elem = A>,
{
    type EigVal = Array1<A::Real>;

    fn eigvalsh_into(mut self, uplo: UPLO) -> Result<Self::EigVal> {
        self.eigvalsh_inplace(uplo)
    }
}

impl<A, S> EigValsh for ArrayBase<S, Ix2>
where
    A: Scalar + Lapack,
    S: Data<Elem = A>,
{
    type EigVal = Array1<A::Real>;

    fn eigvalsh(&self, uplo: UPLO) -> Result<Self::EigVal> {
        let a = self.to_owned();
        a.eigvalsh_into(uplo)
    }
}

impl<A, S> EigValshInplace for ArrayBase<S, Ix2>
where
    A: Scalar + Lapack,
    S: DataMut<Elem = A>,
{
    type EigVal = Array1<A::Real>;

    fn eigvalsh_inplace(&mut self, uplo: UPLO) -> Result<Self::EigVal> {
        let s = unsafe { A::eigh(true, self.square_layout()?, uplo, self.as_allocated_mut()?)? };
        Ok(ArrayBase::from(s))
    }
}

/// Calculate symmetric square-root matrix using `eigh`
pub trait SymmetricSqrt {
    type Output;
    fn ssqrt(&self, uplo: UPLO) -> Result<Self::Output>;
}

impl<A, S> SymmetricSqrt for ArrayBase<S, Ix2>
where
    A: Scalar + Lapack,
    S: Data<Elem = A>,
{
    type Output = Array2<A>;

    fn ssqrt(&self, uplo: UPLO) -> Result<Self::Output> {
        let a = self.to_owned();
        a.ssqrt_into(uplo)
    }
}

/// Calculate symmetric square-root matrix using `eigh`
pub trait SymmetricSqrtInto {
    type Output;
    fn ssqrt_into(self, uplo: UPLO) -> Result<Self::Output>;
}

impl<A, S> SymmetricSqrtInto for ArrayBase<S, Ix2>
where
    A: Scalar + Lapack,
    S: DataMut<Elem = A> + DataOwned,
{
    type Output = Array2<A>;

    fn ssqrt_into(self, uplo: UPLO) -> Result<Self::Output> {
        let (e, v) = self.eigh_into(uplo)?;
        let e_sqrt = Array::from_iter(e.iter().map(|r| Scalar::from_real(r.sqrt())));
        let ev = e_sqrt.into_diagonal().apply2(&v.t());
        Ok(v.apply2(&ev))
    }
}
<commit_msg>Relax requirement for mass matrix B<commit_after>//! Eigenvalue decomposition for Hermite matrices

use ndarray::*;

use crate::diagonal::*;
use crate::error::*;
use crate::layout::*;
use crate::operator::LinearOperator;
use crate::types::*;
use crate::UPLO;
use std::iter::FromIterator;

/// Eigenvalue decomposition of Hermite matrix reference
pub trait Eigh {
    type EigVal;
    type EigVec;
    fn eigh(&self, uplo: UPLO) -> Result<(Self::EigVal, Self::EigVec)>;
}

/// Eigenvalue decomposition of mutable reference of Hermite matrix
pub trait EighInplace {
    type EigVal;
    fn eigh_inplace(&mut self, uplo: UPLO) -> Result<(Self::EigVal, &mut Self)>;
}

/// Eigenvalue decomposition of Hermite matrix
pub trait EighInto: Sized {
    type EigVal;
    fn eigh_into(self, uplo: UPLO) -> Result<(Self::EigVal, Self)>;
}

impl<A, S> EighInto for ArrayBase<S, Ix2>
where
    A: Scalar + Lapack,
    S: DataMut<Elem = A>,
{
    type EigVal = Array1<A::Real>;

    fn eigh_into(mut self, uplo: UPLO) -> Result<(Self::EigVal, Self)> {
        let (val, _) = self.eigh_inplace(uplo)?;
        Ok((val, self))
    }
}

impl<A, S, S2> EighInto for (ArrayBase<S, Ix2>, ArrayBase<S2, Ix2>)
where
    A: Scalar + Lapack,
    S: DataMut<Elem = A>,
    S2: DataMut<Elem = A>,
{
    type EigVal = Array1<A::Real>;

    fn eigh_into(mut self, uplo: UPLO) -> Result<(Self::EigVal, Self)> {
        let (val, _) = self.eigh_inplace(uplo)?;
        Ok((val, self))
    }
}

impl<A, S> Eigh for ArrayBase<S, Ix2>
where
    A: Scalar + Lapack,
    S: Data<Elem = A>,
{
    type EigVal = Array1<A::Real>;
    type EigVec = Array2<A>;

    fn eigh(&self, uplo: UPLO) -> Result<(Self::EigVal, Self::EigVec)> {
        let a = self.to_owned();
        a.eigh_into(uplo)
    }
}

impl<A, S, S2> Eigh for (ArrayBase<S, Ix2>, ArrayBase<S2, Ix2>)
where
    A: Scalar + Lapack,
    S: Data<Elem = A>,
    S2: Data<Elem = A>,
{
    type EigVal = Array1<A::Real>;
    type EigVec = (Array2<A>, Array2<A>);

    fn eigh(&self, uplo: UPLO) -> Result<(Self::EigVal, Self::EigVec)> {
        let (a,b) = (self.0.to_owned(), self.1.to_owned());
        (a,b).eigh_into(uplo)
    }
}

impl<A, S> EighInplace for ArrayBase<S, Ix2>
where
    A: Scalar + Lapack,
    S: DataMut<Elem = A>,
{
    type EigVal = Array1<A::Real>;

    fn eigh_inplace(&mut self, uplo: UPLO) -> Result<(Self::EigVal, &mut Self)> {
        let layout = self.square_layout()?;
        // XXX Force layout to be Fortran (see #146)
        match layout {
            MatrixLayout::C(_) => self.swap_axes(0, 1),
            MatrixLayout::F(_) => {}
        }
        let s = unsafe { A::eigh(true, self.square_layout()?, uplo, self.as_allocated_mut()?)? };
        Ok((ArrayBase::from(s), self))
    }
}

impl<A, S, S2> EighInplace for (ArrayBase<S, Ix2>, ArrayBase<S2, Ix2>)
where
    A: Scalar + Lapack,
    S: DataMut<Elem = A>,
    S2: DataMut<Elem = A>,
{
    type EigVal = Array1<A::Real>;

    fn eigh_inplace(&mut self, uplo: UPLO) -> Result<(Self::EigVal, &mut Self)> {
        let layout = self.0.square_layout()?;
        // XXX Force layout to be Fortran (see #146)
        match layout {
            MatrixLayout::C(_) => self.0.swap_axes(0, 1),
            MatrixLayout::F(_) => {}
        }

        let layout = self.1.square_layout()?;
        match layout {
            MatrixLayout::C(_) => self.1.swap_axes(0, 1),
            MatrixLayout::F(_) => {}
        }

        let s = unsafe { A::eigh_generalized(true, self.0.square_layout()?, uplo, self.0.as_allocated_mut()?, self.1.as_allocated_mut()?)? };

        Ok((ArrayBase::from(s), self))
    }
}

/// Calculate eigenvalues without eigenvectors
pub trait EigValsh {
    type EigVal;
    fn eigvalsh(&self, uplo: UPLO) -> Result<Self::EigVal>;
}

/// Calculate eigenvalues without eigenvectors
pub trait EigValshInto {
    type EigVal;
    fn eigvalsh_into(self, uplo: UPLO) -> Result<Self::EigVal>;
}

/// Calculate eigenvalues without eigenvectors
pub trait EigValshInplace {
    type EigVal;
    fn eigvalsh_inplace(&mut self, uplo: UPLO) -> Result<Self::EigVal>;
}

impl<A, S> EigValshInto for ArrayBase<S, Ix2>
where
    A: Scalar + Lapack,
    S: DataMut<Elem = A>,
{
    type EigVal = Array1<A::Real>;

    fn eigvalsh_into(mut self, uplo: UPLO) -> Result<Self::EigVal> {
        self.eigvalsh_inplace(uplo)
    }
}

impl<A, S> EigValsh for ArrayBase<S, Ix2>
where
    A: Scalar + Lapack,
    S: Data<Elem = A>,
{
    type EigVal = Array1<A::Real>;

    fn eigvalsh(&self, uplo: UPLO) -> Result<Self::EigVal> {
        let a = self.to_owned();
        a.eigvalsh_into(uplo)
    }
}

impl<A, S> EigValshInplace for ArrayBase<S, Ix2>
where
    A: Scalar + Lapack,
    S: DataMut<Elem = A>,
{
    type EigVal = Array1<A::Real>;

    fn eigvalsh_inplace(&mut self, uplo: UPLO) -> Result<Self::EigVal> {
        let s = unsafe { A::eigh(true, self.square_layout()?, uplo, self.as_allocated_mut()?)? };
        Ok(ArrayBase::from(s))
    }
}

/// Calculate symmetric square-root matrix using `eigh`
pub trait SymmetricSqrt {
    type Output;
    fn ssqrt(&self, uplo: UPLO) -> Result<Self::Output>;
}

impl<A, S> SymmetricSqrt for ArrayBase<S, Ix2>
where
    A: Scalar + Lapack,
    S: Data<Elem = A>,
{
    type Output = Array2<A>;

    fn ssqrt(&self, uplo: UPLO) -> Result<Self::Output> {
        let a = self.to_owned();
        a.ssqrt_into(uplo)
    }
}

/// Calculate symmetric square-root matrix using `eigh`
pub trait SymmetricSqrtInto {
    type Output;
    fn ssqrt_into(self, uplo: UPLO) -> Result<Self::Output>;
}

impl<A, S> SymmetricSqrtInto for ArrayBase<S, Ix2>
where
    A: Scalar + Lapack,
    S: DataMut<Elem = A> + DataOwned,
{
    type Output = Array2<A>;

    fn ssqrt_into(self, uplo: UPLO) -> Result<Self::Output> {
        let (e, v) = self.eigh_into(uplo)?;
        let e_sqrt = Array::from_iter(e.iter().map(|r| Scalar::from_real(r.sqrt())));
        let ev = e_sqrt.into_diagonal().apply2(&v.t());
        Ok(v.apply2(&ev))
    }
}
<|endoftext|>


<commit_before>//!
//! Expression Plan Representation for Tajo Kernel
//!

use common::types::{DataType, HasTypeKind, TypeKind};
use common::schema::Column;
use common::P;

#[derive(Clone)]
pub enum Datum {
  Bool(bool),
  Int1(i8),
  Int2(i16),
  Int4(i32),
  Int8(i64),
  Float4(f32),
  Float8(f64),
  Time(i64),
  Date(i32),
  Timestamp(i64),
  Interval(i64, i32),
  Char(String),
  Text(String),
  Varchar(String),
  Blob(Vec<u8>)
}

impl HasTypeKind for Datum {
  fn type_kind(&self) -> TypeKind {
    match *self {
      Datum::Bool(ref x) => TypeKind::Bool,
      Datum::Int1(ref x) => TypeKind::Int1,
      Datum::Int2(ref x) => TypeKind::Int2,
      Datum::Int4(ref x) => TypeKind::Int4,
      Datum::Int8(ref x) => TypeKind::Int8,
      Datum::Float4(ref x) => TypeKind::Float4,
      Datum::Float8(ref x) => TypeKind::Float8,
      Datum::Time(ref x) => TypeKind::Time,
      Datum::Date(ref x) => TypeKind::Date,
      Datum::Timestamp(ref x) => TypeKind::Timestamp,
      Datum::Interval(ref x,ref y) => TypeKind::Interval,
      Datum::Char(ref x) => TypeKind::Char,
      Datum::Text(ref x) => TypeKind::Text,
      Datum::Varchar(ref x) => TypeKind::Varchar,
      Datum::Blob(ref x) => TypeKind::Blob
    }
  }
}

pub struct FnDecl {
  signature: String
}

pub struct AggFnDecl {
  signature: String
}

pub struct WinFnDecl {
  signature: String
}

pub enum BinCompOp {
  Eq,
  NotEq,
  Lth,
  Leq,
  Gth,
  Geq
}

pub enum BinArithOp {
  Plus,
  Minus,
  Multiply,
  Divide,
  Modular,
}

pub struct Expr {
  data_ty: DataType,
  node: ExprSpec
}

pub enum ExprSpec {
  // Unary Expressions
  Not(Box<Expr>),
  IsNull(Box<Expr>,Box<Expr>, bool), // bool - 'is not null' if true
  Signed(Box<Expr>),

  // Binary Arithmetic Expressions
  And(Box<Expr>,Box<Expr>),
  Or(Box<Expr>,Box<Expr>),
  Comp(BinCompOp, Box<Expr>,Box<Expr>),
  BinArithmetic(BinArithOp,Box<Expr>,Box<Expr>),
  Concatenate(Box<Expr>,Box<Expr>),

  // Functions
  Function(Box<FnDecl>, Vec<Box<Expr>>),
  AggFunction(Box<AggFnDecl>, Vec<Box<Expr>>),
  WindowFunction(Box<WinFnDecl>, Vec<Box<Expr>>),

  // String operators or pattern matching predicates: lhs - pattern, rhs - value
  Like(Box<Expr>,Box<Expr>),
  SimilarTo(Box<Expr>,Box<Expr>),
  RegexMatch(Box<Expr>,Box<Expr>),

  // Other predicates
  Between(Box<Expr>,Box<Expr>,Box<Expr>), // predicand, begin, end
  In(Box<Expr>, Vec<Box<Expr>>), // predicand, a set

  // condition
  Case(Vec<Box<Expr>>, Box<Expr>), // multiple conditions, else return value
  IfThen(Box<Expr>, Box<Expr>), // condition, return value

  // values
  Cast(Box<Expr>,Box<DataType>,Box<DataType>),
  Row(Vec<Box<Expr>>),
  Field(Box<Column>),
  Const(Box<Datum>)
}

pub trait Visitor<'v>: Sized {
  fn visit_not(&mut self, child: &'v Expr);
  fn visit_is_null(&mut self, child: &'v Expr, not: bool);

  fn visit_and(&mut self, lhs: &'v Expr, rhs: &'v Expr);
  fn visit_or(&mut self, lhs: &'v Expr, rhs: &'v Expr);
  fn visit_comp(&mut self, lhs: &'v Expr, rhs: &'v Expr);
  fn visit_bin_arith_op(&mut self, op: &BinArithOp, lhs: &'v Expr, rhs: &'v Expr);
  fn visit_concat(&mut self, lhs: &'v Expr, rhs: &'v Expr);

  fn visit_fn(&mut self, fd: &'v FnDecl, args: &'v Vec<Expr>);
  fn visit_aggfn(&mut self, aggfd: &'v AggFnDecl, args: &'v Vec<Expr>);
  fn visit_winfn(&mut self, winfd: &'v WinFnDecl, args: &'v Vec<Expr>);

  fn visit_like(&mut self, pattern: &'v Expr, pred: &'v Expr, not: bool);
  fn visit_similarto(&mut self, pattern: &'v Expr, pred: &'v Expr, not: bool);
  fn visit_regexmatch(&mut self, pattern: &'v Expr, pred: &'v Expr, not: bool);

  fn visit_between(&mut self, pred: &'v Expr, begin: &'v Expr, end: &'v Expr);
  fn visit_in(&mut self, pred: &'v Expr, &'v Vec<Expr>);

  fn visit_case(&mut self, ifconds: &'v Vec<Box<Expr>>, else_result: &'v Expr);
  fn visit_if_then(&mut self, ifcond: &'v Expr, result: &'v Expr);

  fn visit_cast(&mut self, expr: &'v Expr, from: &'v DataType, to: &'v DataType);
  fn visit_row(&mut self, row: &'v Vec<Box<Expr>>);

  fn visit_field(&mut self, field: &'v Column);
  fn visit_const(&mut self, datum: &'v Datum);
}<commit_msg>Implement main walker for Expr visitor.<commit_after>//!
//! Expression Plan Representation for Tajo Kernel
//!

use common::types::{DataType, HasTypeKind, TypeKind};
use common::schema::Column;
use common::P;

#[derive(Clone)]
pub enum Datum {
  Bool(bool),
  Int1(i8),
  Int2(i16),
  Int4(i32),
  Int8(i64),
  Float4(f32),
  Float8(f64),
  Time(i64),
  Date(i32),
  Timestamp(i64),
  Interval(i64, i32),
  Char(String),
  Text(String),
  Varchar(String),
  Blob(Vec<u8>)
}

impl HasTypeKind for Datum {
  fn type_kind(&self) -> TypeKind {
    match *self {
      Datum::Bool(ref x) => TypeKind::Bool,
      Datum::Int1(ref x) => TypeKind::Int1,
      Datum::Int2(ref x) => TypeKind::Int2,
      Datum::Int4(ref x) => TypeKind::Int4,
      Datum::Int8(ref x) => TypeKind::Int8,
      Datum::Float4(ref x) => TypeKind::Float4,
      Datum::Float8(ref x) => TypeKind::Float8,
      Datum::Time(ref x) => TypeKind::Time,
      Datum::Date(ref x) => TypeKind::Date,
      Datum::Timestamp(ref x) => TypeKind::Timestamp,
      Datum::Interval(ref x,ref y) => TypeKind::Interval,
      Datum::Char(ref x) => TypeKind::Char,
      Datum::Text(ref x) => TypeKind::Text,
      Datum::Varchar(ref x) => TypeKind::Varchar,
      Datum::Blob(ref x) => TypeKind::Blob
    }
  }
}

pub struct FnDecl {
  signature: String
}

pub struct AggFnDecl {
  signature: String
}

pub struct WinFnDecl {
  signature: String
}

pub enum CompOp {
  Eq,
  NotEq,
  Lth,
  Leq,
  Gth,
  Geq
}

pub enum ArithmOp {
  Plus,
  Minus,
  Multiply,
  Divide,
  Modular,
}

pub struct Expr {
  data_ty: DataType,
  node: ExprSpec
}

pub enum ExprSpec {
  // Unary Expressions
  Not(Box<Expr>),
  IsNull(Box<Expr>, bool), // bool - 'is null' if true. 'is not null' if false.
  Sign(Box<Expr>, bool), // true - Plus, false - Minus

  // Binary Arithmetic Expressions
  And(Box<Expr>,Box<Expr>),
  Or(Box<Expr>,Box<Expr>),
  Comp(CompOp, Box<Expr>,Box<Expr>),
  Arithm(ArithmOp,Box<Expr>,Box<Expr>),
  Concat(Box<Expr>,Box<Expr>),

  // Functions
  Fn(Box<FnDecl>, Vec<Box<Expr>>),
  AggFn(Box<AggFnDecl>, Vec<Box<Expr>>),
  WinFn(Box<WinFnDecl>, Vec<Box<Expr>>),

  // String operators or pattern matching predicates: lhs - pattern, rhs - value
  Like(Box<Expr>,Box<Expr>, bool),
  SimilarTo(Box<Expr>,Box<Expr>, bool),
  RegexMatch(Box<Expr>,Box<Expr>, bool),

  // Other predicates
  Between(Box<Expr>,Box<Expr>,Box<Expr>), // predicand, begin, end
  In(Box<Expr>, Vec<Box<Expr>>), // predicand, a set

  // condition
  Case(Vec<Box<Expr>>, Box<Expr>), // multiple conditions, else return value
  IfThen(Box<Expr>, Box<Expr>), // condition, return value

  // values
  Cast(Box<Expr>,Box<DataType>,Box<DataType>),
  Row(Vec<Box<Expr>>),
  Field(Box<Column>),
  Const(Box<Datum>)
}

pub trait Visitor<'v>: Sized {
  fn visit_not(&mut self, child: &'v Expr);
  fn visit_is_null(&mut self, child: &'v Expr, not: bool);
  fn visit_sign(&mut self, child: &'v Expr, not: bool);

  fn visit_and(&mut self, lhs: &'v Expr, rhs: &'v Expr);
  fn visit_or(&mut self, lhs: &'v Expr, rhs: &'v Expr);
  fn visit_comp(&mut self, op: &CompOp, lhs: &'v Expr, rhs: &'v Expr);
  fn visit_arithm(&mut self, op: &ArithmOp,
    lhs: &'v Expr, rhs: &'v Expr);
  fn visit_concat(&mut self, lhs: &'v Expr, rhs: &'v Expr);

  fn visit_fn(&mut self, fd: &'v FnDecl, args: &'v Vec<Box<Expr>>);
  fn visit_aggfn(&mut self, aggfd: &'v AggFnDecl, args: &'v Vec<Box<Expr>>);
  fn visit_winfn(&mut self, winfd: &'v WinFnDecl, args: &'v Vec<Box<Expr>>);

  fn visit_like(&mut self, pat: &'v Expr, pred: &'v Expr, not: bool);
  fn visit_similarto(&mut self, pat: &'v Expr, pred: &'v Expr, not: bool);
  fn visit_regexmatch(&mut self, pat: &'v Expr, pred: &'v Expr, not: bool);

  fn visit_between(&mut self, pred: &'v Expr, begin: &'v Expr, end: &'v Expr);
  fn visit_in(&mut self, pred: &'v Expr, &'v Vec<Box<Expr>>);

  fn visit_case(&mut self, ifconds: &'v Vec<Box<Expr>>, else_result: &'v Expr);
  fn visit_if_then(&mut self, ifcond: &'v Expr, result: &'v Expr);

  fn visit_cast(&mut self, expr: &'v Expr, from: &'v DataType,
    to: &'v DataType);
  fn visit_row(&mut self, row: &'v Vec<Box<Expr>>);
  fn visit_field(&mut self, field: &'v Column);
  fn visit_const(&mut self, datum: &'v Datum);
}

pub fn walk_expr<'v, V: Visitor<'v>>(visitor: &mut V, expr: &'v Expr) {

  match expr.node {

    ExprSpec::Not(ref child) => {
      visitor.visit_not(child);
    }

    ExprSpec::IsNull(ref child, positive) => {
      visitor.visit_is_null(child, positive);
    }

    ExprSpec::Sign(ref child, positive) => {
      visitor.visit_sign(child, positive);
    }

    ExprSpec::And(ref lhs, ref rhs) => {
      visitor.visit_and(lhs, rhs);
    }

    ExprSpec::Or(ref lhs, ref rhs) => {
      visitor.visit_or(lhs, rhs);
    }

    ExprSpec::Comp(ref op, ref lhs, ref rhs) => {
      visitor.visit_comp(op, lhs, rhs);
    }

    ExprSpec::Arithm(ref op, ref lhs, ref rhs) => {
      visitor.visit_arithm(op, lhs, rhs);
    }

    ExprSpec::Concat(ref lhs, ref rhs) => {
      visitor.visit_concat(lhs, rhs);
    }

    ExprSpec::Fn(ref fd, ref args) => {
      visitor.visit_fn(fd, args);
    },

    ExprSpec::AggFn(ref fd, ref args) => {
      visitor.visit_aggfn(fd, args);
    },

    ExprSpec::WinFn(ref fd, ref args) => {
      visitor.visit_winfn(fd, args);
    },

    ExprSpec::Like(ref pat, ref pred, not) => {
      visitor.visit_like(pat, pred, not)
    },

    ExprSpec::SimilarTo(ref pat, ref pred, not) => {
      visitor.visit_similarto(pat, pred, not)
    },

    ExprSpec::RegexMatch(ref pat, ref pred, not) => {
      visitor.visit_regexmatch(pat, pred, not)
    },

    ExprSpec::Between(ref pred, ref begin, ref end) => {
      visitor.visit_between(pred, begin, end)
    }

    ExprSpec::In(ref pred, ref values) => {
      visitor.visit_in(pred, values)
    }

    ExprSpec::Case(ref ifconds, ref else_result) => {
      visitor.visit_case(ifconds, else_result)
    }

    ExprSpec::IfThen(ref ifcond, ref result) => {
      visitor.visit_if_then(ifcond, result)
    },

    ExprSpec::Cast(ref value, ref from, ref to) => {
      visitor.visit_cast(value, from, to)
    },

    ExprSpec::Row(ref values) => visitor.visit_row(values),

    ExprSpec::Field(ref column) => visitor.visit_field(column),

    ExprSpec::Const(ref datum) => visitor.visit_const(datum),
  }
}<|endoftext|>