<commit_before>// Copyright 2014 The Servo Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.
//! A type-checked scaling factor between units.

use crate::num::One;

use crate::{Point2D, Rect, Size2D, Vector2D};
use core::cmp::Ordering;
use core::fmt;
use core::hash::{Hash, Hasher};
use core::marker::PhantomData;
use core::ops::{Add, Div, Mul, Sub};
use num_traits::NumCast;
#[cfg(feature = "serde")]
use serde::{Deserialize, Serialize};

/// A scaling factor between two different units of measurement.
///
/// This is effectively a type-safe float, intended to be used in combination with other types like
/// `length::Length` to enforce conversion between systems of measurement at compile time.
///
/// `Src` and `Dst` represent the units before and after multiplying a value by a `Scale`. They
/// may be types without values, such as empty enums.  For example:
///
/// ```rust
/// use euclid::Scale;
/// use euclid::Length;
/// enum Mm {};
/// enum Inch {};
///
/// let mm_per_inch: Scale<f32, Inch, Mm> = Scale::new(25.4);
///
/// let one_foot: Length<f32, Inch> = Length::new(12.0);
/// let one_foot_in_mm: Length<f32, Mm> = one_foot * mm_per_inch;
/// ```
#[repr(C)]
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
#[cfg_attr(
    feature = "serde",
    serde(bound(
        serialize = "T: serde::Serialize",
        deserialize = "T: serde::Deserialize<'de>"
    ))
)]
pub struct Scale<T, Src, Dst>(pub T, #[doc(hidden)] pub PhantomData<(Src, Dst)>);

impl<T, Src, Dst> Scale<T, Src, Dst> {
    #[inline]
    pub const fn new(x: T) -> Self {
        Scale(x, PhantomData)
    }

    /// Returns the given point transformed by this scale.
    ///
    /// # Example
    ///
    /// ```rust
    /// use euclid::{Scale, point2};
    /// enum Mm {};
    /// enum Cm {};
    ///
    /// let to_mm: Scale<i32, Cm, Mm> = Scale::new(10);
    ///
    /// assert_eq!(to_mm.transform_point(point2(42, -42)), point2(420, -420));
    /// ```
    #[inline]
    pub fn transform_point(self, point: Point2D<T, Src>) -> Point2D<T::Output, Dst>
    where
        T: Copy + Mul,
    {
        Point2D::new(point.x * self.0, point.y * self.0)
    }

    /// Returns the given vector transformed by this scale.
    ///
    /// # Example
    ///
    /// ```rust
    /// use euclid::{Scale, vec2};
    /// enum Mm {};
    /// enum Cm {};
    ///
    /// let to_mm: Scale<i32, Cm, Mm> = Scale::new(10);
    ///
    /// assert_eq!(to_mm.transform_vector(vec2(42, -42)), vec2(420, -420));
    /// ```
    #[inline]
    pub fn transform_vector(self, vec: Vector2D<T, Src>) -> Vector2D<T::Output, Dst>
    where
        T: Copy + Mul,
    {
        Vector2D::new(vec.x * self.0, vec.y * self.0)
    }

    /// Returns the given vector transformed by this scale.
    ///
    /// # Example
    ///
    /// ```rust
    /// use euclid::{Scale, size2};
    /// enum Mm {};
    /// enum Cm {};
    ///
    /// let to_mm: Scale<i32, Cm, Mm> = Scale::new(10);
    ///
    /// assert_eq!(to_mm.transform_size(size2(42, -42)), size2(420, -420));
    /// ```
    #[inline]
    pub fn transform_size(self, size: Size2D<T, Src>) -> Size2D<T::Output, Dst>
    where
        T: Copy + Mul,
    {
        Size2D::new(size.width * self.0, size.height * self.0)
    }

    /// Returns the given rect transformed by this scale.
    ///
    /// # Example
    ///
    /// ```rust
    /// use euclid::{Scale, rect};
    /// enum Mm {};
    /// enum Cm {};
    ///
    /// let to_mm: Scale<i32, Cm, Mm> = Scale::new(10);
    ///
    /// assert_eq!(to_mm.transform_rect(&rect(1, 2, 42, -42)), rect(10, 20, 420, -420));
    /// ```
    #[inline]
    pub fn transform_rect(self, rect: &Rect<T, Src>) -> Rect<T::Output, Dst>
    where
        T: Copy + Mul,
    {
        Rect::new(
            self.transform_point(rect.origin),
            self.transform_size(rect.size),
        )
    }

    /// Returns `true` if this scale has no effect.
    ///
    /// # Example
    ///
    /// ```rust
    /// use euclid::Scale;
    /// use euclid::num::One;
    /// enum Mm {};
    /// enum Cm {};
    ///
    /// let cm_per_mm: Scale<f32, Mm, Cm> = Scale::new(0.1);
    /// let mm_per_mm: Scale<f32, Mm, Mm> = Scale::new(1.0);
    ///
    /// assert_eq!(cm_per_mm.is_identity(), false);
    /// assert_eq!(mm_per_mm.is_identity(), true);
    /// assert_eq!(mm_per_mm, Scale::one());
    /// ```
    #[inline]
    pub fn is_identity(self) -> bool
    where
        T: PartialEq + One,
    {
        self.0 == T::one()
    }

    /// Returns the underlying scalar scale factor.
    #[inline]
    pub fn get(self) -> T {
        self.0
    }

    /// The inverse Scale (1.0 / self).
    ///
    /// # Example
    ///
    /// ```rust
    /// use euclid::Scale;
    /// enum Mm {};
    /// enum Cm {};
    ///
    /// let cm_per_mm: Scale<f32, Cm, Mm> = Scale::new(0.1);
    ///
    /// assert_eq!(cm_per_mm.inverse(), Scale::new(10.0));
    /// ```
    pub fn inverse(self) -> Scale<T::Output, Dst, Src>
    where
        T: One + Div,
    {
        let one: T = One::one();
        Scale::new(one / self.0)
    }
}

impl<T: NumCast, Src, Dst> Scale<T, Src, Dst> {
    /// Cast from one numeric representation to another, preserving the units.
    ///
    /// # Panics
    ///
    /// If the source value cannot be represented by the target type `NewT`, then
    /// method panics. Use `try_cast` if that must be case.
    ///
    /// # Example
    ///
    /// ```rust
    /// use euclid::Scale;
    /// enum Mm {};
    /// enum Cm {};
    ///
    /// let to_mm: Scale<i32, Cm, Mm> = Scale::new(10);
    ///
    /// assert_eq!(to_mm.cast::<f32>(), Scale::new(10.0));
    /// ```
    /// That conversion will panic, because `i32` not enough to store such big numbers:
    /// ```rust,should_panic
    /// use euclid::Scale;
    /// enum Mm {};// millimeter = 10^-2 meters
    /// enum Em {};// exameter   = 10^18 meters
    ///
    /// // Panics
    /// let to_em: Scale<i32, Mm, Em> = Scale::new(10e20).cast();
    /// ```
    #[inline]
    pub fn cast<NewT: NumCast>(self) -> Scale<NewT, Src, Dst> {
        self.try_cast().unwrap()
    }

    /// Fallible cast from one numeric representation to another, preserving the units.
    /// If the source value cannot be represented by the target type `NewT`, then `None`
    /// is returned.
    ///
    /// # Example
    ///
    /// ```rust
    /// use euclid::Scale;
    /// enum Mm {};
    /// enum Cm {};
    /// enum Em {};// Exameter = 10^18 meters
    ///
    /// let to_mm: Scale<i32, Cm, Mm> = Scale::new(10);
    /// let to_em: Scale<f32, Mm, Em> = Scale::new(10e20);
    ///
    /// assert_eq!(to_mm.try_cast::<f32>(), Some(Scale::new(10.0)));
    /// // Integer to small to store that number
    /// assert_eq!(to_em.try_cast::<i32>(), None);
    /// ```
    pub fn try_cast<NewT: NumCast>(self) -> Option<Scale<NewT, Src, Dst>> {
        NumCast::from(self.0).map(Scale::new)
    }
}

impl<Src, Dst> Scale<f32, Src, Dst> {
    /// Identity scaling, could be used to safely transit from one space to another.
    pub const ONE: Self = Scale(1.0, PhantomData);
}

// scale0 * scale1
// (A,B) * (B,C) = (A,C)
impl<T: Mul, A, B, C> Mul<Scale<T, B, C>> for Scale<T, A, B> {
    type Output = Scale<T::Output, A, C>;

    #[inline]
    fn mul(self, other: Scale<T, B, C>) -> Self::Output {
        Scale::new(self.0 * other.0)
    }
}

// scale0 + scale1
impl<T: Add, Src, Dst> Add for Scale<T, Src, Dst> {
    type Output = Scale<T::Output, Src, Dst>;

    #[inline]
    fn add(self, other: Scale<T, Src, Dst>) -> Self::Output {
        Scale::new(self.0 + other.0)
    }
}

// scale0 - scale1
impl<T: Sub, Src, Dst> Sub for Scale<T, Src, Dst> {
    type Output = Scale<T::Output, Src, Dst>;

    #[inline]
    fn sub(self, other: Scale<T, Src, Dst>) -> Self::Output {
        Scale::new(self.0 - other.0)
    }
}

// FIXME: Switch to `derive(PartialEq, Clone)` after this Rust issue is fixed:
// https://github.com/rust-lang/rust/issues/26925

impl<T: PartialEq, Src, Dst> PartialEq for Scale<T, Src, Dst> {
    fn eq(&self, other: &Scale<T, Src, Dst>) -> bool {
        self.0 == other.0
    }
}

impl<T: Eq, Src, Dst> Eq for Scale<T, Src, Dst> {}

impl<T: PartialOrd, Src, Dst> PartialOrd for Scale<T, Src, Dst> {
    fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
        self.0.partial_cmp(&other.0)
    }
}

impl<T: Ord, Src, Dst> Ord for Scale<T, Src, Dst> {
    fn cmp(&self, other: &Self) -> Ordering {
        self.0.cmp(&other.0)
    }
}

impl<T: Clone, Src, Dst> Clone for Scale<T, Src, Dst> {
    fn clone(&self) -> Scale<T, Src, Dst> {
        Scale::new(self.0.clone())
    }
}

impl<T: Copy, Src, Dst> Copy for Scale<T, Src, Dst> {}

impl<T: fmt::Debug, Src, Dst> fmt::Debug for Scale<T, Src, Dst> {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        self.0.fmt(f)
    }
}

impl<T: Default, Src, Dst> Default for Scale<T, Src, Dst> {
    fn default() -> Self {
        Self::new(T::default())
    }
}

impl<T: Hash, Src, Dst> Hash for Scale<T, Src, Dst> {
    fn hash<H: Hasher>(&self, state: &mut H) {
        self.0.hash(state)
    }
}

impl<T: One, Src, Dst> One for Scale<T, Src, Dst> {
    #[inline]
    fn one() -> Self {
        Scale::new(T::one())
    }
}

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

    enum Inch {}
    enum Cm {}
    enum Mm {}

    #[test]
    fn test_scale() {
        let mm_per_inch: Scale<f32, Inch, Mm> = Scale::new(25.4);
        let cm_per_mm: Scale<f32, Mm, Cm> = Scale::new(0.1);

        let mm_per_cm: Scale<f32, Cm, Mm> = cm_per_mm.inverse();
        assert_eq!(mm_per_cm.get(), 10.0);

        let one: Scale<f32, Mm, Mm> = cm_per_mm * mm_per_cm;
        assert_eq!(one.get(), 1.0);

        let one: Scale<f32, Cm, Cm> = mm_per_cm * cm_per_mm;
        assert_eq!(one.get(), 1.0);

        let cm_per_inch: Scale<f32, Inch, Cm> = mm_per_inch * cm_per_mm;
        //  mm     cm     cm
        // ---- x ---- = ----
        // inch    mm    inch
        assert_eq!(cm_per_inch, Scale::new(2.54));

        let a: Scale<isize, Inch, Inch> = Scale::new(2);
        let b: Scale<isize, Inch, Inch> = Scale::new(3);
        assert_ne!(a, b);
        assert_eq!(a, a.clone());
        assert_eq!(a.clone() + b.clone(), Scale::new(5));
        assert_eq!(a - b, Scale::new(-1));
    }
}
<commit_msg>Replace Scale::ONE with Scale::identity.<commit_after>// Copyright 2014 The Servo Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.
//! A type-checked scaling factor between units.

use crate::num::One;

use crate::{Point2D, Rect, Size2D, Vector2D};
use core::cmp::Ordering;
use core::fmt;
use core::hash::{Hash, Hasher};
use core::marker::PhantomData;
use core::ops::{Add, Div, Mul, Sub};
use num_traits::NumCast;
#[cfg(feature = "serde")]
use serde::{Deserialize, Serialize};

