<commit_before>use serde::{de, ser};
use std::fmt;

pub(crate) const NAME: &str = "$__toml_private_Spanned";
pub(crate) const START: &str = "$__toml_private_start";
pub(crate) const END: &str = "$__toml_private_end";
pub(crate) const VALUE: &str = "$__toml_private_value";

/// A spanned value, indicating the range at which it is defined in the source.
///
/// ```
/// use serde_derive::Deserialize;
/// use toml::Spanned;
///
/// #[derive(Deserialize)]
/// struct Value {
///     s: Spanned<String>,
/// }
///
/// fn main() {
///     let t = "s = \"value\"\n";
///
///     let u: Value = toml::from_str(t).unwrap();
///
///     assert_eq!(u.s.start(), 4);
///     assert_eq!(u.s.end(), 11);
///     assert_eq!(u.s.get_ref(), "value");
///     assert_eq!(u.s.into_inner(), String::from("value"));
/// }
/// ```
#[derive(Clone, Debug, PartialEq, Eq, Hash)]
pub struct Spanned<T> {
    /// The start range.
    start: usize,
    /// The end range (exclusive).
    end: usize,
    /// The spanned value.
    value: T,
}

impl<T> Spanned<T> {
    /// Access the start of the span of the contained value.
    pub fn start(&self) -> usize {
        self.start
    }

    /// Access the end of the span of the contained value.
    pub fn end(&self) -> usize {
        self.end
    }

    /// Get the span of the contained value.
    pub fn span(&self) -> (usize, usize) {
        (self.start, self.end)
    }

    /// Consumes the spanned value and returns the contained value.
    pub fn into_inner(self) -> T {
        self.value
    }

    /// Returns a reference to the contained value.
    pub fn get_ref(&self) -> &T {
        &self.value
    }

    /// Returns a mutable reference to the contained value.
    pub fn get_mut(&self) -> &T {
        &self.value
    }
}

