<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.

#![experimental]
#![macro_escape]

//! A typesafe bitmask flag generator.

/// 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
#[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! {
        #[doc = "> The first principle is that you must not fool yourself — and"]
        #[doc = "> you are the easiest person to fool."]
        #[doc = "> "]
        #[doc = "> - Richard Feynman"]
        flags Flags: u32 {
            static FlagA       = 0x00000001,
            #[doc = "<pcwalton> macros are way better at generating code than trans is"]
            static FlagB       = 0x00000010,
            static FlagC       = 0x00000100,
            #[doc = "* cmr bed"]
            #[doc = "* strcat table"]
            #[doc = "<strcat> wait what?"]
            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>inlines contains in bitflags!<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.

#![experimental]
#![macro_escape]

//! A typesafe bitmask flag generator.

/// 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
#[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`.
            #[inline]
            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! {
        #[doc = "> The first principle is that you must not fool yourself — and"]
        #[doc = "> you are the easiest person to fool."]
        #[doc = "> "]
        #[doc = "> - Richard Feynman"]
        flags Flags: u32 {
            static FlagA       = 0x00000001,
            #[doc = "<pcwalton> macros are way better at generating code than trans is"]
            static FlagB       = 0x00000010,
            static FlagC       = 0x00000100,
            #[doc = "* cmr bed"]
            #[doc = "* strcat table"]
            #[doc = "<strcat> wait what?"]
            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>extern crate piston_window;

use piston_window::Transformed;

use piston_window as pw;

fn main() {
    let window: pw::PistonWindow = pw::WindowSettings::new("rrthozopsi", [600, 600])
        .exit_on_esc(true)
        .build()
        .unwrap();

    for w in window {
		w.draw_2d(|context, graphics| {
			pw::clear([0.0, 0.0, 0.0, 1.0], graphics);

			let red = [1.0, 0.0, 0.0, 1.0];
			let square = pw::rectangle::square(0.0, 0.0, 100.0);
			let center = context.transform.trans(300.0, 300.0);
			pw::rectangle(red, square, center.trans(-50.0, -50.0), graphics);
		});
    }
}
<commit_msg>rotation<commit_after>extern crate piston_window;

use piston_window::Transformed;

use piston_window as pw;

fn main() {
    let window: pw::PistonWindow = pw::WindowSettings::new("rrthozopsi", [600, 600])
        .exit_on_esc(true)
        .build()
        .unwrap();

	let mut rotation: f64 = 0.0;
    for w in window {
		match w.event {
			Some(pw::Event::Update(pw::UpdateArgs { dt })) => { rotation += 3.0 * dt; }
			_ => {}
		}

		w.draw_2d(|context, graphics| {
			pw::clear([0.0, 0.0, 0.0, 1.0], graphics);

			let red = [1.0, 0.0, 0.0, 1.0];
			let square = pw::rectangle::square(0.0, 0.0, 100.0);
			let center = context.transform.trans(300.0, 300.0);
			pw::rectangle(red, square, center.rot_rad(rotation).trans(-50.0, -50.0), graphics);
		});
    }
}
<|endoftext|>


<commit_before>use proc_macro::{
    Ident, TokenStream, TokenTree,
    token_stream,
};

#[proc_macro_attribute]
pub fn solutions(attrs: TokenStream, input: TokenStream) -> TokenStream {
    unimplemented!("Implement me to simplify test cases for multiple solutions")
}

#[cfg(test)]
mod tests {
    #[test]
    fn it_works() {
        let result = 2 + 2;
        assert_eq!(result, 4);
    }
}
<commit_msg>The "unconfident" attribute macro<commit_after>use proc_macro::{
    Ident, TokenStream, TokenTree,
    token_stream,
};

#[proc_macro_attribute]
pub fn solutions(attrs: TokenStream, input: TokenStream) -> TokenStream {
    unimplemented!("Implement me to simplify test cases for multiple solutions")
}

#[proc_macro_attribute]
pub fn unconfident(_attr: TokenStream, input: TokenStream) -> TokenStream {
    input
}

#[cfg(test)]
mod tests {
    #[test]
    fn it_works() {
        let result = 2 + 2;
        assert_eq!(result, 4);
    }
}
<|endoftext|>


<commit_before>extern crate chrono;

use flowgger::config::Config;
use flowgger::record::{Record, StructuredData, SDValue, SDValueType};
use self::chrono::DateTime;
use std::collections::HashMap;
use super::Decoder;

#[derive(Clone)]
struct Suffixes {
    s_bool: Option<String>,
    s_f64: Option<String>,
    s_i64: Option<String>,
    s_u64: Option<String>
}

#[derive(Clone)]
pub struct LTSVDecoder {
    schema: Option<HashMap<String, SDValueType>>,
    suffixes: Suffixes
}

impl LTSVDecoder {
    pub fn new(config: &Config) -> LTSVDecoder {
        let schema = match config.lookup("input.ltsv_schema") {
            None => None,
            Some(pairs) => {
                let mut schema = HashMap::new();
                for (name, sdtype) in pairs.as_table().expect("input.ltsv_schema must be a list of key/type pairs") {
                    let sdtype = match sdtype.as_str().expect("input.ltsv_schema types must be strings").to_lowercase().as_ref() {
                        "string" => SDValueType::String,
                        "bool" => SDValueType::Bool,
                        "f64" => SDValueType::F64,
                        "i64" => SDValueType::I64,
                        "u64" => SDValueType::U64,
                        _ => panic!(format!("Unsupported type in input.ltsv_schema for name [{}]", name))
                    };
                    schema.insert(name.to_owned(), sdtype);
                }
                Some(schema)
            }
        };
        let mut suffixes = Suffixes {
            s_bool: None,
            s_f64: None,
            s_i64: None,
            s_u64: None
        };
        match config.lookup("input.ltsv_suffixes") {
            None => { }
            Some(pairs) => {
                for (sdtype, suffix) in pairs.as_table().expect("input.ltsv_suffixes must be a list of type/suffixes pairs") {
                    let suffix = suffix.as_str().expect("input.ltsv_suffixes suffixes must be strings").to_owned();
                    match sdtype.to_lowercase().as_ref() {
                        "string" => panic!("Strings cannot be suffixed"),
                        "bool" => suffixes.s_bool = Some(suffix),
                        "f64" => suffixes.s_f64 = Some(suffix),
                        "i64" => suffixes.s_i64 = Some(suffix),
                        "u64" => suffixes.s_u64 = Some(suffix),
                        _ => panic!(format!("Unsupported type in input.ltsv_suffixes for type [{}]", sdtype))
                    }
                }
            }
        };
        LTSVDecoder {
            schema: schema,
            suffixes: suffixes
        }
    }
}

impl Decoder for LTSVDecoder {
    fn decode(&self, line: &str) -> Result<Record, &'static str> {
        let mut sd = StructuredData::new(None);
        let mut ts = None;
        let mut hostname = None;
        let mut msg = None;
        let mut severity = None;

        for part in line.split('\t') {
            let mut pair = part.splitn(2, ':');
            let name = try!(pair.next().ok_or("Missing name in an LTSV record"));
            let value = try!(pair.next().ok_or("Missing value in an LTSV record"));
            match name {
                "time" => {
                    let ts_s = if value.starts_with('[') && value.ends_with(']') {
                        &value[1..(value.len() -1)]
                    } else {
                        value
                    };
                    ts = Some(try!(parse_ts(ts_s)));
                },
                "host" =>
                    hostname = Some(value.to_owned()),
                "message" =>
                    msg = Some(value.to_owned()),
                "level" => {
                    let severity_given: u8 = try!(value.parse().or(Err("Invalid severity level")));
                    if severity_given > 7 {
                        return Err("Severity level should be <= 7")
                    }
                    severity = Some(severity_given);
                },
                name => {
                    let (final_name, value): (String, SDValue) = if let Some(ref schema) = self.schema {
                        match schema.get(name) {
                            None | Some(&SDValueType::String) =>
                                (format!("_{}", name), SDValue::String(value.to_owned())),
                            Some(&SDValueType::Bool) => {
                                let final_name = match self.suffixes.s_bool {
                                    Some(ref suffix) if !name.ends_with(suffix) => format!("_{}{}", name, suffix),
                                    _ => format!("_{}", name)
                                };
                                (final_name, SDValue::Bool(try!(value.parse::<bool>().or(Err("Type error; boolean was expected")))))
                            }
                            Some(&SDValueType::F64) => {
                                let final_name = match self.suffixes.s_f64 {
                                    Some(ref suffix) if !name.ends_with(suffix) => format!("_{}{}", name, suffix),
                                    _ => format!("_{}", name)
                                };
                                (final_name, SDValue::F64(try!(value.parse::<f64>().or(Err("Type error; f64 was expected")))))
                            }
                            Some(&SDValueType::I64) => {
                                let final_name = match self.suffixes.s_i64 {
                                    Some(ref suffix) if !name.ends_with(suffix) => format!("_{}{}", name, suffix),
                                    _ => format!("_{}", name)
                                };
                                (final_name, SDValue::I64(try!(value.parse::<i64>().or(Err("Type error; i64 was expected")))))
                            }
                            Some(&SDValueType::U64) => {
                                let final_name = match self.suffixes.s_u64 {
                                    Some(ref suffix) if !name.ends_with(suffix) => format!("_{}{}", name, suffix),
                                    _ => format!("_{}", name)
                                };
                                (final_name, SDValue::U64(try!(value.parse::<u64>().or(Err("Type error; u64 was expected")))))
                            }
                        }
                    } else {
                        (format!("_{}", name), SDValue::String(value.to_owned()))
                    };
                    sd.pairs.push((final_name, value));
                }
            };
        }
        let record = Record {
            ts: try!(ts.ok_or("Missing timestamp")),
            hostname: try!(hostname.ok_or("Missing hostname")),
            facility: None,
            severity: severity,
            appname: None,
            procid: None,
            msgid: None,
            sd: if sd.pairs.is_empty() { None } else { Some(sd) },
            msg: msg,
            full_msg: None
        };
        Ok(record)
    }
}

fn rfc3339_to_unix(rfc3339: &str) -> Result<i64, &'static str> {
    match DateTime::parse_from_rfc3339(rfc3339) {
        Ok(date) => Ok(date.timestamp()),
        Err(_) => Err("Unable to parse the date")
    }
}

fn english_time_to_unix(et: &str) -> Result<i64, &'static str> {
    match DateTime::parse_from_str(et, "%e/%b/%Y:%H:%M:%S %z") {
        Ok(date) => Ok(date.timestamp()),
        Err(_) => Err("Unable to parse the date")
    }
}