/// A scaling factor between two different units of measurement.
///
/// This is effectively a type-safe float, intended to be used in combination with other types like
/// `length::Length` to enforce conversion between systems of measurement at compile time.
///
/// `Src` and `Dst` represent the units before and after multiplying a value by a `Scale`. They
/// may be types without values, such as empty enums.  For example:
///
/// ```rust
/// use euclid::Scale;
/// use euclid::Length;
/// enum Mm {};
/// enum Inch {};
///
/// let mm_per_inch: Scale<f32, Inch, Mm> = Scale::new(25.4);
///
/// let one_foot: Length<f32, Inch> = Length::new(12.0);
/// let one_foot_in_mm: Length<f32, Mm> = one_foot * mm_per_inch;
/// ```
#[repr(C)]
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
#[cfg_attr(
    feature = "serde",
    serde(bound(
        serialize = "T: serde::Serialize",
        deserialize = "T: serde::Deserialize<'de>"
    ))
)]
pub struct Scale<T, Src, Dst>(pub T, #[doc(hidden)] pub PhantomData<(Src, Dst)>);

impl<T, Src, Dst> Scale<T, Src, Dst> {
    #[inline]
    pub const fn new(x: T) -> Self {
        Scale(x, PhantomData)
    }

    /// Creates an identity scale (1.0).
    #[inline]
    pub fn identity() -> Self
    where
        T: One
    {
        Scale::new(T::one())
    }

    /// Returns the given point transformed by this scale.
    ///
    /// # Example
    ///
    /// ```rust
    /// use euclid::{Scale, point2};
    /// enum Mm {};
    /// enum Cm {};
    ///
    /// let to_mm: Scale<i32, Cm, Mm> = Scale::new(10);
    ///
    /// assert_eq!(to_mm.transform_point(point2(42, -42)), point2(420, -420));
    /// ```
    #[inline]
    pub fn transform_point(self, point: Point2D<T, Src>) -> Point2D<T::Output, Dst>
    where
        T: Copy + Mul,
    {
        Point2D::new(point.x * self.0, point.y * self.0)
    }

    /// Returns the given vector transformed by this scale.
    ///
    /// # Example
    ///
    /// ```rust
    /// use euclid::{Scale, vec2};
    /// enum Mm {};
    /// enum Cm {};
    ///
    /// let to_mm: Scale<i32, Cm, Mm> = Scale::new(10);
    ///
    /// assert_eq!(to_mm.transform_vector(vec2(42, -42)), vec2(420, -420));
    /// ```
    #[inline]
    pub fn transform_vector(self, vec: Vector2D<T, Src>) -> Vector2D<T::Output, Dst>
    where
        T: Copy + Mul,
    {
        Vector2D::new(vec.x * self.0, vec.y * self.0)
    }

    /// Returns the given vector transformed by this scale.
    ///
    /// # Example
    ///
    /// ```rust
    /// use euclid::{Scale, size2};
    /// enum Mm {};
    /// enum Cm {};
    ///
    /// let to_mm: Scale<i32, Cm, Mm> = Scale::new(10);
    ///
    /// assert_eq!(to_mm.transform_size(size2(42, -42)), size2(420, -420));
    /// ```
    #[inline]
    pub fn transform_size(self, size: Size2D<T, Src>) -> Size2D<T::Output, Dst>
    where
        T: Copy + Mul,
    {
        Size2D::new(size.width * self.0, size.height * self.0)
    }

    /// Returns the given rect transformed by this scale.
    ///
    /// # Example
    ///
    /// ```rust
    /// use euclid::{Scale, rect};
    /// enum Mm {};
    /// enum Cm {};
    ///
    /// let to_mm: Scale<i32, Cm, Mm> = Scale::new(10);
    ///
    /// assert_eq!(to_mm.transform_rect(&rect(1, 2, 42, -42)), rect(10, 20, 420, -420));
    /// ```
    #[inline]
    pub fn transform_rect(self, rect: &Rect<T, Src>) -> Rect<T::Output, Dst>
    where
        T: Copy + Mul,
    {
        Rect::new(
            self.transform_point(rect.origin),
            self.transform_size(rect.size),
        )
    }

    /// Returns `true` if this scale has no effect.
    ///
    /// # Example
    ///
    /// ```rust
    /// use euclid::Scale;
    /// use euclid::num::One;
    /// enum Mm {};
    /// enum Cm {};
    ///
    /// let cm_per_mm: Scale<f32, Mm, Cm> = Scale::new(0.1);
    /// let mm_per_mm: Scale<f32, Mm, Mm> = Scale::new(1.0);
    ///
    /// assert_eq!(cm_per_mm.is_identity(), false);
    /// assert_eq!(mm_per_mm.is_identity(), true);
    /// assert_eq!(mm_per_mm, Scale::one());
    /// ```
    #[inline]
    pub fn is_identity(self) -> bool
    where
        T: PartialEq + One,
    {
        self.0 == T::one()
    }

    /// Returns the underlying scalar scale factor.
    #[inline]
    pub fn get(self) -> T {
        self.0
    }

    /// The inverse Scale (1.0 / self).
    ///
    /// # Example
    ///
    /// ```rust
    /// use euclid::Scale;
    /// enum Mm {};
    /// enum Cm {};
    ///
    /// let cm_per_mm: Scale<f32, Cm, Mm> = Scale::new(0.1);
    ///
    /// assert_eq!(cm_per_mm.inverse(), Scale::new(10.0));
    /// ```
    pub fn inverse(self) -> Scale<T::Output, Dst, Src>
    where
        T: One + Div,
    {
        let one: T = One::one();
        Scale::new(one / self.0)
    }
}

impl<T: NumCast, Src, Dst> Scale<T, Src, Dst> {
    /// Cast from one numeric representation to another, preserving the units.
    ///
    /// # Panics
    ///
    /// If the source value cannot be represented by the target type `NewT`, then
    /// method panics. Use `try_cast` if that must be case.
    ///
    /// # Example
    ///
    /// ```rust
    /// use euclid::Scale;
    /// enum Mm {};
    /// enum Cm {};
    ///
    /// let to_mm: Scale<i32, Cm, Mm> = Scale::new(10);
    ///
    /// assert_eq!(to_mm.cast::<f32>(), Scale::new(10.0));
    /// ```
    /// That conversion will panic, because `i32` not enough to store such big numbers:
    /// ```rust,should_panic
    /// use euclid::Scale;
    /// enum Mm {};// millimeter = 10^-2 meters
    /// enum Em {};// exameter   = 10^18 meters
    ///
    /// // Panics
    /// let to_em: Scale<i32, Mm, Em> = Scale::new(10e20).cast();
    /// ```
    #[inline]
    pub fn cast<NewT: NumCast>(self) -> Scale<NewT, Src, Dst> {
        self.try_cast().unwrap()
    }

    /// Fallible cast from one numeric representation to another, preserving the units.
    /// If the source value cannot be represented by the target type `NewT`, then `None`
    /// is returned.
    ///
    /// # Example
    ///
    /// ```rust
    /// use euclid::Scale;
    /// enum Mm {};
    /// enum Cm {};
    /// enum Em {};// Exameter = 10^18 meters
    ///
    /// let to_mm: Scale<i32, Cm, Mm> = Scale::new(10);
    /// let to_em: Scale<f32, Mm, Em> = Scale::new(10e20);
    ///
    /// assert_eq!(to_mm.try_cast::<f32>(), Some(Scale::new(10.0)));
    /// // Integer to small to store that number
    /// assert_eq!(to_em.try_cast::<i32>(), None);
    /// ```
    pub fn try_cast<NewT: NumCast>(self) -> Option<Scale<NewT, Src, Dst>> {
        NumCast::from(self.0).map(Scale::new)
    }
}

// scale0 * scale1
// (A,B) * (B,C) = (A,C)
impl<T: Mul, A, B, C> Mul<Scale<T, B, C>> for Scale<T, A, B> {
    type Output = Scale<T::Output, A, C>;

    #[inline]
    fn mul(self, other: Scale<T, B, C>) -> Self::Output {
        Scale::new(self.0 * other.0)
    }
}

// scale0 + scale1
impl<T: Add, Src, Dst> Add for Scale<T, Src, Dst> {
    type Output = Scale<T::Output, Src, Dst>;

    #[inline]
    fn add(self, other: Scale<T, Src, Dst>) -> Self::Output {
        Scale::new(self.0 + other.0)
    }
}

// scale0 - scale1
impl<T: Sub, Src, Dst> Sub for Scale<T, Src, Dst> {
    type Output = Scale<T::Output, Src, Dst>;

    #[inline]
    fn sub(self, other: Scale<T, Src, Dst>) -> Self::Output {
        Scale::new(self.0 - other.0)
    }
}

// FIXME: Switch to `derive(PartialEq, Clone)` after this Rust issue is fixed:
// https://github.com/rust-lang/rust/issues/26925

impl<T: PartialEq, Src, Dst> PartialEq for Scale<T, Src, Dst> {
    fn eq(&self, other: &Scale<T, Src, Dst>) -> bool {
        self.0 == other.0
    }
}

impl<T: Eq, Src, Dst> Eq for Scale<T, Src, Dst> {}

impl<T: PartialOrd, Src, Dst> PartialOrd for Scale<T, Src, Dst> {
    fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
        self.0.partial_cmp(&other.0)
    }
}

impl<T: Ord, Src, Dst> Ord for Scale<T, Src, Dst> {
    fn cmp(&self, other: &Self) -> Ordering {
        self.0.cmp(&other.0)
    }
}

impl<T: Clone, Src, Dst> Clone for Scale<T, Src, Dst> {
    fn clone(&self) -> Scale<T, Src, Dst> {
        Scale::new(self.0.clone())
    }
}

impl<T: Copy, Src, Dst> Copy for Scale<T, Src, Dst> {}

impl<T: fmt::Debug, Src, Dst> fmt::Debug for Scale<T, Src, Dst> {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        self.0.fmt(f)
    }
}

impl<T: Default, Src, Dst> Default for Scale<T, Src, Dst> {
    fn default() -> Self {
        Self::new(T::default())
    }
}

impl<T: Hash, Src, Dst> Hash for Scale<T, Src, Dst> {
    fn hash<H: Hasher>(&self, state: &mut H) {
        self.0.hash(state)
    }
}

impl<T: One, Src, Dst> One for Scale<T, Src, Dst> {
    #[inline]
    fn one() -> Self {
        Scale::new(T::one())
    }
}

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

    enum Inch {}
    enum Cm {}
    enum Mm {}

    #[test]
    fn test_scale() {
        let mm_per_inch: Scale<f32, Inch, Mm> = Scale::new(25.4);
        let cm_per_mm: Scale<f32, Mm, Cm> = Scale::new(0.1);

        let mm_per_cm: Scale<f32, Cm, Mm> = cm_per_mm.inverse();
        assert_eq!(mm_per_cm.get(), 10.0);

        let one: Scale<f32, Mm, Mm> = cm_per_mm * mm_per_cm;
        assert_eq!(one.get(), 1.0);

        let one: Scale<f32, Cm, Cm> = mm_per_cm * cm_per_mm;
        assert_eq!(one.get(), 1.0);

        let cm_per_inch: Scale<f32, Inch, Cm> = mm_per_inch * cm_per_mm;
        //  mm     cm     cm
        // ---- x ---- = ----
        // inch    mm    inch
        assert_eq!(cm_per_inch, Scale::new(2.54));

        let a: Scale<isize, Inch, Inch> = Scale::new(2);
        let b: Scale<isize, Inch, Inch> = Scale::new(3);
        assert_ne!(a, b);
        assert_eq!(a, a.clone());
        assert_eq!(a.clone() + b.clone(), Scale::new(5));
        assert_eq!(a - b, Scale::new(-1));
    }
}
<|endoftext|>


<commit_before>
use std::collections::hashmap::HashMap;
use uuid::Uuid;

use graphics::*;

use event::{
    Event,
    Behavior,
    State,
    Running,
};

use Sprite;

use animation::{
    Animation,
    AnimationState,
};

/// A scene is used to manage sprite's life and run animation with sprite
pub struct Scene<I: ImageSize> {
    children: Vec<Sprite<I>>,
    children_index: HashMap<Uuid, uint>,
    running: HashMap<Uuid,
        Vec<(Behavior<Animation>, State<Animation, AnimationState>, bool)>>,
}

impl<I: ImageSize> Scene<I> {
    /// Create a new scene
    pub fn new() -> Scene<I> {
        Scene {
            children: Vec::new(),
            children_index: HashMap::new(),
            running: HashMap::new(),
        }
    }

    /// Update animation's state
    pub fn update(&mut self, e: &Event) {
        // regenerate the animations and their states
        let running = self.running.clone();
        self.running.clear();

        for (id, animations) in running.into_iter() {
            let mut new_animations = Vec::new();

            for (b, mut a, paused) in animations.into_iter() {
                if paused {
                    new_animations.push((b, a, paused));
                    continue;
                }

                let sprite = self.child_mut(id).unwrap();
                let (status, _) = a.event(e, |_, dt, animation, s| {
                    let (state, status, remain) = {
                        let start_state;
                        let state = match *s {
                            None => { start_state = animation.to_state(sprite); &start_state },
                            Some(ref state) => state,
                        };
                        state.update(sprite, dt)
                    };
                    *s = state;
                    (status, remain)
                });

                match status {
                    // the behavior is still running, add it for next update
                    Running => {
                        new_animations.push((b, a, paused));
                    },
                    _ => {},
                }
            }

            if new_animations.len() > 0 {
                self.running.insert(id, new_animations);
            }
        }
    }