impl<'de, T> de::Deserialize<'de> for Spanned<T>
where
    T: de::Deserialize<'de>,
{
    fn deserialize<D>(deserializer: D) -> Result<Spanned<T>, D::Error>
    where
        D: de::Deserializer<'de>,
    {
        struct SpannedVisitor<T>(::std::marker::PhantomData<T>);

        impl<'de, T> de::Visitor<'de> for SpannedVisitor<T>
        where
            T: de::Deserialize<'de>,
        {
            type Value = Spanned<T>;

            fn expecting(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result {
                formatter.write_str("a TOML spanned")
            }

            fn visit_map<V>(self, mut visitor: V) -> Result<Spanned<T>, V::Error>
            where
                V: de::MapAccess<'de>,
            {
                if visitor.next_key()? != Some(START) {
                    return Err(de::Error::custom("spanned start key not found"));
                }

                let start: usize = visitor.next_value()?;

                if visitor.next_key()? != Some(END) {
                    return Err(de::Error::custom("spanned end key not found"));
                }

                let end: usize = visitor.next_value()?;

                if visitor.next_key()? != Some(VALUE) {
                    return Err(de::Error::custom("spanned value key not found"));
                }

                let value: T = visitor.next_value()?;

                Ok(Spanned { start, end, value })
            }
        }

        let visitor = SpannedVisitor(::std::marker::PhantomData);

        static FIELDS: [&str; 3] = [START, END, VALUE];
        deserializer.deserialize_struct(NAME, &FIELDS, visitor)
    }
}

impl<T: ser::Serialize> ser::Serialize for Spanned<T> {
    fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
    where
        S: ser::Serializer,
    {
        self.value.serialize(serializer)
    }
}
<commit_msg>get_mut should return a mutable reference (#338)<commit_after>use serde::{de, ser};
use std::fmt;

pub(crate) const NAME: &str = "$__toml_private_Spanned";
pub(crate) const START: &str = "$__toml_private_start";
pub(crate) const END: &str = "$__toml_private_end";
pub(crate) const VALUE: &str = "$__toml_private_value";

/// A spanned value, indicating the range at which it is defined in the source.
///
/// ```
/// use serde_derive::Deserialize;
/// use toml::Spanned;
///
/// #[derive(Deserialize)]
/// struct Value {
///     s: Spanned<String>,
/// }
///
/// fn main() {
///     let t = "s = \"value\"\n";
///
///     let u: Value = toml::from_str(t).unwrap();
///
///     assert_eq!(u.s.start(), 4);
///     assert_eq!(u.s.end(), 11);
///     assert_eq!(u.s.get_ref(), "value");
///     assert_eq!(u.s.into_inner(), String::from("value"));
/// }
/// ```
#[derive(Clone, Debug, PartialEq, Eq, Hash)]
pub struct Spanned<T> {
    /// The start range.
    start: usize,
    /// The end range (exclusive).
    end: usize,
    /// The spanned value.
    value: T,
}

impl<T> Spanned<T> {
    /// Access the start of the span of the contained value.
    pub fn start(&self) -> usize {
        self.start
    }

    /// Access the end of the span of the contained value.
    pub fn end(&self) -> usize {
        self.end
    }

    /// Get the span of the contained value.
    pub fn span(&self) -> (usize, usize) {
        (self.start, self.end)
    }

    /// Consumes the spanned value and returns the contained value.
    pub fn into_inner(self) -> T {
        self.value
    }

    /// Returns a reference to the contained value.
    pub fn get_ref(&self) -> &T {
        &self.value
    }

    /// Returns a mutable reference to the contained value.
    pub fn get_mut(&mut self) -> &mut T {
        &mut self.value
    }
}

impl<'de, T> de::Deserialize<'de> for Spanned<T>
where
    T: de::Deserialize<'de>,
{
    fn deserialize<D>(deserializer: D) -> Result<Spanned<T>, D::Error>
    where
        D: de::Deserializer<'de>,
    {
        struct SpannedVisitor<T>(::std::marker::PhantomData<T>);

        impl<'de, T> de::Visitor<'de> for SpannedVisitor<T>
        where
            T: de::Deserialize<'de>,
        {
            type Value = Spanned<T>;

            fn expecting(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result {
                formatter.write_str("a TOML spanned")
            }

            fn visit_map<V>(self, mut visitor: V) -> Result<Spanned<T>, V::Error>
            where
                V: de::MapAccess<'de>,
            {
                if visitor.next_key()? != Some(START) {
                    return Err(de::Error::custom("spanned start key not found"));
                }

                let start: usize = visitor.next_value()?;

                if visitor.next_key()? != Some(END) {
                    return Err(de::Error::custom("spanned end key not found"));
                }

                let end: usize = visitor.next_value()?;

                if visitor.next_key()? != Some(VALUE) {
                    return Err(de::Error::custom("spanned value key not found"));
                }

                let value: T = visitor.next_value()?;

                Ok(Spanned { start, end, value })
            }
        }

        let visitor = SpannedVisitor(::std::marker::PhantomData);

        static FIELDS: [&str; 3] = [START, END, VALUE];
        deserializer.deserialize_struct(NAME, &FIELDS, visitor)
    }
}

impl<T: ser::Serialize> ser::Serialize for Spanned<T> {
    fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
    where
        S: ser::Serializer,
    {
        self.value.serialize(serializer)
    }
}
<|endoftext|>


<commit_before>use ndarray::*;
use ndarray_linalg::*;

#[test]
fn solve_random() {
    let a: Array2<f64> = random((3, 3));
    let x: Array1<f64> = random(3);
    let b = a.dot(&x);
    let y = a.solve_into(b).unwrap();
    assert_close_l2!(&x, &y, 1e-7);
}

#[test]
fn solve_random_t() {
    let a: Array2<f64> = random((3, 3).f());
    let x: Array1<f64> = random(3);
    let b = a.dot(&x);
    let y = a.solve_into(b).unwrap();
    assert_close_l2!(&x, &y, 1e-7);
}

#[test]
fn rcond() {
    macro_rules! rcond {
        ($elem:ty, $rows:expr, $atol:expr) => {
            let a: Array2<$elem> = random(($rows, $rows));
            let rcond = 1. / (a.opnorm_one().unwrap() * a.inv().unwrap().opnorm_one().unwrap());
            assert_aclose!(a.rcond().unwrap(), rcond, $atol);
            assert_aclose!(a.rcond_into().unwrap(), rcond, $atol);
        };
    }
    for rows in 1..6 {
        rcond!(f64, rows, 0.2);
        rcond!(f32, rows, 0.5);
        rcond!(c64, rows, 0.2);
        rcond!(c32, rows, 0.5);
    }
}

#[test]
fn rcond_hilbert() {
    macro_rules! rcond_hilbert {
        ($elem:ty, $rows:expr, $atol:expr) => {
            let a = Array2::<$elem>::from_shape_fn(($rows, $rows), |(i, j)| 1. / (i as $elem + j as $elem - 1.));
            assert_aclose!(a.rcond().unwrap(), 0., $atol);
            assert_aclose!(a.rcond_into().unwrap(), 0., $atol);
        };
    }
    rcond_hilbert!(f64, 10, 1e-9);
    rcond_hilbert!(f32, 10, 1e-3);
}

#[test]
fn rcond_identity() {
    macro_rules! rcond_identity {
        ($elem:ty, $rows:expr, $atol:expr) => {
            let a = Array2::<$elem>::eye($rows);
            assert_aclose!(a.rcond().unwrap(), 1., $atol);
            assert_aclose!(a.rcond_into().unwrap(), 1., $atol);
        };
    }
    for rows in 1..6 {
        rcond_identity!(f64, rows, 1e-9);
        rcond_identity!(f32, rows, 1e-3);
        rcond_identity!(c64, rows, 1e-9);
        rcond_identity!(c32, rows, 1e-3);
    }
}
<commit_msg>Use rand_hpd for rcond test<commit_after>use ndarray::*;
use ndarray_linalg::*;

#[test]
fn solve_random() {
    let a: Array2<f64> = random((3, 3));
    let x: Array1<f64> = random(3);
    let b = a.dot(&x);
    let y = a.solve_into(b).unwrap();
    assert_close_l2!(&x, &y, 1e-7);
}

#[test]
fn solve_random_t() {
    let a: Array2<f64> = random((3, 3).f());
    let x: Array1<f64> = random(3);
    let b = a.dot(&x);
    let y = a.solve_into(b).unwrap();
    assert_close_l2!(&x, &y, 1e-7);
}

#[test]
fn rcond() {
    macro_rules! rcond {
        ($elem:ty, $rows:expr, $atol:expr) => {
            let a: Array2<$elem> = random_hpd($rows);
            let rcond = 1. / (a.opnorm_one().unwrap() * a.inv().unwrap().opnorm_one().unwrap());
            assert_aclose!(a.rcond().unwrap(), rcond, $atol);
            assert_aclose!(a.rcond_into().unwrap(), rcond, $atol);
        };
    }
    for rows in 1..6 {
        rcond!(f64, rows, 0.2);
        rcond!(f32, rows, 0.5);
        rcond!(c64, rows, 0.2);
        rcond!(c32, rows, 0.5);
    }
}

#[test]
fn rcond_hilbert() {
    macro_rules! rcond_hilbert {
        ($elem:ty, $rows:expr, $atol:expr) => {
            let a = Array2::<$elem>::from_shape_fn(($rows, $rows), |(i, j)| 1. / (i as $elem + j as $elem - 1.));
            assert_aclose!(a.rcond().unwrap(), 0., $atol);
            assert_aclose!(a.rcond_into().unwrap(), 0., $atol);
        };
    }
    rcond_hilbert!(f64, 10, 1e-9);
    rcond_hilbert!(f32, 10, 1e-3);
}

#[test]
fn rcond_identity() {
    macro_rules! rcond_identity {
        ($elem:ty, $rows:expr, $atol:expr) => {
            let a = Array2::<$elem>::eye($rows);
            assert_aclose!(a.rcond().unwrap(), 1., $atol);
            assert_aclose!(a.rcond_into().unwrap(), 1., $atol);
        };
    }
    for rows in 1..6 {
        rcond_identity!(f64, rows, 1e-9);
        rcond_identity!(f32, rows, 1e-3);
        rcond_identity!(c64, rows, 1e-9);
        rcond_identity!(c32, rows, 1e-3);
    }
}
<|endoftext|>


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

//! The `bitflags!` macro generates a `struct` that holds a set of C-style
//! bitmask flags. It is useful for creating typesafe wrappers for C APIs.
//!
//! The flags should only be defined for integer types, otherwise unexpected
//! type errors may occur at compile time.
//!
//! # Example
//!
//! ~~~rust
//! bitflags!(
//!     flags Flags: u32 {
//!         static FlagA       = 0x00000001,
//!         static FlagB       = 0x00000010,
//!         static FlagC       = 0x00000100,
//!         static FlagABC     = FlagA.bits
//!                            | FlagB.bits
//!                            | FlagC.bits
//!     }
//! )
//!
//! fn main() {
//!     let e1 = FlagA | FlagC;
//!     let e2 = FlagB | FlagC;
//!     assert!((e1 | e2) == FlagABC);   // union
//!     assert!((e1 & e2) == FlagC);     // intersection
//!     assert!((e1 - e2) == FlagA);     // set difference
//!     assert!(!e2 == FlagA);           // set complement
//! }
//! ~~~
//!
//! The generated `struct`s can also be extended with type and trait implementations:
//!
//! ~~~rust
//! use std::fmt;
//!
//! bitflags!(
//!     flags Flags: u32 {
//!         static FlagA   = 0x00000001,
//!         static FlagB   = 0x00000010
//!     }
//! )
//!
//! impl Flags {
//!     pub fn clear(&mut self) {
//!         self.bits = 0;  // The `bits` field can be accessed from within the
//!                         // same module where the `bitflags!` macro was invoked.
//!     }
//! }
//!
//! impl fmt::Show for Flags {
//!     fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
//!         write!(f, "hi!")
//!     }
//! }
//!
//! fn main() {
//!     let mut flags = FlagA | FlagB;
//!     flags.clear();
//!     assert!(flags.is_empty());
//!     assert_eq!(format!("{}", flags).as_slice(), "hi!");
//! }
//! ~~~
//!
//! # Attributes
//!
//! Attributes can be attached to the generated `struct` by placing them
//! before the `flags` keyword.
//!
//! # Derived traits
//!
//! The `PartialEq` and `Clone` traits are automatically derived for the `struct` using
//! the `deriving` attribute. Additional traits can be derived by providing an
//! explicit `deriving` attribute on `flags`.
//!
//! # Operators
//!
//! The following operator traits are implemented for the generated `struct`:
//!
//! - `BitOr`: union
//! - `BitAnd`: intersection
//! - `Sub`: set difference
//! - `Not`: set complement
//!
//! # Methods
//!
//! The following methods are defined for the generated `struct`:
//!
//! - `empty`: an empty set of flags
//! - `all`: the set of all flags
//! - `bits`: the raw value of the flags currently stored
//! - `is_empty`: `true` if no flags are currently stored
//! - `is_all`: `true` if all flags are currently set
//! - `intersects`: `true` if there are flags common to both `self` and `other`
//! - `contains`: `true` all of the flags in `other` are contained within `self`
//! - `insert`: inserts the specified flags in-place
//! - `remove`: removes the specified flags in-place

#![experimental]
#![macro_escape]

#[macro_export]
macro_rules! bitflags(
    ($(#[$attr:meta])* flags $BitFlags:ident: $T:ty {
        $($(#[$Flag_attr:meta])* static $Flag:ident = $value:expr),+
    }) => (
        #[deriving(PartialEq, Eq, Clone, PartialOrd, Ord, Hash)]
        $(#[$attr])*
        pub struct $BitFlags {
            bits: $T,
        }

        $($(#[$Flag_attr])* pub static $Flag: $BitFlags = $BitFlags { bits: $value };)+

        impl $BitFlags {
            /// Returns an empty set of flags.
            pub fn empty() -> $BitFlags {
                $BitFlags { bits: 0 }
            }

            /// Returns the set containing all flags.
            pub fn all() -> $BitFlags {
                $BitFlags { bits: $($value)|+ }
            }

            /// Returns the raw value of the flags currently stored.
            pub fn bits(&self) -> $T {
                self.bits
            }

            /// Convert from underlying bit representation, unless that
            /// representation contains bits that do not correspond to a flag.
            pub fn from_bits(bits: $T) -> ::std::option::Option<$BitFlags> {
                if (bits & !$BitFlags::all().bits()) != 0 {
                    ::std::option::None
                } else {
                    ::std::option::Some($BitFlags { bits: bits })
                }
            }

            /// Convert from underlying bit representation, dropping any bits
            /// that do not correspond to flags.
            pub fn from_bits_truncate(bits: $T) -> $BitFlags {
                $BitFlags { bits: bits } & $BitFlags::all()
            }

            /// Returns `true` if no flags are currently stored.
            pub fn is_empty(&self) -> bool {
                *self == $BitFlags::empty()
            }

            /// Returns `true` if all flags are currently set.
            pub fn is_all(&self) -> bool {
                *self == $BitFlags::all()
            }

            /// Returns `true` if there are flags common to both `self` and `other`.
            pub fn intersects(&self, other: $BitFlags) -> bool {
                !(self & other).is_empty()
            }

            /// Returns `true` all of the flags in `other` are contained within `self`.
            pub fn contains(&self, other: $BitFlags) -> bool {
                (self & other) == other
            }

            /// Inserts the specified flags in-place.
            pub fn insert(&mut self, other: $BitFlags) {
                self.bits |= other.bits;
            }

            /// Removes the specified flags in-place.
            pub fn remove(&mut self, other: $BitFlags) {
                self.bits &= !other.bits;
            }
        }

        impl BitOr<$BitFlags, $BitFlags> for $BitFlags {
            /// Returns the union of the two sets of flags.
            #[inline]
            fn bitor(&self, other: &$BitFlags) -> $BitFlags {
                $BitFlags { bits: self.bits | other.bits }
            }
        }

        impl BitAnd<$BitFlags, $BitFlags> for $BitFlags {
            /// Returns the intersection between the two sets of flags.
            #[inline]
            fn bitand(&self, other: &$BitFlags) -> $BitFlags {
                $BitFlags { bits: self.bits & other.bits }
            }
        }

        impl Sub<$BitFlags, $BitFlags> for $BitFlags {
            /// Returns the set difference of the two sets of flags.
            #[inline]
            fn sub(&self, other: &$BitFlags) -> $BitFlags {
                $BitFlags { bits: self.bits & !other.bits }
            }
        }

        impl Not<$BitFlags> for $BitFlags {
            /// Returns the complement of this set of flags.
            #[inline]
            fn not(&self) -> $BitFlags {
                $BitFlags { bits: !self.bits } & $BitFlags::all()
            }
        }
    )
)

#[cfg(test)]
mod tests {
    use hash;
    use option::{Some, None};
    use ops::{BitOr, BitAnd, Sub, Not};

    bitflags!(
        flags Flags: u32 {
            static FlagA       = 0x00000001,
            static FlagB       = 0x00000010,
            static FlagC       = 0x00000100,
            static FlagABC     = FlagA.bits
                               | FlagB.bits
                               | FlagC.bits
        }
    )

    #[test]
    fn test_bits(){
        assert_eq!(Flags::empty().bits(), 0x00000000);
        assert_eq!(FlagA.bits(), 0x00000001);
        assert_eq!(FlagABC.bits(), 0x00000111);
    }

    #[test]
    fn test_from_bits() {
        assert!(Flags::from_bits(0) == Some(Flags::empty()));
        assert!(Flags::from_bits(0x1) == Some(FlagA));
        assert!(Flags::from_bits(0x10) == Some(FlagB));
        assert!(Flags::from_bits(0x11) == Some(FlagA | FlagB));
        assert!(Flags::from_bits(0x1000) == None);
    }

    #[test]
    fn test_from_bits_truncate() {
        assert!(Flags::from_bits_truncate(0) == Flags::empty());
        assert!(Flags::from_bits_truncate(0x1) == FlagA);
        assert!(Flags::from_bits_truncate(0x10) == FlagB);
        assert!(Flags::from_bits_truncate(0x11) == (FlagA | FlagB));
        assert!(Flags::from_bits_truncate(0x1000) == Flags::empty());
        assert!(Flags::from_bits_truncate(0x1001) == FlagA);
    }

    #[test]
    fn test_is_empty(){
        assert!(Flags::empty().is_empty());
        assert!(!FlagA.is_empty());
        assert!(!FlagABC.is_empty());
    }

    #[test]
    fn test_is_all() {
        assert!(Flags::all().is_all());
        assert!(!FlagA.is_all());
        assert!(FlagABC.is_all());
    }

    #[test]
    fn test_two_empties_do_not_intersect() {
        let e1 = Flags::empty();
        let e2 = Flags::empty();
        assert!(!e1.intersects(e2));
    }

    #[test]
    fn test_empty_does_not_intersect_with_full() {
        let e1 = Flags::empty();
        let e2 = FlagABC;
        assert!(!e1.intersects(e2));
    }

    #[test]
    fn test_disjoint_intersects() {
        let e1 = FlagA;
        let e2 = FlagB;
        assert!(!e1.intersects(e2));
    }

    #[test]
    fn test_overlapping_intersects() {
        let e1 = FlagA;
        let e2 = FlagA | FlagB;
        assert!(e1.intersects(e2));
    }

    #[test]
    fn test_contains() {
        let e1 = FlagA;
        let e2 = FlagA | FlagB;
        assert!(!e1.contains(e2));
        assert!(e2.contains(e1));
        assert!(FlagABC.contains(e2));
    }

    #[test]
    fn test_insert(){
        let mut e1 = FlagA;
        let e2 = FlagA | FlagB;
        e1.insert(e2);
        assert!(e1 == e2);
    }

    #[test]
    fn test_remove(){
        let mut e1 = FlagA | FlagB;
        let e2 = FlagA | FlagC;
        e1.remove(e2);
        assert!(e1 == FlagB);
    }

    #[test]
    fn test_operators() {
        let e1 = FlagA | FlagC;
        let e2 = FlagB | FlagC;
        assert!((e1 | e2) == FlagABC);   // union
        assert!((e1 & e2) == FlagC);     // intersection
        assert!((e1 - e2) == FlagA);     // set difference
        assert!(!e2 == FlagA);           // set complement
    }

    #[test]
    fn test_lt() {
        let mut a = Flags::empty();
        let mut b = Flags::empty();

        assert!(!(a < b) && !(b < a));
        b = FlagB;
        assert!(a < b);
        a = FlagC;
        assert!(!(a < b) && b < a);
        b = FlagC | FlagB;
        assert!(a < b);
    }

    #[test]
    fn test_ord() {
        let mut a = Flags::empty();
        let mut b = Flags::empty();

        assert!(a <= b && a >= b);
        a = FlagA;
        assert!(a > b && a >= b);
        assert!(b < a && b <= a);
        b = FlagB;
        assert!(b > a && b >= a);
        assert!(a < b && a <= b);
    }

    #[test]
    fn test_hash() {
      let mut x = Flags::empty();
      let mut y = Flags::empty();
      assert!(hash::hash(&x) == hash::hash(&y));
      x = Flags::all();
      y = FlagABC;
      assert!(hash::hash(&x) == hash::hash(&y));
    }
}
<commit_msg>Allow trailing commas in bitflags! macro<commit_after>// Copyright 2014 The Rust Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution and at
// http://rust-lang.org/COPYRIGHT.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.

//! The `bitflags!` macro generates a `struct` that holds a set of C-style
//! bitmask flags. It is useful for creating typesafe wrappers for C APIs.
//!
//! The flags should only be defined for integer types, otherwise unexpected
//! type errors may occur at compile time.
//!
//! # Example
//!
//! ~~~rust
//! bitflags!(
//!     flags Flags: u32 {
//!         static FlagA       = 0x00000001,
//!         static FlagB       = 0x00000010,
//!         static FlagC       = 0x00000100,
//!         static FlagABC     = FlagA.bits
//!                            | FlagB.bits
//!                            | FlagC.bits,
//!     }
//! )
//!
//! fn main() {
//!     let e1 = FlagA | FlagC;
//!     let e2 = FlagB | FlagC;
//!     assert!((e1 | e2) == FlagABC);   // union
//!     assert!((e1 & e2) == FlagC);     // intersection
//!     assert!((e1 - e2) == FlagA);     // set difference
//!     assert!(!e2 == FlagA);           // set complement
//! }
//! ~~~
//!
//! The generated `struct`s can also be extended with type and trait implementations:
//!
//! ~~~rust
//! use std::fmt;
//!
//! bitflags!(
//!     flags Flags: u32 {
//!         static FlagA   = 0x00000001,
//!         static FlagB   = 0x00000010,
//!     }
//! )
//!
//! impl Flags {
//!     pub fn clear(&mut self) {
//!         self.bits = 0;  // The `bits` field can be accessed from within the
//!                         // same module where the `bitflags!` macro was invoked.
//!     }
//! }
//!
//! impl fmt::Show for Flags {
//!     fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
//!         write!(f, "hi!")
//!     }
//! }
//!
//! fn main() {
//!     let mut flags = FlagA | FlagB;
//!     flags.clear();
//!     assert!(flags.is_empty());
//!     assert_eq!(format!("{}", flags).as_slice(), "hi!");
//! }
//! ~~~
//!
//! # Attributes
//!
//! Attributes can be attached to the generated `struct` by placing them
//! before the `flags` keyword.
//!
//! # Derived traits
//!
//! The `PartialEq` and `Clone` traits are automatically derived for the `struct` using
//! the `deriving` attribute. Additional traits can be derived by providing an
//! explicit `deriving` attribute on `flags`.
//!
//! # Operators
//!
//! The following operator traits are implemented for the generated `struct`:
//!
//! - `BitOr`: union
//! - `BitAnd`: intersection
//! - `Sub`: set difference
//! - `Not`: set complement
//!
//! # Methods
//!
//! The following methods are defined for the generated `struct`:
//!
//! - `empty`: an empty set of flags
//! - `all`: the set of all flags
//! - `bits`: the raw value of the flags currently stored
//! - `is_empty`: `true` if no flags are currently stored
//! - `is_all`: `true` if all flags are currently set
//! - `intersects`: `true` if there are flags common to both `self` and `other`
//! - `contains`: `true` all of the flags in `other` are contained within `self`
//! - `insert`: inserts the specified flags in-place
//! - `remove`: removes the specified flags in-place

#![experimental]
#![macro_escape]

#[macro_export]
macro_rules! bitflags(
    ($(#[$attr:meta])* flags $BitFlags:ident: $T:ty {
        $($(#[$Flag_attr:meta])* static $Flag:ident = $value:expr),+
    }) => (
        #[deriving(PartialEq, Eq, Clone, PartialOrd, Ord, Hash)]
        $(#[$attr])*
        pub struct $BitFlags {
            bits: $T,
        }

        $($(#[$Flag_attr])* pub static $Flag: $BitFlags = $BitFlags { bits: $value };)+

        impl $BitFlags {
            /// Returns an empty set of flags.
            pub fn empty() -> $BitFlags {
                $BitFlags { bits: 0 }
            }

            /// Returns the set containing all flags.
            pub fn all() -> $BitFlags {
                $BitFlags { bits: $($value)|+ }
            }

            /// Returns the raw value of the flags currently stored.
            pub fn bits(&self) -> $T {
                self.bits
            }

            /// Convert from underlying bit representation, unless that
            /// representation contains bits that do not correspond to a flag.
            pub fn from_bits(bits: $T) -> ::std::option::Option<$BitFlags> {
                if (bits & !$BitFlags::all().bits()) != 0 {
                    ::std::option::None
                } else {
                    ::std::option::Some($BitFlags { bits: bits })
                }
            }

            /// Convert from underlying bit representation, dropping any bits
            /// that do not correspond to flags.
            pub fn from_bits_truncate(bits: $T) -> $BitFlags {
                $BitFlags { bits: bits } & $BitFlags::all()
            }

            /// Returns `true` if no flags are currently stored.
            pub fn is_empty(&self) -> bool {
                *self == $BitFlags::empty()
            }

            /// Returns `true` if all flags are currently set.
            pub fn is_all(&self) -> bool {
                *self == $BitFlags::all()
            }

            /// Returns `true` if there are flags common to both `self` and `other`.
            pub fn intersects(&self, other: $BitFlags) -> bool {
                !(self & other).is_empty()
            }

            /// Returns `true` all of the flags in `other` are contained within `self`.
            pub fn contains(&self, other: $BitFlags) -> bool {
                (self & other) == other
            }

            /// Inserts the specified flags in-place.
            pub fn insert(&mut self, other: $BitFlags) {
                self.bits |= other.bits;
            }

            /// Removes the specified flags in-place.
            pub fn remove(&mut self, other: $BitFlags) {
                self.bits &= !other.bits;
            }
        }

        impl BitOr<$BitFlags, $BitFlags> for $BitFlags {
            /// Returns the union of the two sets of flags.
            #[inline]
            fn bitor(&self, other: &$BitFlags) -> $BitFlags {
                $BitFlags { bits: self.bits | other.bits }
            }
        }

        impl BitAnd<$BitFlags, $BitFlags> for $BitFlags {
            /// Returns the intersection between the two sets of flags.
            #[inline]
            fn bitand(&self, other: &$BitFlags) -> $BitFlags {
                $BitFlags { bits: self.bits & other.bits }
            }
        }

        impl Sub<$BitFlags, $BitFlags> for $BitFlags {
            /// Returns the set difference of the two sets of flags.
            #[inline]
            fn sub(&self, other: &$BitFlags) -> $BitFlags {
                $BitFlags { bits: self.bits & !other.bits }
            }
        }

        impl Not<$BitFlags> for $BitFlags {
            /// Returns the complement of this set of flags.
            #[inline]
            fn not(&self) -> $BitFlags {
                $BitFlags { bits: !self.bits } & $BitFlags::all()
            }
        }
    );
    ($(#[$attr:meta])* flags $BitFlags:ident: $T:ty {
        $($(#[$Flag_attr:meta])* static $Flag:ident = $value:expr),+,
    }) => (
        bitflags!(
            $(#[$attr])*
            flags $BitFlags: u32 {
                $($(#[$Flag_attr])* static $Flag = $value),+
            }
        )
    );
)

#[cfg(test)]
mod tests {
    use hash;
    use option::{Some, None};
    use ops::{BitOr, BitAnd, Sub, Not};

    bitflags!(
        flags Flags: u32 {
            static FlagA       = 0x00000001,
            static FlagB       = 0x00000010,
            static FlagC       = 0x00000100,
            static FlagABC     = FlagA.bits
                               | FlagB.bits
                               | FlagC.bits,
        }
    )

    #[test]
    fn test_bits(){
        assert_eq!(Flags::empty().bits(), 0x00000000);
        assert_eq!(FlagA.bits(), 0x00000001);
        assert_eq!(FlagABC.bits(), 0x00000111);
    }

    #[test]
    fn test_from_bits() {
        assert!(Flags::from_bits(0) == Some(Flags::empty()));
        assert!(Flags::from_bits(0x1) == Some(FlagA));
        assert!(Flags::from_bits(0x10) == Some(FlagB));
        assert!(Flags::from_bits(0x11) == Some(FlagA | FlagB));
        assert!(Flags::from_bits(0x1000) == None);
    }

    #[test]
    fn test_from_bits_truncate() {
        assert!(Flags::from_bits_truncate(0) == Flags::empty());
        assert!(Flags::from_bits_truncate(0x1) == FlagA);
        assert!(Flags::from_bits_truncate(0x10) == FlagB);
        assert!(Flags::from_bits_truncate(0x11) == (FlagA | FlagB));
        assert!(Flags::from_bits_truncate(0x1000) == Flags::empty());
        assert!(Flags::from_bits_truncate(0x1001) == FlagA);
    }

    #[test]
    fn test_is_empty(){
        assert!(Flags::empty().is_empty());
        assert!(!FlagA.is_empty());
        assert!(!FlagABC.is_empty());
    }

    #[test]
    fn test_is_all() {
        assert!(Flags::all().is_all());
        assert!(!FlagA.is_all());
        assert!(FlagABC.is_all());
    }

    #[test]
    fn test_two_empties_do_not_intersect() {
        let e1 = Flags::empty();
        let e2 = Flags::empty();
        assert!(!e1.intersects(e2));
    }

    #[test]
    fn test_empty_does_not_intersect_with_full() {
        let e1 = Flags::empty();
        let e2 = FlagABC;
        assert!(!e1.intersects(e2));
    }

    #[test]
    fn test_disjoint_intersects() {
        let e1 = FlagA;
        let e2 = FlagB;
        assert!(!e1.intersects(e2));
    }

    #[test]
    fn test_overlapping_intersects() {
        let e1 = FlagA;
        let e2 = FlagA | FlagB;
        assert!(e1.intersects(e2));
    }

    #[test]
    fn test_contains() {
        let e1 = FlagA;
        let e2 = FlagA | FlagB;
        assert!(!e1.contains(e2));
        assert!(e2.contains(e1));
        assert!(FlagABC.contains(e2));
    }

    #[test]
    fn test_insert(){
        let mut e1 = FlagA;
        let e2 = FlagA | FlagB;
        e1.insert(e2);
        assert!(e1 == e2);
    }

    #[test]
    fn test_remove(){
        let mut e1 = FlagA | FlagB;
        let e2 = FlagA | FlagC;
        e1.remove(e2);
        assert!(e1 == FlagB);
    }

    #[test]
    fn test_operators() {
        let e1 = FlagA | FlagC;
        let e2 = FlagB | FlagC;
        assert!((e1 | e2) == FlagABC);   // union
        assert!((e1 & e2) == FlagC);     // intersection
        assert!((e1 - e2) == FlagA);     // set difference
        assert!(!e2 == FlagA);           // set complement
    }

    #[test]
    fn test_lt() {
        let mut a = Flags::empty();
        let mut b = Flags::empty();

        assert!(!(a < b) && !(b < a));
        b = FlagB;
        assert!(a < b);
        a = FlagC;
        assert!(!(a < b) && b < a);
        b = FlagC | FlagB;
        assert!(a < b);
    }

    #[test]
    fn test_ord() {
        let mut a = Flags::empty();
        let mut b = Flags::empty();

        assert!(a <= b && a >= b);
        a = FlagA;
        assert!(a > b && a >= b);
        assert!(b < a && b <= a);
        b = FlagB;
        assert!(b > a && b >= a);
        assert!(a < b && a <= b);
    }

    #[test]
    fn test_hash() {
      let mut x = Flags::empty();
      let mut y = Flags::empty();
      assert!(hash::hash(&x) == hash::hash(&y));
      x = Flags::all();
      y = FlagABC;
      assert!(hash::hash(&x) == hash::hash(&y));
    }
}
<|endoftext|>


<commit_before>//! Create textures and build texture atlas.

use std::collections::HashMap;
use std::collections::hash_map::Entry::{ Occupied, Vacant };
use std::fmt::{ Debug, Formatter, Error };
use std::path::{ Path, PathBuf };
use std::mem;

use gfx;
use image::{
    self,
    ImageBuffer,
    RgbaImage,
    DynamicImage,
    ImageResult,
    SubImage,
    ImageError,
    GenericImage,
    Pixel
};

pub use gfx_texture::{ Texture, ImageSize, Settings };

// Loads RGBA image from path.
fn load_rgba8(path: &Path) -> ImageResult<RgbaImage> {
    image::open(path).map(|img| match img {
        DynamicImage::ImageRgba8(img) => img,
        img => img.to_rgba()
    })
}

/// An enumeration of ColorMap errors.
pub enum ColorMapError {
    /// The image opening error.
    Img(ImageError),

    /// The image size error.
    Size(u32, u32, String)
}

impl Debug for ColorMapError {
    fn fmt(&self, f: &mut Formatter) -> Result<(), Error> {
        match *self {
            ColorMapError::Img(ref e) => e.fmt(f),
            ColorMapError::Size(w, h, ref path) =>
                format!("ColorMap expected 256x256, found {}x{} in '{}'", w, h, path).fmt(f)
        }
    }
}

impl From<ImageError> for ColorMapError {
    fn from(img_err: ImageError) -> Self {
        ColorMapError::Img(img_err)
    }
}

/// A 256x256 image that stores colors.
pub struct ColorMap(RgbaImage);

impl ColorMap {
    /// Creates a new `ColorMap` from path.
    pub fn from_path<P>(path: P) -> Result<Self, ColorMapError>
        where P: AsRef<Path>
    {
        let img = try!(load_rgba8(path.as_ref()));

        match img.dimensions() {
            (256, 256) => Ok(ColorMap(img)),
            (w, h) => Err(ColorMapError::Size(w, h, path.as_ref().display().to_string()))
        }
    }

    /// Gets RGB color from the color map.
    pub fn get(&self, x: f32, y: f32) -> [u8; 3] {
        // Clamp to [0.0, 1.0].
        let x = x.max(0.0).min(1.0);
        let y = y.max(0.0).min(1.0);

        // Scale y from [0.0, 1.0] to [0.0, x], forming a triangle.
        let y = x * y;

        // Origin is in the bottom-right corner.
        let x = ((1.0 - x) * 255.0) as u8;
        let y = ((1.0 - y) * 255.0) as u8;

        let col = self.0.get_pixel(x as u32, y as u32).channels();
        [col[0], col[1], col[2]]
    }
}

/// Builds an atlas of textures.
pub struct AtlasBuilder {
    image: RgbaImage,
    // Base path for loading tiles.
    path: PathBuf,
    // Size of an individual tile.
    unit_width: u32,
    unit_height: u32,
    // Size of the entirely occupied square, in tiles.
    completed_tiles_size: u32,
    // Position in the current strip.
    position: u32,
    // Position cache for loaded tiles (in pixels).
    tile_positions: HashMap<String, (u32, u32)>,
    // Lowest-alpha cache for rectangles in the atlas.
    min_alpha_cache: HashMap<(u32, u32, u32, u32), u8>
}

impl AtlasBuilder {
    /// Creates a new `AtlasBuilder`.
    pub fn new<P>(path: P, unit_width: u32, unit_height: u32) -> Self
        where P: Into<PathBuf>
    {
        AtlasBuilder {
            image: ImageBuffer::new(unit_width * 4, unit_height * 4),
            path: path.into(),
            unit_width: unit_width,
            unit_height: unit_height,
            completed_tiles_size: 0,
            position: 0,
            tile_positions: HashMap::new(),
            min_alpha_cache: HashMap::new()
        }
    }

    /// Loads a file into the texture atlas.
    /// Checks if the file is loaded and returns position within the atlas.
    /// The name should be specified without file extension.
    /// PNG is the only supported format.
    pub fn load(&mut self, name: &str) -> (u32, u32) {
        if let Some(&pos) = self.tile_positions.get(name) {
            return pos
        }

        let mut path = self.path.join(name);
        path.set_extension("png");
        let img = load_rgba8(&path).unwrap();

        let (iw, ih) = img.dimensions();
        assert!(iw == self.unit_width);
        assert!((ih % self.unit_height) == 0);
        if ih > self.unit_height {
            println!("ignoring {} extra frames in '{}'", (ih / self.unit_height) - 1, name);
        }

        let (uw, uh) = (self.unit_width, self.unit_height);
        let (w, h) = self.image.dimensions();
        let size = self.completed_tiles_size;

        // Expand the image buffer if necessary.
        if self.position == 0 && (uw * size >= w || uh * size >= h) {
            let old = mem::replace(&mut self.image, ImageBuffer::new(w * 2, h * 2));
            for ix in 0 .. w {
                for iy in 0 .. h {
                    *self.image.get_pixel_mut(ix, iy) = old[(ix, iy)];
                }
            }

            /*
            let mut dest = SubImage::new(&mut self.image, 0, 0, w, h);
            for ((_, _, a), b) in dest.pixels_mut().zip(old.pixels()) {
                *a = *b;
            }
            */
        }

        let (x, y) = if self.position < size {
            (self.position, size)
        } else {
            (size, self.position - size)
        };

        self.position += 1;
        if self.position >= size * 2 + 1 {
            self.position = 0;
            self.completed_tiles_size += 1;
        }

        {
            let (x, y, w, h) = (x * uw, y * uh, uw, uh);
            for ix in 0 .. w {
                for iy in 0 .. h {
                    *self.image.get_pixel_mut(ix + x, iy + y) = img[(ix, iy)];
                }
            }
        }

        /*
        let mut dest = SubImage::new(&mut self.image, x * uw, y * uh, uw, uh);
        for ((_, _, a), b) in dest.pixels_mut().zip(img.pixels()) {
            *a = *b;
        }
        */

        *match self.tile_positions.entry(name.to_string()) {
            Occupied(entry) => entry.into_mut(),
            Vacant(entry) => entry.insert((x * uw, y * uh))
        }
    }

    /// Finds the minimum alpha value in a given sub texture of the image.
    pub fn min_alpha(&mut self, rect: [u32; 4]) -> u8 {
        let x = rect[0];
        let y = rect[1];
        let w = rect[2];
        let h = rect[3];
        if let Some(&alpha) = self.min_alpha_cache.get(&(x, y, w, h)) {
            return alpha
        }

        let tile = SubImage::new(&mut self.image, x, y, w, h);
        let min_alpha = tile.pixels().map(|(_, _, p)| p[3]).min().unwrap_or(0);
        self.min_alpha_cache.insert((x, y, w, h), min_alpha);
        min_alpha
    }

    /// Returns the complete texture atlas as a texture.
    pub fn complete<R, F>(self, factory: &mut F) -> Texture<R>
        where R: gfx::Resources, F: gfx::Factory<R>
    {
        Texture::from_image(factory, &self.image, false, true)
    }
}
<commit_msg>Update to latest gfx_texture<commit_after>//! Create textures and build texture atlas.

use std::collections::HashMap;
use std::collections::hash_map::Entry::{ Occupied, Vacant };
use std::fmt::{ Debug, Formatter, Error };
use std::path::{ Path, PathBuf };
use std::mem;

use gfx;
use image::{
    self,
    ImageBuffer,
    RgbaImage,
    DynamicImage,
    ImageResult,
    SubImage,
    ImageError,
    GenericImage,
    Pixel
};

pub use gfx_texture::{ Texture, ImageSize, Settings };

// Loads RGBA image from path.
fn load_rgba8(path: &Path) -> ImageResult<RgbaImage> {
    image::open(path).map(|img| match img {
        DynamicImage::ImageRgba8(img) => img,
        img => img.to_rgba()
    })
}

/// An enumeration of ColorMap errors.
pub enum ColorMapError {
    /// The image opening error.
    Img(ImageError),

    /// The image size error.
    Size(u32, u32, String)
}

impl Debug for ColorMapError {
    fn fmt(&self, f: &mut Formatter) -> Result<(), Error> {
        match *self {
            ColorMapError::Img(ref e) => e.fmt(f),
            ColorMapError::Size(w, h, ref path) =>
                format!("ColorMap expected 256x256, found {}x{} in '{}'", w, h, path).fmt(f)
        }
    }
}

impl From<ImageError> for ColorMapError {
    fn from(img_err: ImageError) -> Self {
        ColorMapError::Img(img_err)
    }
}

/// A 256x256 image that stores colors.
pub struct ColorMap(RgbaImage);

impl ColorMap {
    /// Creates a new `ColorMap` from path.
    pub fn from_path<P>(path: P) -> Result<Self, ColorMapError>
        where P: AsRef<Path>
    {
        let img = try!(load_rgba8(path.as_ref()));

        match img.dimensions() {
            (256, 256) => Ok(ColorMap(img)),
            (w, h) => Err(ColorMapError::Size(w, h, path.as_ref().display().to_string()))
        }
    }

    /// Gets RGB color from the color map.
    pub fn get(&self, x: f32, y: f32) -> [u8; 3] {
        // Clamp to [0.0, 1.0].
        let x = x.max(0.0).min(1.0);
        let y = y.max(0.0).min(1.0);

        // Scale y from [0.0, 1.0] to [0.0, x], forming a triangle.
        let y = x * y;

        // Origin is in the bottom-right corner.
        let x = ((1.0 - x) * 255.0) as u8;
        let y = ((1.0 - y) * 255.0) as u8;

        let col = self.0.get_pixel(x as u32, y as u32).channels();
        [col[0], col[1], col[2]]
    }
}

/// Builds an atlas of textures.
pub struct AtlasBuilder {
    image: RgbaImage,
    // Base path for loading tiles.
    path: PathBuf,
    // Size of an individual tile.
    unit_width: u32,
    unit_height: u32,
    // Size of the entirely occupied square, in tiles.
    completed_tiles_size: u32,
    // Position in the current strip.
    position: u32,
    // Position cache for loaded tiles (in pixels).
    tile_positions: HashMap<String, (u32, u32)>,
    // Lowest-alpha cache for rectangles in the atlas.
    min_alpha_cache: HashMap<(u32, u32, u32, u32), u8>
}

impl AtlasBuilder {
    /// Creates a new `AtlasBuilder`.
    pub fn new<P>(path: P, unit_width: u32, unit_height: u32) -> Self
        where P: Into<PathBuf>
    {
        AtlasBuilder {
            image: ImageBuffer::new(unit_width * 4, unit_height * 4),
            path: path.into(),
            unit_width: unit_width,
            unit_height: unit_height,
            completed_tiles_size: 0,
            position: 0,
            tile_positions: HashMap::new(),
            min_alpha_cache: HashMap::new()
        }
    }

    /// Loads a file into the texture atlas.
    /// Checks if the file is loaded and returns position within the atlas.
    /// The name should be specified without file extension.
    /// PNG is the only supported format.
    pub fn load(&mut self, name: &str) -> (u32, u32) {
        if let Some(&pos) = self.tile_positions.get(name) {
            return pos
        }

        let mut path = self.path.join(name);
        path.set_extension("png");
        let img = load_rgba8(&path).unwrap();

        let (iw, ih) = img.dimensions();
        assert!(iw == self.unit_width);
        assert!((ih % self.unit_height) == 0);
        if ih > self.unit_height {
            println!("ignoring {} extra frames in '{}'", (ih / self.unit_height) - 1, name);
        }

        let (uw, uh) = (self.unit_width, self.unit_height);
        let (w, h) = self.image.dimensions();
        let size = self.completed_tiles_size;

        // Expand the image buffer if necessary.
        if self.position == 0 && (uw * size >= w || uh * size >= h) {
            let old = mem::replace(&mut self.image, ImageBuffer::new(w * 2, h * 2));
            for ix in 0 .. w {
                for iy in 0 .. h {
                    *self.image.get_pixel_mut(ix, iy) = old[(ix, iy)];
                }
            }

            /*
            let mut dest = SubImage::new(&mut self.image, 0, 0, w, h);
            for ((_, _, a), b) in dest.pixels_mut().zip(old.pixels()) {
                *a = *b;
            }
            */
        }

        let (x, y) = if self.position < size {
            (self.position, size)
        } else {
            (size, self.position - size)
        };

        self.position += 1;
        if self.position >= size * 2 + 1 {
            self.position = 0;
            self.completed_tiles_size += 1;
        }

        {
            let (x, y, w, h) = (x * uw, y * uh, uw, uh);
            for ix in 0 .. w {
                for iy in 0 .. h {
                    *self.image.get_pixel_mut(ix + x, iy + y) = img[(ix, iy)];
                }
            }
        }

        /*
        let mut dest = SubImage::new(&mut self.image, x * uw, y * uh, uw, uh);
        for ((_, _, a), b) in dest.pixels_mut().zip(img.pixels()) {
            *a = *b;
        }
        */

        *match self.tile_positions.entry(name.to_string()) {
            Occupied(entry) => entry.into_mut(),
            Vacant(entry) => entry.insert((x * uw, y * uh))
        }
    }

    /// Finds the minimum alpha value in a given sub texture of the image.
    pub fn min_alpha(&mut self, rect: [u32; 4]) -> u8 {
        let x = rect[0];
        let y = rect[1];
        let w = rect[2];
        let h = rect[3];
        if let Some(&alpha) = self.min_alpha_cache.get(&(x, y, w, h)) {
            return alpha
        }

        let tile = SubImage::new(&mut self.image, x, y, w, h);
        let min_alpha = tile.pixels().map(|(_, _, p)| p[3]).min().unwrap_or(0);
        self.min_alpha_cache.insert((x, y, w, h), min_alpha);
        min_alpha
    }

    /// Returns the complete texture atlas as a texture.
    pub fn complete<R, F>(self, factory: &mut F) -> Texture<R>
        where R: gfx::Resources, F: gfx::Factory<R>
    {
        Texture::from_image(factory, &self.image, false, false, true)
    }
}
<|endoftext|>


<commit_before>// TODO: Make TextureBuilder completely ignorant of the Texture struct,
//       load Texture2d's instead.

use glium::backend::Facade;
use glium::texture::{Texture2d, RawImage2d};
use std::sync::{Arc, Weak};
use std::collections::HashMap;
use std::path::PathBuf;
use texture_flags::*;
use std::fs::PathExt;
use image;

#[derive(Debug, Clone)]
pub struct Texture {
    texture: Arc<Texture2d>,
    surface_flags: SurfaceFlags,
}

pub trait CreateTexture {
    fn create_texture(self, flags: SurfaceFlags) -> Texture;
}

impl CreateTexture for Arc<Texture2d> {
    fn create_texture(self, flags: SurfaceFlags) -> Texture {
        Texture {
            texture: self,
            surface_flags: flags,
        }
    }
}

impl CreateTexture for Texture2d {
    fn create_texture(self, flags: SurfaceFlags) -> Texture {
        Arc::new(self).create_texture(flags)
    }
}

// TODO: make this take a list of root directories
//       -- also, allow sub-builders so that builders
//          for different maps can share cache information
//       -- use enum with root (Vec<pathbuf>, facade, cache) or
//          inherit(texturebuilder, pathbuf)
pub struct TextureBuilder<'a, T: Facade + 'a> {
    roots: Arc<Vec<PathBuf>>,
    missing: Option<String>,
    facade: &'a T,
    cache: HashMap<String, Weak<Texture2d>>,
}

impl<'a, T: Facade + 'a> TextureBuilder<'a, T> {
    pub fn new<A: Into<PathBuf>, I: IntoIterator<Item=A>>(
        a: I, facade: &'a T, ms: Option<String>
    ) -> TextureBuilder<'a, T> {
        TextureBuilder {
            roots: Arc::new(
                a.into_iter().map(|e| e.into()).collect::<Vec<_>>()
            ),
            missing: ms.clone(),
            facade: facade,
            cache: HashMap::new()
        }
    }

    fn get_real_path_and_ext(
        roots: &[PathBuf],
        path: &str
    ) -> Option<(image::ImageFormat, PathBuf)> {
        use image::ImageFormat;
        use image::ImageFormat::*;

        fn get_extensions(i: &ImageFormat) -> &'static [&'static str] {
            static PNG_EXT:  [&'static str; 1] = ["png"];
            static JPEG_EXT: [&'static str; 2] = ["jpeg", "jpg"];
            static GIF_EXT:  [&'static str; 1] = ["gif"];
            static WEBP_EXT: [&'static str; 1] = ["webp"];
            static PPM_EXT:  [&'static str; 1] = ["ppm"];
            static TIFF_EXT: [&'static str; 1] = ["tiff"];
            static TGA_EXT:  [&'static str; 1] = ["tga"];
            static BMP_EXT:  [&'static str; 1] = ["bmp"];
            static ICO_EXT:  [&'static str; 1] = ["ico"];

            match *i {
                PNG  => &PNG_EXT,
                JPEG => &JPEG_EXT,
                GIF  => &GIF_EXT,
                WEBP => &WEBP_EXT,
                PPM  => &PPM_EXT,
                TIFF => &TIFF_EXT,
                TGA  => &TGA_EXT,
                BMP  => &BMP_EXT,
                ICO  => &ICO_EXT,
            }
        }

        for root in roots {
            let root: PathBuf = root.join(path);
            let file_name: String =
                if let Some(Some(f)) = root.file_name().map(|o| o.to_str()) {
                    f.into()
                } else {
                    return None
                };
            for ex in [PNG, JPEG, GIF, WEBP, PPM, TIFF, TGA, BMP, ICO].into_iter() {
                let extensions = get_extensions(&ex);

                for str_ex in extensions {
                    let out = root.with_file_name(format!("{}.{}", file_name, str_ex));

                    if out.is_file() { return Some((*ex, out.to_path_buf())); }
                }
            }
        }

        None
    }

    fn find_in_cache(&self, hash: String) -> Option<Arc<Texture2d>> {
        self.cache.get(&hash).and_then(|weak| weak.upgrade())
    }

    pub fn load(
        &mut self, path: &str
    ) -> Option<Arc<Texture2d>> {
        self.find_in_cache(path.into()).or_else(||
            Self::load_inner(self.roots.clone(), path).and_then(|image|
                Texture2d::new(self.facade, image).ok()
                    .map(|t| {
                        let out = Arc::new(t);
                        self.cache.insert(path.into(), Arc::downgrade(&out));
                        out
                    })
            )
        )
    }

    pub fn load_async(
        &mut self, many: Vec<String>
    ) -> Vec<Option<Arc<Texture2d>>> {
        use eventual::*;
        use itertools::*;

        let cached = many.iter()
            .enumerate()
            .map(|(i, path)|
                (i, path.clone(), self.find_in_cache(path.clone()))
            )
            .collect::<Vec<_>>();
        let promises =
            cached.iter()
            .cloned()
            .filter_map(|(n, path, opt)|
                if opt.is_none() {
                    let rclone = self.roots.clone();
                    let msclone = self.missing.clone();
                    Some(Future::spawn(move || {
                        let load = Self::load_inner(rclone.clone(), &path)
                            .or_else(||
                                msclone.and_then(|inner|
                                    Self::load_inner(rclone, &inner)
                                )
                            );
                        (
                            n,
                            path,
                            load,
                        )
                    }))
                } else {
                    None
                }
            )
            .collect::<Vec<_>>();
        let textures = join(
            promises
        ).await()
        .unwrap()
        .into_iter()
        .map(|(n, path, raw)|
            (
                n,
                raw.and_then(|image|
                    Texture2d::new(self.facade, image).ok()
                        .map(|t| {
                            let out = Arc::new(t);
                            self.cache.insert(path.into(), Arc::downgrade(&out));
                            out
                        })
                ),
            )
        )
        .collect::<Vec<_>>();

        cached.into_iter()
            .filter_map(|(n, _, maybe_tex)|
                maybe_tex.map(|t| (n, Some(t)))
            )
            .chain(textures.into_iter())
            .sorted_by(|a, b| a.0.cmp(&b.0))
            .into_iter()
            .zip(0..)
            .map(|((n, t), i)| {
                 debug_assert!(n==i);
                 t
            })
            .collect::<Vec<_>>()
    }

    fn load_inner<'b: 'a>(
        roots: Arc<Vec<PathBuf>>, path: &str
    ) -> Option<RawImage2d<'b, u8>> {
        use std::io::BufReader;
        use std::fs::File;

        let (ext, real_path) =
            if let Some(tup) = Self::get_real_path_and_ext(&*roots, path) {
                tup
            } else {
                return None
            };

        let f = if let Ok(a) = File::open(&real_path) {
                a
            } else {
                return None
            };
        let reader = BufReader::new(f);

        let raw = if let Ok(a) = image::load(
                reader,
                ext
            ) {
                a.to_rgba()
            } else {
                return None
            };
        let image_dimensions = raw.dimensions();
        Some(
            RawImage2d::from_raw_rgba_reversed(
                raw.into_raw(), image_dimensions
            )
        )
    }
}
<commit_msg>Add texturebuilder inheritence<commit_after>// TODO: Make TextureBuilder completely ignorant of the Texture struct,
//       load Texture2d's instead.

use glium::backend::Facade;
use glium::texture::{Texture2d, RawImage2d};
use std::sync::{Arc, Weak, RwLock};
use std::collections::HashMap;
use std::path::PathBuf;
use texture_flags::*;
use std::fs::PathExt;
use image;

#[derive(Debug, Clone)]
pub struct Texture {
    texture: Arc<Texture2d>,
    surface_flags: SurfaceFlags,
}

pub trait CreateTexture {
    fn create_texture(self, flags: SurfaceFlags) -> Texture;
}

impl CreateTexture for Arc<Texture2d> {
    fn create_texture(self, flags: SurfaceFlags) -> Texture {
        Texture {
            texture: self,
            surface_flags: flags,
        }
    }
}

impl CreateTexture for Texture2d {
    fn create_texture(self, flags: SurfaceFlags) -> Texture {
        Arc::new(self).create_texture(flags)
    }
}

// TODO: make this take a list of root directories
//       -- also, allow sub-builders so that builders
//          for different maps can share cache information
//       -- use enum with root (Vec<pathbuf>, facade, cache) or
//          inherit(texturebuilder, pathbuf)
pub struct TextureBuilder<'a, T: Facade + 'a> {
    roots: Arc<Vec<PathBuf>>,
    missing: Option<String>,
    facade: &'a T,
    cache: Arc<RwLock<HashMap<String, Weak<Texture2d>>>>,
}

impl<'a, T: Facade + 'a> TextureBuilder<'a, T> {
    pub fn new<A: Into<PathBuf>, I: IntoIterator<Item=A>>(
        a: I, facade: &'a T, ms: Option<String>
    ) -> TextureBuilder<'a, T> {
        TextureBuilder {
            roots: Arc::new(
                a.into_iter().map(|e| e.into()).collect::<Vec<_>>()
            ),
            missing: ms,
            facade: facade,
            cache: Arc::new(RwLock::new(HashMap::new())),
        }
    }

    pub fn inherit<A: Into<PathBuf>, I: IntoIterator<Item=A>>(
        parent: &TextureBuilder<'a, T>, a: I
    ) -> TextureBuilder<'a, T> {
        TextureBuilder {
            roots:
                Arc::new(
                    parent.roots.iter()
                        .cloned()
                        .chain(a.into_iter().map(|e| e.into()))
                        .collect()
                ),
            missing: parent.missing.clone(),
            facade: parent.facade,
            cache: parent.cache.clone(),
        }
    }

    fn get_real_path_and_ext(
        roots: &[PathBuf],
        path: &str
    ) -> Option<(image::ImageFormat, PathBuf)> {
        use image::ImageFormat;
        use image::ImageFormat::*;

        fn get_extensions(i: &ImageFormat) -> &'static [&'static str] {
            static PNG_EXT:  [&'static str; 1] = ["png"];
            static JPEG_EXT: [&'static str; 2] = ["jpeg", "jpg"];
            static GIF_EXT:  [&'static str; 1] = ["gif"];
            static WEBP_EXT: [&'static str; 1] = ["webp"];
            static PPM_EXT:  [&'static str; 1] = ["ppm"];
            static TIFF_EXT: [&'static str; 1] = ["tiff"];
            static TGA_EXT:  [&'static str; 1] = ["tga"];
            static BMP_EXT:  [&'static str; 1] = ["bmp"];
            static ICO_EXT:  [&'static str; 1] = ["ico"];

            match *i {
                PNG  => &PNG_EXT,
                JPEG => &JPEG_EXT,
                GIF  => &GIF_EXT,
                WEBP => &WEBP_EXT,
                PPM  => &PPM_EXT,
                TIFF => &TIFF_EXT,
                TGA  => &TGA_EXT,
                BMP  => &BMP_EXT,
                ICO  => &ICO_EXT,
            }
        }

        for root in roots {
            let root: PathBuf = root.join(path);
            let file_name: String =
                if let Some(Some(f)) = root.file_name().map(|o| o.to_str()) {
                    f.into()
                } else {
                    return None
                };
            for ex in [PNG, JPEG, GIF, WEBP, PPM, TIFF, TGA, BMP, ICO].into_iter() {
                let extensions = get_extensions(&ex);

                for str_ex in extensions {
                    let out = root.with_file_name(format!("{}.{}", file_name, str_ex));

                    if out.is_file() { return Some((*ex, out.to_path_buf())); }
                }
            }
        }

        None
    }

    pub fn load(
        &mut self, path: &str
    ) -> Option<Arc<Texture2d>> {
        self.cache.read().unwrap()
            .get(path)
            .and_then(|weak| weak.upgrade())
            .or_else(||
                Self::load_inner(self.roots.clone(), path).and_then(|image|
                    Texture2d::new(self.facade, image).ok()
                        .map(|t| {
                            let out = Arc::new(t);
                            self.cache.write().unwrap()
                                .insert(path.into(), Arc::downgrade(&out));
                            out
                        })
                )
            )
    }

    pub fn load_async(
        &mut self, many: Vec<String>
    ) -> Vec<Option<Arc<Texture2d>>> {
        use eventual::*;
        use itertools::*;

        let cached;
        {
            let cache = self.cache.read().unwrap();
            cached = many.iter()
                .enumerate()
                .map(|(i, path)|
                    (
                        i,
                        path.clone(),
                        cache.get(path).and_then(|weak| weak.upgrade())
                    )
                )
                .collect::<Vec<_>>();
        }

        let mut cache = self.cache.write().unwrap();
        let promises =
            cached.iter()
            .cloned()
            .filter_map(|(n, path, opt)|
                if opt.is_none() {
                    let rclone = self.roots.clone();
                    let msclone = self.missing.clone();
                    Some(Future::spawn(move || {
                        let load = Self::load_inner(rclone.clone(), &path)
                            .or_else(||
                                msclone.and_then(|inner|
                                    Self::load_inner(rclone, &inner)
                                )
                            );
                        (
                            n,
                            path,
                            load,
                        )
                    }))
                } else {
                    None
                }
            )
            .collect::<Vec<_>>();
        let textures = join(
            promises
        ).await()
        .unwrap()
        .into_iter()
        .map(|(n, path, raw)|
            (
                n,
                raw.and_then(|image|
                    Texture2d::new(self.facade, image).ok()
                        .map(|t| {
                            let out = Arc::new(t);
                            cache.insert(path.into(), Arc::downgrade(&out));
                            out
                        })
                ),
            )
        )
        .collect::<Vec<_>>();

        cached.into_iter()
            .filter_map(|(n, _, maybe_tex)|
                maybe_tex.map(|t| (n, Some(t)))
            )
            .chain(textures.into_iter())
            .sorted_by(|a, b| a.0.cmp(&b.0))
            .into_iter()
            .zip(0..)
            .map(|((n, t), i)| {
                 debug_assert!(n==i);
                 t
            })
            .collect::<Vec<_>>()
    }

    fn load_inner<'b: 'a>(
        roots: Arc<Vec<PathBuf>>, path: &str
    ) -> Option<RawImage2d<'b, u8>> {
        use std::io::BufReader;
        use std::fs::File;

        let (ext, real_path) =
            if let Some(tup) = Self::get_real_path_and_ext(&*roots, path) {
                tup
            } else {
                return None
            };

        let f = if let Ok(a) = File::open(&real_path) {
                a
            } else {
                return None
            };
        let reader = BufReader::new(f);

        let raw = if let Ok(a) = image::load(
                reader,
                ext
            ) {
                a.to_rgba()
            } else {
                return None
            };
        let image_dimensions = raw.dimensions();
        Some(
            RawImage2d::from_raw_rgba_reversed(
                raw.into_raw(), image_dimensions
            )
        )
    }
}
<|endoftext|>


<commit_before>use gfx;
use image;
use image::{
    DynamicImage,
    GenericImage,
    RgbaImage,
};
use texture_lib::ImageSize;

/// Represents a texture.
pub struct Texture<R: gfx::Resources> {
    /// A handle to the Gfx texture.
    pub handle: gfx::TextureHandle<R>,
}

impl<R: gfx::Resources> Texture<R> {
    /// Creates a texture from path.
    pub fn from_path<D: gfx::Factory<R>>(
        device: &mut D,
        path: &Path
    ) -> Result<Self, String> {
        let img = match image::open(path) {
            Ok(img) => img,
            Err(e)  => return Err(format!("Could not load '{:?}': {:?}",
                path.filename_str().unwrap(), e)),
        };

        let img = match img {
            DynamicImage::ImageRgba8(img) => img,
            x => x.to_rgba()
        };

        let (width, height) = img.dimensions();
        let texture_info = gfx::tex::TextureInfo {
            width: width as u16,
            height: height as u16,
            depth: 1,
            levels: 1,
            kind: gfx::tex::TextureKind::Texture2D,
            format: gfx::tex::RGBA8,
        };
        let image_info = texture_info.to_image_info();
        let texture = device.create_texture(texture_info).ok().unwrap();
        device.update_texture(&texture, &image_info,
            img.as_slice())
        .ok().unwrap();

        Ok(Texture {
            handle: texture
        })
    }

    /// Creates a texture from image.
    pub fn from_image<D: gfx::Factory<R>>(
        device: &mut D,
        image: &RgbaImage
    ) -> Self {
        let (width, height) = image.dimensions();
        let texture_info = gfx::tex::TextureInfo {
            width: width as u16,
            height: height as u16,
            depth: 1,
            levels: 1,
            kind: gfx::tex::TextureKind::Texture2D,
            format: gfx::tex::RGBA8,
        };
        let image_info = texture_info.to_image_info();
        let texture = device.create_texture(texture_info).ok().unwrap();
        device.update_texture(&texture, &image_info,
            image.as_slice())
        .ok().unwrap();

        Texture {
            handle: texture
        }
    }

    /// Creates a texture from image and generates mipmap.
    pub fn from_image_with_mipmap<D: gfx::Factory<R>>(
        device: &mut D,
        image: &RgbaImage
    ) -> Self {
        let texture = Texture::from_image(device, image);
        device.generate_mipmap(&texture.handle);

        texture
    }

    /// Creates texture from memory alpha.
    pub fn from_memory_alpha<D: gfx::Factory<R>>(
        device: &mut D,
        buffer: &[u8],
        width: u32,
        height: u32,
    ) -> Self {
        use std::cmp::max;

        let width = max(width, 1);
        let height = max(height, 1);

        let mut pixels = Vec::new();
        for alpha in buffer.iter() {
            pixels.push(255);
            pixels.push(255);
            pixels.push(255);
            pixels.push(*alpha);
        }

        let texture_info = gfx::tex::TextureInfo {
            width: width as u16,
            height: height as u16,
            depth: 1,
            levels: 1,
            kind: gfx::tex::TextureKind::Texture2D,
            format: gfx::tex::RGBA8,
        };

        let image_info = texture_info.to_image_info();
        let texture = device.create_texture(texture_info).ok().unwrap();
        device.update_texture(&texture, &image_info,
            &pixels)
            .ok().unwrap();
        Texture {
            handle: texture
        }
    }

    /// Updates the texture with an image.
    pub fn update<D: gfx::Factory<R>>(&mut self, device: &mut D, image: &RgbaImage) {
        device.update_texture(&self.handle,
            &self.handle.get_info().to_image_info(),
            image.as_slice()
        ).ok().unwrap();
    }
}

impl<R: gfx::Resources> ImageSize for Texture<R> {
    #[inline(always)]
    fn get_size(&self) -> (u32, u32) {
        let info = self.handle.get_info();
        (info.width as u32, info.height as u32)
    }
}

<commit_msg>Fix old_path import<commit_after>use std::old_path::*;

use gfx;
use image;
use image::{
    DynamicImage,
    GenericImage,
    RgbaImage,
};
use texture_lib::ImageSize;

/// Represents a texture.
pub struct Texture<R: gfx::Resources> {
    /// A handle to the Gfx texture.
    pub handle: gfx::TextureHandle<R>,
}

impl<R: gfx::Resources> Texture<R> {
    /// Creates a texture from path.
    pub fn from_path<D: gfx::Factory<R>>(
        device: &mut D,
        path: &Path
    ) -> Result<Self, String> {
        let img = match image::open(path) {
            Ok(img) => img,
            Err(e)  => return Err(format!("Could not load '{:?}': {:?}",
                path.filename_str().unwrap(), e)),
        };

        let img = match img {
            DynamicImage::ImageRgba8(img) => img,
            x => x.to_rgba()
        };

        let (width, height) = img.dimensions();
        let texture_info = gfx::tex::TextureInfo {
            width: width as u16,
            height: height as u16,
            depth: 1,
            levels: 1,
            kind: gfx::tex::TextureKind::Texture2D,
            format: gfx::tex::RGBA8,
        };
        let image_info = texture_info.to_image_info();
        let texture = device.create_texture(texture_info).ok().unwrap();
        device.update_texture(&texture, &image_info,
            img.as_slice())
        .ok().unwrap();

        Ok(Texture {
            handle: texture
        })
    }

    /// Creates a texture from image.
    pub fn from_image<D: gfx::Factory<R>>(
        device: &mut D,
        image: &RgbaImage
    ) -> Self {
        let (width, height) = image.dimensions();
        let texture_info = gfx::tex::TextureInfo {
            width: width as u16,
            height: height as u16,
            depth: 1,
            levels: 1,
            kind: gfx::tex::TextureKind::Texture2D,
            format: gfx::tex::RGBA8,
        };
        let image_info = texture_info.to_image_info();
        let texture = device.create_texture(texture_info).ok().unwrap();
        device.update_texture(&texture, &image_info,
            image.as_slice())
        .ok().unwrap();

        Texture {
            handle: texture
        }
    }

    /// Creates a texture from image and generates mipmap.
    pub fn from_image_with_mipmap<D: gfx::Factory<R>>(
        device: &mut D,
        image: &RgbaImage
    ) -> Self {
        let texture = Texture::from_image(device, image);
        device.generate_mipmap(&texture.handle);

        texture
    }

    /// Creates texture from memory alpha.
    pub fn from_memory_alpha<D: gfx::Factory<R>>(
        device: &mut D,
        buffer: &[u8],
        width: u32,
        height: u32,
    ) -> Self {
        use std::cmp::max;

        let width = max(width, 1);
        let height = max(height, 1);

        let mut pixels = Vec::new();
        for alpha in buffer.iter() {
            pixels.push(255);
            pixels.push(255);
            pixels.push(255);
            pixels.push(*alpha);
        }

        let texture_info = gfx::tex::TextureInfo {
            width: width as u16,
            height: height as u16,
            depth: 1,
            levels: 1,
            kind: gfx::tex::TextureKind::Texture2D,
            format: gfx::tex::RGBA8,
        };

        let image_info = texture_info.to_image_info();
        let texture = device.create_texture(texture_info).ok().unwrap();
        device.update_texture(&texture, &image_info,
            &pixels)
            .ok().unwrap();
        Texture {
            handle: texture
        }
    }

    /// Updates the texture with an image.
    pub fn update<D: gfx::Factory<R>>(&mut self, device: &mut D, image: &RgbaImage) {
        device.update_texture(&self.handle,
            &self.handle.get_info().to_image_info(),
            image.as_slice()
        ).ok().unwrap();
    }
}

impl<R: gfx::Resources> ImageSize for Texture<R> {
    #[inline(always)]
    fn get_size(&self) -> (u32, u32) {
        let info = self.handle.get_info();
        (info.width as u32, info.height as u32)
    }
}

<|endoftext|>


<commit_before>use std::result::*;
use std::rc::*;

use rustc_serialize::*;

use super::treenode::*;
use super::basictree::*;
use super::values::*;

///
/// Encoder that will write to the specified tree node
///
struct TreeNodeEncoder<'a> {
    root: &'a mut MutableTreeNode
}

impl<'a> TreeNodeEncoder<'a> {
    fn new(root: &'a mut MutableTreeNode) -> TreeNodeEncoder<'a> {
        TreeNodeEncoder { root: root }
    }
}

pub enum TreeNodeCodingError {
    UnsupportedType
}

impl<'a> Encoder for TreeNodeEncoder<'a> {
    type Error = TreeNodeCodingError;

    fn emit_nil(&mut self) -> Result<(), Self::Error> {
        self.root.set_tree_value(TreeValue::Nothing);
        Ok(())
    }

    fn emit_i32(&mut self, v: i32) -> Result<(), Self::Error> {
        self.root.set_tree_value(TreeValue::Int(v));
        Ok(())
    }

    fn emit_i16(&mut self, v: i16) -> Result<(), Self::Error> {
        self.root.set_tree_value(TreeValue::Int(v as i32));
        Ok(())
    }

    fn emit_i8(&mut self, v: i8) -> Result<(), Self::Error> {
        self.root.set_tree_value(TreeValue::Int(v as i32));
        Ok(())
    }

    fn emit_bool(&mut self, v: bool) -> Result<(), Self::Error> {
        self.root.set_tree_value(TreeValue::Bool(v));
        Ok(())
    }

    fn emit_f64(&mut self, v: f64) -> Result<(), Self::Error> {
        self.root.set_tree_value(TreeValue::Real(v));
        Ok(())
    }

    fn emit_f32(&mut self, v: f32) -> Result<(), Self::Error> {
        self.root.set_tree_value(TreeValue::Real(v as f64));
        Ok(())
    }

    fn emit_str(&mut self, v: &str) -> Result<(), Self::Error> {
        self.root.set_tree_value(TreeValue::String(v.to_string()));
        Ok(())
    }

    fn emit_struct<F>(&mut self, name: &str, len: usize, f: F) -> Result<(), Self::Error> where F: FnOnce(&mut Self) -> Result<(), Self::Error> {
        self.root.set_tree_value(TreeValue::String(name.to_string()));

        f(self)
    }

    fn emit_struct_field<F>(&mut self, f_name: &str, f_idx: usize, f: F) -> Result<(), Self::Error> where F: FnOnce(&mut Self) -> Result<(), Self::Error> {
        // Hrm, so what I want to do is create a new encoder with a new node and call f on it.
        // But rust has other ideas; it doesn't know that f(X) doesn't reference X after it returns, so it moans
        // Other ideas
        //   * create a whole new encoder (can't do it, we don't have any access to the struct)
        //   * swap the reference to the node (can't do it, the new node has the same lifetime problems)
        //   * use a CloneCell (can't do it, set_tree_value and set_tag aren't supported)

        // Insert a new node into the tree
        let new_node = BasicTree::new(f_name, ());

        self.root.get_child_ref().and_then(|sibling| {
            new_node.set_sibling_ref(sibling);
            Some(())
        });

        // Encode the field into the new node (would be super-elegant if this works but Rust is all 'nooope, you need to write a
        // billion more lines of code'). I know *why* but this is stupid, if the encoder function had a better lifetime specifier
        // it'd be unnecessary.
        // Rust thinks that f() needs stuff with a lifetime the same as this struct rather than stuff with a lifetime as long
        // as the function call (it's not obvious from a casual reading of the definition, rust likes to be inscrutable).
        // This means we need to do dumb stuff to make it work.
        /*
        let node_encoder = TreeNodeEncoder::new(&mut new_node);
        f(&mut node_encoder);
        */

        // Save the node we just created and update the tree
        self.root.set_child_ref(Rc::new(new_node));

        Err(TreeNodeCodingError::UnsupportedType)
    }

    fn emit_usize(&mut self, v: usize) -> Result<(), Self::Error> {
        Err(TreeNodeCodingError::UnsupportedType)
    }

    fn emit_u64(&mut self, v: u64) -> Result<(), Self::Error> {
        Err(TreeNodeCodingError::UnsupportedType)
    }

    fn emit_u32(&mut self, v: u32) -> Result<(), Self::Error> {
        Err(TreeNodeCodingError::UnsupportedType)
    }

    fn emit_u16(&mut self, v: u16) -> Result<(), Self::Error> {
        Err(TreeNodeCodingError::UnsupportedType)
    }

    fn emit_u8(&mut self, v: u8) -> Result<(), Self::Error> {
        Err(TreeNodeCodingError::UnsupportedType)
    }

    fn emit_isize(&mut self, v: isize) -> Result<(), Self::Error> {
        Err(TreeNodeCodingError::UnsupportedType)
    }

    fn emit_i64(&mut self, v: i64) -> Result<(), Self::Error> {
        Err(TreeNodeCodingError::UnsupportedType)
    }

    fn emit_char(&mut self, v: char) -> Result<(), Self::Error> {
        Err(TreeNodeCodingError::UnsupportedType)
    }

    fn emit_enum<F>(&mut self, name: &str, f: F) -> Result<(), Self::Error> where F: FnOnce(&mut Self) -> Result<(), Self::Error> {
        Err(TreeNodeCodingError::UnsupportedType)
    }

    fn emit_enum_variant<F>(&mut self, v_name: &str, v_id: usize, len: usize, f: F) -> Result<(), Self::Error> where F: FnOnce(&mut Self) -> Result<(), Self::Error> {
        Err(TreeNodeCodingError::UnsupportedType)
    }

    fn emit_enum_variant_arg<F>(&mut self, a_idx: usize, f: F) -> Result<(), Self::Error> where F: FnOnce(&mut Self) -> Result<(), Self::Error> {
        Err(TreeNodeCodingError::UnsupportedType)
    }

    fn emit_enum_struct_variant<F>(&mut self, v_name: &str, v_id: usize, len: usize, f: F) -> Result<(), Self::Error> where F: FnOnce(&mut Self) -> Result<(), Self::Error> {
        Err(TreeNodeCodingError::UnsupportedType)
    }

    fn emit_enum_struct_variant_field<F>(&mut self, f_name: &str, f_idx: usize, f: F) -> Result<(), Self::Error> where F: FnOnce(&mut Self) -> Result<(), Self::Error> {
        Err(TreeNodeCodingError::UnsupportedType)
    }

    fn emit_tuple<F>(&mut self, len: usize, f: F) -> Result<(), Self::Error> where F: FnOnce(&mut Self) -> Result<(), Self::Error> {
        Err(TreeNodeCodingError::UnsupportedType)
    }

    fn emit_tuple_arg<F>(&mut self, idx: usize, f: F) -> Result<(), Self::Error> where F: FnOnce(&mut Self) -> Result<(), Self::Error> {
        Err(TreeNodeCodingError::UnsupportedType)
    }

    fn emit_tuple_struct<F>(&mut self, name: &str, len: usize, f: F) -> Result<(), Self::Error> where F: FnOnce(&mut Self) -> Result<(), Self::Error> {
        Err(TreeNodeCodingError::UnsupportedType)
    }

    fn emit_tuple_struct_arg<F>(&mut self, f_idx: usize, f: F) -> Result<(), Self::Error> where F: FnOnce(&mut Self) -> Result<(), Self::Error> {
        Err(TreeNodeCodingError::UnsupportedType)
    }

    fn emit_option<F>(&mut self, f: F) -> Result<(), Self::Error> where F: FnOnce(&mut Self) -> Result<(), Self::Error> {
        Err(TreeNodeCodingError::UnsupportedType)
    }

    fn emit_option_none(&mut self) -> Result<(), Self::Error> {
        Err(TreeNodeCodingError::UnsupportedType)
    }

    fn emit_option_some<F>(&mut self, f: F) -> Result<(), Self::Error> where F: FnOnce(&mut Self) -> Result<(), Self::Error> {
        Err(TreeNodeCodingError::UnsupportedType)
    }

    fn emit_seq<F>(&mut self, len: usize, f: F) -> Result<(), Self::Error> where F: FnOnce(&mut Self) -> Result<(), Self::Error> {
        Err(TreeNodeCodingError::UnsupportedType)
    }

    fn emit_seq_elt<F>(&mut self, idx: usize, f: F) -> Result<(), Self::Error> where F: FnOnce(&mut Self) -> Result<(), Self::Error> {
        Err(TreeNodeCodingError::UnsupportedType)
    }

    fn emit_map<F>(&mut self, len: usize, f: F) -> Result<(), Self::Error> where F: FnOnce(&mut Self) -> Result<(), Self::Error> {
        Err(TreeNodeCodingError::UnsupportedType)
    }

    fn emit_map_elt_key<F>(&mut self, idx: usize, f: F) -> Result<(), Self::Error> where F: FnOnce(&mut Self) -> Result<(), Self::Error> {
        Err(TreeNodeCodingError::UnsupportedType)
    }

    fn emit_map_elt_val<F>(&mut self, idx: usize, f: F) -> Result<(), Self::Error> where F: FnOnce(&mut Self) -> Result<(), Self::Error> {
        Err(TreeNodeCodingError::UnsupportedType)
    }
}
<commit_msg>Can fix the lifetime thing by not making a lifetime part of the type, which means we can't directly encode to a TreeNode but instead need to encode something that can be made into a treenode later on<commit_after>use std::result::*;
use std::rc::*;

use rustc_serialize::*;

use super::treenode::*;
use super::basictree::*;
use super::values::*;

///
/// Encoder that will write to the specified tree node
///
struct TreeNodeEncoder {
    tag:    String,
    value:  TreeValue,
    child:  Option<Rc<TreeNode>>
}

impl TreeNodeEncoder {
    fn new() -> TreeNodeEncoder {
        TreeNodeEncoder {
            tag:    "".to_string(),
            value:  TreeValue::Nothing,
            child:  None }
    }
}

pub enum TreeNodeCodingError {
    UnsupportedType
}

impl Encoder for TreeNodeEncoder {
    type Error = TreeNodeCodingError;

    fn emit_nil(&mut self) -> Result<(), Self::Error> {
        self.value = TreeValue::Nothing;
        Ok(())
    }

    fn emit_i32(&mut self, v: i32) -> Result<(), Self::Error> {
        self.value = TreeValue::Int(v);
        Ok(())
    }

    fn emit_i16(&mut self, v: i16) -> Result<(), Self::Error> {
        self.value = TreeValue::Int(v as i32);
        Ok(())
    }

    fn emit_i8(&mut self, v: i8) -> Result<(), Self::Error> {
        self.value = TreeValue::Int(v as i32);
        Ok(())
    }

    fn emit_bool(&mut self, v: bool) -> Result<(), Self::Error> {
        self.value = TreeValue::Bool(v);
        Ok(())
    }

    fn emit_f64(&mut self, v: f64) -> Result<(), Self::Error> {
        self.value = TreeValue::Real(v);
        Ok(())
    }

    fn emit_f32(&mut self, v: f32) -> Result<(), Self::Error> {
        self.value = TreeValue::Real(v as f64);
        Ok(())
    }

    fn emit_str(&mut self, v: &str) -> Result<(), Self::Error> {
        self.value = TreeValue::String(v.to_string());
        Ok(())
    }

    fn emit_struct<F>(&mut self, name: &str, len: usize, f: F) -> Result<(), Self::Error> where F: FnOnce(&mut Self) -> Result<(), Self::Error> {
        self.value = TreeValue::String(name.to_string());

        f(self)
    }

    fn emit_struct_field<F>(&mut self, f_name: &str, f_idx: usize, f: F) -> Result<(), Self::Error> where F: FnOnce(&mut Self) -> Result<(), Self::Error> {
        // Hrm, so what I want to do is create a new encoder with a new node and call f on it.
        // But rust has other ideas; it doesn't know that f(X) doesn't reference X after it returns, so it moans
        // Other ideas
        //   * create a whole new encoder (can't do it, we don't have any access to the struct)
        //   * swap the reference to the node (can't do it, the new node has the same lifetime problems)
        //   * use a CloneCell (can't do it, set_tree_value and set_tag aren't supported)

        // Insert a new node into the tree
        let new_node = BasicTree::new(f_name, ());

        self.child.to_owned().and_then(|sibling| {
            new_node.set_sibling_ref(sibling);
            Some(())
        });

        // Encode the field into the new node (would be super-elegant if this works but Rust is all 'nooope, you need to write a
        // billion more lines of code'). I know *why* but this is stupid, if the encoder function had a better lifetime specifier
        // it'd be unnecessary.
        // Rust thinks that f() needs stuff with a lifetime the same as this struct rather than stuff with a lifetime as long
        // as the function call (it's not obvious from a casual reading of the definition, rust likes to be inscrutable).
        // This means we need to do dumb stuff to make it work.
        let mut node_encoder = TreeNodeEncoder::new();
        f(&mut node_encoder);

        // Save the node we just created and update the tree
        self.child = Some(Rc::new(new_node));

        Err(TreeNodeCodingError::UnsupportedType)
    }

    fn emit_usize(&mut self, v: usize) -> Result<(), Self::Error> {
        Err(TreeNodeCodingError::UnsupportedType)
    }

    fn emit_u64(&mut self, v: u64) -> Result<(), Self::Error> {
        Err(TreeNodeCodingError::UnsupportedType)
    }

    fn emit_u32(&mut self, v: u32) -> Result<(), Self::Error> {
        Err(TreeNodeCodingError::UnsupportedType)
    }

    fn emit_u16(&mut self, v: u16) -> Result<(), Self::Error> {
        Err(TreeNodeCodingError::UnsupportedType)
    }

    fn emit_u8(&mut self, v: u8) -> Result<(), Self::Error> {
        Err(TreeNodeCodingError::UnsupportedType)
    }

    fn emit_isize(&mut self, v: isize) -> Result<(), Self::Error> {
        Err(TreeNodeCodingError::UnsupportedType)
    }

    fn emit_i64(&mut self, v: i64) -> Result<(), Self::Error> {
        Err(TreeNodeCodingError::UnsupportedType)
    }

    fn emit_char(&mut self, v: char) -> Result<(), Self::Error> {
        Err(TreeNodeCodingError::UnsupportedType)
    }

    fn emit_enum<F>(&mut self, name: &str, f: F) -> Result<(), Self::Error> where F: FnOnce(&mut Self) -> Result<(), Self::Error> {
        Err(TreeNodeCodingError::UnsupportedType)
    }

    fn emit_enum_variant<F>(&mut self, v_name: &str, v_id: usize, len: usize, f: F) -> Result<(), Self::Error> where F: FnOnce(&mut Self) -> Result<(), Self::Error> {
        Err(TreeNodeCodingError::UnsupportedType)
    }

    fn emit_enum_variant_arg<F>(&mut self, a_idx: usize, f: F) -> Result<(), Self::Error> where F: FnOnce(&mut Self) -> Result<(), Self::Error> {
        Err(TreeNodeCodingError::UnsupportedType)
    }

    fn emit_enum_struct_variant<F>(&mut self, v_name: &str, v_id: usize, len: usize, f: F) -> Result<(), Self::Error> where F: FnOnce(&mut Self) -> Result<(), Self::Error> {
        Err(TreeNodeCodingError::UnsupportedType)
    }

    fn emit_enum_struct_variant_field<F>(&mut self, f_name: &str, f_idx: usize, f: F) -> Result<(), Self::Error> where F: FnOnce(&mut Self) -> Result<(), Self::Error> {
        Err(TreeNodeCodingError::UnsupportedType)
    }

    fn emit_tuple<F>(&mut self, len: usize, f: F) -> Result<(), Self::Error> where F: FnOnce(&mut Self) -> Result<(), Self::Error> {
        Err(TreeNodeCodingError::UnsupportedType)
    }

    fn emit_tuple_arg<F>(&mut self, idx: usize, f: F) -> Result<(), Self::Error> where F: FnOnce(&mut Self) -> Result<(), Self::Error> {
        Err(TreeNodeCodingError::UnsupportedType)
    }

    fn emit_tuple_struct<F>(&mut self, name: &str, len: usize, f: F) -> Result<(), Self::Error> where F: FnOnce(&mut Self) -> Result<(), Self::Error> {
        Err(TreeNodeCodingError::UnsupportedType)
    }

    fn emit_tuple_struct_arg<F>(&mut self, f_idx: usize, f: F) -> Result<(), Self::Error> where F: FnOnce(&mut Self) -> Result<(), Self::Error> {
        Err(TreeNodeCodingError::UnsupportedType)
    }

    fn emit_option<F>(&mut self, f: F) -> Result<(), Self::Error> where F: FnOnce(&mut Self) -> Result<(), Self::Error> {
        Err(TreeNodeCodingError::UnsupportedType)
    }

    fn emit_option_none(&mut self) -> Result<(), Self::Error> {
        Err(TreeNodeCodingError::UnsupportedType)
    }

    fn emit_option_some<F>(&mut self, f: F) -> Result<(), Self::Error> where F: FnOnce(&mut Self) -> Result<(), Self::Error> {
        Err(TreeNodeCodingError::UnsupportedType)
    }

    fn emit_seq<F>(&mut self, len: usize, f: F) -> Result<(), Self::Error> where F: FnOnce(&mut Self) -> Result<(), Self::Error> {
        Err(TreeNodeCodingError::UnsupportedType)
    }

    fn emit_seq_elt<F>(&mut self, idx: usize, f: F) -> Result<(), Self::Error> where F: FnOnce(&mut Self) -> Result<(), Self::Error> {
        Err(TreeNodeCodingError::UnsupportedType)
    }

    fn emit_map<F>(&mut self, len: usize, f: F) -> Result<(), Self::Error> where F: FnOnce(&mut Self) -> Result<(), Self::Error> {
        Err(TreeNodeCodingError::UnsupportedType)
    }

    fn emit_map_elt_key<F>(&mut self, idx: usize, f: F) -> Result<(), Self::Error> where F: FnOnce(&mut Self) -> Result<(), Self::Error> {
        Err(TreeNodeCodingError::UnsupportedType)
    }

    fn emit_map_elt_val<F>(&mut self, idx: usize, f: F) -> Result<(), Self::Error> where F: FnOnce(&mut Self) -> Result<(), Self::Error> {
        Err(TreeNodeCodingError::UnsupportedType)
    }
}
<|endoftext|>


<commit_before>use std::{env, thread, time};
use std::sync::mpsc;

use reqwest;
use crossbeam;

use bot;
use command_handler::CommandHandler;
use update::Update;

const BASE_URL: &'static str = "https://api.telegram.org/bot";

pub struct Updater {
    token: String,
    last_update_id: i32,
    pub running: bool,
    pub is_idle: bool,
}

impl Updater {
    /// Creates a new Updater struct.
    pub fn start(token: Option<String>,
                 poll_interval: Option<u64>,
                 timeout: Option<i32>,
                 network_delay: Option<i32>,
                 command_handler: CommandHandler) {
        let token = token.or_else(|| env::var("TELEGRAM_BOT_TOKEN").ok())
            .expect("You should pass in a token to new or set TELEGRAM_BOT_TOKEN");

        let updater = Updater {
            token: token,
            last_update_id: 0,
            running: false,
            is_idle: false,
        };

        updater.start_polling(poll_interval, timeout, network_delay, command_handler);
    }

    pub fn start_polling(mut self,
                         poll_interval: Option<u64>,
                         timeout: Option<i32>,
                         network_delay: Option<i32>,
                         mut command_handler: CommandHandler) {
        if !self.running {
            self.running = true;

            let (tx, rx) = mpsc::channel();
            let bot = bot::Bot::new([BASE_URL, &self.token].concat()).unwrap();

            // Spawn scoped threads
            crossbeam::scope(|scope| {
                scope.spawn(|| {
                    self.start_polling_thread(poll_interval, timeout, network_delay, &bot, tx)
                });
                scope.spawn(|| {
                    command_handler.start_command_handling(rx, &bot);
                });
            });
        }
    }

    fn start_polling_thread(&mut self,
                            poll_interval: Option<u64>,
                            timeout: Option<i32>,
                            network_delay: Option<i32>,
                            bot: &bot::Bot,
                            tx: mpsc::Sender<Update>) {
        let poll_interval = time::Duration::from_secs(poll_interval.unwrap_or(0));

        while self.running {
            let updates = bot.get_updates(self.last_update_id, None, timeout, network_delay);

            match updates {
                Ok(Some(ref v)) => {
                    if let Some(u) = v.last() {
                        for update in v {
                            tx.send(update.clone()).unwrap();
                        }
                        let update_id_store = u.update_id + 1;
                        self.last_update_id = update_id_store as i32;
                    } else {
                        // Do nothing, the vector is empty
                        continue;
                    }
                }
                Ok(None) => {
                    // Do nothing, we have nothing
                    continue;
                }
                Err(err) => {
                    // Handle error
                    continue;
                }
            };

            thread::sleep(poll_interval);
        }
    }
}
<commit_msg>Removing reqwest from file<commit_after>use std::{env, thread, time};
use std::sync::mpsc;

use crossbeam;

use bot;
use command_handler::CommandHandler;
use update::Update;

const BASE_URL: &'static str = "https://api.telegram.org/bot";

pub struct Updater {
    token: String,
    last_update_id: i32,
    pub running: bool,
    pub is_idle: bool,
}

impl Updater {
    /// Creates a new Updater struct.
    pub fn start(token: Option<String>,
                 poll_interval: Option<u64>,
                 timeout: Option<i32>,
                 network_delay: Option<i32>,
                 command_handler: CommandHandler) {
        let token = token.or_else(|| env::var("TELEGRAM_BOT_TOKEN").ok())
            .expect("You should pass in a token to new or set TELEGRAM_BOT_TOKEN");

        let updater = Updater {
            token: token,
            last_update_id: 0,
            running: false,
            is_idle: false,
        };

        updater.start_polling(poll_interval, timeout, network_delay, command_handler);
    }

    pub fn start_polling(mut self,
                         poll_interval: Option<u64>,
                         timeout: Option<i32>,
                         network_delay: Option<i32>,
                         mut command_handler: CommandHandler) {
        if !self.running {
            self.running = true;

            let (tx, rx) = mpsc::channel();
            let bot = bot::Bot::new([BASE_URL, &self.token].concat()).unwrap();

            // Spawn scoped threads
            crossbeam::scope(|scope| {
                scope.spawn(|| {
                    self.start_polling_thread(poll_interval, timeout, network_delay, &bot, tx)
                });
                scope.spawn(|| {
                    command_handler.start_command_handling(rx, &bot);
                });
            });
        }
    }

    fn start_polling_thread(&mut self,
                            poll_interval: Option<u64>,
                            timeout: Option<i32>,
                            network_delay: Option<i32>,
                            bot: &bot::Bot,
                            tx: mpsc::Sender<Update>) {
        let poll_interval = time::Duration::from_secs(poll_interval.unwrap_or(0));

        while self.running {
            let updates = bot.get_updates(self.last_update_id, None, timeout, network_delay);

            match updates {
                Ok(Some(ref v)) => {
                    if let Some(u) = v.last() {
                        for update in v {
                            tx.send(update.clone()).unwrap();
                        }
                        let update_id_store = u.update_id + 1;
                        self.last_update_id = update_id_store as i32;
                    } else {
                        // Do nothing, the vector is empty
                        continue;
                    }
                }
                Ok(None) => {
                    // Do nothing, we have nothing
                    continue;
                }
                Err(err) => {
                    // Handle error
                    continue;
                }
            };

            thread::sleep(poll_interval);
        }
    }
}
<|endoftext|>


<commit_before>use update_client::*;
use errors::*;
use database::*;
// use diesel::prelude::*;
// use diesel::pg::PgConnection;
// use dotenv::dotenv;
//
// use rocksdb::DB;

use std::collections::HashMap;
use std::env;
use std::str;
use std::thread;
use std::sync::atomic::AtomicBool;
use std::sync::{Arc, Mutex};

enum CurrentState {
    Running,
    Stopped,
}

// Using the client, fetches updates periodically, storing the results in a database
pub struct GSBUpdater<'a, T>
    where T: 'a + Database
{
    update_client: Arc<Mutex<UpdateClient<'a>>>,
    db: &'a mut T,
    period: usize, // 30 seconds - will be 30 minutes later...
    thread: Option<thread::JoinHandle<Result<()>>>,
    should_execute: AtomicBool,
}

impl<'a, T> GSBUpdater<'a, T>
    where T: Database
{
    pub fn new(api_key: &'a str, db: &'a mut T) -> Result<GSBUpdater<'a, T>> {
        Ok(GSBUpdater {
            update_client: Arc::new(Mutex::new(UpdateClient::new(api_key))),
            db: db,
            period: 30,
            thread: None,
            should_execute: AtomicBool::new(false),
        })
    }

    pub fn begin_update(&mut self) -> Result<()> {
        self.thread = Some(thread::spawn(|| {
            loop {
                let update_client = self.update_client.lock().unwrap();

                let fetch_response = try!(update_client.fetch().send());

                try!(self.db.update(&fetch_response));

            }
        }));
        Ok(())
    }

    pub fn set_period() {
        unimplemented!();
    }

    pub fn stop_updates() {
        unimplemented!();
    }
}
<commit_msg>Make GsbUpdater period atomic<commit_after>use update_client::*;
use errors::*;
use database::*;
// use diesel::prelude::*;
// use diesel::pg::PgConnection;
// use dotenv::dotenv;
//
// use rocksdb::DB;

use std::collections::HashMap;
use std::env;
use std::str;
use std::thread;
use std::sync::atomic::{AtomicBool, AtomicUsize};
use std::sync::{Arc, Mutex};

enum CurrentState {
    Running,
    Stopped,
}

// Using the client, fetches updates periodically, storing the results in a database
pub struct GSBUpdater<'a, T>
    where T: 'a + Database
{
    update_client: Arc<Mutex<UpdateClient<'a>>>,
    db: &'a mut T,
    period: AtomicUsize,
    thread: Option<thread::JoinHandle<Result<()>>>,
    should_execute: AtomicBool,
}

impl<'a, T> GSBUpdater<'a, T>
    where T: Database
{
    pub fn new(api_key: &'a str, db: &'a mut T) -> Result<GSBUpdater<'a, T>> {
        Ok(GSBUpdater {
            update_client: Arc::new(Mutex::new(UpdateClient::new(api_key))),
            db: db,
            period: AtomicUsize::new(30), // 30 seconds - will be 30 minutes later...
            thread: None,
            should_execute: AtomicBool::new(false),
        })
    }

    pub fn begin_update(&mut self) -> Result<()> {
        self.thread = Some(thread::spawn(|| {
            loop {
                let update_client = self.update_client.lock().unwrap();

                let fetch_response = try!(update_client.fetch().send());

                try!(self.db.update(&fetch_response));

            }
        }));
        Ok(())
    }

    pub fn set_period() {
        unimplemented!();
    }

    pub fn stop_updates() {
        unimplemented!();
    }
}
<|endoftext|>