fn parse_ts(line: &str) -> Result<i64, &'static str> {
    rfc3339_to_unix(line).or(english_time_to_unix(line))
}

#[test]
fn test_ltsv_suffixes() {
    let config = Config::from_string("[input]\n[input.ltsv_schema]\ncounter = \"u64\"\nscore = \"i64\"\nmean = \"f64\"\ndone = \"bool\"\n[input.ltsv_suffixes]\nu64 = \"_u64\"\ni64 = \"_i64\"\nf64 = \"_f64\"\nbool = \"_bool\"\n");
    let ltsv_decoder = LTSVDecoder::new(&config.unwrap());
    let msg = "time:[10/Oct/2000:13:55:36 -0700]\tdone:true\tscore:-1\tmean:0.42\tcounter:42\tlevel:3\thost:testhostname\tname1:value1\tname 2: value 2\tn3:v3\tmessage:this is a test";
    let res = ltsv_decoder.decode(msg).unwrap();
    let sd = res.sd.unwrap();
    let pairs = sd.pairs;
    assert!(pairs.iter().cloned().any(|(k, v)|
        if let SDValue::U64(v) = v { k == "_counter_u64" && v == 42 } else { false }
    ));
    assert!(pairs.iter().cloned().any(|(k, v)|
        if let SDValue::I64(v) = v { k == "_score_i64" && v == -1 } else { false }
    ));
    assert!(pairs.iter().cloned().any(|(k, v)|
        if let SDValue::F64(v) = v { k == "_mean_f64" && f64::abs(v - 0.42) < 1e-5 } else { false }
    ));
    assert!(pairs.iter().cloned().any(|(k, v)|
        if let SDValue::Bool(v) = v { k == "_done_bool" && v == true } else { false }
    ));
}

#[test]
fn test_ltsv_suffixes_2() {
    let config = Config::from_string("[input]\n[input.ltsv_schema]\ncounter_u64 = \"u64\"\nscore_i64 = \"i64\"\nmean_f64 = \"f64\"\ndone_bool = \"bool\"\n[input.ltsv_suffixes]\nu64 = \"_u64\"\ni64 = \"_i64\"\nf64 = \"_f64\"\nbool = \"_bool\"\n");
    let ltsv_decoder = LTSVDecoder::new(&config.unwrap());
    let msg = "time:[10/Oct/2000:13:55:36 -0700]\tdone_bool:true\tscore_i64:-1\tmean_f64:0.42\tcounter_u64:42\tlevel:3\thost:testhostname\tname1:value1\tname 2: value 2\tn3:v3\tmessage:this is a test";
    let res = ltsv_decoder.decode(msg).unwrap();
    let sd = res.sd.unwrap();
    let pairs = sd.pairs;
    assert!(pairs.iter().cloned().any(|(k, v)|
        if let SDValue::U64(v) = v { k == "_counter_u64" && v == 42 } else { false }
    ));
    assert!(pairs.iter().cloned().any(|(k, v)|
        if let SDValue::I64(v) = v { k == "_score_i64" && v == -1 } else { false }
    ));
    assert!(pairs.iter().cloned().any(|(k, v)|
        if let SDValue::F64(v) = v { k == "_mean_f64" && f64::abs(v - 0.42) < 1e-5 } else { false }
    ));
    assert!(pairs.iter().cloned().any(|(k, v)|
        if let SDValue::Bool(v) = v { k == "_done_bool" && v == true } else { false }
    ));
}

#[test]
fn test_ltsv() {
    let config = Config::from_string("[input]\n[input.ltsv_schema]\ncounter = \"u64\"\nscore = \"i64\"\nmean = \"f64\"\ndone = \"bool\"\n");
    let ltsv_decoder = LTSVDecoder::new(&config.unwrap());
    let msg = "time:[2015-08-05T15:53:45.637824Z]\thost:testhostname\tname1:value1\tname 2: value 2\tn3:v3";
    let res = ltsv_decoder.decode(msg).unwrap();
    assert!(res.ts == 1438790025);
}

#[test]
fn test_ltsv_2() {
    let config = Config::from_string("[input]\n[input.ltsv_schema]\ncounter = \"u64\"\nscore = \"i64\"\nmean = \"f64\"\ndone = \"bool\"\n");
    let ltsv_decoder = LTSVDecoder::new(&config.unwrap());
    let msg = "time:[10/Oct/2000:13:55:36 -0700]\tdone:true\tscore:-1\tmean:0.42\tcounter:42\tlevel:3\thost:testhostname\tname1:value1\tname 2: value 2\tn3:v3\tmessage:this is a test";
    let res = ltsv_decoder.decode(msg).unwrap();
    assert!(res.ts == 971211336);
    assert!(res.severity.unwrap() == 3);

    assert!(res.hostname == "testhostname");
    assert!(res.msg.unwrap() == "this is a test");
    let sd = res.sd.unwrap();
    let pairs = sd.pairs;
    assert!(pairs.iter().cloned().any(|(k, v)|
        if let SDValue::String(v) = v { k == "_name1" && v == "value1" } else { false }
    ));
    assert!(pairs.iter().cloned().any(|(k, v)|
        if let SDValue::String(v) = v { k == "_name 2" && v == " value 2" } else { false }
    ));
    assert!(pairs.iter().cloned().any(|(k, v)|
        if let SDValue::String(v) = v { k == "_n3" && v == "v3" } else { false }
    ));
    assert!(pairs.iter().cloned().any(|(k, v)|
        if let SDValue::U64(v) = v { k == "_counter" && v == 42 } else { false }
    ));
    assert!(pairs.iter().cloned().any(|(k, v)|
        if let SDValue::I64(v) = v { k == "_score" && v == -1 } else { false }
    ));
    assert!(pairs.iter().cloned().any(|(k, v)|
        if let SDValue::F64(v) = v { k == "_mean" && f64::abs(v - 0.42) < 1e-5 } else { false }
    ));
    assert!(pairs.iter().cloned().any(|(k, v)|
        if let SDValue::Bool(v) = v { k == "_done" && v == true } else { false }
    ));
}
<commit_msg>Mix type cases in the LTSV suffix tests<commit_after>extern crate chrono;