    /// Render this scene
    pub fn draw<B: BackEnd<I>>(&self, c: &Context, b: &mut B) {
        for child in self.children.iter() {
            child.draw(c, b);
        }
    }

    /// Register animation with sprite
    pub fn run(&mut self, sprite_id: Uuid, animation: &Behavior<Animation>) {
        use std::collections::hashmap::{ Vacant, Occupied };
        let animations = match self.running.entry(sprite_id) {
            Vacant(entry) => entry.set(Vec::new()),
            Occupied(entry) => entry.into_mut()
        };
        let state = State::new(animation.clone());
        animations.push((animation.clone(), state, false));
    }

    fn find(&self, sprite_id: Uuid, animation: &Behavior<Animation>) -> Option<uint> {
        let mut index = None;
        match self.running.find(&sprite_id) {
            Some(animations) => {
                for i in range(0, animations.len()) {
                    let (ref b, _, _) = animations[i];
                    if b == animation {
                        index = Some(i);
                        break;
                    }
                }
            },
            _ => {},
        }
        index
    }

    /// Pause a running animation of the sprite
    pub fn pause(&mut self, sprite_id: Uuid, animation: &Behavior<Animation>) {
        let index = self.find(sprite_id, animation);
        if index.is_some() {
            println!("found");
            let i = index.unwrap();
            let animations = self.running.get_mut(&sprite_id);
            let (b, s, _) = animations.remove(i).unwrap();
            animations.push((b, s, true));
        }
    }

    /// Resume a paused animation of the sprite
    pub fn resume(&mut self, sprite_id: Uuid, animation: &Behavior<Animation>) {
        let index = self.find(sprite_id, animation);
        if index.is_some() {
            println!("found");
            let i = index.unwrap();
            let animations = self.running.get_mut(&sprite_id);
            let (b, s, _) = animations.remove(i).unwrap();
            animations.push((b, s, false));
        }
    }

    /// Toggle an animation of the sprite
    pub fn toggle(&mut self, sprite_id: Uuid, animation: &Behavior<Animation>) {
        let index = self.find(sprite_id, animation);
        if index.is_some() {
            let i = index.unwrap();
            let animations = self.running.get_mut(&sprite_id);
            let (b, s, paused) = animations.remove(i).unwrap();
            animations.push((b, s, !paused));
        }
    }

    /// Stop a running animation of the sprite
    pub fn stop(&mut self, sprite_id: Uuid, animation: &Behavior<Animation>) {
        let index = self.find(sprite_id, animation);
        if index.is_some() {
            let i = index.unwrap();
            self.running.get_mut(&sprite_id).remove(i);
        }
    }

    /// Stop all running animations of the sprite
    pub fn stop_all(&mut self, sprite_id: Uuid) {
        self.running.remove(&sprite_id);
    }

    /// Get all the running animations in the scene
    pub fn running(&self) -> uint {
        let mut total = 0;
        for (_, animations) in self.running.iter() {
            total += animations.len();
        }
        total
    }

    /// Add sprite to scene
    pub fn add_child(&mut self, sprite: Sprite<I>) -> Uuid {
        let id = sprite.id();
        self.children.push(sprite);
        self.children_index.insert(id, self.children.len() - 1);
        id
    }

    fn stop_all_including_children(&mut self, sprite: &Sprite<I>) {
        self.stop_all(sprite.id());
        for child in sprite.children().iter() {
            self.stop_all_including_children(child);
        }
    }

    /// Remove the child by `id` from the scene's children or grandchild
    /// will stop all the animations run by this child
    pub fn remove_child(&mut self, id: Uuid) -> Option<Sprite<I>> {
        let removed = match self.children_index.pop(&id) {
            Some(i) => {
                let removed = self.children.remove(i).unwrap();
                // Removing a element of vector will alter the index,
                // update the mapping from uuid to index.
                for index in range(i, self.children.len()) {
                    let uuid = self.children[index].id();
                    self.children_index.insert(uuid, index);
                }
                Some(removed)
            },
            None => {
                for child in self.children.iter_mut() {
                    match child.remove_child(id) {
                        Some(c) => {
                            return Some(c);
                        }
                        _ => {}
                    }
                }

                None
            }
        };

        if removed.is_some() {
            self.stop_all_including_children(removed.as_ref().unwrap());
        }

        removed
    }

    /// Find the child by `id` from the scene's children or grandchild
    pub fn child(&self, id: Uuid) -> Option<&Sprite<I>> {
        match self.children_index.find(&id) {
            Some(i) => { Some(&self.children[*i]) },
            None => {
                for child in self.children.iter() {
                    match child.child(id) {
                        Some(c) => {
                            return Some(c);
                        }
                        _ => {}
                    }
                }

                None
            }
        }
    }

    /// Find the child by `id` from this sprite's children or grandchild, mutability
    pub fn child_mut(&mut self, id: Uuid) -> Option<&mut Sprite<I>> {
        match self.children_index.find(&id) {
            Some(i) => { Some(self.children.get_mut(*i)) },
            None => {
                for child in self.children.iter_mut() {
                    match child.child_mut(id) {
                        Some(c) => {
                            return Some(c);
                        }
                        _ => {}
                    }
                }

                None
            }
        }
    }
}
<commit_msg>Rename `update` to `event`<commit_after>
use std::collections::hashmap::HashMap;
use uuid::Uuid;

use graphics::*;

use event::{
    Event,
    Behavior,
    State,
    Running,
};

use Sprite;

use animation::{
    Animation,
    AnimationState,
};

/// A scene is used to manage sprite's life and run animation with sprite
pub struct Scene<I: ImageSize> {
    children: Vec<Sprite<I>>,
    children_index: HashMap<Uuid, uint>,
    running: HashMap<Uuid,
        Vec<(Behavior<Animation>, State<Animation, AnimationState>, bool)>>,
}

impl<I: ImageSize> Scene<I> {
    /// Create a new scene
    pub fn new() -> Scene<I> {
        Scene {
            children: Vec::new(),
            children_index: HashMap::new(),
            running: HashMap::new(),
        }
    }

    /// Update animation's state
    pub fn event(&mut self, e: &Event) {
        // regenerate the animations and their states
        let running = self.running.clone();
        self.running.clear();

        for (id, animations) in running.into_iter() {
            let mut new_animations = Vec::new();

            for (b, mut a, paused) in animations.into_iter() {
                if paused {
                    new_animations.push((b, a, paused));
                    continue;
                }

                let sprite = self.child_mut(id).unwrap();
                let (status, _) = a.event(e, |_, dt, animation, s| {
                    let (state, status, remain) = {
                        let start_state;
                        let state = match *s {
                            None => { start_state = animation.to_state(sprite); &start_state },
                            Some(ref state) => state,
                        };
                        state.update(sprite, dt)
                    };
                    *s = state;
                    (status, remain)
                });

                match status {
                    // the behavior is still running, add it for next update
                    Running => {
                        new_animations.push((b, a, paused));
                    },
                    _ => {},
                }
            }

            if new_animations.len() > 0 {
                self.running.insert(id, new_animations);
            }
        }
    }

    /// Render this scene
    pub fn draw<B: BackEnd<I>>(&self, c: &Context, b: &mut B) {
        for child in self.children.iter() {
            child.draw(c, b);
        }
    }

    /// Register animation with sprite
    pub fn run(&mut self, sprite_id: Uuid, animation: &Behavior<Animation>) {
        use std::collections::hashmap::{ Vacant, Occupied };
        let animations = match self.running.entry(sprite_id) {
            Vacant(entry) => entry.set(Vec::new()),
            Occupied(entry) => entry.into_mut()
        };
        let state = State::new(animation.clone());
        animations.push((animation.clone(), state, false));
    }

    fn find(&self, sprite_id: Uuid, animation: &Behavior<Animation>) -> Option<uint> {
        let mut index = None;
        match self.running.find(&sprite_id) {
            Some(animations) => {
                for i in range(0, animations.len()) {
                    let (ref b, _, _) = animations[i];
                    if b == animation {
                        index = Some(i);
                        break;
                    }
                }
            },
            _ => {},
        }
        index
    }

    /// Pause a running animation of the sprite
    pub fn pause(&mut self, sprite_id: Uuid, animation: &Behavior<Animation>) {
        let index = self.find(sprite_id, animation);
        if index.is_some() {
            println!("found");
            let i = index.unwrap();
            let animations = self.running.get_mut(&sprite_id);
            let (b, s, _) = animations.remove(i).unwrap();
            animations.push((b, s, true));
        }
    }

    /// Resume a paused animation of the sprite
    pub fn resume(&mut self, sprite_id: Uuid, animation: &Behavior<Animation>) {
        let index = self.find(sprite_id, animation);
        if index.is_some() {
            println!("found");
            let i = index.unwrap();
            let animations = self.running.get_mut(&sprite_id);
            let (b, s, _) = animations.remove(i).unwrap();
            animations.push((b, s, false));
        }
    }

    /// Toggle an animation of the sprite
    pub fn toggle(&mut self, sprite_id: Uuid, animation: &Behavior<Animation>) {
        let index = self.find(sprite_id, animation);
        if index.is_some() {
            let i = index.unwrap();
            let animations = self.running.get_mut(&sprite_id);
            let (b, s, paused) = animations.remove(i).unwrap();
            animations.push((b, s, !paused));
        }
    }

    /// Stop a running animation of the sprite
    pub fn stop(&mut self, sprite_id: Uuid, animation: &Behavior<Animation>) {
        let index = self.find(sprite_id, animation);
        if index.is_some() {
            let i = index.unwrap();
            self.running.get_mut(&sprite_id).remove(i);
        }
    }

    /// Stop all running animations of the sprite
    pub fn stop_all(&mut self, sprite_id: Uuid) {
        self.running.remove(&sprite_id);
    }

    /// Get all the running animations in the scene
    pub fn running(&self) -> uint {
        let mut total = 0;
        for (_, animations) in self.running.iter() {
            total += animations.len();
        }
        total
    }

    /// Add sprite to scene
    pub fn add_child(&mut self, sprite: Sprite<I>) -> Uuid {
        let id = sprite.id();
        self.children.push(sprite);
        self.children_index.insert(id, self.children.len() - 1);
        id
    }

    fn stop_all_including_children(&mut self, sprite: &Sprite<I>) {
        self.stop_all(sprite.id());
        for child in sprite.children().iter() {
            self.stop_all_including_children(child);
        }
    }

    /// Remove the child by `id` from the scene's children or grandchild
    /// will stop all the animations run by this child
    pub fn remove_child(&mut self, id: Uuid) -> Option<Sprite<I>> {
        let removed = match self.children_index.pop(&id) {
            Some(i) => {
                let removed = self.children.remove(i).unwrap();
                // Removing a element of vector will alter the index,
                // update the mapping from uuid to index.
                for index in range(i, self.children.len()) {
                    let uuid = self.children[index].id();
                    self.children_index.insert(uuid, index);
                }
                Some(removed)
            },
            None => {
                for child in self.children.iter_mut() {
                    match child.remove_child(id) {
                        Some(c) => {
                            return Some(c);
                        }
                        _ => {}
                    }
                }

                None
            }
        };

        if removed.is_some() {
            self.stop_all_including_children(removed.as_ref().unwrap());
        }

        removed
    }

    /// Find the child by `id` from the scene's children or grandchild
    pub fn child(&self, id: Uuid) -> Option<&Sprite<I>> {
        match self.children_index.find(&id) {
            Some(i) => { Some(&self.children[*i]) },
            None => {
                for child in self.children.iter() {
                    match child.child(id) {
                        Some(c) => {
                            return Some(c);
                        }
                        _ => {}
                    }
                }

                None
            }
        }
    }

    /// Find the child by `id` from this sprite's children or grandchild, mutability
    pub fn child_mut(&mut self, id: Uuid) -> Option<&mut Sprite<I>> {
        match self.children_index.find(&id) {
            Some(i) => { Some(self.children.get_mut(*i)) },
            None => {
                for child in self.children.iter_mut() {
                    match child.child_mut(id) {
                        Some(c) => {
                            return Some(c);
                        }
                        _ => {}
                    }
                }

                None
            }
        }
    }
}
<|endoftext|>


<commit_before>use core::pin::Pin;
use futures_core::future::{FusedFuture, Future, TryFuture};
use futures_core::task::{Context, Poll};
use pin_utils::{unsafe_pinned, unsafe_unpinned};

/// Future for the [`map_ok_or_else`](super::TryFutureExt::map_ok_or_else) method.
#[derive(Debug)]
#[must_use = "futures do nothing unless you `.await` or poll them"]
pub struct MapOkOrElse<Fut, F, E> {
    future: Fut,
    f: Option<F>,
    e: Option<E>,
}

impl<Fut, F, E> MapOkOrElse<Fut, F, E> {
    unsafe_pinned!(future: Fut);
    unsafe_unpinned!(f: Option<F>);
    unsafe_unpinned!(e: Option<E>);

    /// Creates a new MapOkOrElse.
    pub(super) fn new(future: Fut, e: E, f: F) -> Self {
        Self { future, f: Some(f), e: Some(e) }
    }
}

impl<Fut: Unpin, F, E> Unpin for MapOkOrElse<Fut, F, E> {}