use flowgger::config::Config;
use flowgger::record::{Record, StructuredData, SDValue, SDValueType};
use self::chrono::DateTime;
use std::collections::HashMap;
use super::Decoder;

#[derive(Clone)]
struct Suffixes {
    s_bool: Option<String>,
    s_f64: Option<String>,
    s_i64: Option<String>,
    s_u64: Option<String>
}

#[derive(Clone)]
pub struct LTSVDecoder {
    schema: Option<HashMap<String, SDValueType>>,
    suffixes: Suffixes
}

impl LTSVDecoder {
    pub fn new(config: &Config) -> LTSVDecoder {
        let schema = match config.lookup("input.ltsv_schema") {
            None => None,
            Some(pairs) => {
                let mut schema = HashMap::new();
                for (name, sdtype) in pairs.as_table().expect("input.ltsv_schema must be a list of key/type pairs") {
                    let sdtype = match sdtype.as_str().expect("input.ltsv_schema types must be strings").to_lowercase().as_ref() {
                        "string" => SDValueType::String,
                        "bool" => SDValueType::Bool,
                        "f64" => SDValueType::F64,
                        "i64" => SDValueType::I64,
                        "u64" => SDValueType::U64,
                        _ => panic!(format!("Unsupported type in input.ltsv_schema for name [{}]", name))
                    };
                    schema.insert(name.to_owned(), sdtype);
                }
                Some(schema)
            }
        };
        let mut suffixes = Suffixes {
            s_bool: None,
            s_f64: None,
            s_i64: None,
            s_u64: None
        };
        match config.lookup("input.ltsv_suffixes") {
            None => { }
            Some(pairs) => {
                for (sdtype, suffix) in pairs.as_table().expect("input.ltsv_suffixes must be a list of type/suffixes pairs") {
                    let suffix = suffix.as_str().expect("input.ltsv_suffixes suffixes must be strings").to_owned();
                    match sdtype.to_lowercase().as_ref() {
                        "string" => panic!("Strings cannot be suffixed"),
                        "bool" => suffixes.s_bool = Some(suffix),
                        "f64" => suffixes.s_f64 = Some(suffix),
                        "i64" => suffixes.s_i64 = Some(suffix),
                        "u64" => suffixes.s_u64 = Some(suffix),
                        _ => panic!(format!("Unsupported type in input.ltsv_suffixes for type [{}]", sdtype))
                    }
                }
            }
        };
        LTSVDecoder {
            schema: schema,
            suffixes: suffixes
        }
    }
}

impl Decoder for LTSVDecoder {
    fn decode(&self, line: &str) -> Result<Record, &'static str> {
        let mut sd = StructuredData::new(None);
        let mut ts = None;
        let mut hostname = None;
        let mut msg = None;
        let mut severity = None;

        for part in line.split('\t') {
            let mut pair = part.splitn(2, ':');
            let name = try!(pair.next().ok_or("Missing name in an LTSV record"));
            let value = try!(pair.next().ok_or("Missing value in an LTSV record"));
            match name {
                "time" => {
                    let ts_s = if value.starts_with('[') && value.ends_with(']') {
                        &value[1..(value.len() -1)]
                    } else {
                        value
                    };
                    ts = Some(try!(parse_ts(ts_s)));
                },
                "host" =>
                    hostname = Some(value.to_owned()),
                "message" =>
                    msg = Some(value.to_owned()),
                "level" => {
                    let severity_given: u8 = try!(value.parse().or(Err("Invalid severity level")));
                    if severity_given > 7 {
                        return Err("Severity level should be <= 7")
                    }
                    severity = Some(severity_given);
                },
                name => {
                    let (final_name, value): (String, SDValue) = if let Some(ref schema) = self.schema {
                        match schema.get(name) {
                            None | Some(&SDValueType::String) =>
                                (format!("_{}", name), SDValue::String(value.to_owned())),
                            Some(&SDValueType::Bool) => {
                                let final_name = match self.suffixes.s_bool {
                                    Some(ref suffix) if !name.ends_with(suffix) => format!("_{}{}", name, suffix),
                                    _ => format!("_{}", name)
                                };
                                (final_name, SDValue::Bool(try!(value.parse::<bool>().or(Err("Type error; boolean was expected")))))
                            }
                            Some(&SDValueType::F64) => {
                                let final_name = match self.suffixes.s_f64 {
                                    Some(ref suffix) if !name.ends_with(suffix) => format!("_{}{}", name, suffix),
                                    _ => format!("_{}", name)
                                };
                                (final_name, SDValue::F64(try!(value.parse::<f64>().or(Err("Type error; f64 was expected")))))
                            }
                            Some(&SDValueType::I64) => {
                                let final_name = match self.suffixes.s_i64 {
                                    Some(ref suffix) if !name.ends_with(suffix) => format!("_{}{}", name, suffix),
                                    _ => format!("_{}", name)
                                };
                                (final_name, SDValue::I64(try!(value.parse::<i64>().or(Err("Type error; i64 was expected")))))
                            }
                            Some(&SDValueType::U64) => {
                                let final_name = match self.suffixes.s_u64 {
                                    Some(ref suffix) if !name.ends_with(suffix) => format!("_{}{}", name, suffix),
                                    _ => format!("_{}", name)
                                };
                                (final_name, SDValue::U64(try!(value.parse::<u64>().or(Err("Type error; u64 was expected")))))
                            }
                        }
                    } else {
                        (format!("_{}", name), SDValue::String(value.to_owned()))
                    };
                    sd.pairs.push((final_name, value));
                }
            };
        }
        let record = Record {
            ts: try!(ts.ok_or("Missing timestamp")),
            hostname: try!(hostname.ok_or("Missing hostname")),
            facility: None,
            severity: severity,
            appname: None,
            procid: None,
            msgid: None,
            sd: if sd.pairs.is_empty() { None } else { Some(sd) },
            msg: msg,
            full_msg: None
        };
        Ok(record)
    }
}

fn rfc3339_to_unix(rfc3339: &str) -> Result<i64, &'static str> {
    match DateTime::parse_from_rfc3339(rfc3339) {
        Ok(date) => Ok(date.timestamp()),
        Err(_) => Err("Unable to parse the date")
    }
}

fn english_time_to_unix(et: &str) -> Result<i64, &'static str> {
    match DateTime::parse_from_str(et, "%e/%b/%Y:%H:%M:%S %z") {
        Ok(date) => Ok(date.timestamp()),
        Err(_) => Err("Unable to parse the date")
    }
}

fn parse_ts(line: &str) -> Result<i64, &'static str> {
    rfc3339_to_unix(line).or(english_time_to_unix(line))
}

#[test]
fn test_ltsv_suffixes() {
    let config = Config::from_string("[input]\n[input.ltsv_schema]\ncounter = \"U64\"\nscore = \"I64\"\nmean = \"f64\"\ndone = \"bool\"\n[input.ltsv_suffixes]\nu64 = \"_u64\"\ni64 = \"_i64\"\nF64 = \"_f64\"\nBool = \"_bool\"\n");
    let ltsv_decoder = LTSVDecoder::new(&config.unwrap());
    let msg = "time:[10/Oct/2000:13:55:36 -0700]\tdone:true\tscore:-1\tmean:0.42\tcounter:42\tlevel:3\thost:testhostname\tname1:value1\tname 2: value 2\tn3:v3\tmessage:this is a test";
    let res = ltsv_decoder.decode(msg).unwrap();
    let sd = res.sd.unwrap();
    let pairs = sd.pairs;
    assert!(pairs.iter().cloned().any(|(k, v)|
        if let SDValue::U64(v) = v { k == "_counter_u64" && v == 42 } else { false }
    ));
    assert!(pairs.iter().cloned().any(|(k, v)|
        if let SDValue::I64(v) = v { k == "_score_i64" && v == -1 } else { false }
    ));
    assert!(pairs.iter().cloned().any(|(k, v)|
        if let SDValue::F64(v) = v { k == "_mean_f64" && f64::abs(v - 0.42) < 1e-5 } else { false }
    ));
    assert!(pairs.iter().cloned().any(|(k, v)|
        if let SDValue::Bool(v) = v { k == "_done_bool" && v == true } else { false }
    ));
}