impl<Fut, F, E, T> FusedFuture for MapOkOrElse<Fut, F, E>
    where Fut: TryFuture,
          F: FnOnce(Fut::Ok) -> T,
          E: FnOnce(Fut::Error) -> T,
{
    fn is_terminated(&self) -> bool {
        self.f.is_none()
    }
}

impl<Fut, F, E, T> Future for MapOkOrElse<Fut, F, E>
    where Fut: TryFuture,
          F: FnOnce(Fut::Ok) -> T,
          E: FnOnce(Fut::Error) -> T,
{
    type Output = T;

    fn poll(
        mut self: Pin<&mut Self>,
        cx: &mut Context<'_>,
    ) -> Poll<Self::Output> {
        self.as_mut()
            .future()
            .try_poll(cx)
            .map(|result| {
                match result {
                    Ok(i) => (self.as_mut().f().take().expect("MapOkOrElse must not be polled after it returned `Poll::Ready`"))(i),
                    Err(e) => (self.as_mut().e().take().expect("MapOkOrElse must not be polled after it returned `Poll::Ready`"))(e),
                }
            })
    }
}
<commit_msg>Fix is_terminated<commit_after>use core::pin::Pin;
use futures_core::future::{FusedFuture, Future, TryFuture};
use futures_core::task::{Context, Poll};
use pin_utils::{unsafe_pinned, unsafe_unpinned};

/// Future for the [`map_ok_or_else`](super::TryFutureExt::map_ok_or_else) method.
#[derive(Debug)]
#[must_use = "futures do nothing unless you `.await` or poll them"]
pub struct MapOkOrElse<Fut, F, E> {
    future: Fut,
    f: Option<F>,
    e: Option<E>,
}

impl<Fut, F, E> MapOkOrElse<Fut, F, E> {
    unsafe_pinned!(future: Fut);
    unsafe_unpinned!(f: Option<F>);
    unsafe_unpinned!(e: Option<E>);

    /// Creates a new MapOkOrElse.
    pub(super) fn new(future: Fut, e: E, f: F) -> Self {
        Self { future, f: Some(f), e: Some(e) }
    }
}

impl<Fut: Unpin, F, E> Unpin for MapOkOrElse<Fut, F, E> {}

impl<Fut, F, E, T> FusedFuture for MapOkOrElse<Fut, F, E>
    where Fut: TryFuture,
          F: FnOnce(Fut::Ok) -> T,
          E: FnOnce(Fut::Error) -> T,
{
    fn is_terminated(&self) -> bool {
        self.f.is_none() || self.e.is_none()
    }
}

impl<Fut, F, E, T> Future for MapOkOrElse<Fut, F, E>
    where Fut: TryFuture,
          F: FnOnce(Fut::Ok) -> T,
          E: FnOnce(Fut::Error) -> T,
{
    type Output = T;

    fn poll(
        mut self: Pin<&mut Self>,
        cx: &mut Context<'_>,
    ) -> Poll<Self::Output> {
        self.as_mut()
            .future()
            .try_poll(cx)
            .map(|result| {
                match result {
                    Ok(i) => (self.as_mut().f().take().expect("MapOkOrElse must not be polled after it returned `Poll::Ready`"))(i),
                    Err(e) => (self.as_mut().e().take().expect("MapOkOrElse must not be polled after it returned `Poll::Ready`"))(e),
                }
            })
    }
}
<|endoftext|>


<commit_before>use elf::*;
use context::Context;
use function::*;
use types::Type;
use types::kind::*;
use get;
macro_rules! test_compile(
    ($ty:ty, $test_name:ident, $kind:expr) => (
        #[test]
        fn $test_name() {
            use std::default::Default;
            let default_value:$ty = Default::default();
            Context::new().build_func(get::<fn() -> $ty>(), |func| {
                let val = func.insn_of(&default_value);
                assert!(val.get_type().get_kind() == $kind);
                func.insn_return(&val);
            }).with::<(), $ty>(|gen_value| {
                assert_eq!(gen_value(()), default_value)
            });
        }
    );
)
#[test]
fn test_sqrt() {
    println!("Testing square root");
    Context::new().build_func(get::<fn(uint) -> uint>(), |func:&UncompiledFunction| {
        let ref arg = func[0];
        assert_eq!(arg.get_type(), get::<uint>());
        let sqrt_arg = func.insn_sqrt(arg);
        let sqrt_arg_ui = func.insn_convert(&sqrt_arg, get::<uint>(), false);
        func.insn_return(&sqrt_arg_ui);
    }).with::<uint, uint>(|sqrt| {
        assert_eq!(sqrt(64), 8);
        assert_eq!(sqrt(16), 4);
        assert_eq!(sqrt(9), 3);
        assert_eq!(sqrt(4), 2);
        assert_eq!(sqrt(1), 1);
    });
}

#[test]
fn test_struct() {
    println!("Testing struct");
    ::init();
    let double_float_t = jit!(struct {
        "first": f64,
        "second": f64
    });
    assert_eq!(double_float_t.find_name("first").index, 0);
    assert_eq!(double_float_t.find_name("second").index, 1);
    let fields:Vec<String> = double_float_t.fields().map(|field| field.get_name().unwrap()).collect();
    assert_eq!(fields[], [
        "first".into_string(),
        "second".into_string()
    ][]);
    assert_eq!(double_float_t.fields().count(), 2);
    assert!({
        let field:Option<String> = double_float_t.fields().nth(1).unwrap().get_name();
        field.unwrap().as_slice() == "second"
    });
}

test_compile!((), test_compile_void, Void)
test_compile!(f64, test_compile_f64, Float64)
test_compile!(f32, test_compile_f32, Float32)
test_compile!(int, test_compile_int, NInt)
test_compile!(uint, test_compile_uint, NUInt)
test_compile!(i32, test_compile_i32, Int)
test_compile!(u32, test_compile_u32, UInt)
test_compile!(i16, test_compile_i16, Short)
test_compile!(u16, test_compile_u16, UShort)
test_compile!(i8, test_compile_i8, SByte)
test_compile!(u8, test_compile_u8, UByte)
<commit_msg>Tidy up tests<commit_after>use context::Context;
use function::*;
use get;
use std::default::Default;
use types::Type;
use types::kind::*;
macro_rules! test_compile(
    ($ty:ty, $test_name:ident, $kind:expr) => (
        #[test]
        fn $test_name() {
            let default_value:$ty = Default::default();
            Context::new().build_func(get::<fn() -> $ty>(), |func| {
                let ref val = func.insn_of(&default_value);
                assert!(val.get_type().get_kind() == $kind);
                func.insn_return(val);
            }).with::<(), $ty>(|func| {
                assert_eq!(func(()), default_value);
            });
        }
    );
)
#[test]
fn test_sqrt() {
    Context::new().build_func(get::<fn(uint) -> uint>(), |func:&UncompiledFunction| {
        let ref arg = func[0];
        assert_eq!(arg.get_type(), get::<uint>());
        let sqrt_arg = func.insn_sqrt(arg);
        let sqrt_arg_ui = func.insn_convert(&sqrt_arg, get::<uint>(), false);
        func.insn_return(&sqrt_arg_ui);
    }).with::<uint, uint>(|sqrt| {
        assert_eq!(sqrt(64), 8);
        assert_eq!(sqrt(16), 4);
        assert_eq!(sqrt(9), 3);
        assert_eq!(sqrt(4), 2);
        assert_eq!(sqrt(1), 1);
    });
}

#[test]
fn test_struct() {
    ::init();
    let double_float_t = jit!(struct {
        "first": f64,
        "second": f64
    });
    assert_eq!(double_float_t.find_name("first").index, 0);
    assert_eq!(double_float_t.find_name("second").index, 1);
    let fields:Vec<String> = double_float_t.fields().map(|field| field.get_name().unwrap()).collect();
    assert_eq!(fields[], [
        "first".into_string(),
        "second".into_string()
    ][]);
    assert_eq!(double_float_t.fields().count(), 2);
    assert!({
        let field:Option<String> = double_float_t.fields().nth(1).unwrap().get_name();
        field.unwrap().as_slice() == "second"
    });
}

test_compile!((), test_compile_void, Void)
test_compile!(f64, test_compile_f64, Float64)
test_compile!(f32, test_compile_f32, Float32)
test_compile!(int, test_compile_int, NInt)
test_compile!(uint, test_compile_uint, NUInt)
test_compile!(i32, test_compile_i32, Int)
test_compile!(u32, test_compile_u32, UInt)
test_compile!(i16, test_compile_i16, Short)
test_compile!(u16, test_compile_u16, UShort)
test_compile!(i8, test_compile_i8, SByte)
test_compile!(u8, test_compile_u8, UByte)
<|endoftext|>


<commit_before>#[derive(Debug, Copy, Eq, PartialEq)]
pub struct Posn {
    pub offset: u32,
    pub line: u32,
    pub column: u32
}

#[derive(Debug, Eq, PartialEq)]
pub struct Span {
    start: Posn,
    end: Posn
}

#[derive(Debug, PartialEq)]
#[allow(dead_code)]
pub enum Token {
    Null,
    True,
    False,

    // 11.6.2.1 Keywords
    Break,
    Case,
    Catch,
    Class,
    Const,
    Continue,
    Debugger,
    Default,
    Delete,
    Do,
    Else,
    Export,
    Extends,
    Finally,
    For,
    Function,
    If,
    Import,
    In,
    Instanceof,
    Let,
    New,
    Return,
    Static,
    Super,
    Switch,
    This,
    Throw,
    Try,
    Typeof,
    Var,
    Void,
    While,
    With,
    Yield,

    // 11.6.2.2 Future Reserved Words
    Enum,
    Await,
    Implements,
    Interface,
    Package,
    Private,
    Protected,
    Public,

    // 11.7 Punctuators
    LBrace,
    RBrace,
    LParen,
    RParen,
    LBrack,
    RBrack,
    Dot,
    Ellipsis,
    Semi,
    Comma,
    LAngle,
    RAngle,
    LEq,
    GEq,
    Eq,
    NEq,
    StrictEq,
    StrictNEq,
    Plus,
    Minus,
    Star,
    Mod,
    Slash,
    Inc,
    Dec,
    LShift,
    RShift,
    URShift,
    BitAnd,
    BitOr,
    BitXor,
    Bang,
    Tilde,
    LogicalAnd,
    LogicalOr,
    Question,
    Colon,
    Assign,
    PlusAssign,
    MinusAssign,
    StarAssign,
    SlashAssign,
    ModAssign,
    LShiftAssign,
    RShiftAssign,
    URShiftAssign,
    BitAndAssign,
    BitOrAssign,
    BitXorAssign,
    Arrow,

    DecimalInt(String),
    BinaryInt(String),
    OctalInt(String),
    HexInt(String),
    Float(String),

    String(String),
    RegExp(String),

    Identifier(String),

    Newline,
    Error(char)
}
<commit_msg>oops, we can't make Token copyable because it has owned Strings!<commit_after>#[derive(Debug, Copy, Eq, PartialEq)]
pub struct Posn {
    pub offset: u32,
    pub line: u32,
    pub column: u32
}

#[derive(Debug, Eq, PartialEq)]
pub struct Span {
    start: Posn,
    end: Posn
}

#[derive(Debug, Copy, PartialEq)]
#[allow(dead_code)]
pub enum Token {
    Null,
    True,
    False,

    // 11.6.2.1 Keywords
    Break,
    Case,
    Catch,
    Class,
    Const,
    Continue,
    Debugger,
    Default,
    Delete,
    Do,
    Else,
    Export,
    Extends,
    Finally,
    For,
    Function,
    If,
    Import,
    In,
    Instanceof,
    Let,
    New,
    Return,
    Static,
    Super,
    Switch,
    This,
    Throw,
    Try,
    Typeof,
    Var,
    Void,
    While,
    With,
    Yield,

    // 11.6.2.2 Future Reserved Words
    Enum,
    Await,
    Implements,
    Interface,
    Package,
    Private,
    Protected,
    Public,

    // 11.7 Punctuators
    LBrace,
    RBrace,
    LParen,
    RParen,
    LBrack,
    RBrack,
    Dot,
    Ellipsis,
    Semi,
    Comma,
    LAngle,
    RAngle,
    LEq,
    GEq,
    Eq,
    NEq,
    StrictEq,
    StrictNEq,
    Plus,
    Minus,
    Star,
    Mod,
    Slash,
    Inc,
    Dec,
    LShift,
    RShift,
    URShift,
    BitAnd,
    BitOr,
    BitXor,
    Bang,
    Tilde,
    LogicalAnd,
    LogicalOr,
    Question,
    Colon,
    Assign,
    PlusAssign,
    MinusAssign,
    StarAssign,
    SlashAssign,
    ModAssign,
    LShiftAssign,
    RShiftAssign,
    URShiftAssign,
    BitAndAssign,
    BitOrAssign,
    BitXorAssign,
    Arrow,

    DecimalInt(String),
    BinaryInt(String),
    OctalInt(String),
    HexInt(String),
    Float(String),

    String(String),
    RegExp(String),

    Identifier(String),

    Newline,
    Error(char)
}
<|endoftext|>


<commit_before>// This Source Code Form is subject to the terms of the Mozilla Public
// License, v. 2.0. If a copy of the MPL was not distributed with this
// file, You can obtain one at http://mozilla.org/MPL/2.0/.