#[test]
fn test_ltsv_suffixes_2() {
    let config = Config::from_string("[input]\n[input.ltsv_schema]\ncounter_u64 = \"U64\"\nscore_i64 = \"I64\"\nmean_f64 = \"f64\"\ndone_bool = \"bool\"\n[input.ltsv_suffixes]\nu64 = \"_u64\"\ni64 = \"_i64\"\nf64 = \"_f64\"\nbool = \"_bool\"\n");
    let ltsv_decoder = LTSVDecoder::new(&config.unwrap());
    let msg = "time:[10/Oct/2000:13:55:36 -0700]\tdone_bool:true\tscore_i64:-1\tmean_f64:0.42\tcounter_u64:42\tlevel:3\thost:testhostname\tname1:value1\tname 2: value 2\tn3:v3\tmessage:this is a test";
    let res = ltsv_decoder.decode(msg).unwrap();
    let sd = res.sd.unwrap();
    let pairs = sd.pairs;
    assert!(pairs.iter().cloned().any(|(k, v)|
        if let SDValue::U64(v) = v { k == "_counter_u64" && v == 42 } else { false }
    ));
    assert!(pairs.iter().cloned().any(|(k, v)|
        if let SDValue::I64(v) = v { k == "_score_i64" && v == -1 } else { false }
    ));
    assert!(pairs.iter().cloned().any(|(k, v)|
        if let SDValue::F64(v) = v { k == "_mean_f64" && f64::abs(v - 0.42) < 1e-5 } else { false }
    ));
    assert!(pairs.iter().cloned().any(|(k, v)|
        if let SDValue::Bool(v) = v { k == "_done_bool" && v == true } else { false }
    ));
}

#[test]
fn test_ltsv() {
    let config = Config::from_string("[input]\n[input.ltsv_schema]\ncounter = \"u64\"\nscore = \"i64\"\nmean = \"f64\"\ndone = \"bool\"\n");
    let ltsv_decoder = LTSVDecoder::new(&config.unwrap());
    let msg = "time:[2015-08-05T15:53:45.637824Z]\thost:testhostname\tname1:value1\tname 2: value 2\tn3:v3";
    let res = ltsv_decoder.decode(msg).unwrap();
    assert!(res.ts == 1438790025);
}

#[test]
fn test_ltsv_2() {
    let config = Config::from_string("[input]\n[input.ltsv_schema]\ncounter = \"u64\"\nscore = \"i64\"\nmean = \"f64\"\ndone = \"bool\"\n");
    let ltsv_decoder = LTSVDecoder::new(&config.unwrap());
    let msg = "time:[10/Oct/2000:13:55:36 -0700]\tdone:true\tscore:-1\tmean:0.42\tcounter:42\tlevel:3\thost:testhostname\tname1:value1\tname 2: value 2\tn3:v3\tmessage:this is a test";
    let res = ltsv_decoder.decode(msg).unwrap();
    assert!(res.ts == 971211336);
    assert!(res.severity.unwrap() == 3);

    assert!(res.hostname == "testhostname");
    assert!(res.msg.unwrap() == "this is a test");
    let sd = res.sd.unwrap();
    let pairs = sd.pairs;
    assert!(pairs.iter().cloned().any(|(k, v)|
        if let SDValue::String(v) = v { k == "_name1" && v == "value1" } else { false }
    ));
    assert!(pairs.iter().cloned().any(|(k, v)|
        if let SDValue::String(v) = v { k == "_name 2" && v == " value 2" } else { false }
    ));
    assert!(pairs.iter().cloned().any(|(k, v)|
        if let SDValue::String(v) = v { k == "_n3" && v == "v3" } else { false }
    ));
    assert!(pairs.iter().cloned().any(|(k, v)|
        if let SDValue::U64(v) = v { k == "_counter" && v == 42 } else { false }
    ));
    assert!(pairs.iter().cloned().any(|(k, v)|
        if let SDValue::I64(v) = v { k == "_score" && v == -1 } else { false }
    ));
    assert!(pairs.iter().cloned().any(|(k, v)|
        if let SDValue::F64(v) = v { k == "_mean" && f64::abs(v - 0.42) < 1e-5 } else { false }
    ));
    assert!(pairs.iter().cloned().any(|(k, v)|
        if let SDValue::Bool(v) = v { k == "_done" && v == true } else { false }
    ));
}
<|endoftext|>


<commit_before>// because we reuse the type names as idents in the macros as a dirty hack to
// work around `concat_idents!` being unstable.
#![allow(non_snake_case)]

///! Automatically serialize and deserialize parameters around a strongly-typed function.

use jsonrpc_core::{Error, Params, Value, from_params, to_value};
use serde::{Serialize, Deserialize};
use util::{invalid_params, expect_no_params};