use std::error::Error;
use std::fmt;
use std::io;

use dbus;
use devicemapper;
use nix;
use term;

pub type StratisResult<T> = Result<T, StratisError>;

#[derive(Debug)]
pub enum StratisError {
    StderrNotFound,
    Io(io::Error),
    Nix(nix::Error),
    Dbus(dbus::Error),
    Term(term::Error),
    DM(devicemapper::DmError),
}

impl fmt::Display for StratisError {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        match *self {
            StratisError::StderrNotFound => write!(f, "stderr not found"),
            StratisError::Io(ref err) => write!(f, "IO error: {}", err),
            StratisError::Nix(ref err) => write!(f, "Nix error: {}", err.errno().desc()),
            StratisError::Dbus(ref err) => {
                write!(f, "Dbus error: {}", err.message().unwrap_or("Unknown"))
            }
            StratisError::Term(ref err) => write!(f, "Term error: {}", err),
            StratisError::DM(ref err) => write!(f, "DM error: {}", err),
        }
    }
}

impl Error for StratisError {
    fn description(&self) -> &str {
        match *self {
            StratisError::StderrNotFound => "stderr not found",
            StratisError::Io(ref err) => err.description(),
            StratisError::Nix(ref err) => err.errno().desc(),
            StratisError::Dbus(ref err) => err.message().unwrap_or("D-Bus Error"),
            StratisError::Term(ref err) => Error::description(err),
            StratisError::DM(ref err) => Error::description(err),
        }
    }

    fn cause(&self) -> Option<&Error> {
        match *self {
            StratisError::StderrNotFound => None,
            StratisError::Io(ref err) => Some(err),
            StratisError::Nix(ref err) => Some(err),
            StratisError::Dbus(ref err) => Some(err),
            StratisError::Term(ref err) => Some(err),
            StratisError::DM(ref err) => Some(err),
        }
    }
}

impl From<io::Error> for StratisError {
    fn from(err: io::Error) -> StratisError {
        StratisError::Io(err)
    }
}

impl From<nix::Error> for StratisError {
    fn from(err: nix::Error) -> StratisError {
        StratisError::Nix(err)
    }
}

impl From<dbus::Error> for StratisError {
    fn from(err: dbus::Error) -> StratisError {
        StratisError::Dbus(err)
    }
}

impl From<term::Error> for StratisError {
    fn from(err: term::Error) -> StratisError {
        StratisError::Term(err)
    }
}

impl From<devicemapper::DmError> for StratisError {
    fn from(err: devicemapper::DmError) -> StratisError {
        StratisError::DM(err)
    }
}
<commit_msg>Omit unused StratisError constructors<commit_after>// This Source Code Form is subject to the terms of the Mozilla Public
// License, v. 2.0. If a copy of the MPL was not distributed with this
// file, You can obtain one at http://mozilla.org/MPL/2.0/.

use std::error::Error;
use std::fmt;
use std::io;

use dbus;
use term;

pub type StratisResult<T> = Result<T, StratisError>;

#[derive(Debug)]
pub enum StratisError {
    StderrNotFound,
    Io(io::Error),
    Dbus(dbus::Error),
    Term(term::Error),
}

impl fmt::Display for StratisError {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        match *self {
            StratisError::StderrNotFound => write!(f, "stderr not found"),
            StratisError::Io(ref err) => write!(f, "IO error: {}", err),
            StratisError::Dbus(ref err) => {
                write!(f, "Dbus error: {}", err.message().unwrap_or("Unknown"))
            }
            StratisError::Term(ref err) => write!(f, "Term error: {}", err),
        }
    }
}

impl Error for StratisError {
    fn description(&self) -> &str {
        match *self {
            StratisError::StderrNotFound => "stderr not found",
            StratisError::Io(ref err) => err.description(),
            StratisError::Dbus(ref err) => err.message().unwrap_or("D-Bus Error"),
            StratisError::Term(ref err) => Error::description(err),
        }
    }

    fn cause(&self) -> Option<&Error> {
        match *self {
            StratisError::StderrNotFound => None,
            StratisError::Io(ref err) => Some(err),
            StratisError::Dbus(ref err) => Some(err),
            StratisError::Term(ref err) => Some(err),
        }
    }
}

impl From<io::Error> for StratisError {
    fn from(err: io::Error) -> StratisError {
        StratisError::Io(err)
    }
}

impl From<dbus::Error> for StratisError {
    fn from(err: dbus::Error) -> StratisError {
        StratisError::Dbus(err)
    }
}

impl From<term::Error> for StratisError {
    fn from(err: term::Error) -> StratisError {
        StratisError::Term(err)
    }
}
<|endoftext|>


<commit_before>#![macro_use]

use std::ffi::CStr;
use std::mem;
use std::time::{Duration, Instant};

use gl;
use gl::types::GLubyte;

use log::{debug, info, error};

pub fn elapsed(start_time: Instant) -> String {
    let elapsed = start_time.elapsed();
    format_duration(elapsed)
}

fn format_duration(duration: Duration) -> String {
    let secs = duration.as_secs();
    let nanos = duration.subsec_nanos();
    let ms = f64::from(nanos) / 1_000_000.0;
    if secs > 0 {
        let secs = secs as f64 + ms / 1000.0;
        format!("{:<4.*} s", 1, secs)
    }
    else {
        let places =
            if ms >= 20.0      { 0 }
            else if ms >= 1.0  { 1 }
            else {
                let micros = f64::from(nanos) / 1000.0;
                let places = if micros >= 10.0 { 0 } else { 2 };
                return format!("{:>3.*} µs", places, micros)
            };
        format!("{:>3.*} ms", places, ms)
    }
}

pub fn print_elapsed(message: &str, start_time: Instant) {
    info!("{:<25}{}", message, elapsed(start_time));
}

pub struct FrameTimer {
    message: String,
    averaging_window: usize,
    current_frame_start: Instant,
    pub frame_times: Vec<Duration>,
}

/// Timing helper that averages timings over `averaging_window`
// frames and then prints avg/min/max
impl FrameTimer {
    pub fn new(message: &str, averaging_window: usize) -> FrameTimer {
        FrameTimer {
            message: message.to_owned(),
            averaging_window,
            current_frame_start: Instant::now(),
            frame_times: Vec::with_capacity(averaging_window),
        }
    }

    pub fn start(&mut self) {
        self.current_frame_start = Instant::now();
    }

    pub fn end(&mut self) {
        self.frame_times.push(self.current_frame_start.elapsed());
        if self.frame_times.len() == self.averaging_window {
            self.print_and_reset();
        }
    }

    pub fn print_and_reset(&mut self) {
        {
            let avg = self.frame_times.iter().sum::<Duration>() / self.frame_times.len() as u32;
            let min = self.frame_times.iter().min().unwrap();
            let max = self.frame_times.iter().max().unwrap();
            info!("{:<15}{} (min: {}, max: {})", self.message,
                format_duration(avg), format_duration(*min), format_duration(*max));
        }
        self.frame_times.clear();
    }
}

pub unsafe fn gl_check_error(file: &str, line: u32) -> u32 {
    let mut error_code = gl::GetError();
    while error_code != gl::NO_ERROR {
        let error = match error_code {
            gl::INVALID_ENUM => "INVALID_ENUM",
            gl::INVALID_VALUE => "INVALID_VALUE",
            gl::INVALID_OPERATION => "INVALID_OPERATION",
            gl::STACK_OVERFLOW => "STACK_OVERFLOW",
            gl::STACK_UNDERFLOW => "STACK_UNDERFLOW",
            gl::OUT_OF_MEMORY => "OUT_OF_MEMORY",
            gl::INVALID_FRAMEBUFFER_OPERATION => "INVALID_FRAMEBUFFER_OPERATION",
            _ => "unknown GL error code"
        };

        error!("{} | {} ({})", error, file, line);

        error_code = gl::GetError();
    }
    error_code
}

#[allow(unused_macros)]
macro_rules! gl_check_error {
    () => (
        gl_check_error(file!(), line!())
    )
}

/// Prints information about the current OpenGL context
/// Based on glium's `context::capabilities::get_capabilities`
pub unsafe fn print_context_info() {
    debug!("Renderer     : {}", gl_string(gl::GetString(gl::RENDERER)));
    debug!("Vendor       : {}", gl_string(gl::GetString(gl::VENDOR)));
    debug!("Version      : {}", gl_string(gl::GetString(gl::VERSION)));
    debug!("GLSL         : {}", gl_string(gl::GetString(gl::SHADING_LANGUAGE_VERSION)));

    let mut val = mem::MaybeUninit::uninit().assume_init();
    gl::GetIntegerv(gl::CONTEXT_PROFILE_MASK, &mut val);
    let val = val as gl::types::GLenum;
    let profile = if (val & gl::CONTEXT_COMPATIBILITY_PROFILE_BIT) != 0 {
        "Compatibility"
    } else if (val & gl::CONTEXT_CORE_PROFILE_BIT) != 0 {
        "Core"
    } else {
        "None"
    };
    debug!("Profile      : {}", profile);

    let (debug, forward_compatible) = {
        let mut val = mem::MaybeUninit::uninit().assume_init();
        gl::GetIntegerv(gl::CONTEXT_FLAGS, &mut val);
        let val = val as gl::types::GLenum;
        ((val & gl::CONTEXT_FLAG_DEBUG_BIT) != 0,
         (val & gl::CONTEXT_FLAG_FORWARD_COMPATIBLE_BIT) != 0)
    };
    debug!("Context Flags: Debug: {}, Forward Compatible: {}", debug, forward_compatible);

    let mut num_extensions = 0;
    gl::GetIntegerv(gl::NUM_EXTENSIONS, &mut num_extensions);
    let extensions: Vec<_> = (0 .. num_extensions).map(|num| {
        gl_string(gl::GetStringi(gl::EXTENSIONS, num as gl::types::GLuint))
    }).collect();
    debug!("Extensions   : {}", extensions.join(", "))
}

pub unsafe fn gl_string(raw_string: *const GLubyte) -> String {
    if raw_string.is_null() { return "(NULL)".into() }
    String::from_utf8(CStr::from_ptr(raw_string as *const _).to_bytes().to_vec())
                                .expect("gl_string: non-UTF8 string")
}
<commit_msg>fix undefined behavior in use of MaybeUninit<commit_after>#![macro_use]

use std::ffi::CStr;
use std::mem;
use std::time::{Duration, Instant};

use gl;
use gl::types::GLubyte;

use log::{debug, info, error};

pub fn elapsed(start_time: Instant) -> String {
    let elapsed = start_time.elapsed();
    format_duration(elapsed)
}

fn format_duration(duration: Duration) -> String {
    let secs = duration.as_secs();
    let nanos = duration.subsec_nanos();
    let ms = f64::from(nanos) / 1_000_000.0;
    if secs > 0 {
        let secs = secs as f64 + ms / 1000.0;
        format!("{:<4.*} s", 1, secs)
    }
    else {
        let places =
            if ms >= 20.0      { 0 }
            else if ms >= 1.0  { 1 }
            else {
                let micros = f64::from(nanos) / 1000.0;
                let places = if micros >= 10.0 { 0 } else { 2 };
                return format!("{:>3.*} µs", places, micros)
            };
        format!("{:>3.*} ms", places, ms)
    }
}

pub fn print_elapsed(message: &str, start_time: Instant) {
    info!("{:<25}{}", message, elapsed(start_time));
}

pub struct FrameTimer {
    message: String,
    averaging_window: usize,
    current_frame_start: Instant,
    pub frame_times: Vec<Duration>,
}

/// Timing helper that averages timings over `averaging_window`
// frames and then prints avg/min/max
impl FrameTimer {
    pub fn new(message: &str, averaging_window: usize) -> FrameTimer {
        FrameTimer {
            message: message.to_owned(),
            averaging_window,
            current_frame_start: Instant::now(),
            frame_times: Vec::with_capacity(averaging_window),
        }
    }

    pub fn start(&mut self) {
        self.current_frame_start = Instant::now();
    }

    pub fn end(&mut self) {
        self.frame_times.push(self.current_frame_start.elapsed());
        if self.frame_times.len() == self.averaging_window {
            self.print_and_reset();
        }
    }

    pub fn print_and_reset(&mut self) {
        {
            let avg = self.frame_times.iter().sum::<Duration>() / self.frame_times.len() as u32;
            let min = self.frame_times.iter().min().unwrap();
            let max = self.frame_times.iter().max().unwrap();
            info!("{:<15}{} (min: {}, max: {})", self.message,
                format_duration(avg), format_duration(*min), format_duration(*max));
        }
        self.frame_times.clear();
    }
}

pub unsafe fn gl_check_error(file: &str, line: u32) -> u32 {
    let mut error_code = gl::GetError();
    while error_code != gl::NO_ERROR {
        let error = match error_code {
            gl::INVALID_ENUM => "INVALID_ENUM",
            gl::INVALID_VALUE => "INVALID_VALUE",
            gl::INVALID_OPERATION => "INVALID_OPERATION",
            gl::STACK_OVERFLOW => "STACK_OVERFLOW",
            gl::STACK_UNDERFLOW => "STACK_UNDERFLOW",
            gl::OUT_OF_MEMORY => "OUT_OF_MEMORY",
            gl::INVALID_FRAMEBUFFER_OPERATION => "INVALID_FRAMEBUFFER_OPERATION",
            _ => "unknown GL error code"
        };

        error!("{} | {} ({})", error, file, line);

        error_code = gl::GetError();
    }
    error_code
}

#[allow(unused_macros)]
macro_rules! gl_check_error {
    () => (
        gl_check_error(file!(), line!())
    )
}

/// Prints information about the current OpenGL context
/// Based on glium's `context::capabilities::get_capabilities`
pub unsafe fn print_context_info() {
    debug!("Renderer     : {}", gl_string(gl::GetString(gl::RENDERER)));
    debug!("Vendor       : {}", gl_string(gl::GetString(gl::VENDOR)));
    debug!("Version      : {}", gl_string(gl::GetString(gl::VERSION)));
    debug!("GLSL         : {}", gl_string(gl::GetString(gl::SHADING_LANGUAGE_VERSION)));

    let mut val = mem::MaybeUninit::uninit();
    gl::GetIntegerv(gl::CONTEXT_PROFILE_MASK, val.as_mut_ptr());
    let val = val.assume_init() as gl::types::GLenum;
    let profile = if (val & gl::CONTEXT_COMPATIBILITY_PROFILE_BIT) != 0 {
        "Compatibility"
    } else if (val & gl::CONTEXT_CORE_PROFILE_BIT) != 0 {
        "Core"
    } else {
        "None"
    };
    debug!("Profile      : {}", profile);

    let (debug, forward_compatible) = {
        let mut val = mem::MaybeUninit::uninit();
        gl::GetIntegerv(gl::CONTEXT_FLAGS, val.as_mut_ptr());
        let val = val.assume_init() as gl::types::GLenum;
        ((val & gl::CONTEXT_FLAG_DEBUG_BIT) != 0,
         (val & gl::CONTEXT_FLAG_FORWARD_COMPATIBLE_BIT) != 0)
    };
    debug!("Context Flags: Debug: {}, Forward Compatible: {}", debug, forward_compatible);

    let mut num_extensions = 0;
    gl::GetIntegerv(gl::NUM_EXTENSIONS, &mut num_extensions);
    let extensions: Vec<_> = (0 .. num_extensions).map(|num| {
        gl_string(gl::GetStringi(gl::EXTENSIONS, num as gl::types::GLuint))
    }).collect();
    debug!("Extensions   : {}", extensions.join(", "))
}

pub unsafe fn gl_string(raw_string: *const GLubyte) -> String {
    if raw_string.is_null() { return "(NULL)".into() }
    String::from_utf8(CStr::from_ptr(raw_string as *const _).to_bytes().to_vec())
                                .expect("gl_string: non-UTF8 string")
}
<|endoftext|>


<commit_before>//! Graph visitor algorithms.
//!

use std::marker;
use std::collections::{
    HashSet,
    BitSet,
    VecDeque,
};
use std::hash::Hash;

use super::{
    graphmap,
    graph,
    EdgeType,
    EdgeDirection,
    Graph,
    GraphMap,
};

use graph::{
    IndexType,
};

pub trait Graphlike : marker::MarkerTrait {
    type NodeId: Clone;
}

/// A graph trait for accessing the neighbors iterator
pub trait NeighborIter<'a, N> {
    type Iter: Iterator<Item=N>;
    fn neighbors(&'a self, n: N) -> Self::Iter;
}