/// Auto-generates an RPC trait from trait definition.
///
/// This just copies out all the methods, docs, and adds another
/// function `to_delegate` which will automatically wrap each strongly-typed
/// function in a wrapper which handles parameter and output type serialization.
///
/// RPC functions may come in a couple forms: async and synchronous.
/// These are parsed with the custom `#[rpc]` attribute, which must follow
/// documentation.
///
/// ## The #[rpc] attribute
///
/// Valid forms:
///  - `#[rpc(name = "name_here")]` (a synchronous rpc function which should be bound to the given name)
///  - `#[rpc(async, name = "name_here")]` (an async rpc function which should be bound to the given name)
///
/// Synchronous function format:
/// `fn foo(&self, Param1, Param2, Param3) -> Out`.
///
/// Asynchronous RPC functions must come in this form:
/// `fn foo(&self, Param1, Param2, Param3, Ready<Out>);
///
/// Anything else will be rejected by the code generator.
macro_rules! build_rpc_trait {
	// entry-point. todo: make another for traits w/ bounds.
	(
		$(#[$t_attr: meta])*
		pub trait $name: ident {
			$(
				$( #[doc=$m_doc:expr] )*
				#[ rpc( $($t:tt)* ) ]
				fn $m_name: ident ( $($p: tt)* ) $( -> Result<$out: ty, Error> )* ;
			)*
		}
	) => {
		$(#[$t_attr])*
		pub trait $name: Sized + Send + Sync + 'static {
			$(
				$(#[doc=$m_doc])*
				fn $m_name ( $($p)* ) $( -> Result<$out, Error> )* ;
			)*

			/// Transform this into an `IoDelegate`, automatically wrapping
			/// the parameters.
			fn to_delegate(self) -> ::jsonrpc_core::IoDelegate<Self> {
				let mut del = ::jsonrpc_core::IoDelegate::new(self.into());
				$(
					build_rpc_trait!(WRAP del =>
						( $($t)* )
						fn $m_name ( $($p)* ) $( -> Result<$out, Error> )*
					);
				)*
				del
			}
		}
	};

	( WRAP $del: expr =>
		(name = $name: expr)
		fn $method: ident (&self $(, $param: ty)*) -> Result<$out: ty, Error>
	) => {
		$del.add_method($name, move |base, params| {
			(Self::$method as fn(&_ $(, $param)*) -> Result<$out, Error>).wrap_rpc(base, params)
		})
	};

	( WRAP $del: expr =>
		(async, name = $name: expr)
		fn $method: ident (&self, Ready<$out: ty> $(, $param: ty)*)
	) => {
		$del.add_async_method($name, move |base, params, ready| {
			(Self::$method as fn(&_, Ready<$out> $(, $param)*)).wrap_rpc(base, params, ready)
		})
	};
}

/// A wrapper type without an implementation of `Deserialize`
/// which allows a special implementation of `Wrap` for functions
/// that take a trailing default parameter.
pub struct Trailing<T: Default + Deserialize>(pub T);

/// A wrapper type for `jsonrpc_core`'s weakly-typed `Ready` struct.
pub struct Ready<T: Serialize> {
	inner: ::jsonrpc_core::Ready,
	_marker: ::std::marker::PhantomData<T>,
}

impl<T: Serialize> From<::jsonrpc_core::Ready> for Ready<T> {
	fn from(ready: ::jsonrpc_core::Ready) -> Self {
		Ready { inner: ready, _marker: ::std::marker::PhantomData }
	}
}

impl<T: Serialize> Ready<T> {
	/// Respond withthe asynchronous result.
	pub fn ready(self, result: Result<T, Error>) {
		self.inner.ready(result.map(to_value))
	}
}

/// Wrapper trait for synchronous RPC functions.
pub trait Wrap<B: Send + Sync + 'static> {
	fn wrap_rpc(&self, base: &B, params: Params) -> Result<Value, Error>;
}

/// Wrapper trait for asynchronous RPC functions.
pub trait WrapAsync<B: Send + Sync + 'static> {
	fn wrap_rpc(&self, base: &B, params: Params, ready: ::jsonrpc_core::Ready);
}

// special impl for no parameters.
impl<B, OUT> Wrap<B> for fn(&B) -> Result<OUT, Error>
	where B: Send + Sync + 'static, OUT: Serialize
{
	fn wrap_rpc(&self, base: &B, params: Params) -> Result<Value, Error> {
		expect_no_params(params)
			.and_then(|()| (self)(base))
			.map(to_value)
	}
}

impl<B, OUT> WrapAsync<B> for fn(&B, Ready<OUT>)
	where B: Send + Sync + 'static, OUT: Serialize
{
	fn wrap_rpc(&self, base: &B, params: Params, ready: ::jsonrpc_core::Ready) {
		match expect_no_params(params) {
			Ok(()) => (self)(base, ready.into()),
			Err(e) => ready.ready(Err(e)),
		}
	}
}

// creates a wrapper implementation which deserializes the parameters,
// calls the function with concrete type, and serializes the output.
macro_rules! wrap {
	($($x: ident),+) => {

		// synchronous implementation
		impl <
			BASE: Send + Sync + 'static,
			OUT: Serialize,
			$($x: Deserialize,)+
		> Wrap<BASE> for fn(&BASE, $($x,)+) -> Result<OUT, Error> {
			fn wrap_rpc(&self, base: &BASE, params: Params) -> Result<Value, Error> {
				from_params::<($($x,)+)>(params).and_then(|($($x,)+)| {
					(self)(base, $($x,)+)
				}).map(to_value)
			}
		}

		// asynchronous implementation
		impl <
			BASE: Send + Sync + 'static,
			OUT: Serialize,
			$($x: Deserialize,)+
		> WrapAsync<BASE> for fn(&BASE, Ready<OUT>, $($x,)+ ) {
			fn wrap_rpc(&self, base: &BASE, params: Params, ready: ::jsonrpc_core::Ready) {
				match from_params::<($($x,)+)>(params) {
					Ok(($($x,)+)) => (self)(base, ready.into(), $($x,)+),
					Err(e) => ready.ready(Err(e)),
				}
			}
		}
	}
}

// special impl for no parameters other than block parameter.
impl<B, OUT, T> Wrap<B> for fn(&B, Trailing<T>) -> Result<OUT, Error>
	where B: Send + Sync + 'static, OUT: Serialize, T: Default + Deserialize
{
	fn wrap_rpc(&self, base: &B, params: Params) -> Result<Value, Error> {
		let len = match params {
			Params::Array(ref v) => v.len(),
			Params::None => 0,
			_ => return Err(invalid_params("not an array", "")),
		};

		let (id,) = match len {
			0 => (T::default(),),
			1 => try!(from_params::<(T,)>(params)),
			_ => return Err(Error::invalid_params()),
		};

		(self)(base, Trailing(id)).map(to_value)
	}
}

impl<B, OUT, T> WrapAsync<B> for fn(&B, Ready<OUT>, Trailing<T>)
	where B: Send + Sync + 'static, OUT: Serialize, T: Default + Deserialize
{
	fn wrap_rpc(&self, base: &B, params: Params, ready: ::jsonrpc_core::Ready) {
		let len = match params {
			Params::Array(ref v) => v.len(),
			Params::None => 0,
			_ => return ready.ready(Err(invalid_params("not an array", ""))),
		};

		let id = match len {
			0 => Ok((T::default(),)),
			1 => from_params::<(T,)>(params),
			_ => Err(Error::invalid_params()),
		};

		match id {
			Ok((id,)) => (self)(base, ready.into(), Trailing(id)),
			Err(e) => ready.ready(Err(e)),
		}
	}
}

// similar to `wrap!`, but handles a single default trailing parameter
// accepts an additional argument indicating the number of non-trailing parameters.
macro_rules! wrap_with_trailing {
	($num: expr, $($x: ident),+) => {
		// synchronous implementation
		impl <
			BASE: Send + Sync + 'static,
			OUT: Serialize,
			$($x: Deserialize,)+
			TRAILING: Default + Deserialize,
		> Wrap<BASE> for fn(&BASE, $($x,)+ Trailing<TRAILING>) -> Result<OUT, Error> {
			fn wrap_rpc(&self, base: &BASE, params: Params) -> Result<Value, Error> {
				let len = match params {
					Params::Array(ref v) => v.len(),
					Params::None => 0,
					_ => return Err(invalid_params("not an array", "")),
				};

				let params = match len - $num {
					0 => from_params::<($($x,)+)>(params)
						.map(|($($x,)+)| ($($x,)+ TRAILING::default())),
					1 => from_params::<($($x,)+ TRAILING)>(params)
						.map(|($($x,)+ id)| ($($x,)+ id)),
					_ => Err(Error::invalid_params()),
				};

				let ($($x,)+ id) = try!(params);
				(self)(base, $($x,)+ Trailing(id)).map(to_value)
			}
		}

		// asynchronous implementation
		impl <
			BASE: Send + Sync + 'static,
			OUT: Serialize,
			$($x: Deserialize,)+
			TRAILING: Default + Deserialize,
		> WrapAsync<BASE> for fn(&BASE, Ready<OUT>, $($x,)+ Trailing<TRAILING>) {
			fn wrap_rpc(&self, base: &BASE, params: Params, ready: ::jsonrpc_core::Ready) {
				let len = match params {
					Params::Array(ref v) => v.len(),
					Params::None => 0,
					_ => return ready.ready(Err(invalid_params("not an array", ""))),
				};

				let params = match len - $num {
					0 => from_params::<($($x,)+)>(params)
						.map(|($($x,)+)| ($($x,)+ TRAILING::default())),
					1 => from_params::<($($x,)+ TRAILING)>(params)
						.map(|($($x,)+ id)| ($($x,)+ id)),
					_ => Err(Error::invalid_params()),
				};

				match params {
					Ok(($($x,)+ id)) => (self)(base, ready.into(), $($x,)+ Trailing(id)),
					Err(e) => ready.ready(Err(e))
				}
			}
		}
	}
}

wrap!(A, B, C, D, E);
wrap!(A, B, C, D);
wrap!(A, B, C);
wrap!(A, B);
wrap!(A);

wrap_with_trailing!(5, A, B, C, D, E);
wrap_with_trailing!(4, A, B, C, D);
wrap_with_trailing!(3, A, B, C);
wrap_with_trailing!(2, A, B);
wrap_with_trailing!(1, A);

<commit_msg>added macro_export<commit_after>// because we reuse the type names as idents in the macros as a dirty hack to
// work around `concat_idents!` being unstable.
#![allow(non_snake_case)]

///! Automatically serialize and deserialize parameters around a strongly-typed function.

use jsonrpc_core::{Error, Params, Value, from_params, to_value};
use serde::{Serialize, Deserialize};
use util::{invalid_params, expect_no_params};

/// Auto-generates an RPC trait from trait definition.
///
/// This just copies out all the methods, docs, and adds another
/// function `to_delegate` which will automatically wrap each strongly-typed
/// function in a wrapper which handles parameter and output type serialization.
///
/// RPC functions may come in a couple forms: async and synchronous.
/// These are parsed with the custom `#[rpc]` attribute, which must follow
/// documentation.
///
/// ## The #[rpc] attribute
///
/// Valid forms:
///  - `#[rpc(name = "name_here")]` (a synchronous rpc function which should be bound to the given name)
///  - `#[rpc(async, name = "name_here")]` (an async rpc function which should be bound to the given name)
///
/// Synchronous function format:
/// `fn foo(&self, Param1, Param2, Param3) -> Out`.
///
/// Asynchronous RPC functions must come in this form:
/// `fn foo(&self, Param1, Param2, Param3, Ready<Out>);
///
/// Anything else will be rejected by the code generator.
#[macro_export]
macro_rules! build_rpc_trait {
	// entry-point. todo: make another for traits w/ bounds.
	(
		$(#[$t_attr: meta])*
		pub trait $name: ident {
			$(
				$( #[doc=$m_doc:expr] )*
				#[ rpc( $($t:tt)* ) ]
				fn $m_name: ident ( $($p: tt)* ) $( -> Result<$out: ty, Error> )* ;
			)*
		}
	) => {
		$(#[$t_attr])*
		pub trait $name: Sized + Send + Sync + 'static {
			$(
				$(#[doc=$m_doc])*
				fn $m_name ( $($p)* ) $( -> Result<$out, Error> )* ;
			)*

			/// Transform this into an `IoDelegate`, automatically wrapping
			/// the parameters.
			fn to_delegate(self) -> ::jsonrpc_core::IoDelegate<Self> {
				let mut del = ::jsonrpc_core::IoDelegate::new(self.into());
				$(
					build_rpc_trait!(WRAP del =>
						( $($t)* )
						fn $m_name ( $($p)* ) $( -> Result<$out, Error> )*
					);
				)*
				del
			}
		}
	};

	( WRAP $del: expr =>
		(name = $name: expr)
		fn $method: ident (&self $(, $param: ty)*) -> Result<$out: ty, Error>
	) => {
		$del.add_method($name, move |base, params| {
			(Self::$method as fn(&_ $(, $param)*) -> Result<$out, Error>).wrap_rpc(base, params)
		})
	};

	( WRAP $del: expr =>
		(async, name = $name: expr)
		fn $method: ident (&self, Ready<$out: ty> $(, $param: ty)*)
	) => {
		$del.add_async_method($name, move |base, params, ready| {
			(Self::$method as fn(&_, Ready<$out> $(, $param)*)).wrap_rpc(base, params, ready)
		})
	};
}

/// A wrapper type without an implementation of `Deserialize`
/// which allows a special implementation of `Wrap` for functions
/// that take a trailing default parameter.
pub struct Trailing<T: Default + Deserialize>(pub T);

/// A wrapper type for `jsonrpc_core`'s weakly-typed `Ready` struct.
pub struct Ready<T: Serialize> {
	inner: ::jsonrpc_core::Ready,
	_marker: ::std::marker::PhantomData<T>,
}

impl<T: Serialize> From<::jsonrpc_core::Ready> for Ready<T> {
	fn from(ready: ::jsonrpc_core::Ready) -> Self {
		Ready { inner: ready, _marker: ::std::marker::PhantomData }
	}
}

impl<T: Serialize> Ready<T> {
	/// Respond withthe asynchronous result.
	pub fn ready(self, result: Result<T, Error>) {
		self.inner.ready(result.map(to_value))
	}
}

/// Wrapper trait for synchronous RPC functions.
pub trait Wrap<B: Send + Sync + 'static> {
	fn wrap_rpc(&self, base: &B, params: Params) -> Result<Value, Error>;
}

/// Wrapper trait for asynchronous RPC functions.
pub trait WrapAsync<B: Send + Sync + 'static> {
	fn wrap_rpc(&self, base: &B, params: Params, ready: ::jsonrpc_core::Ready);
}

// special impl for no parameters.
impl<B, OUT> Wrap<B> for fn(&B) -> Result<OUT, Error>
	where B: Send + Sync + 'static, OUT: Serialize
{
	fn wrap_rpc(&self, base: &B, params: Params) -> Result<Value, Error> {
		expect_no_params(params)
			.and_then(|()| (self)(base))
			.map(to_value)
	}
}

impl<B, OUT> WrapAsync<B> for fn(&B, Ready<OUT>)
	where B: Send + Sync + 'static, OUT: Serialize
{
	fn wrap_rpc(&self, base: &B, params: Params, ready: ::jsonrpc_core::Ready) {
		match expect_no_params(params) {
			Ok(()) => (self)(base, ready.into()),
			Err(e) => ready.ready(Err(e)),
		}
	}
}

// creates a wrapper implementation which deserializes the parameters,
// calls the function with concrete type, and serializes the output.
macro_rules! wrap {
	($($x: ident),+) => {

		// synchronous implementation
		impl <
			BASE: Send + Sync + 'static,
			OUT: Serialize,
			$($x: Deserialize,)+
		> Wrap<BASE> for fn(&BASE, $($x,)+) -> Result<OUT, Error> {
			fn wrap_rpc(&self, base: &BASE, params: Params) -> Result<Value, Error> {
				from_params::<($($x,)+)>(params).and_then(|($($x,)+)| {
					(self)(base, $($x,)+)
				}).map(to_value)
			}
		}

		// asynchronous implementation
		impl <
			BASE: Send + Sync + 'static,
			OUT: Serialize,
			$($x: Deserialize,)+
		> WrapAsync<BASE> for fn(&BASE, Ready<OUT>, $($x,)+ ) {
			fn wrap_rpc(&self, base: &BASE, params: Params, ready: ::jsonrpc_core::Ready) {
				match from_params::<($($x,)+)>(params) {
					Ok(($($x,)+)) => (self)(base, ready.into(), $($x,)+),
					Err(e) => ready.ready(Err(e)),
				}
			}
		}
	}
}

// special impl for no parameters other than block parameter.
impl<B, OUT, T> Wrap<B> for fn(&B, Trailing<T>) -> Result<OUT, Error>
	where B: Send + Sync + 'static, OUT: Serialize, T: Default + Deserialize
{
	fn wrap_rpc(&self, base: &B, params: Params) -> Result<Value, Error> {
		let len = match params {
			Params::Array(ref v) => v.len(),
			Params::None => 0,
			_ => return Err(invalid_params("not an array", "")),
		};

		let (id,) = match len {
			0 => (T::default(),),
			1 => try!(from_params::<(T,)>(params)),
			_ => return Err(Error::invalid_params()),
		};

		(self)(base, Trailing(id)).map(to_value)
	}
}

impl<B, OUT, T> WrapAsync<B> for fn(&B, Ready<OUT>, Trailing<T>)
	where B: Send + Sync + 'static, OUT: Serialize, T: Default + Deserialize
{
	fn wrap_rpc(&self, base: &B, params: Params, ready: ::jsonrpc_core::Ready) {
		let len = match params {
			Params::Array(ref v) => v.len(),
			Params::None => 0,
			_ => return ready.ready(Err(invalid_params("not an array", ""))),
		};

		let id = match len {
			0 => Ok((T::default(),)),
			1 => from_params::<(T,)>(params),
			_ => Err(Error::invalid_params()),
		};

		match id {
			Ok((id,)) => (self)(base, ready.into(), Trailing(id)),
			Err(e) => ready.ready(Err(e)),
		}
	}
}

// similar to `wrap!`, but handles a single default trailing parameter
// accepts an additional argument indicating the number of non-trailing parameters.
macro_rules! wrap_with_trailing {
	($num: expr, $($x: ident),+) => {
		// synchronous implementation
		impl <
			BASE: Send + Sync + 'static,
			OUT: Serialize,
			$($x: Deserialize,)+
			TRAILING: Default + Deserialize,
		> Wrap<BASE> for fn(&BASE, $($x,)+ Trailing<TRAILING>) -> Result<OUT, Error> {
			fn wrap_rpc(&self, base: &BASE, params: Params) -> Result<Value, Error> {
				let len = match params {
					Params::Array(ref v) => v.len(),
					Params::None => 0,
					_ => return Err(invalid_params("not an array", "")),
				};

				let params = match len - $num {
					0 => from_params::<($($x,)+)>(params)
						.map(|($($x,)+)| ($($x,)+ TRAILING::default())),
					1 => from_params::<($($x,)+ TRAILING)>(params)
						.map(|($($x,)+ id)| ($($x,)+ id)),
					_ => Err(Error::invalid_params()),
				};

				let ($($x,)+ id) = try!(params);
				(self)(base, $($x,)+ Trailing(id)).map(to_value)
			}
		}

		// asynchronous implementation
		impl <
			BASE: Send + Sync + 'static,
			OUT: Serialize,
			$($x: Deserialize,)+
			TRAILING: Default + Deserialize,
		> WrapAsync<BASE> for fn(&BASE, Ready<OUT>, $($x,)+ Trailing<TRAILING>) {
			fn wrap_rpc(&self, base: &BASE, params: Params, ready: ::jsonrpc_core::Ready) {
				let len = match params {
					Params::Array(ref v) => v.len(),
					Params::None => 0,
					_ => return ready.ready(Err(invalid_params("not an array", ""))),
				};

				let params = match len - $num {
					0 => from_params::<($($x,)+)>(params)
						.map(|($($x,)+)| ($($x,)+ TRAILING::default())),
					1 => from_params::<($($x,)+ TRAILING)>(params)
						.map(|($($x,)+ id)| ($($x,)+ id)),
					_ => Err(Error::invalid_params()),
				};

				match params {
					Ok(($($x,)+ id)) => (self)(base, ready.into(), $($x,)+ Trailing(id)),
					Err(e) => ready.ready(Err(e))
				}
			}
		}
	}
}

wrap!(A, B, C, D, E);
wrap!(A, B, C, D);
wrap!(A, B, C);
wrap!(A, B);
wrap!(A);

wrap_with_trailing!(5, A, B, C, D, E);
wrap_with_trailing!(4, A, B, C, D);
wrap_with_trailing!(3, A, B, C);
wrap_with_trailing!(2, A, B);
wrap_with_trailing!(1, A);

<|endoftext|>


<commit_before>//! `Source` data description.
use crate::data::RoomName;

with_base_fields_and_update_struct! {
    /// A source object, which creeps can gain energy by mining from.
    #[derive(Clone, Debug, PartialEq)]
    #[serde(rename_all = "camelCase")]
    pub struct Source {
        /// The source's current energy - available to be mined be creeps.
        pub energy: u32,
        /// The source's maximum energy - what `energy` resets to on regeneration.
        pub energy_capacity: u32,
        /// The amount of energy either harvested on this source specifically or for the room since
        /// the last invasion (not sure which it is).
        #[serde(default)]
        pub invader_harvested: u32,
        /// The game time at which the source will next regenerate. `None` when waiting on a creep to
        /// first harvest it.
        pub next_regeneration_time: Option<u64>,
        /// The number of ticks between when a source is first harvested after regeneration and when it next
        /// regenerates.
        pub ticks_to_regeneration: u32,
    }

    /// The update structure for a source object.
    #[derive(Clone, Debug)]
    #[serde(rename_all = "camelCase")]
    pub struct SourceUpdate {
        - energy: u32,
        - energy_capacity: u32,
        - invader_harvested: u32,
        - next_regeneration_time: Option<u64>,
        - ticks_to_regeneration: u32,
    }
}

#[cfg(test)]
mod test {
    use serde::Deserialize;
    use serde_json;

    use crate::data::RoomName;

    use super::Source;

    #[test]
    fn parse_source_and_update() {
        let json = json!({
            "_id": "57ef9dba86f108ae6e60e2fc",
            "energy": 260,
            "energyCapacity": 3000,
            "invaderHarvested": 29240,
            "nextRegenerationTime": 19894026,
            "room": "E4S61",
            "ticksToRegeneration": 300,
            "type": "source",
            "x": 26,
            "y": 9,
        });

        let mut obj = Source::deserialize(&json).unwrap();

        assert_eq!(
            obj,
            Source {
                id: "57ef9dba86f108ae6e60e2fc".to_owned(),
                room: RoomName::new("E4S61").unwrap(),
                x: 26,
                y: 9,
                energy: 260,
                energy_capacity: 3000,
                invader_harvested: 29240,
                next_regeneration_time: Some(19894026),
                ticks_to_regeneration: 300,
            }
        );

        obj.update(
            serde_json::from_value(json!({
                "x": 40,
                "y": 50,
                "energy": 0,
            }))
            .unwrap(),
        );

        assert_eq!(
            obj,
            Source {
                id: "57ef9dba86f108ae6e60e2fc".to_owned(),
                room: RoomName::new("E4S61").unwrap(),
                x: 40,
                y: 50,
                energy: 0,
                energy_capacity: 3000,
                invader_harvested: 29240,
                next_regeneration_time: Some(19894026),
                ticks_to_regeneration: 300,
            }
        );
    }

    #[test]
    fn handle_no_invader_harvested() {
        let json = json!({
            "_id": "5bbcad499099fc012e6370ab",
            "energy": 4000,
            "energyCapacity": 4000,
            "nextRegenerationTime": null,
            "room": "E6S26",
            "ticksToRegeneration": 300,
            "type": "source",
            "x": 40,
            "y": 34,
        });

        let obj = Source::deserialize(&json).unwrap();

        assert_eq!(
            obj,
            Source {
                id: "5bbcad499099fc012e6370ab".to_owned(),
                room: RoomName::new("E6S26").unwrap(),
                x: 40,
                y: 34,
                energy: 4000,
                energy_capacity: 4000,
                invader_harvested: 0,
                next_regeneration_time: None,
                ticks_to_regeneration: 300,
            }
        );
    }
}
<commit_msg>next_regeneration_time should be the same type as game_time<commit_after>//! `Source` data description.
use crate::data::RoomName;

with_base_fields_and_update_struct! {
    /// A source object, which creeps can gain energy by mining from.
    #[derive(Clone, Debug, PartialEq)]
    #[serde(rename_all = "camelCase")]
    pub struct Source {
        /// The source's current energy - available to be mined be creeps.
        pub energy: u32,
        /// The source's maximum energy - what `energy` resets to on regeneration.
        pub energy_capacity: u32,
        /// The amount of energy either harvested on this source specifically or for the room since
        /// the last invasion (not sure which it is).
        #[serde(default)]
        pub invader_harvested: u32,
        /// The game time at which the source will next regenerate. `None` when waiting on a creep to
        /// first harvest it.
        pub next_regeneration_time: Option<u32>,
        /// The number of ticks between when a source is first harvested after regeneration and when it next
        /// regenerates.
        pub ticks_to_regeneration: u32,
    }

    /// The update structure for a source object.
    #[derive(Clone, Debug)]
    #[serde(rename_all = "camelCase")]
    pub struct SourceUpdate {
        - energy: u32,
        - energy_capacity: u32,
        - invader_harvested: u32,
        - next_regeneration_time: Option<u64>,
        - ticks_to_regeneration: u32,
    }
}

#[cfg(test)]
mod test {
    use serde::Deserialize;
    use serde_json;

    use crate::data::RoomName;

    use super::Source;

    #[test]
    fn parse_source_and_update() {
        let json = json!({
            "_id": "57ef9dba86f108ae6e60e2fc",
            "energy": 260,
            "energyCapacity": 3000,
            "invaderHarvested": 29240,
            "nextRegenerationTime": 19894026,
            "room": "E4S61",
            "ticksToRegeneration": 300,
            "type": "source",
            "x": 26,
            "y": 9,
        });

        let mut obj = Source::deserialize(&json).unwrap();

        assert_eq!(
            obj,
            Source {
                id: "57ef9dba86f108ae6e60e2fc".to_owned(),
                room: RoomName::new("E4S61").unwrap(),
                x: 26,
                y: 9,
                energy: 260,
                energy_capacity: 3000,
                invader_harvested: 29240,
                next_regeneration_time: Some(19894026),
                ticks_to_regeneration: 300,
            }
        );

        obj.update(
            serde_json::from_value(json!({
                "x": 40,
                "y": 50,
                "energy": 0,
            }))
            .unwrap(),
        );

        assert_eq!(
            obj,
            Source {
                id: "57ef9dba86f108ae6e60e2fc".to_owned(),
                room: RoomName::new("E4S61").unwrap(),
                x: 40,
                y: 50,
                energy: 0,
                energy_capacity: 3000,
                invader_harvested: 29240,
                next_regeneration_time: Some(19894026),
                ticks_to_regeneration: 300,
            }
        );
    }

    #[test]
    fn handle_no_invader_harvested() {
        let json = json!({
            "_id": "5bbcad499099fc012e6370ab",
            "energy": 4000,
            "energyCapacity": 4000,
            "nextRegenerationTime": null,
            "room": "E6S26",
            "ticksToRegeneration": 300,
            "type": "source",
            "x": 40,
            "y": 34,
        });

        let obj = Source::deserialize(&json).unwrap();

        assert_eq!(
            obj,
            Source {
                id: "5bbcad499099fc012e6370ab".to_owned(),
                room: RoomName::new("E6S26").unwrap(),
                x: 40,
                y: 34,
                energy: 4000,
                energy_capacity: 4000,
                invader_harvested: 0,
                next_regeneration_time: None,
                ticks_to_regeneration: 300,
            }
        );
    }
}
<|endoftext|>


<commit_before>// This module contains helpers functions and types that
// are not test in themselves, but are used by several tests.

#![allow(dead_code)]

pub extern crate wayland_client as wayc;
pub extern crate wayland_server as ways;

use std::ffi::{OsStr, OsString};

pub struct TestServer {
    pub display: self::ways::Display,
    pub event_loop: self::ways::EventLoop,
    pub socket_name: OsString,
}

impl TestServer {
    pub fn new() -> TestServer {
        let (mut display, event_loop) = self::ways::Display::new();
        let socket_name = display
            .add_socket_auto()
            .expect("Failed to create a server socket.");

        TestServer {
            display: display,
            event_loop: event_loop,
            socket_name: socket_name,
        }
    }

    pub fn answer(&mut self) {
        // for some reason, two dispatches are needed
        self.event_loop.dispatch(Some(10)).unwrap();
        self.event_loop.dispatch(Some(10)).unwrap();
        self.display.flush_clients();
    }
}

pub struct TestClient {
    pub display: self::wayc::Display,
    pub event_queue: self::wayc::EventQueue,
}

impl TestClient {
    pub fn new(socket_name: &OsStr) -> TestClient {
        let (display, event_queue) =
            self::wayc::Display::connect_to_name(socket_name).expect("Failed to connect to server.");
        TestClient {
            display: display,
            event_queue: event_queue,
        }
    }
}

pub fn roundtrip(client: &mut TestClient, server: &mut TestServer) {
    // send to the server
    client.display.flush().unwrap();
    // make it answer messages
    server.answer();
    // dispatch all client-side
    client.event_queue.dispatch_pending().unwrap();
    client.event_queue.prepare_read().unwrap().read_events().unwrap();
    client.event_queue.dispatch_pending().unwrap();
}
<commit_msg>tests: do a proper roundtrip<commit_after>// This module contains helpers functions and types that
// are not test in themselves, but are used by several tests.

#![allow(dead_code)]

pub extern crate wayland_client as wayc;
pub extern crate wayland_server as ways;

use std::cell::Cell;
use std::ffi::{OsStr, OsString};
use std::rc::Rc;

pub struct TestServer {
    pub display: self::ways::Display,
    pub event_loop: self::ways::EventLoop,
    pub socket_name: OsString,
}

impl TestServer {
    pub fn new() -> TestServer {
        let (mut display, event_loop) = self::ways::Display::new();
        let socket_name = display
            .add_socket_auto()
            .expect("Failed to create a server socket.");

        TestServer {
            display: display,
            event_loop: event_loop,
            socket_name: socket_name,
        }
    }

    pub fn answer(&mut self) {
        // for some reason, two dispatches are needed
        self.event_loop.dispatch(Some(10)).unwrap();
        self.display.flush_clients();
    }
}

pub struct TestClient {
    pub display: self::wayc::Display,
    pub event_queue: self::wayc::EventQueue,
}

impl TestClient {
    pub fn new(socket_name: &OsStr) -> TestClient {
        let (display, event_queue) =
            self::wayc::Display::connect_to_name(socket_name).expect("Failed to connect to server.");
        TestClient {
            display: display,
            event_queue: event_queue,
        }
    }
}

pub fn roundtrip(client: &mut TestClient, server: &mut TestServer) {
    use self::wayc::protocol::wl_display::RequestsTrait;
    // send to the server
    let done = Rc::new(Cell::new(false));
    let done2 = done.clone();
    let token = client.event_queue.get_token();
    client.display.sync(move |newcb| unsafe { newcb.implement_nonsend(move |_, _| done2.set(true), &token)}).unwrap();
    while !done.get() {
        client.display.flush().unwrap();
        ::std::thread::sleep(::std::time::Duration::from_millis(100));
        // make it answer messages
        server.answer();
        ::std::thread::sleep(::std::time::Duration::from_millis(100));
        // dispatch all client-side
        client.event_queue.dispatch_pending().unwrap();
        client.event_queue.prepare_read().unwrap().read_events().unwrap();
        client.event_queue.dispatch_pending().unwrap();
    }
}
<|endoftext|>


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

//! Servo's compiler plugin/macro crate
//!
//! Attributes this crate provides:
//!
//!  - `#[derive(DenyPublicFields)]` : Forces all fields in a struct/enum to be private
//!  - `#[derive(JSTraceable)]` : Auto-derives an implementation of `JSTraceable` for a struct in the script crate
//!  - `#[must_root]` : Prevents data of the marked type from being used on the stack.
//!                     See the lints module for more details
//!  - `#[dom_struct]` : Implies #[derive(JSTraceable, DenyPublicFields)]`, and `#[must_root]`.
//!                       Use this for structs that correspond to a DOM type

#![deny(unsafe_code)]
#![feature(plugin)]
#![feature(plugin_registrar)]
#![feature(rustc_private)]

#[macro_use]
extern crate rustc;
extern crate rustc_plugin;
extern crate syntax;

use rustc_plugin::Registry;
use syntax::feature_gate::AttributeType::Whitelisted;

mod unrooted_must_root;
/// Utilities for writing plugins
mod utils;

#[plugin_registrar]
pub fn plugin_registrar(reg: &mut Registry) {
    reg.register_late_lint_pass(Box::new(unrooted_must_root::UnrootedPass::new()));
    reg.register_attribute("allow_unrooted_interior".to_string(), Whitelisted);
    reg.register_attribute("must_root".to_string(), Whitelisted);
}
<commit_msg>Auto merge of #19083 - servo:vis, r=SimonSapin<commit_after>/* This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */

//! Servo's compiler plugin/macro crate
//!
//! Attributes this crate provides:
//!
//!  - `#[derive(DenyPublicFields)]` : Forces all fields in a struct/enum to be private
//!  - `#[derive(JSTraceable)]` : Auto-derives an implementation of `JSTraceable` for a struct in the script crate
//!  - `#[must_root]` : Prevents data of the marked type from being used on the stack.
//!                     See the lints module for more details
//!  - `#[dom_struct]` : Implies #[derive(JSTraceable, DenyPublicFields)]`, and `#[must_root]`.
//!                       Use this for structs that correspond to a DOM type

#![deny(unsafe_code)]
#![feature(macro_vis_matcher)]
#![feature(plugin)]
#![feature(plugin_registrar)]
#![feature(rustc_private)]

#[macro_use]
extern crate rustc;
extern crate rustc_plugin;
extern crate syntax;

use rustc_plugin::Registry;
use syntax::feature_gate::AttributeType::Whitelisted;

mod unrooted_must_root;
/// Utilities for writing plugins
mod utils;

#[plugin_registrar]
pub fn plugin_registrar(reg: &mut Registry) {
    reg.register_late_lint_pass(Box::new(unrooted_must_root::UnrootedPass::new()));
    reg.register_attribute("allow_unrooted_interior".to_string(), Whitelisted);
    reg.register_attribute("must_root".to_string(), Whitelisted);
}
<|endoftext|>