impl<'a, N, E, Ty, Ix> NeighborIter<'a, graph::NodeIndex<Ix>> for Graph<N, E, Ty, Ix> where
    Ty: EdgeType,
    Ix: IndexType,
{
    type Iter = graph::Neighbors<'a, E, Ix>;
    fn neighbors(&'a self, n: graph::NodeIndex<Ix>) -> graph::Neighbors<'a, E, Ix>
    {
        Graph::neighbors(self, n)
    }
}

impl<'a, N, E> NeighborIter<'a, N> for GraphMap<N, E>
where N: Copy + Clone + Ord + Hash + Eq
{
    type Iter = graphmap::Neighbors<'a, N>;
    fn neighbors(&'a self, n: N) -> graphmap::Neighbors<'a, N>
    {
        GraphMap::neighbors(self, n)
    }
}

/// Wrapper type for walking the graph as if it is undirected
pub struct AsUndirected<G>(pub G);
/// Wrapper type for walking edges the other way
pub struct Reversed<G>(pub G);

impl<'a, 'b, N, E, Ty, Ix> NeighborIter<'a, graph::NodeIndex<Ix>> for AsUndirected<&'b Graph<N, E, Ty, Ix>> where
    Ty: EdgeType,
    Ix: IndexType,
{
    type Iter = graph::Neighbors<'a, E, Ix>;

    fn neighbors(&'a self, n: graph::NodeIndex<Ix>) -> graph::Neighbors<'a, E, Ix>
    {
        Graph::neighbors_undirected(self.0, n)
    }
}

impl<'a, 'b, N, E, Ty, Ix> NeighborIter<'a, graph::NodeIndex<Ix>> for Reversed<&'b Graph<N, E, Ty, Ix>> where
    Ty: EdgeType,
    Ix: IndexType,
{
    type Iter = graph::Neighbors<'a, E, Ix>;
    fn neighbors(&'a self, n: graph::NodeIndex<Ix>) -> graph::Neighbors<'a, E, Ix>
    {
        Graph::neighbors_directed(self.0, n, EdgeDirection::Incoming)
    }
}

pub trait VisitMap<N> {
    /// Return **true** if the value is not already present.
    fn visit(&mut self, N) -> bool;
    fn is_visited(&self, &N) -> bool;
}

impl<Ix> VisitMap<graph::NodeIndex<Ix>> for BitSet where
    Ix: IndexType,
{
    fn visit(&mut self, x: graph::NodeIndex<Ix>) -> bool {
        self.insert(x.index())
    }
    fn is_visited(&self, x: &graph::NodeIndex<Ix>) -> bool {
        self.contains(&x.index())
    }
}

impl<N: Eq + Hash> VisitMap<N> for HashSet<N> {
    fn visit(&mut self, x: N) -> bool {
        self.insert(x)
    }
    fn is_visited(&self, x: &N) -> bool {
        self.contains(x)
    }
}

/// Trait for GraphMap that knows which datastructure is the best for its visitor map
pub trait Visitable : Graphlike {
    type Map: VisitMap<<Self as Graphlike>::NodeId>;
    fn visit_map(&self) -> Self::Map;
}

impl<N, E, Ty, Ix> Graphlike for Graph<N, E, Ty, Ix> where
    Ix: IndexType,
{
    type NodeId = graph::NodeIndex<Ix>;
}

impl<N, E, Ty, Ix> Visitable for Graph<N, E, Ty, Ix> where
    Ty: EdgeType,
    Ix: IndexType,
{
    type Map = BitSet;
    fn visit_map(&self) -> BitSet { BitSet::with_capacity(self.node_count()) }
}

impl<N: Clone, E> Graphlike for GraphMap<N, E>
{
    type NodeId = N;
}

impl<N, E> Visitable for GraphMap<N, E>
    where N: Copy + Clone + Ord + Eq + Hash
{
    type Map = HashSet<N>;
    fn visit_map(&self) -> HashSet<N> { HashSet::with_capacity(self.node_count()) }
}

impl<'a, V: Graphlike> Graphlike for AsUndirected<&'a V>
{
    type NodeId = <V as Graphlike>::NodeId;
}

impl<'a, V: Graphlike> Graphlike for Reversed<&'a V>
{
    type NodeId = <V as Graphlike>::NodeId;
}

impl<'a, V: Visitable> Visitable for AsUndirected<&'a V>
{
    type Map = <V as Visitable>::Map;
    fn visit_map(&self) -> <V as Visitable>::Map {
        self.0.visit_map()
    }
}

impl<'a, V: Visitable> Visitable for Reversed<&'a V>
{
    type Map = <V as Visitable>::Map;
    fn visit_map(&self) -> <V as Visitable>::Map {
        self.0.visit_map()
    }
}

/// Create or access the adjacency matrix of a graph
pub trait GetAdjacencyMatrix : Graphlike {
    type AdjMatrix;
    fn adjacency_matrix(&self) -> Self::AdjMatrix;
    fn is_adjacent(&self, matrix: &Self::AdjMatrix, a: Self::NodeId, b: Self::NodeId) -> bool;
}

/// A depth first search (DFS) of a graph.
///
/// Using a **Dfs** you can run a traversal over a graph while still retaining
/// mutable access to it, if you use it like the following example:
///
/// ```
/// use petgraph::{Graph, Dfs};
///
/// let mut graph = Graph::<_,()>::new();
/// let a = graph.add_node(0);
///
/// let mut dfs = Dfs::new(&graph, a);
/// while let Some(nx) = dfs.next(&graph) {
///     // we can access `graph` mutably here still
///     graph[nx] += 1;
/// }
///
/// assert_eq!(graph[a], 1);
/// ```
///
/// **Note:** The algorithm may not behave correctly if nodes are removed
/// during iteration. It may not necessarily visit added nodes or edges.
#[derive(Clone, Debug)]
pub struct Dfs<N, VM> {
    pub stack: Vec<N>,
    pub discovered: VM,
}

impl<G: Visitable> Dfs<G::NodeId, <G as Visitable>::Map>
{
    /// Create a new **Dfs**, using the graph's visitor map, and put **start**
    /// in the stack of nodes to visit.
    pub fn new(graph: &G, start: G::NodeId) -> Self
    {
        let mut dfs = Dfs::empty(graph);
        dfs.move_to(start);
        dfs
    }

    /// Create a new **Dfs** using the graph's visitor map, and no stack.
    pub fn empty(graph: &G) -> Self
    {
        Dfs {
            stack: Vec::new(),
            discovered: graph.visit_map(),
        }
    }
}

impl<N, VM> Dfs<N, VM> where
    N: Clone,
    VM: VisitMap<N>
{
    /// Keep the discovered map, but clear the visit stack and restart
    /// the dfs from a particular node.
    pub fn move_to(&mut self, start: N)
    {
        self.discovered.visit(start.clone());
        self.stack.clear();
        self.stack.push(start);
    }
}

impl<N, VM> Dfs<N, VM> where
    N: Clone,
    VM: VisitMap<N>
{
    /// Return the next node in the dfs, or **None** if the traversal is done.
    pub fn next<'a, G>(&mut self, graph: &'a G) -> Option<N> where
        G: for<'b> NeighborIter<'b, N>,
    {
        while let Some(node) = self.stack.pop() {
            for succ in graph.neighbors(node.clone()) {
                if self.discovered.visit(succ.clone()) {
                    self.stack.push(succ);
                }
            }

            return Some(node);
        }
        None
    }
}

/// An iterator for a depth first traversal of a graph.
pub struct DfsIter<'a, G: 'a + Visitable>
{
    graph: &'a G,
    dfs: Dfs<G::NodeId, G::Map>,
}

impl<'a, G: Visitable> DfsIter<'a, G>
{
    pub fn new(graph: &'a G, start: G::NodeId) -> Self
    {
        DfsIter {
            graph: graph,
            dfs: Dfs::new(graph, start)
        }
    }
}

impl<'a, G: 'a + Visitable> Iterator for DfsIter<'a, G> where
    G: for<'b> NeighborIter<'b, G::NodeId>,
{
    type Item = G::NodeId;
    fn next(&mut self) -> Option<G::NodeId>
    {
        self.dfs.next(self.graph)
    }
}

/// A breadth first search (BFS) of a graph.
///
/// Using a **Bfs** you can run a traversal over a graph while still retaining
/// mutable access to it, if you use it like the following example:
///
/// ```
/// use petgraph::{Graph, Bfs};
///
/// let mut graph = Graph::<_,()>::new();
/// let a = graph.add_node(0);
///
/// let mut bfs = Bfs::new(&graph, a);
/// while let Some(nx) = bfs.next(&graph) {
///     // we can access `graph` mutably here still
///     graph[nx] += 1;
/// }
///
/// assert_eq!(graph[a], 1);
/// ```
///
/// **Note:** The algorithm may not behave correctly if nodes are removed
/// during iteration. It may not necessarily visit added nodes or edges.
#[derive(Clone)]
pub struct Bfs<N, VM> {
    pub stack: VecDeque<N>,
    pub discovered: VM,
}

impl<G: Visitable> Bfs<G::NodeId, <G as Visitable>::Map> where
    G::NodeId: Clone,
{
    /// Create a new **Bfs**, using the graph's visitor map, and put **start**
    /// in the stack of nodes to visit.
    pub fn new(graph: &G, start: G::NodeId) -> Self
    {
        let mut discovered = graph.visit_map();
        discovered.visit(start.clone());
        let mut stack = VecDeque::new();
        stack.push_front(start.clone());
        Bfs {
            stack: stack,
            discovered: discovered,
        }
    }
}

impl<N, VM> Bfs<N, VM> where
    N: Clone,
    VM: VisitMap<N>
{
    /// Return the next node in the dfs, or **None** if the traversal is done.
    pub fn next<'a, G>(&mut self, graph: &'a G) -> Option<N> where
        G: for<'b> NeighborIter<'b, N>,
    {
        while let Some(node) = self.stack.pop_front() {
            for succ in graph.neighbors(node.clone()) {
                if self.discovered.visit(succ.clone()) {
                    self.stack.push_back(succ);
                }
            }

            return Some(node);
        }
        None
    }

}

/*
pub struct Visitor<G> where
    G: Visitable,
{
    stack: Vec<<G as Graphlike>::NodeId>,
    discovered: <G as Visitable>::Map,
}

pub fn visitor<G>(graph: &G, start: <G as Graphlike>::NodeId) -> Visitor<G> where
    G: Visitable
{
    Visitor{
        stack: vec![start],
        discovered: graph.visit_map(),
    }
}
*/

/// An iterator for a breadth first traversal of a graph.
pub struct BfsIter<'a, G: 'a + Visitable>
{
    graph: &'a G,
    bfs: Bfs<G::NodeId, G::Map>,
}

impl<'a, G: Visitable> BfsIter<'a, G> where
    G::NodeId: Clone,
{
    pub fn new(graph: &'a G, start: G::NodeId) -> Self
    {
        BfsIter {
            graph: graph,
            bfs: Bfs::new(graph, start)
        }
    }
}

impl<'a, G: 'a + Visitable> Iterator for BfsIter<'a, G> where
    G::NodeId: Clone,
    G: for<'b> NeighborIter<'b, G::NodeId>,
{
    type Item = G::NodeId;
    fn next(&mut self) -> Option<G::NodeId>
    {
        self.bfs.next(self.graph)
    }
}
<commit_msg>Update NeighborIter trait due to Rust changes<commit_after>//! Graph visitor algorithms.
//!

use std::marker;
use std::collections::{
    HashSet,
    BitSet,
    VecDeque,
};
use std::hash::Hash;

use super::{
    graphmap,
    graph,
    EdgeType,
    EdgeDirection,
    Graph,
    GraphMap,
};

use graph::{
    IndexType,
};

pub trait Graphlike : marker::MarkerTrait {
    type NodeId: Clone;
}

/// A graph trait for accessing the neighbors iterator
pub trait NeighborIter<'a> : Graphlike{
    type Iter: Iterator<Item=Self::NodeId>;
    fn neighbors(&'a self, n: Self::NodeId) -> Self::Iter;
}

impl<'a, N, E, Ty, Ix> NeighborIter<'a> for Graph<N, E, Ty, Ix> where
    Ty: EdgeType,
    Ix: IndexType,
{
    type Iter = graph::Neighbors<'a, E, Ix>;
    fn neighbors(&'a self, n: graph::NodeIndex<Ix>) -> graph::Neighbors<'a, E, Ix>
    {
        Graph::neighbors(self, n)
    }
}

impl<'a, N, E> NeighborIter<'a> for GraphMap<N, E>
where N: Copy + Clone + Ord + Hash + Eq
{
    type Iter = graphmap::Neighbors<'a, N>;
    fn neighbors(&'a self, n: N) -> graphmap::Neighbors<'a, N>
    {
        GraphMap::neighbors(self, n)
    }
}

/// Wrapper type for walking the graph as if it is undirected
pub struct AsUndirected<G>(pub G);
/// Wrapper type for walking edges the other way
pub struct Reversed<G>(pub G);

impl<'a, 'b, N, E, Ty, Ix> NeighborIter<'a> for AsUndirected<&'b Graph<N, E, Ty, Ix>> where
    Ty: EdgeType,
    Ix: IndexType,
{
    type Iter = graph::Neighbors<'a, E, Ix>;

    fn neighbors(&'a self, n: graph::NodeIndex<Ix>) -> graph::Neighbors<'a, E, Ix>
    {
        Graph::neighbors_undirected(self.0, n)
    }
}

impl<'a, 'b, N, E, Ty, Ix> NeighborIter<'a> for Reversed<&'b Graph<N, E, Ty, Ix>> where
    Ty: EdgeType,
    Ix: IndexType,
{
    type Iter = graph::Neighbors<'a, E, Ix>;
    fn neighbors(&'a self, n: graph::NodeIndex<Ix>) -> graph::Neighbors<'a, E, Ix>
    {
        Graph::neighbors_directed(self.0, n, EdgeDirection::Incoming)
    }
}

pub trait VisitMap<N> {
    /// Return **true** if the value is not already present.
    fn visit(&mut self, N) -> bool;
    fn is_visited(&self, &N) -> bool;
}

impl<Ix> VisitMap<graph::NodeIndex<Ix>> for BitSet where
    Ix: IndexType,
{
    fn visit(&mut self, x: graph::NodeIndex<Ix>) -> bool {
        self.insert(x.index())
    }
    fn is_visited(&self, x: &graph::NodeIndex<Ix>) -> bool {
        self.contains(&x.index())
    }
}

impl<N: Eq + Hash> VisitMap<N> for HashSet<N> {
    fn visit(&mut self, x: N) -> bool {
        self.insert(x)
    }
    fn is_visited(&self, x: &N) -> bool {
        self.contains(x)
    }
}

/// Trait for GraphMap that knows which datastructure is the best for its visitor map
pub trait Visitable : Graphlike {
    type Map: VisitMap<<Self as Graphlike>::NodeId>;
    fn visit_map(&self) -> Self::Map;
}

impl<N, E, Ty, Ix> Graphlike for Graph<N, E, Ty, Ix> where
    Ix: IndexType,
{
    type NodeId = graph::NodeIndex<Ix>;
}

impl<N, E, Ty, Ix> Visitable for Graph<N, E, Ty, Ix> where
    Ty: EdgeType,
    Ix: IndexType,
{
    type Map = BitSet;
    fn visit_map(&self) -> BitSet { BitSet::with_capacity(self.node_count()) }
}

impl<N: Clone, E> Graphlike for GraphMap<N, E>
{
    type NodeId = N;
}

impl<N, E> Visitable for GraphMap<N, E>
    where N: Copy + Clone + Ord + Eq + Hash
{
    type Map = HashSet<N>;
    fn visit_map(&self) -> HashSet<N> { HashSet::with_capacity(self.node_count()) }
}

impl<'a, V: Graphlike> Graphlike for AsUndirected<&'a V>
{
    type NodeId = <V as Graphlike>::NodeId;
}

impl<'a, V: Graphlike> Graphlike for Reversed<&'a V>
{
    type NodeId = <V as Graphlike>::NodeId;
}

impl<'a, V: Visitable> Visitable for AsUndirected<&'a V>
{
    type Map = <V as Visitable>::Map;
    fn visit_map(&self) -> <V as Visitable>::Map {
        self.0.visit_map()
    }
}

impl<'a, V: Visitable> Visitable for Reversed<&'a V>
{
    type Map = <V as Visitable>::Map;
    fn visit_map(&self) -> <V as Visitable>::Map {
        self.0.visit_map()
    }
}

/// Create or access the adjacency matrix of a graph
pub trait GetAdjacencyMatrix : Graphlike {
    type AdjMatrix;
    fn adjacency_matrix(&self) -> Self::AdjMatrix;
    fn is_adjacent(&self, matrix: &Self::AdjMatrix, a: Self::NodeId, b: Self::NodeId) -> bool;
}

/// A depth first search (DFS) of a graph.
///
/// Using a **Dfs** you can run a traversal over a graph while still retaining
/// mutable access to it, if you use it like the following example:
///
/// ```
/// use petgraph::{Graph, Dfs};
///
/// let mut graph = Graph::<_,()>::new();
/// let a = graph.add_node(0);
///
/// let mut dfs = Dfs::new(&graph, a);
/// while let Some(nx) = dfs.next(&graph) {
///     // we can access `graph` mutably here still
///     graph[nx] += 1;
/// }
///
/// assert_eq!(graph[a], 1);
/// ```
///
/// **Note:** The algorithm may not behave correctly if nodes are removed
/// during iteration. It may not necessarily visit added nodes or edges.
#[derive(Clone, Debug)]
pub struct Dfs<N, VM> {
    pub stack: Vec<N>,
    pub discovered: VM,
}

impl<G: Visitable> Dfs<G::NodeId, G::Map>
{
    /// Create a new **Dfs**, using the graph's visitor map, and put **start**
    /// in the stack of nodes to visit.
    pub fn new(graph: &G, start: G::NodeId) -> Self
    {
        let mut dfs = Dfs::empty(graph);
        dfs.move_to(start);
        dfs
    }

    /// Create a new **Dfs** using the graph's visitor map, and no stack.
    pub fn empty(graph: &G) -> Self
    {
        Dfs {
            stack: Vec::new(),
            discovered: graph.visit_map(),
        }
    }
}

impl<N, VM> Dfs<N, VM> where
    N: Clone,
    VM: VisitMap<N>
{
    /// Keep the discovered map, but clear the visit stack and restart
    /// the dfs from a particular node.
    pub fn move_to(&mut self, start: N)
    {
        self.discovered.visit(start.clone());
        self.stack.clear();
        self.stack.push(start);
    }
}

impl<N, VM> Dfs<N, VM> where
    N: Clone,
    VM: VisitMap<N>
{
    /// Return the next node in the dfs, or **None** if the traversal is done.
    pub fn next<'a, G>(&mut self, graph: &'a G) -> Option<N> where
        G: Graphlike<NodeId=N>,
        G: for<'b> NeighborIter<'b>,
    {
        while let Some(node) = self.stack.pop() {
            for succ in graph.neighbors(node.clone()) {
                if self.discovered.visit(succ.clone()) {
                    self.stack.push(succ);
                }
            }

            return Some(node);
        }
        None
    }
}

/// An iterator for a depth first traversal of a graph.
pub struct DfsIter<'a, G: 'a + Visitable>
{
    graph: &'a G,
    dfs: Dfs<G::NodeId, G::Map>,
}

impl<'a, G: Visitable> DfsIter<'a, G>
{
    pub fn new(graph: &'a G, start: G::NodeId) -> Self
    {
        DfsIter {
            graph: graph,
            dfs: Dfs::new(graph, start)
        }
    }
}

impl<'a, G: 'a + Visitable> Iterator for DfsIter<'a, G> where
    G: for<'b> NeighborIter<'b>,
{
    type Item = G::NodeId;
    fn next(&mut self) -> Option<G::NodeId>
    {
        self.dfs.next(self.graph)
    }
}

/// A breadth first search (BFS) of a graph.
///
/// Using a **Bfs** you can run a traversal over a graph while still retaining
/// mutable access to it, if you use it like the following example:
///
/// ```
/// use petgraph::{Graph, Bfs};
///
/// let mut graph = Graph::<_,()>::new();
/// let a = graph.add_node(0);
///
/// let mut bfs = Bfs::new(&graph, a);
/// while let Some(nx) = bfs.next(&graph) {
///     // we can access `graph` mutably here still
///     graph[nx] += 1;
/// }
///
/// assert_eq!(graph[a], 1);
/// ```
///
/// **Note:** The algorithm may not behave correctly if nodes are removed
/// during iteration. It may not necessarily visit added nodes or edges.
#[derive(Clone)]
pub struct Bfs<N, VM> {
    pub stack: VecDeque<N>,
    pub discovered: VM,
}

impl<G: Visitable> Bfs<G::NodeId, <G as Visitable>::Map> where
    G::NodeId: Clone,
{
    /// Create a new **Bfs**, using the graph's visitor map, and put **start**
    /// in the stack of nodes to visit.
    pub fn new(graph: &G, start: G::NodeId) -> Self
    {
        let mut discovered = graph.visit_map();
        discovered.visit(start.clone());
        let mut stack = VecDeque::new();
        stack.push_front(start.clone());
        Bfs {
            stack: stack,
            discovered: discovered,
        }
    }
}

impl<N, VM> Bfs<N, VM> where
    N: Clone,
    VM: VisitMap<N>
{
    /// Return the next node in the dfs, or **None** if the traversal is done.
    pub fn next<'a, G>(&mut self, graph: &'a G) -> Option<N> where
        G: Graphlike<NodeId=N>,
        G: for<'b> NeighborIter<'b>,
    {
        while let Some(node) = self.stack.pop_front() {
            for succ in graph.neighbors(node.clone()) {
                if self.discovered.visit(succ.clone()) {
                    self.stack.push_back(succ);
                }
            }

            return Some(node);
        }
        None
    }

}

/*
pub struct Visitor<G> where
    G: Visitable,
{
    stack: Vec<<G as Graphlike>::NodeId>,
    discovered: <G as Visitable>::Map,
}

pub fn visitor<G>(graph: &G, start: <G as Graphlike>::NodeId) -> Visitor<G> where
    G: Visitable
{
    Visitor{
        stack: vec![start],
        discovered: graph.visit_map(),
    }
}
*/

/// An iterator for a breadth first traversal of a graph.
pub struct BfsIter<'a, G: 'a + Visitable>
{
    graph: &'a G,
    bfs: Bfs<G::NodeId, G::Map>,
}

impl<'a, G: Visitable> BfsIter<'a, G> where
    G::NodeId: Clone,
{
    pub fn new(graph: &'a G, start: G::NodeId) -> Self
    {
        BfsIter {
            graph: graph,
            bfs: Bfs::new(graph, start)
        }
    }
}

impl<'a, G: 'a + Visitable> Iterator for BfsIter<'a, G> where
    G::NodeId: Clone,
    G: for<'b> NeighborIter<'b>,
{
    type Item = G::NodeId;
    fn next(&mut self) -> Option<G::NodeId>
    {
        self.bfs.next(self.graph)
    }
}
<|endoftext|>


<commit_before>use std::num::{div_rem};
use self::Decode::{V, C};

static VS: [char, ..5] = ['a', 'e', 'i', 'o', 'u'];
static CS: [char, ..14] = ['b', 'd', 'f', 'g', 'j', 'k', 'm', 'n',
    'p', 'r', 's', 't', 'v', 'z'];

enum Decode {
    V(u16),
    C(u16),
}

static LUT: [Option<Decode>, ..26] = [
    Some(V(0)),  // a (ASCII 97)
    Some(C(0)),  // b
    None,        // c
    Some(C(1)),  // d
    Some(V(1)),  // e
    Some(C(2)),  // f
    Some(C(3)),  // g
    None,        // h
    Some(V(2)),  // i
    Some(C(4)),  // j
    Some(C(5)),  // k
    None,        // l
    Some(C(6)),  // m
    Some(C(7)),  // n
    Some(V(3)),  // o
    Some(C(8)),  // p
    None,        // q
    Some(C(9)),  // r
    Some(C(10)), // s
    Some(C(11)), // t
    Some(V(4)),  // u
    Some(C(12)), // v
    None,        // w
    None,        // x
    None,        // y
    Some(C(13)), // z
];

fn vorud_chunk(data: u16) -> String {
    let (data, c5) = div_rem(data, CS.len() as u16);
    let (data, v4) = div_rem(data, VS.len() as u16);
    let (data, c3) = div_rem(data, CS.len() as u16);
    let (data, v2) = div_rem(data, VS.len() as u16);
    let (_, c1) = div_rem(data, CS.len() as u16);
    [CS[c1 as uint],
     VS[v2 as uint],
     CS[c3 as uint],
     VS[v4 as uint],
     CS[c5 as uint],
    ].iter().map(|&x| x).collect()
}

fn decode(c: char) -> Option<Decode> {
    let idx = c as int - 97;
    if idx < 0 || idx >= LUT.len() as int { return None; }
    LUT[idx as uint]
}

fn v(c: char) -> Result<u16, ()> {
    match decode(c) {
        Some(V(i)) => Ok(i),
        _ => Err(())
    }
}

fn c(c: char) -> Result<u16, ()> {
    match decode(c) {
        Some(C(i)) => Ok(i),
        _ => Err(())
    }
}

fn durov_chunk(s: &str) -> Result<u16, ()> {
    if s.len() != 5 { return Err(()); }
    let s: Vec<char> = s.chars().collect();
    let (mut ret, mut n) = (0u16, 1u16);
    ret += try!(c(s[4])) * n; n *= CS.len() as u16;
    ret += try!(v(s[3])) * n; n *= VS.len() as u16;
    ret += try!(c(s[2])) * n; n *= CS.len() as u16;
    ret += try!(v(s[1])) * n; n *= VS.len() as u16;
    ret += try!(c(s[0])) * n;

    Ok(ret)
}

#[deriving(PartialEq, Eq, Show)]
pub struct Vorud(String);

impl Vorud {
    pub fn new(s: String) -> Result<Vorud, ()> {
        if s.len() == 0 { return Ok(Vorud("".to_string())); }
        let ch = s.as_slice().chars().collect::<Vec<char>>();
        let mut i = 0;
        loop {
            if i > ch.len() - 5 { return Err(()); }
            try!(c(ch[i]));
            try!(v(ch[i + 1]));
            try!(c(ch[i + 2]));
            try!(v(ch[i + 3]));
            try!(c(ch[i + 4]));
            if i == ch.len() - 5 { return Ok(Vorud(s)); }
            if ch[i + 5] != '-' { return Err(()); }
            i += 6;
        }
    }
}

pub trait FromVorud<E> {
    fn from_vorud(v: &Vorud) -> Result<Self, E>;
}

pub trait ToVorud {
    fn to_vorud(&self) -> Vorud;
}

impl<'a> ToVorud for &'a [u8] {
    fn to_vorud(&self) -> Vorud {
        let mut ret = String::new();
        for i in range(0, self.len() / 2) {
            if ret.len() > 0 { ret.push_str("-"); }
            let b0 = self[i * 2] as u16;
            let b1 = if self.len() == i * 2 + 1 { 0 } else { self[i * 2 + 1] as u16 };
            ret.push_str(vorud_chunk(b1 + (b0 << 8)).as_slice());
        }
        Vorud(ret)
    }
}

impl FromVorud<()> for Vec<u8> {
    fn from_vorud(&Vorud(ref s): &Vorud) -> Result<Vec<u8>, ()> {
        let mut ret = Vec::new();
        for chunk in s.as_slice().split('-') {
            let x = try!(durov_chunk(chunk));
            ret.push((x / 0xff) as u8);
            ret.push((x % 0xff) as u8);
        }
        Ok(ret)
    }
}

impl ToVorud for u32 {
    fn to_vorud(&self) -> Vorud {
        let mut vec = Vec::new();
        vec.push(((*self >> 24) % 0xff) as u8);
        vec.push(((*self >> 16) % 0xff) as u8);
        vec.push(((*self >> 8) % 0xff) as u8);
        vec.push((*self % 0xff) as u8);
        vec.as_slice().to_vorud()
    }
}

impl FromVorud<()> for u32 {
    fn from_vorud(v: &Vorud) -> Result<u32, ()> {
        let v: Vec<u8> = try!(FromVorud::from_vorud(v));
        if v.len() != 4 { return Err(()); }
        Ok(v[3] as u32 +
            ((v[2] as u32) << 8) +
            ((v[1] as u32) << 16) +
            ((v[0] as u32) << 24))
    }
}

#[cfg(test)]
mod test {
    #[test]
    fn test_vorud() {
        use super::ToVorud;

        assert_eq!("babab", super::vorud_chunk(0).as_slice());
        assert_eq!("babad", super::vorud_chunk(1).as_slice());
        assert_eq!(Ok(0u16), super::durov_chunk("babab"));
        assert_eq!(Ok(1234u16), super::durov_chunk(super::vorud_chunk(1234).as_slice()));
        assert_eq!("togas", super::vorud_chunk(super::durov_chunk("togas").unwrap()).as_slice());
        assert_eq!(super::Vorud("babab-babab".to_string()), 0u32.to_vorud());
        assert_eq!(super::Vorud("babab-babad".to_string()), 1u32.to_vorud());
        assert_eq!(Ok(1u32), super::FromVorud::from_vorud(&super::Vorud("babab-babad".to_string())));
    }
}
<commit_msg>Update to latest Rust<commit_after>use self::Decode::{V, C};

static VS: [char, ..5] = ['a', 'e', 'i', 'o', 'u'];
static CS: [char, ..14] = ['b', 'd', 'f', 'g', 'j', 'k', 'm', 'n',
    'p', 'r', 's', 't', 'v', 'z'];

enum Decode {
    V(u16),
    C(u16),
}

static LUT: [Option<Decode>, ..26] = [
    Some(V(0)),  // a (ASCII 97)
    Some(C(0)),  // b
    None,        // c
    Some(C(1)),  // d
    Some(V(1)),  // e
    Some(C(2)),  // f
    Some(C(3)),  // g
    None,        // h
    Some(V(2)),  // i
    Some(C(4)),  // j
    Some(C(5)),  // k
    None,        // l
    Some(C(6)),  // m
    Some(C(7)),  // n
    Some(V(3)),  // o
    Some(C(8)),  // p
    None,        // q
    Some(C(9)),  // r
    Some(C(10)), // s
    Some(C(11)), // t
    Some(V(4)),  // u
    Some(C(12)), // v
    None,        // w
    None,        // x
    None,        // y
    Some(C(13)), // z
];

fn vorud_chunk(data: u16) -> String {
    let (data, c5) = (data / CS.len() as u16, data % CS.len() as u16);
    let (data, v4) = (data / VS.len() as u16, data % VS.len() as u16);
    let (data, c3) = (data / CS.len() as u16, data % CS.len() as u16);
    let (data, v2) = (data / VS.len() as u16, data % VS.len() as u16);
    let (_, c1) =    (data / CS.len() as u16, data % CS.len() as u16);
    [CS[c1 as uint],
     VS[v2 as uint],
     CS[c3 as uint],
     VS[v4 as uint],
     CS[c5 as uint],
    ].iter().map(|&x| x).collect()
}

fn decode(c: char) -> Option<Decode> {
    let idx = c as int - 97;
    if idx < 0 || idx >= LUT.len() as int { return None; }
    LUT[idx as uint]
}

fn v(c: char) -> Result<u16, ()> {
    match decode(c) {
        Some(V(i)) => Ok(i),
        _ => Err(())
    }
}

fn c(c: char) -> Result<u16, ()> {
    match decode(c) {
        Some(C(i)) => Ok(i),
        _ => Err(())
    }
}

fn durov_chunk(s: &str) -> Result<u16, ()> {
    if s.len() != 5 { return Err(()); }
    let s: Vec<char> = s.chars().collect();
    let (mut ret, mut n) = (0u16, 1u16);
    ret += try!(c(s[4])) * n; n *= CS.len() as u16;
    ret += try!(v(s[3])) * n; n *= VS.len() as u16;
    ret += try!(c(s[2])) * n; n *= CS.len() as u16;
    ret += try!(v(s[1])) * n; n *= VS.len() as u16;
    ret += try!(c(s[0])) * n;

    Ok(ret)
}

#[deriving(PartialEq, Eq, Show)]
pub struct Vorud(String);

impl Vorud {
    pub fn new(s: String) -> Result<Vorud, ()> {
        if s.len() == 0 { return Ok(Vorud("".to_string())); }
        let ch = s.as_slice().chars().collect::<Vec<char>>();
        let mut i = 0;
        loop {
            if i > ch.len() - 5 { return Err(()); }
            try!(c(ch[i]));
            try!(v(ch[i + 1]));
            try!(c(ch[i + 2]));
            try!(v(ch[i + 3]));
            try!(c(ch[i + 4]));
            if i == ch.len() - 5 { return Ok(Vorud(s)); }
            if ch[i + 5] != '-' { return Err(()); }
            i += 6;
        }
    }
}

pub trait FromVorud<E> {
    fn from_vorud(v: &Vorud) -> Result<Self, E>;
}

pub trait ToVorud {
    fn to_vorud(&self) -> Vorud;
}

impl<'a> ToVorud for &'a [u8] {
    fn to_vorud(&self) -> Vorud {
        let mut ret = String::new();
        for i in range(0, self.len() / 2) {
            if ret.len() > 0 { ret.push_str("-"); }
            let b0 = self[i * 2] as u16;
            let b1 = if self.len() == i * 2 + 1 { 0 } else { self[i * 2 + 1] as u16 };
            ret.push_str(vorud_chunk(b1 + (b0 << 8)).as_slice());
        }
        Vorud(ret)
    }
}

impl FromVorud<()> for Vec<u8> {
    fn from_vorud(&Vorud(ref s): &Vorud) -> Result<Vec<u8>, ()> {
        let mut ret = Vec::new();
        for chunk in s.as_slice().split('-') {
            let x = try!(durov_chunk(chunk));
            ret.push((x / 0xff) as u8);
            ret.push((x % 0xff) as u8);
        }
        Ok(ret)
    }
}

impl ToVorud for u32 {
    fn to_vorud(&self) -> Vorud {
        let mut vec = Vec::new();
        vec.push(((*self >> 24) % 0xff) as u8);
        vec.push(((*self >> 16) % 0xff) as u8);
        vec.push(((*self >> 8) % 0xff) as u8);
        vec.push((*self % 0xff) as u8);
        vec.as_slice().to_vorud()
    }
}

impl FromVorud<()> for u32 {
    fn from_vorud(v: &Vorud) -> Result<u32, ()> {
        let v: Vec<u8> = try!(FromVorud::from_vorud(v));
        if v.len() != 4 { return Err(()); }
        Ok(v[3] as u32 +
            ((v[2] as u32) << 8) +
            ((v[1] as u32) << 16) +
            ((v[0] as u32) << 24))
    }
}

#[cfg(test)]
mod test {
    #[test]
    fn test_vorud() {
        use super::ToVorud;

        assert_eq!("babab", super::vorud_chunk(0).as_slice());
        assert_eq!("babad", super::vorud_chunk(1).as_slice());
        assert_eq!(Ok(0u16), super::durov_chunk("babab"));
        assert_eq!(Ok(1234u16), super::durov_chunk(super::vorud_chunk(1234).as_slice()));
        assert_eq!("togas", super::vorud_chunk(super::durov_chunk("togas").unwrap()).as_slice());
        assert_eq!(super::Vorud("babab-babab".to_string()), 0u32.to_vorud());
        assert_eq!(super::Vorud("babab-babad".to_string()), 1u32.to_vorud());
        assert_eq!(Ok(1u32), super::FromVorud::from_vorud(&super::Vorud("babab-babad".to_string())));
    }
}
<|endoftext|>