<commit_before>// Copyright 2012 The Rust Project Developers.
// Copyright 2015 Guillaume Gomez
//
// 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.

//! Library to interface with chunks of memory allocated in C.
//!
//! It is often desirable to safely interface with memory allocated from C,
//! encapsulating the unsafety into allocation and destruction time.  Indeed,
//! allocating memory externally is currently the only way to give Rust shared
//! mut state with C programs that keep their own references; vectors are
//! unsuitable because they could be reallocated or moved at any time, and
//! importing C memory into a vector takes a one-time snapshot of the memory.
//!
//! This module simplifies the usage of such external blocks of memory.  Memory
//! is encapsulated into an opaque object after creation; the lifecycle of the
//! memory can be optionally managed by Rust, if an appropriate destructor
//! closure is provided.  Safety is ensured by bounds-checking accesses, which
//! are marshalled through get and set functions.
//!
//! There are three unsafe functions: the two constructors, and the
//! unwrapping method. The constructors are unsafe for the
//! obvious reason (they act on a pointer that cannot be checked inside the
//! method), but `into_inner()` is somewhat more subtle in its unsafety.
//! It returns the contained pointer, but at the same time destroys the CVec
//! without running its destructor. This can be used to pass memory back to
//! C, but care must be taken that the ownership of underlying resources are
//! handled correctly, i.e. that allocated memory is eventually freed
//! if necessary.

#![feature(unsafe_destructor, std_misc, unique, convert)]
#![cfg_attr(test, feature(alloc))]

use std::ptr;
use std::slice;
use std::ptr::Unique;
use std::thunk::Invoke;
use std::ops::{Index, IndexMut};

/// The type representing a foreign chunk of memory
pub struct CVec<T> {
    base: Unique<T>,
    len: usize,
    dtor: Option<Box<Invoke<*mut T> + 'static>>
}

#[unsafe_destructor]
impl<T> Drop for CVec<T> {
    fn drop(&mut self) {
        match self.dtor.take() {
            None => (),
            Some(f) => f.invoke(*self.base),
        }
    }
}

impl<T> CVec<T> {
    /// Create a `CVec` from a raw pointer to a buffer with a given length.
    ///
    /// Panics if the given pointer is null. The returned vector will not attempt
    /// to deallocate the vector when dropped.
    ///
    /// # Arguments
    ///
    /// * base - A unique pointer to a buffer
    /// * len - The number of elements in the buffer
    pub unsafe fn new(base: Unique<T>, len: usize) -> CVec<T> {
        assert!(*base != ptr::null_mut());
        CVec {
            base: base,
            len: len,
            dtor: None,
        }
    }

    /// Create a `CVec` from a foreign buffer, with a given length,
    /// and a function to run upon destruction.
    ///
    /// Panics if the given pointer is null.
    ///
    /// # Arguments
    ///
    /// * base - A unique pointer to a buffer
    /// * len - The number of elements in the buffer
    /// * dtor - A fn to run when the value is destructed, useful
    ///          for freeing the buffer, etc. `base` will be passed
    ///          to it as an argument.
    pub unsafe fn new_with_dtor<F>(base: Unique<T>,
                                   len: usize,
                                   dtor: F)
                                   -> CVec<T>
        where F : FnOnce(*mut T) + 'static
    {
        assert!(*base != ptr::null_mut());
        let dtor = Box::new(dtor);
        CVec {
            base: base,
            len: len,
            dtor: Some(dtor)
        }
    }

    /// Retrieves an element at a given index, returning `None` if the requested
    /// index is greater than the length of the vector.
    pub fn get<'a>(&'a self, ofs: usize) -> Option<&'a T> {
        if ofs < self.len {
            Some(unsafe { &*self.base.offset(ofs as isize) })
        } else {
            None
        }
    }

    /// Retrieves a mutable element at a given index, returning `None` if the
    /// requested index is greater than the length of the vector.
    pub fn get_mut<'a>(&'a mut self, ofs: usize) -> Option<&'a mut T> {
        if ofs < self.len {
            Some(unsafe { &mut *self.base.offset(ofs as isize) })
        } else {
            None
        }
    }

    /// Unwrap the pointer without running the destructor
    ///
    /// This method retrieves the underlying pointer, and in the process
    /// destroys the CVec but without running the destructor. A use case
    /// would be transferring ownership of the buffer to a C function, as
    /// in this case you would not want to run the destructor.
    ///
    /// Note that if you want to access the underlying pointer without
    /// cancelling the destructor, you can simply call `transmute` on the return
    /// value of `get(0)`.
    pub unsafe fn into_inner(mut self) -> *mut T {
        self.dtor = None;
        *self.base
    }

    /// Returns the number of items in this vector.
    pub fn len(&self) -> usize { self.len }

    /// Returns whether this vector is empty.
    pub fn is_empty(&self) -> bool { self.len() == 0 }

    /// Convert to CSlice
    pub fn as_cslice(&self) -> CSlice<T> {
        CSlice {
            base: *self.base,
            len: self.len
        }
    }
}

impl<T> AsRef<[T]> for CVec<T> {
    /// View the stored data as a slice.
    fn as_ref(&self) -> &[T] {
        unsafe {
            slice::from_raw_parts(*self.base as *const T, self.len)
        }
    }
}

impl<T> AsMut<[T]> for CVec<T> {
    /// View the stored data as a slice.
    fn as_mut(&mut self) -> &mut [T] {
        unsafe {
            slice::from_raw_parts_mut(*self.base, self.len)
        }
    }
}

/// The type representing an 'unsafe' foreign chunk of memory
pub struct CSlice<T> {
    base: *mut T,
    len: usize
}

impl<T> CSlice<T> {
    /// Create a `CSlice` from a raw pointer to a buffer with a given length.
    ///
    /// Panics if the given pointer is null. The returned vector will not attempt
    /// to deallocate the vector when dropped.
    ///
    /// # Arguments
    ///
    /// * base - A raw pointer to a buffer
    /// * len - The number of elements in the buffer
    pub unsafe fn new(base: *mut T, len: usize) -> CSlice<T> {
        assert!(base != ptr::null_mut());
        CSlice {
            base: base,
            len: len
        }
    }

    /// Retrieves an element at a given index, returning `None` if the requested
    /// index is greater than the length of the vector.
    pub fn get<'a>(&'a self, ofs: usize) -> Option<&'a T> {
        if ofs < self.len {
            Some(unsafe { &*self.base.offset(ofs as isize) })
        } else {
            None
        }
    }

    /// Retrieves a mutable element at a given index, returning `None` if the
    /// requested index is greater than the length of the vector.
    pub fn get_mut<'a>(&'a mut self, ofs: usize) -> Option<&'a mut T> {
        if ofs < self.len {
            Some(unsafe { &mut *self.base.offset(ofs as isize) })
        } else {
            None
        }
    }

    /// Returns the number of items in this vector.
    pub fn len(&self) -> usize { self.len }

    /// Returns whether this vector is empty.
    pub fn is_empty(&self) -> bool { self.len() == 0 }
}

impl<T> AsRef<[T]> for CSlice<T> {
    /// View the stored data as a slice.
    fn as_ref(&self) -> &[T] {
        unsafe {
            slice::from_raw_parts(self.base as *const T, self.len)
        }
    }
}

impl<T> AsMut<[T]> for CSlice<T> {
    /// View the stored data as a slice.
    fn as_mut(&mut self) -> &mut [T] {
        unsafe {
            slice::from_raw_parts_mut(self.base, self.len)
        }
    }
}

impl<T> Index<usize> for CSlice<T> {
    type Output = T;

    fn index<'a>(&'a self, _index: usize) -> &'a T {
        assert!(_index < self.len);
        unsafe { &*self.base.offset(_index as isize) }
    }
}

impl<T> IndexMut<usize> for CSlice<T> {
    fn index_mut<'a>(&'a mut self, _index: usize) -> &'a mut T {
        assert!(_index < self.len);
        unsafe { &mut *self.base.offset(_index as isize) }
    }
}

#[cfg(test)]
mod tests {
    extern crate alloc;
    extern crate libc;

    use super::{CVec, CSlice};
    use std::ptr::{self, Unique};

    // allocation of CVec
    fn v_malloc(n: usize) -> CVec<u8> {
        unsafe {
            let mem: Unique<u8> = Unique::new(
                libc::malloc(n as libc::size_t) as *mut _);
            if (*mem).is_null() { alloc::oom() }

            CVec::new_with_dtor(mem, n,
                                |mem| { libc::free((mem) as *mut _); })
        }
    }

    // allocation of CSlice
    fn s_malloc(n: usize) -> CSlice<u8> {
        unsafe {
            let mem: *mut u8 = libc::malloc(n as libc::size_t) as *mut _;
            if mem.is_null() { alloc::oom() }

            CSlice::new(mem, n)
        }
    }

    #[test]
    fn vec_test_basic() {
        let mut cv = v_malloc(16);

        *cv.get_mut(3).unwrap() = 8;
        *cv.get_mut(4).unwrap() = 9;
        assert_eq!(*cv.get(3).unwrap(), 8);
        assert_eq!(*cv.get(4).unwrap(), 9);
        assert_eq!(cv.len(), 16);
    }

    #[test]
    fn slice_test_basic() {
        let mut cs = s_malloc(16);

        cs[3] = 8;
        cs[4] = 9;
        assert_eq!(cs[3], 8);
        assert_eq!(cs[4], 9);
        assert_eq!(cs.len(), 16);
    }

    #[test]
    #[should_panic]
    fn vec_test_panic_at_null() {
        unsafe {
            CVec::new(Unique::new(ptr::null_mut::<u8>()), 9);
        }
    }

    #[test]
    #[should_panic]
    fn slice_test_panic_at_null() {
        unsafe {
            CSlice::new(ptr::null_mut::<u8>(), 9);
        }
    }

    #[test]
    fn vec_test_overrun_get() {
        let cv = v_malloc(16);

        assert!(cv.get(17).is_none());
    }

    #[test]
    #[should_panic]
    fn slice_test_overrun_get() {
        let cs = s_malloc(16);

        assert!(cs[17] == 18);
    }

    #[test]
    fn vec_test_overrun_set() {
        let mut cv = v_malloc(16);

        assert!(cv.get_mut(17).is_none());
    }

    #[test]
    fn vec_test_unwrap() {
        unsafe {
            let cv = CVec::new_with_dtor(Unique::new(1 as *mut isize),
                                         0,
                                         |_| panic!("Don't run this destructor!"));
            let p = cv.into_inner();
            assert_eq!(p, 1 as *mut isize);
        }
    }

    #[test]
    fn vec_to_slice_test() {
        let mut cv = v_malloc(2);

        *cv.get_mut(0).unwrap() = 10;
        *cv.get_mut(1).unwrap() = 12;
        let cs = cv.as_cslice();

        assert_eq!(cs[0], 10);
        assert_eq!(cs[1], 12);
    }

    #[test]
    fn slice_to_vec_test() {
        let cv = v_malloc(2);
        let mut cs = cv.as_cslice();

        cs[0] = 13;
        cs[1] = 26;
        assert_eq!(*cv.get(0).unwrap(), 13);
        assert_eq!(*cv.get(1).unwrap(), 26);
    }
}
<commit_msg>Replace Invoke with FnBox<commit_after>// Copyright 2012 The Rust Project Developers.
// Copyright 2015 Guillaume Gomez
//
// 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.

//! Library to interface with chunks of memory allocated in C.
//!
//! It is often desirable to safely interface with memory allocated from C,
//! encapsulating the unsafety into allocation and destruction time.  Indeed,
//! allocating memory externally is currently the only way to give Rust shared
//! mut state with C programs that keep their own references; vectors are
//! unsuitable because they could be reallocated or moved at any time, and
//! importing C memory into a vector takes a one-time snapshot of the memory.
//!
//! This module simplifies the usage of such external blocks of memory.  Memory
//! is encapsulated into an opaque object after creation; the lifecycle of the
//! memory can be optionally managed by Rust, if an appropriate destructor
//! closure is provided.  Safety is ensured by bounds-checking accesses, which
//! are marshalled through get and set functions.
//!
//! There are three unsafe functions: the two constructors, and the
//! unwrapping method. The constructors are unsafe for the
//! obvious reason (they act on a pointer that cannot be checked inside the
//! method), but `into_inner()` is somewhat more subtle in its unsafety.
//! It returns the contained pointer, but at the same time destroys the CVec
//! without running its destructor. This can be used to pass memory back to
//! C, but care must be taken that the ownership of underlying resources are
//! handled correctly, i.e. that allocated memory is eventually freed
//! if necessary.

#![feature(unsafe_destructor, unique, core)]
#![cfg_attr(test, feature(alloc))]

use std::boxed::FnBox;
use std::ptr;
use std::slice;
use std::ptr::Unique;
use std::ops::{Index, IndexMut};

/// The type representing a foreign chunk of memory
pub struct CVec<T> {
    base: Unique<T>,
    len: usize,
    dtor: Option<Box<FnBox(*mut T)>>
}

#[unsafe_destructor]
impl<T> Drop for CVec<T> {
    fn drop(&mut self) {
        match self.dtor.take() {
            None => (),
            Some(f) => f(*self.base),
        }
    }
}

impl<T> CVec<T> {
    /// Create a `CVec` from a raw pointer to a buffer with a given length.
    ///
    /// Panics if the given pointer is null. The returned vector will not attempt
    /// to deallocate the vector when dropped.
    ///
    /// # Arguments
    ///
    /// * base - A unique pointer to a buffer
    /// * len - The number of elements in the buffer
    pub unsafe fn new(base: Unique<T>, len: usize) -> CVec<T> {
        assert!(*base != ptr::null_mut());
        CVec {
            base: base,
            len: len,
            dtor: None,
        }
    }

    /// Create a `CVec` from a foreign buffer, with a given length,
    /// and a function to run upon destruction.
    ///
    /// Panics if the given pointer is null.
    ///
    /// # Arguments
    ///
    /// * base - A unique pointer to a buffer
    /// * len - The number of elements in the buffer
    /// * dtor - A fn to run when the value is destructed, useful
    ///          for freeing the buffer, etc. `base` will be passed
    ///          to it as an argument.
    pub unsafe fn new_with_dtor<F>(base: Unique<T>,
                                   len: usize,
                                   dtor: F)
                                   -> CVec<T>
        where F: FnBox(*mut T) + 'static
    {
        assert!(*base != ptr::null_mut());
        let dtor = Box::new(dtor);
        CVec {
            base: base,
            len: len,
            dtor: Some(dtor)
        }
    }

    /// Retrieves an element at a given index, returning `None` if the requested
    /// index is greater than the length of the vector.
    pub fn get<'a>(&'a self, ofs: usize) -> Option<&'a T> {
        if ofs < self.len {
            Some(unsafe { &*self.base.offset(ofs as isize) })
        } else {
            None
        }
    }

    /// Retrieves a mutable element at a given index, returning `None` if the
    /// requested index is greater than the length of the vector.
    pub fn get_mut<'a>(&'a mut self, ofs: usize) -> Option<&'a mut T> {
        if ofs < self.len {
            Some(unsafe { &mut *self.base.offset(ofs as isize) })
        } else {
            None
        }
    }

    /// Unwrap the pointer without running the destructor
    ///
    /// This method retrieves the underlying pointer, and in the process
    /// destroys the CVec but without running the destructor. A use case
    /// would be transferring ownership of the buffer to a C function, as
    /// in this case you would not want to run the destructor.
    ///
    /// Note that if you want to access the underlying pointer without
    /// cancelling the destructor, you can simply call `transmute` on the return
    /// value of `get(0)`.
    pub unsafe fn into_inner(mut self) -> *mut T {
        self.dtor = None;
        *self.base
    }

    /// Returns the number of items in this vector.
    pub fn len(&self) -> usize { self.len }

    /// Returns whether this vector is empty.
    pub fn is_empty(&self) -> bool { self.len() == 0 }

    /// Convert to CSlice
    pub fn as_cslice(&self) -> CSlice<T> {
        CSlice {
            base: *self.base,
            len: self.len
        }
    }
}

impl<T> AsRef<[T]> for CVec<T> {
    /// View the stored data as a slice.
    fn as_ref(&self) -> &[T] {
        unsafe {
            slice::from_raw_parts(*self.base as *const T, self.len)
        }
    }
}

impl<T> AsMut<[T]> for CVec<T> {
    /// View the stored data as a slice.
    fn as_mut(&mut self) -> &mut [T] {
        unsafe {
            slice::from_raw_parts_mut(*self.base, self.len)
        }
    }
}

/// The type representing an 'unsafe' foreign chunk of memory
pub struct CSlice<T> {
    base: *mut T,
    len: usize
}

impl<T> CSlice<T> {
    /// Create a `CSlice` from a raw pointer to a buffer with a given length.
    ///
    /// Panics if the given pointer is null. The returned vector will not attempt
    /// to deallocate the vector when dropped.
    ///
    /// # Arguments
    ///
    /// * base - A raw pointer to a buffer
    /// * len - The number of elements in the buffer
    pub unsafe fn new(base: *mut T, len: usize) -> CSlice<T> {
        assert!(base != ptr::null_mut());
        CSlice {
            base: base,
            len: len
        }
    }

    /// Retrieves an element at a given index, returning `None` if the requested
    /// index is greater than the length of the vector.
    pub fn get<'a>(&'a self, ofs: usize) -> Option<&'a T> {
        if ofs < self.len {
            Some(unsafe { &*self.base.offset(ofs as isize) })
        } else {
            None
        }
    }

    /// Retrieves a mutable element at a given index, returning `None` if the
    /// requested index is greater than the length of the vector.
    pub fn get_mut<'a>(&'a mut self, ofs: usize) -> Option<&'a mut T> {
        if ofs < self.len {
            Some(unsafe { &mut *self.base.offset(ofs as isize) })
        } else {
            None
        }
    }

    /// Returns the number of items in this vector.
    pub fn len(&self) -> usize { self.len }

    /// Returns whether this vector is empty.
    pub fn is_empty(&self) -> bool { self.len() == 0 }
}

impl<T> AsRef<[T]> for CSlice<T> {
    /// View the stored data as a slice.
    fn as_ref(&self) -> &[T] {
        unsafe {
            slice::from_raw_parts(self.base as *const T, self.len)
        }
    }
}

impl<T> AsMut<[T]> for CSlice<T> {
    /// View the stored data as a slice.
    fn as_mut(&mut self) -> &mut [T] {
        unsafe {
            slice::from_raw_parts_mut(self.base, self.len)
        }
    }
}

impl<T> Index<usize> for CSlice<T> {
    type Output = T;

    fn index<'a>(&'a self, _index: usize) -> &'a T {
        assert!(_index < self.len);
        unsafe { &*self.base.offset(_index as isize) }
    }
}

impl<T> IndexMut<usize> for CSlice<T> {
    fn index_mut<'a>(&'a mut self, _index: usize) -> &'a mut T {
        assert!(_index < self.len);
        unsafe { &mut *self.base.offset(_index as isize) }
    }
}

#[cfg(test)]
mod tests {
    extern crate alloc;
    extern crate libc;

    use super::{CVec, CSlice};
    use std::ptr::{self, Unique};

    // allocation of CVec
    fn v_malloc(n: usize) -> CVec<u8> {
        unsafe {
            let mem: Unique<u8> = Unique::new(
                libc::malloc(n as libc::size_t) as *mut _);
            if (*mem).is_null() { alloc::oom() }

            CVec::new_with_dtor(mem, n,
                                |mem| { libc::free((mem) as *mut _); })
        }
    }

    // allocation of CSlice
    fn s_malloc(n: usize) -> CSlice<u8> {
        unsafe {
            let mem: *mut u8 = libc::malloc(n as libc::size_t) as *mut _;
            if mem.is_null() { alloc::oom() }

            CSlice::new(mem, n)
        }
    }

    #[test]
    fn vec_test_basic() {
        let mut cv = v_malloc(16);

        *cv.get_mut(3).unwrap() = 8;
        *cv.get_mut(4).unwrap() = 9;
        assert_eq!(*cv.get(3).unwrap(), 8);
        assert_eq!(*cv.get(4).unwrap(), 9);
        assert_eq!(cv.len(), 16);
    }

    #[test]
    fn slice_test_basic() {
        let mut cs = s_malloc(16);

        cs[3] = 8;
        cs[4] = 9;
        assert_eq!(cs[3], 8);
        assert_eq!(cs[4], 9);
        assert_eq!(cs.len(), 16);
    }

    #[test]
    #[should_panic]
    fn vec_test_panic_at_null() {
        unsafe {
            CVec::new(Unique::new(ptr::null_mut::<u8>()), 9);
        }
    }

    #[test]
    #[should_panic]
    fn slice_test_panic_at_null() {
        unsafe {
            CSlice::new(ptr::null_mut::<u8>(), 9);
        }
    }

    #[test]
    fn vec_test_overrun_get() {
        let cv = v_malloc(16);

        assert!(cv.get(17).is_none());
    }

    #[test]
    #[should_panic]
    fn slice_test_overrun_get() {
        let cs = s_malloc(16);

        assert!(cs[17] == 18);
    }

    #[test]
    fn vec_test_overrun_set() {
        let mut cv = v_malloc(16);

        assert!(cv.get_mut(17).is_none());
    }

    #[test]
    fn vec_test_unwrap() {
        unsafe {
            let cv = CVec::new_with_dtor(Unique::new(1 as *mut isize),
                                         0,
                                         |_| panic!("Don't run this destructor!"));
            let p = cv.into_inner();
            assert_eq!(p, 1 as *mut isize);
        }
    }

    #[test]
    fn vec_to_slice_test() {
        let mut cv = v_malloc(2);

        *cv.get_mut(0).unwrap() = 10;
        *cv.get_mut(1).unwrap() = 12;
        let cs = cv.as_cslice();

        assert_eq!(cs[0], 10);
        assert_eq!(cs[1], 12);
    }

    #[test]
    fn slice_to_vec_test() {
        let cv = v_malloc(2);
        let mut cs = cv.as_cslice();

        cs[0] = 13;
        cs[1] = 26;
        assert_eq!(*cv.get(0).unwrap(), 13);
        assert_eq!(*cv.get(1).unwrap(), 26);
    }
}
<|endoftext|>


<commit_before>extern crate rand;
use ::std::str;
use self::rand::Rng;

#[derive(Debug, Ord, PartialOrd, Eq, PartialEq, Copy, Clone)]
pub enum Suit { Clubs, Diamonds, Hearts, Spades, Stars }

#[derive(Debug, Eq, PartialEq, PartialOrd)]
pub struct Card<'a> {
    suit: Suit,
    value: &'a str,
}

impl<'a> Card<'a> {
    pub fn new(suit: Suit, value: &'a str) -> Card {
        Card { suit: suit, value: value }
    }
}

impl<'a> Ord for Card<'a> {
    fn cmp(&self, other: &Self) -> ::std::cmp::Ordering {
        self.value.cmp(&other.value)
    }
}

pub fn make_standard_deck<'a>() -> Vec<Card<'a>> {
    let mut result = Vec::new();
    let suits  = &[Suit::Clubs, Suit::Diamonds, Suit::Hearts, Suit::Spades];
    let values = &["2", "3", "4", "5", "6", "7", "8", "9", "10",
                   "Jack", "Queen", "King", "Ace"];

    for suit in suits {
        for value in values {
            result.push(Card::new(*suit, value));
        }
    }
    return result;
}

pub fn make_fifth_dimension_deck<'a>() -> Vec<Card<'a>> {
    let mut result = Vec::new();
    let suits  = &[Suit::Clubs, Suit::Diamonds, Suit::Hearts, Suit::Spades, Suit::Stars];
    let values = &["1", "2", "3", "4", "5", "6", "7", "8", "9", "10",
                   "Jack", "Princess", "Queen", "King", "Joker"];

    for suit in suits {
        for value in values {
            result.push(Card::new(*suit, value));
        }
    }
    return result;
}

pub fn shuffle(deck: &mut Vec<Card>) {
    rand::thread_rng().shuffle(deck);
}
<commit_msg>Change to use String instead of str and enum<commit_after>extern crate rand;
use ::std::str;
use self::rand::Rng;

#[derive(Debug, Eq, PartialEq, PartialOrd)]
pub struct Card {
    suit:  String,
    value: String,
}

impl Card {
    pub fn new(suit: String, value: String) -> Card {
        Card { suit: suit, value: value.to_string() }
    }

    pub fn new_from_str(suit: &str, value: &str) -> Card {
        Card::new(suit.to_string(), value.to_string())
    }
}

impl Ord for Card {
    fn cmp(&self, other: &Self) -> ::std::cmp::Ordering {
        self.value.cmp(&other.value)
    }
}

pub fn make_standard_deck() -> Vec<Card> {
    let mut result = Vec::new();
    let suits  = &["♣", "♦", "♥", "♠"];
    let values = &["2", "3", "4", "5", "6", "7", "8", "9", "10",
                   "Jack", "Queen", "King", "Ace"];

    for suit in suits {
        for value in values {
            result.push(Card::new_from_str(*suit, value));
        }
    }
    return result;
}

pub fn make_fifth_dimension_deck<'a>() -> Vec<Card> {
    let mut result = Vec::new();
    let suits  = &["♣", "♦", "♥", "♠", "★"];
    let values = &["1", "2", "3", "4", "5", "6", "7", "8", "9", "10",
                   "Jack", "Princess", "Queen", "King", "Joker"];

    for suit in suits {
        for value in values {
            result.push(Card::new_from_str(*suit, value));
        }
    }
    return result;
}

pub fn shuffle(deck: &mut Vec<Card>) {
    rand::thread_rng().shuffle(deck);
}
<|endoftext|>


<commit_before>use collections::string::String;

use vec4;
use num::Num;
use regex::Regex;

#[inline(always)]
fn to_256_str<T: Num>(value: T) -> String {
    (value * T::from_usize(255usize)).round().to_string()
}

#[inline(always)]
pub fn to_rgb<T: Num>(out: [T; 4]) -> String {
    concat_string!("rgb(", &to_256_str(out[0]), ", ", &to_256_str(out[1]), ", ", &to_256_str(out[2]), ")")
}
#[test]
fn test_to_rgb() {
    assert_eq!(&to_rgb([1.0, 0.5, 0.0, 1.0]), "rgb(255, 128, 0)")
}

#[inline(always)]
pub fn to_rgba<T: Num>(out: [T; 4]) -> String {
    concat_string!("rgba(", &to_256_str(out[0]), ", ", &to_256_str(out[1]), ", ", &to_256_str(out[2]), ", ", &(out[3].to_string()), ")")
}
#[test]
fn test_to_rgba() {
    assert_eq!(&to_rgba([1.0, 0.5, 0.0, 1.0]), "rgba(255, 128, 0, 1)")
}

#[inline(always)]
fn to_number<T: Num>(value: &str) -> T {
    T::from_f64(value.parse::<f64>().unwrap())
}

#[inline(always)]
fn to_256<T: Num>(value: &str) -> T {
    to_number::<T>(value).min(T::from_usize(255usize)) / T::from_usize(255usize)
}

#[inline(always)]
pub fn from_rgba<T: Num>(out: &mut [T; 4], string: String) -> &mut [T; 4] {
    let re = Regex::new(r"^rgba\((?:\s+)?(\d+),(?:\s+)?(\d+),(?:\s+)?(\d+),(?:\s+)?((?:\.)?\d+(?:\.\d+)?)\)$").unwrap();

    match re.captures(&string) {
        Some(matches) => {
            out[0] = to_256(matches.get(1).unwrap().as_str());
            out[1] = to_256(matches.get(2).unwrap().as_str());
            out[2] = to_256(matches.get(3).unwrap().as_str());
            out[3] = to_number::<T>(
                matches.get(4).unwrap().as_str()
            ).min(T::from_usize(1usize));
        },
        None => {
            vec4::set(out, T::zero(), T::zero(), T::zero(), T::one());
        },
    }
    out
}
#[test]
fn test_from_rgba() {
    let mut v = [0.0, 0.0, 0.0, 1.0];

    from_rgba(&mut v, String::from("rgba( 255, 128, 0, 1)"));
    assert_eq!(v, [1.0, 128.0 / 255.0, 0.0, 1.0]);

    from_rgba(&mut v, String::from("rgba(0, 0, 0, 1)"));
    assert_eq!(v, [0.0, 0.0, 0.0, 1.0]);
}

#[inline(always)]
pub fn from_rgb<T: Num>(out: &mut [T; 4], string: String) -> &mut [T; 4] {
    let re = Regex::new(r"^rgb\((?:\s+)?(\d+),(?:\s+)?(\d+),(?:\s+)?(\d+)\)$").unwrap();

    match re.captures(&string) {
        Some(matches) => {
            out[0] = to_256(matches.get(1).unwrap().as_str());
            out[1] = to_256(matches.get(2).unwrap().as_str());
            out[2] = to_256(matches.get(3).unwrap().as_str());
            out[3] = T::one();
        },
        None => {
            vec4::set(out, T::zero(), T::zero(), T::zero(), T::one());
        },
    }

    out
}
#[test]
fn test_from_rgb() {
    let mut v = [0.0, 0.0, 0.0, 1.0];

    from_rgb(&mut v, String::from("rgb( 255, 128, 0)"));
    assert_eq!(v, [1.0, 128.0 / 255.0, 0.0, 1.0]);

    from_rgb(&mut v, String::from("rgb(0, 0, 0)"));
    assert_eq!(v, [0.0, 0.0, 0.0, 1.0]);
}
<commit_msg>clean up<commit_after>use collections::string::String;

use vec4;
use num::Num;
use regex::Regex;

#[inline]
fn to_256_str<T: Copy + Num>(value: T) -> String {
    (value * T::from_usize(255usize)).round().to_string()
}

#[inline]
pub fn to_rgb<T: Copy + Num>(out: [T; 4]) -> String {
    concat_string!("rgb(", &to_256_str(out[0]), ", ", &to_256_str(out[1]), ", ", &to_256_str(out[2]), ")")
}
#[test]
fn test_to_rgb() {
    assert_eq!(&to_rgb([1.0, 0.5, 0.0, 1.0]), "rgb(255, 128, 0)")
}

#[inline]
pub fn to_rgba<T: Copy + Num>(out: [T; 4]) -> String {
    concat_string!("rgba(", &to_256_str(out[0]), ", ", &to_256_str(out[1]), ", ", &to_256_str(out[2]), ", ", &(out[3].to_string()), ")")
}
#[test]
fn test_to_rgba() {
    assert_eq!(&to_rgba([1.0, 0.5, 0.0, 1.0]), "rgba(255, 128, 0, 1)")
}

#[inline]
fn to_number<T: Copy + Num>(value: &str) -> T {
    T::from_f64(value.parse::<f64>().unwrap())
}

#[inline]
fn to_256<T: Copy + Num>(value: &str) -> T {
    to_number::<T>(value).min(&T::from_usize(255usize)) / T::from_usize(255usize)
}

#[inline]
pub fn from_rgba<T: Copy + Num>(out: &mut [T; 4], string: String) -> &mut [T; 4] {
    let re = Regex::new(r"^rgba\((?:\s+)?(\d+),(?:\s+)?(\d+),(?:\s+)?(\d+),(?:\s+)?((?:\.)?\d+(?:\.\d+)?)\)$").unwrap();

    match re.captures(&string) {
        Some(matches) => {
            out[0] = to_256(matches.get(1).unwrap().as_str());
            out[1] = to_256(matches.get(2).unwrap().as_str());
            out[2] = to_256(matches.get(3).unwrap().as_str());
            out[3] = to_number::<T>(
                matches.get(4).unwrap().as_str()
            ).min(&T::from_usize(1usize));
        },
        None => {
            vec4::set(out, T::zero(), T::zero(), T::zero(), T::one());
        },
    }
    out
}
#[test]
fn test_from_rgba() {
    let mut v = [0.0, 0.0, 0.0, 1.0];

    from_rgba(&mut v, String::from("rgba( 255, 128, 0, 1)"));
    assert_eq!(v, [1.0, 128.0 / 255.0, 0.0, 1.0]);

    from_rgba(&mut v, String::from("rgba(0, 0, 0, 1)"));
    assert_eq!(v, [0.0, 0.0, 0.0, 1.0]);
}

#[inline]
pub fn from_rgb<T: Copy + Num>(out: &mut [T; 4], string: String) -> &mut [T; 4] {
    let re = Regex::new(r"^rgb\((?:\s+)?(\d+),(?:\s+)?(\d+),(?:\s+)?(\d+)\)$").unwrap();

    match re.captures(&string) {
        Some(matches) => {
            out[0] = to_256(matches.get(1).unwrap().as_str());
            out[1] = to_256(matches.get(2).unwrap().as_str());
            out[2] = to_256(matches.get(3).unwrap().as_str());
            out[3] = T::one();
        },
        None => {
            vec4::set(out, T::zero(), T::zero(), T::zero(), T::one());
        },
    }

    out
}
#[test]
fn test_from_rgb() {
    let mut v = [0.0, 0.0, 0.0, 1.0];

    from_rgb(&mut v, String::from("rgb( 255, 128, 0)"));
    assert_eq!(v, [1.0, 128.0 / 255.0, 0.0, 1.0]);

    from_rgb(&mut v, String::from("rgb(0, 0, 0)"));
    assert_eq!(v, [0.0, 0.0, 0.0, 1.0]);
}
<|endoftext|>


<commit_before>use actix_web::{self, AsyncResponder, FromRequest, HttpMessage, HttpRequest, HttpResponse, Query};
use failure;
use futures::{Future, IntoFuture};
use serde::de::DeserializeOwned;
use serde::Serialize;

use context::{ApiContext, ApiContextMut};
use {Endpoint, EndpointKind, EndpointMut};

pub type WebRequestHandler =
    Fn(HttpRequest<ApiContextMut>) -> Box<Future<Item = HttpResponse, Error = actix_web::Error>>;

pub struct EndpointHandler {
    pub name: &'static str,
    pub method: actix_web::http::Method,
    pub handler: Box<WebRequestHandler>,
}

pub struct ServiceApiWebBackend {
    endpoints: Vec<EndpointHandler>,
}

impl ServiceApiWebBackend {
    pub fn new() -> ServiceApiWebBackend {
        ServiceApiWebBackend {
            endpoints: Vec::new(),
        }
    }

    pub fn endpoints(self) -> Vec<EndpointHandler> {
        self.endpoints
    }
}

pub trait ServiceApiBackend {
    type RawHandler;
    type Method;

    fn endpoint<Q, R>(self, name: &'static str, f: Endpoint<Q, R>) -> Self
    where
        Q: DeserializeOwned + 'static,
        R: Serialize + 'static;

    fn endpoint_mut<Q, R>(self, name: &'static str, f: EndpointMut<Q, R>) -> Self
    where
        Q: DeserializeOwned + 'static,
        R: Serialize + 'static;

    fn raw_handler(
        self,
        name: &'static str,
        method: Self::Method,
        handler: Self::RawHandler,
    ) -> Self;
}

impl ServiceApiBackend for ServiceApiWebBackend {
    type RawHandler = Box<WebRequestHandler>;
    type Method = actix_web::http::Method;

    fn endpoint<Q, R>(mut self, name: &'static str, f: Endpoint<Q, R>) -> Self
    where
        Q: DeserializeOwned + 'static,
        R: Serialize + 'static,
    {
        self.endpoints
            .push(EndpointHandler::new(name, EndpointKind::Immutable(f)));
        self
    }

    fn endpoint_mut<Q, R>(mut self, name: &'static str, f: EndpointMut<Q, R>) -> Self
    where
        Q: DeserializeOwned + 'static,
        R: Serialize + 'static,
    {
        self.endpoints
            .push(EndpointHandler::new(name, EndpointKind::Mutable(f)));
        self
    }

    fn raw_handler(
        mut self,
        name: &'static str,
        method: Self::Method,
        handler: Self::RawHandler,
    ) -> Self {
        self.endpoints.push(EndpointHandler {
            name,
            method,
            handler,
        });
        self
    }
}

impl EndpointHandler {
    pub fn new<Q, R>(name: &'static str, kind: EndpointKind<Q, R>) -> EndpointHandler
    where
        Q: DeserializeOwned + 'static,
        R: Serialize + 'static,
    {
        let (method, handler) = match kind {
            EndpointKind::Immutable(f) => {
                let index = move |request: HttpRequest<ApiContextMut>| -> Box<Future<Item=HttpResponse, Error=actix_web::Error>> {
                    let to_response = |request: HttpRequest<ApiContextMut>| -> Result<HttpResponse, actix_web::Error> {
                        let context = request.state();
                        let query: Query<Q> = Query::from_request(&request, &())?;
                        let value = f(context, query.into_inner())?;
                        Ok(HttpResponse::Ok().json(value))
                    };

                    Box::new(to_response(request).into_future())
                };
                let index = Box::new(index) as Box<WebRequestHandler>;
                (actix_web::http::Method::GET, index)
            }
            EndpointKind::Mutable(handler) => {
                let index = move |request: HttpRequest<ApiContextMut>| -> Box<Future<Item=HttpResponse, Error=actix_web::Error>> {
                    let context = request.state().clone();
                    request.json().from_err().and_then(move |query: Q| {
                        let value = (handler)(&context, query)?;
                        Ok(HttpResponse::Ok().json(value))
                    }).responder()
                };
                let index = Box::new(index) as Box<WebRequestHandler>;
                (actix_web::http::Method::POST, index)
            }
        };

        EndpointHandler {
            name,
            method,
            handler,
        }
    }
}
<commit_msg>Polish code<commit_after>use actix_web::{self, AsyncResponder, FromRequest, HttpMessage, HttpRequest, HttpResponse, Query};
use failure;
use futures::{Future, IntoFuture};
use serde::de::DeserializeOwned;
use serde::Serialize;

use context::{ApiContext, ApiContextMut};
use {Endpoint, EndpointKind, EndpointMut};

pub type WebRequestHandler =
    Fn(HttpRequest<ApiContextMut>) -> Box<Future<Item = HttpResponse, Error = actix_web::Error>>;

pub struct EndpointHandler {
    pub name: &'static str,
    pub method: actix_web::http::Method,
    pub handler: Box<WebRequestHandler>,
}

pub struct ServiceApiWebBackend {
    endpoints: Vec<EndpointHandler>,
}

impl ServiceApiWebBackend {
    pub fn new() -> ServiceApiWebBackend {
        ServiceApiWebBackend {
            endpoints: Vec::new(),
        }
    }

    pub fn endpoints(self) -> Vec<EndpointHandler> {
        self.endpoints
    }
}

pub trait ServiceApiBackend {
    type RawHandler;
    type Method;

    fn endpoint<Q, R>(self, name: &'static str, f: Endpoint<Q, R>) -> Self
    where
        Q: DeserializeOwned + 'static,
        R: Serialize + 'static;

    fn endpoint_mut<Q, R>(self, name: &'static str, f: EndpointMut<Q, R>) -> Self
    where
        Q: DeserializeOwned + 'static,
        R: Serialize + 'static;

    fn raw_handler(
        self,
        name: &'static str,
        method: Self::Method,
        handler: Self::RawHandler,
    ) -> Self;
}

impl ServiceApiBackend for ServiceApiWebBackend {
    type RawHandler = Box<WebRequestHandler>;
    type Method = actix_web::http::Method;

    fn endpoint<Q, R>(mut self, name: &'static str, f: Endpoint<Q, R>) -> Self
    where
        Q: DeserializeOwned + 'static,
        R: Serialize + 'static,
    {
        self.endpoints
            .push(EndpointHandler::new(name, EndpointKind::Immutable(f)));
        self
    }

    fn endpoint_mut<Q, R>(mut self, name: &'static str, f: EndpointMut<Q, R>) -> Self
    where
        Q: DeserializeOwned + 'static,
        R: Serialize + 'static,
    {
        self.endpoints
            .push(EndpointHandler::new(name, EndpointKind::Mutable(f)));
        self
    }

    fn raw_handler(
        mut self,
        name: &'static str,
        method: Self::Method,
        handler: Self::RawHandler,
    ) -> Self {
        self.endpoints.push(EndpointHandler {
            name,
            method,
            handler,
        });
        self
    }
}

impl EndpointHandler {
    pub fn new<Q, R>(name: &'static str, kind: EndpointKind<Q, R>) -> EndpointHandler
    where
        Q: DeserializeOwned + 'static,
        R: Serialize + 'static,
    {
        let (method, handler) = match kind {
            EndpointKind::Immutable(handler) => {
                let index = move |request: HttpRequest<ApiContextMut>| -> Box<Future<Item=HttpResponse, Error=actix_web::Error>> {
                    let to_response = |request: HttpRequest<ApiContextMut>| -> Result<HttpResponse, actix_web::Error> {
                        let context = request.state();
                        let query: Query<Q> = Query::from_request(&request, &())?;
                        let value = handler(context, query.into_inner())?;
                        Ok(HttpResponse::Ok().json(value))
                    };

                    Box::new(to_response(request).into_future())
                };
                let index = Box::new(index) as Box<WebRequestHandler>;
                (actix_web::http::Method::GET, index)
            }
            EndpointKind::Mutable(handler) => {
                let index = move |request: HttpRequest<ApiContextMut>| -> Box<Future<Item=HttpResponse, Error=actix_web::Error>> {
                    let context = request.state().clone();
                    request.json().from_err().and_then(move |query: Q| {
                        let value = handler(&context, query)?;
                        Ok(HttpResponse::Ok().json(value))
                    }).responder()
                };
                let index = Box::new(index) as Box<WebRequestHandler>;
                (actix_web::http::Method::POST, index)
            }
        };

        EndpointHandler {
            name,
            method,
            handler,
        }
    }
}
<|endoftext|>


<commit_before>use ffi;
use libc;

use std::ffi::CString;
use std::ffi::IntoBytes;
use std::io::Cursor;
use std::io::Read;
use std::io::Error as IoError;
use std::mem;
use std::ptr;

use AsMutLua;

use LuaRead;
use LuaError;
use PushGuard;

///
pub struct LuaFunction<L> {
    variable: L
}

struct ReadData {
    reader: Box<Read + 'static>,
    buffer: [u8 ; 128],
    triggered_error: Option<IoError>,
}

extern fn reader(_: *mut ffi::lua_State, data_raw: *mut libc::c_void, size: *mut libc::size_t) -> *const libc::c_char {
    let data: &mut ReadData = unsafe { mem::transmute(data_raw) };

    if data.triggered_error.is_some() {
        unsafe { (*size) = 0 }
        return data.buffer.as_ptr() as *const libc::c_char;
    }

    match data.reader.read(data.buffer.as_mut_slice()) {
        Ok(len) =>
            unsafe { (*size) = len as libc::size_t },
        Err(e) => {
            unsafe { (*size) = 0 }
            data.triggered_error = Some(e)
        },
    };

    data.buffer.as_ptr() as *const libc::c_char
}

impl<L> LuaFunction<L> where L: AsMutLua {
    pub fn call<V>(&mut self) -> Result<V, LuaError>
                   where V: for<'a> LuaRead<PushGuard<&'a mut L>> +
                            for<'a> LuaRead<&'a mut L>
    {
        // calling pcall pops the parameters and pushes output
        let (pcall_return_value, pushed_value) = unsafe {
            let pcall_return_value = ffi::lua_pcall(self.variable.as_mut_lua().0, 0, 1, 0);     // TODO:
            (pcall_return_value, PushGuard { lua: &mut self.variable, size: 1 })
        };

        // if pcall succeeded, returning
        if pcall_return_value == 0 {
            return match LuaRead::lua_read(pushed_value) {
                None => Err(LuaError::WrongType),
                Some(x) => Ok(x)
            };
        }

        // an error occured during execution
        if pcall_return_value == ffi::LUA_ERRMEM {
            panic!("lua_pcall returned LUA_ERRMEM");
        }

        if pcall_return_value == ffi::LUA_ERRRUN {
            let error_msg: String = LuaRead::lua_read(pushed_value).expect("can't find error \
                                                                            message at the top of \
                                                                            the Lua stack");
            return Err(LuaError::ExecutionError(error_msg));
        }

        panic!("Unknown error code returned by lua_pcall: {}", pcall_return_value)
    }

    pub fn load_from_reader<R>(mut lua: L, code: R) -> Result<LuaFunction<PushGuard<L>>, LuaError>
                               where R: Read + 'static
    {
        let readdata = ReadData {
            reader: Box::new(code),
            buffer: unsafe { ::std::mem::uninitialized() },
            triggered_error: None,
        };

        let (load_return_value, pushed_value) = unsafe {
            let chunk_name = CString::new("chunk").unwrap();
            let code = ffi::lua_load(lua.as_mut_lua().0, reader, mem::transmute(&readdata),
                                     chunk_name.as_ptr(), ptr::null());
            (code, PushGuard { lua: lua, size: 1 })
        };

        if readdata.triggered_error.is_some() {
            let error = readdata.triggered_error.unwrap();
            return Err(LuaError::ReadError(error));
        }

        if load_return_value == 0 {
            return Ok(LuaFunction{
                variable: pushed_value,
            });
        }

        let error_msg: String = LuaRead::lua_read(pushed_value).expect("can't find error message \
                                                                        at the top of the Lua \
                                                                        stack");

        if load_return_value == ffi::LUA_ERRMEM {
            panic!("LUA_ERRMEM");
        }

        if load_return_value == ffi::LUA_ERRSYNTAX {
            return Err(LuaError::SyntaxError(error_msg));
        }

        panic!("Unknown error while calling lua_load");
    }

    pub fn load(lua: L, code: &str) -> Result<LuaFunction<PushGuard<L>>, LuaError> {
        let code = code.into_bytes();
        let reader = Cursor::new(code);
        LuaFunction::load_from_reader(lua, reader)
    }
}

// TODO: return Result<Ret, ExecutionError> instead
/*impl<'a, 'lua, Ret: CopyRead> ::std::ops::FnMut<(), Ret> for LuaFunction<'a,'lua> {
    fn call_mut(&mut self, _: ()) -> Ret {
        self.call().unwrap()
    }
}*/

impl<L> LuaRead<L> for LuaFunction<L> where L: AsMutLua {
    fn lua_read_at_position(mut lua: L, index: i32)
                            -> Option<LuaFunction<L>>
    {
        assert!(index == -1);   // FIXME:
        if unsafe { ffi::lua_isfunction(lua.as_mut_lua().0, -1) } {
            Some(LuaFunction { variable: lua })
        } else {
            None
        }
    }
}
<commit_msg>Fix bug in function_read<commit_after>use ffi;
use libc;

use std::ffi::CString;
use std::ffi::IntoBytes;
use std::io::Cursor;
use std::io::Read;
use std::io::Error as IoError;
use std::mem;
use std::ptr;

use AsMutLua;

use LuaRead;
use LuaError;
use PushGuard;

///
pub struct LuaFunction<L> {
    variable: L
}

struct ReadData {
    reader: Box<Read + 'static>,
    buffer: [u8 ; 128],
    triggered_error: Option<IoError>,
}

extern fn reader(_: *mut ffi::lua_State, data_raw: *mut libc::c_void, size: *mut libc::size_t) -> *const libc::c_char {
    let data: &mut ReadData = unsafe { mem::transmute(data_raw) };

    if data.triggered_error.is_some() {
        unsafe { (*size) = 0 }
        return data.buffer.as_ptr() as *const libc::c_char;
    }

    match data.reader.read(data.buffer.as_mut_slice()) {
        Ok(len) =>
            unsafe { (*size) = len as libc::size_t },
        Err(e) => {
            unsafe { (*size) = 0 }
            data.triggered_error = Some(e)
        },
    };

    data.buffer.as_ptr() as *const libc::c_char
}

impl<L> LuaFunction<L> where L: AsMutLua {
    pub fn call<V>(&mut self) -> Result<V, LuaError>
                   where V: for<'a> LuaRead<PushGuard<&'a mut L>> +
                            for<'a> LuaRead<&'a mut L>
    {
        // calling pcall pops the parameters and pushes output
        let (pcall_return_value, pushed_value) = unsafe {
            ffi::lua_pushvalue(self.variable.as_mut_lua().0, -1);   // lua_pcall pops the function, so we have to make a copy of it
            let pcall_return_value = ffi::lua_pcall(self.variable.as_mut_lua().0, 0, 1, 0);     // TODO:
            (pcall_return_value, PushGuard { lua: &mut self.variable, size: 1 })
        };

        // if pcall succeeded, returning
        if pcall_return_value == 0 {
            return match LuaRead::lua_read(pushed_value) {
                None => Err(LuaError::WrongType),
                Some(x) => Ok(x)
            };
        }

        // an error occured during execution
        if pcall_return_value == ffi::LUA_ERRMEM {
            panic!("lua_pcall returned LUA_ERRMEM");
        }

        if pcall_return_value == ffi::LUA_ERRRUN {
            let error_msg: String = LuaRead::lua_read(pushed_value).expect("can't find error \
                                                                            message at the top of \
                                                                            the Lua stack");
            return Err(LuaError::ExecutionError(error_msg));
        }

        panic!("Unknown error code returned by lua_pcall: {}", pcall_return_value)
    }

    pub fn load_from_reader<R>(mut lua: L, code: R) -> Result<LuaFunction<PushGuard<L>>, LuaError>
                               where R: Read + 'static
    {
        let readdata = ReadData {
            reader: Box::new(code),
            buffer: unsafe { ::std::mem::uninitialized() },
            triggered_error: None,
        };

        let (load_return_value, pushed_value) = unsafe {
            let chunk_name = CString::new("chunk").unwrap();
            let code = ffi::lua_load(lua.as_mut_lua().0, reader, mem::transmute(&readdata),
                                     chunk_name.as_ptr(), ptr::null());
            (code, PushGuard { lua: lua, size: 1 })
        };

        if readdata.triggered_error.is_some() {
            let error = readdata.triggered_error.unwrap();
            return Err(LuaError::ReadError(error));
        }

        if load_return_value == 0 {
            return Ok(LuaFunction{
                variable: pushed_value,
            });
        }

        let error_msg: String = LuaRead::lua_read(pushed_value).expect("can't find error message \
                                                                        at the top of the Lua \
                                                                        stack");

        if load_return_value == ffi::LUA_ERRMEM {
            panic!("LUA_ERRMEM");
        }

        if load_return_value == ffi::LUA_ERRSYNTAX {
            return Err(LuaError::SyntaxError(error_msg));
        }

        panic!("Unknown error while calling lua_load");
    }

    pub fn load(lua: L, code: &str) -> Result<LuaFunction<PushGuard<L>>, LuaError> {
        let code = code.into_bytes();
        let reader = Cursor::new(code);
        LuaFunction::load_from_reader(lua, reader)
    }
}

// TODO: return Result<Ret, ExecutionError> instead
/*impl<'a, 'lua, Ret: CopyRead> ::std::ops::FnMut<(), Ret> for LuaFunction<'a,'lua> {
    fn call_mut(&mut self, _: ()) -> Ret {
        self.call().unwrap()
    }
}*/

impl<L> LuaRead<L> for LuaFunction<L> where L: AsMutLua {
    fn lua_read_at_position(mut lua: L, index: i32)
                            -> Option<LuaFunction<L>>
    {
        assert!(index == -1);   // FIXME:
        if unsafe { ffi::lua_isfunction(lua.as_mut_lua().0, -1) } {
            Some(LuaFunction { variable: lua })
        } else {
            None
        }
    }
}
<|endoftext|>


<commit_before>use crate::{peeking_take_while::PeekableExt, Error};
use proc_macro::{TokenStream, TokenTree};
#[allow(unused_imports)]
use standback::prelude::*; // rem_euclid (1.38)
use std::{
    iter::Peekable,
    str::{Chars, FromStr},
};

pub(crate) fn get_string_literal(tokens: TokenStream) -> Result<String, Error> {
    let mut tokens = tokens.into_iter();

    match tokens.next() {
        Some(TokenTree::Literal(literal)) => {
            let s = literal.to_string();
            if !s.starts_with('"') || !s.ends_with('"') {
                Err(Error::ExpectedString)
            } else if let Some(tree) = tokens.next() {
                Err(Error::UnexpectedToken { tree })
            } else {
                Ok(s[1..(s.len() - 1)].to_owned())
            }
        }
        _ => Err(Error::ExpectedString),
    }
}

pub(crate) fn consume_digits<T: FromStr>(
    component_name: &'static str,
    chars: &mut Peekable<Chars<'_>>,
) -> Result<T, Error> {
    Ok(consume_digits_with_length(component_name, chars)?.0)
}

pub(crate) fn consume_digits_with_length<T: FromStr>(
    component_name: &'static str,
    chars: &mut Peekable<Chars<'_>>,
) -> Result<(T, usize), Error> {
    let digits = chars
        .peeking_take_while(|&c| c.is_ascii_digit() || c == '_')
        .collect::<String>();

    // Internal underscores are allowed.
    if digits.starts_with('_') || digits.ends_with('_') {
        return Err(Error::UnexpectedCharacter('_'));
    }
    let digits = digits.replace('_', "");

    let num_digits = digits.len();

    if digits == "" {
        Err(Error::MissingComponent {
            name: component_name,
        })
    } else {
        match digits.parse() {
            Ok(value) => Ok((value, num_digits)),
            Err(_) => Err(Error::InvalidComponent {
                name: component_name,
                value: digits,
            }),
        }
    }
}

pub(crate) fn consume_char(c: char, chars: &mut Peekable<Chars<'_>>) -> Result<(), Error> {
    match chars.peek() {
        Some(&char) if c == char => {
            let _ = chars.next();
            Ok(())
        }
        Some(&char) => Err(Error::UnexpectedCharacter(char)),
        None => Err(Error::UnexpectedEndOfInput),
    }
}

pub(crate) fn consume_str(s: &str, chars: &mut Peekable<Chars<'_>>) -> Result<(), Error> {
    // If the first character matches, but additional characters don't, we need
    // to be able to reset the iterator to its original state. If this isn't
    // done, a failure would have side effects, which is undesirable.
    let old_chars = chars.clone();

    for c1 in s.chars() {
        match chars.peek() {
            Some(&c2) if c1 == c2 => {
                let _ = chars.next();
            }
            Some(&char) => {
                *chars = old_chars;
                return Err(Error::UnexpectedCharacter(char));
            }
            None => {
                *chars = old_chars;
                return Err(Error::UnexpectedEndOfInput);
            }
        }
    }

    Ok(())
}

fn is_leap_year(year: i32) -> bool {
    (year % 4 == 0) && ((year % 100 != 0) || (year % 400 == 0))
}

#[allow(unstable_name_collisions)]
fn jan_weekday(year: i32, ordinal: i32) -> u8 {
    let adj_year = year - 1;
    ((ordinal + adj_year + adj_year / 4 - adj_year / 100 + adj_year / 400 + 6).rem_euclid(7)) as u8
}

pub(crate) fn days_in_year(year: i32) -> u16 {
    365 + is_leap_year(year) as u16
}

pub(crate) fn days_in_year_month(year: i32, month: u8) -> u8 {
    [31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31][month as usize - 1]
        + (month == 2 && is_leap_year(year)) as u8
}

pub(crate) fn weeks_in_year(year: i32) -> u8 {
    52 + (jan_weekday(year, 1) + is_leap_year(year) as u8 == 3) as u8
}

pub(crate) fn ywd_to_yo(year: i32, week: u8, iso_weekday_number: u8) -> (i32, u16) {
    let (ordinal, overflow) = (u16::from(week) * 7 + u16::from(iso_weekday_number))
        .overflowing_sub(u16::from(jan_weekday(year, 4)) + 4);

    if overflow || ordinal == 0 {
        return (year - 1, (ordinal.wrapping_add(days_in_year(year - 1))));
    }

    let days_in_cur_year = days_in_year(year);
    if ordinal > days_in_cur_year {
        (year + 1, ordinal - days_in_cur_year)
    } else {
        (year, ordinal)
    }
}

pub(crate) fn ymd_to_yo(year: i32, month: u8, day: u8) -> (i32, u16) {
    let ordinal = [0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334][month as usize - 1]
        + (month > 2 && is_leap_year(year)) as u16;

    (year, ordinal + u16::from(day))
}
<commit_msg>Resolve new clippy lint<commit_after>use crate::{peeking_take_while::PeekableExt, Error};
use proc_macro::{TokenStream, TokenTree};
#[allow(unused_imports)]
use standback::prelude::*; // rem_euclid (1.38)
use std::{
    iter::Peekable,
    str::{Chars, FromStr},
};

pub(crate) fn get_string_literal(tokens: TokenStream) -> Result<String, Error> {
    let mut tokens = tokens.into_iter();

    match tokens.next() {
        Some(TokenTree::Literal(literal)) => {
            let s = literal.to_string();
            if s.starts_with('"') && s.ends_with('"') {
                tokens
                    .next()
                    .map_or(Ok(s[1..s.len() - 1].to_owned()), |tree| {
                        Err(Error::UnexpectedToken { tree })
                    })
            } else {
                Err(Error::ExpectedString)
            }
        }
        _ => Err(Error::ExpectedString),
    }
}

pub(crate) fn consume_digits<T: FromStr>(
    component_name: &'static str,
    chars: &mut Peekable<Chars<'_>>,
) -> Result<T, Error> {
    Ok(consume_digits_with_length(component_name, chars)?.0)
}

pub(crate) fn consume_digits_with_length<T: FromStr>(
    component_name: &'static str,
    chars: &mut Peekable<Chars<'_>>,
) -> Result<(T, usize), Error> {
    let digits = chars
        .peeking_take_while(|&c| c.is_ascii_digit() || c == '_')
        .collect::<String>();

    // Internal underscores are allowed.
    if digits.starts_with('_') || digits.ends_with('_') {
        return Err(Error::UnexpectedCharacter('_'));
    }
    let digits = digits.replace('_', "");

    let num_digits = digits.len();

    if digits == "" {
        Err(Error::MissingComponent {
            name: component_name,
        })
    } else {
        match digits.parse() {
            Ok(value) => Ok((value, num_digits)),
            Err(_) => Err(Error::InvalidComponent {
                name: component_name,
                value: digits,
            }),
        }
    }
}

pub(crate) fn consume_char(c: char, chars: &mut Peekable<Chars<'_>>) -> Result<(), Error> {
    match chars.peek() {
        Some(&char) if c == char => {
            let _ = chars.next();
            Ok(())
        }
        Some(&char) => Err(Error::UnexpectedCharacter(char)),
        None => Err(Error::UnexpectedEndOfInput),
    }
}

pub(crate) fn consume_str(s: &str, chars: &mut Peekable<Chars<'_>>) -> Result<(), Error> {
    // If the first character matches, but additional characters don't, we need
    // to be able to reset the iterator to its original state. If this isn't
    // done, a failure would have side effects, which is undesirable.
    let old_chars = chars.clone();

    for c1 in s.chars() {
        match chars.peek() {
            Some(&c2) if c1 == c2 => {
                let _ = chars.next();
            }
            Some(&char) => {
                *chars = old_chars;
                return Err(Error::UnexpectedCharacter(char));
            }
            None => {
                *chars = old_chars;
                return Err(Error::UnexpectedEndOfInput);
            }
        }
    }

    Ok(())
}

fn is_leap_year(year: i32) -> bool {
    (year % 4 == 0) && ((year % 100 != 0) || (year % 400 == 0))
}

#[allow(unstable_name_collisions)]
fn jan_weekday(year: i32, ordinal: i32) -> u8 {
    let adj_year = year - 1;
    ((ordinal + adj_year + adj_year / 4 - adj_year / 100 + adj_year / 400 + 6).rem_euclid(7)) as u8
}

pub(crate) fn days_in_year(year: i32) -> u16 {
    365 + is_leap_year(year) as u16
}

pub(crate) fn days_in_year_month(year: i32, month: u8) -> u8 {
    [31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31][month as usize - 1]
        + (month == 2 && is_leap_year(year)) as u8
}

pub(crate) fn weeks_in_year(year: i32) -> u8 {
    52 + (jan_weekday(year, 1) + is_leap_year(year) as u8 == 3) as u8
}

pub(crate) fn ywd_to_yo(year: i32, week: u8, iso_weekday_number: u8) -> (i32, u16) {
    let (ordinal, overflow) = (u16::from(week) * 7 + u16::from(iso_weekday_number))
        .overflowing_sub(u16::from(jan_weekday(year, 4)) + 4);

    if overflow || ordinal == 0 {
        return (year - 1, (ordinal.wrapping_add(days_in_year(year - 1))));
    }

    let days_in_cur_year = days_in_year(year);
    if ordinal > days_in_cur_year {
        (year + 1, ordinal - days_in_cur_year)
    } else {
        (year, ordinal)
    }
}

pub(crate) fn ymd_to_yo(year: i32, month: u8, day: u8) -> (i32, u16) {
    let ordinal = [0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334][month as usize - 1]
        + (month > 2 && is_leap_year(year)) as u16;

    (year, ordinal + u16::from(day))
}
<|endoftext|>


<commit_before>use std::error::{Error, FromError};
use std::fmt::{self, Display, Debug};
use std::collections::HashSet;
use std::io;
use rustc_serialize::json::DecoderError;
use hyper::HttpError;
use super::RecaptchaErrorCode;

pub enum RecaptchaError {
    Codes(HashSet<RecaptchaErrorCode>),
    Wrapped(Box<Error>)
}

impl Display for RecaptchaError {
    fn fmt(&self, f: &mut fmt::Formatter) -> Result<(), fmt::Error> {
        use self::RecaptchaError::*;
        match *self {
            Codes(ref errs) => write!(f, "{} ({:?})", self.description(), errs),
            Wrapped(ref err) => write!(f, "{} ({})", self.description(), err)
        }
    }
}

impl Debug for RecaptchaError {
    fn fmt(&self, f: &mut fmt::Formatter) -> Result<(), fmt::Error> {
        <RecaptchaError as Display>::fmt(self, f)
    }
}

impl Error for RecaptchaError {
    fn description(&self) -> &str {
        "recaptcha verification failed"
    }

    fn cause(&self) -> Option<&Error> {
        use self::RecaptchaError::*;
        match *self {
            Codes(_) => None,
            Wrapped(ref err) => Some(&**err)
        }
    }
}

impl FromError<DecoderError> for RecaptchaError {
    fn from_error(err: DecoderError) -> RecaptchaError {
        RecaptchaError::Wrapped(Box::new(err))
    }
}

impl FromError<HttpError> for RecaptchaError {
    fn from_error(err: HttpError) -> RecaptchaError {
        RecaptchaError::Wrapped(Box::new(err))
    }
}

impl FromError<io::Error> for RecaptchaError {
    fn from_error(err: io::Error) -> RecaptchaError {
        RecaptchaError::Wrapped(Box::new(err))
    }
}
<commit_msg>Enhance RecaptchaError<commit_after>use std::error::{Error, FromError};
use std::fmt::{self, Display, Debug};
use std::collections::HashSet;
use std::io;
use rustc_serialize::json::DecoderError;
use hyper::HttpError;
use super::RecaptchaErrorCode;

pub enum RecaptchaError {
    Codes(HashSet<RecaptchaErrorCode>),
    Decoder(DecoderError),
    Http(HttpError),
    Io(io::Error),
}

impl Display for RecaptchaError {
    fn fmt(&self, f: &mut fmt::Formatter) -> Result<(), fmt::Error> {
        use self::RecaptchaError::*;
        match self {
            &Codes(ref errs) => write!(f, "{} ({:?})", self.description(), errs),
            &Decoder(ref e) => Display::fmt(e, f),
            &Http(ref e) => Display::fmt(e, f),
            &Io(ref e) => Display::fmt(e, f)
        }
    }
}

impl Debug for RecaptchaError {
    fn fmt(&self, f: &mut fmt::Formatter) -> Result<(), fmt::Error> {
        <RecaptchaError as Display>::fmt(self, f)
    }
}

impl Error for RecaptchaError {
    fn description(&self) -> &str {
        "recaptcha verification failed"
    }

    fn cause(&self) -> Option<&Error> {
        use self::RecaptchaError::*;
        match self {
            &Codes(_) => None,
            &Decoder(ref e) => Some(e),
            &Http(ref e) => Some(e),
            &Io(ref e) => Some(e)
        }
    }
}

impl FromError<DecoderError> for RecaptchaError {
    fn from_error(err: DecoderError) -> RecaptchaError {
        RecaptchaError::Decoder(err)
    }
}

impl FromError<HttpError> for RecaptchaError {
    fn from_error(err: HttpError) -> RecaptchaError {
        RecaptchaError::Http(err)
    }
}

impl FromError<io::Error> for RecaptchaError {
    fn from_error(err: io::Error) -> RecaptchaError {
        RecaptchaError::Io(err)
    }
}
<|endoftext|>


<commit_before>use std::error::{Error, FromError};
use std::fmt::{self, Display, Formatter};

use nanomsg;
use protobuf;
use rustc_serialize;

pub type SimplesResult<Msg> = Result<Msg, SimplesError>;

#[derive(Debug, Eq, PartialEq)]
pub struct SimplesError {
    description: String
}

impl SimplesError {
    pub fn new(description: &str) -> SimplesError {
        SimplesError { description: String::from_str(description) }
    }
}

impl Display for SimplesError {
    fn fmt(&self, formatter: &mut Formatter) -> Result<(), fmt::Error> {
        formatter.write_str(&self.description[])
    }
}

impl Error for SimplesError {
    fn description(&self) -> &str { &self.description[] }

    fn cause(&self) -> Option<&Error> { None }
}

// TODO: Use something like below (albeit with a SimplesErrorTrait)
//       once Rust gets negative trait bounds
//
// impl<Error: ::std::error::Error + !SimplesError>
//     FromError<Error> for SimplesError {
//
//     fn from_error(err: Error) -> SimplesError {
//         SimplesError { description: String::from_str(err.description()) }
//     }
// }

trait ConvertToSimplesError: Error {}
impl ConvertToSimplesError for protobuf::error::ProtobufError {}
impl ConvertToSimplesError for ::std::old_io::IoError {}
impl ConvertToSimplesError for rustc_serialize::json::EncoderError {}

impl<Err: ConvertToSimplesError> FromError<Err> for SimplesError {
    fn from_error(err: Err) -> SimplesError {
        SimplesError { description: String::from_str(err.description()) }
    }
}

impl FromError<nanomsg::NanoError> for SimplesError {
    fn from_error(err: nanomsg::NanoError) -> SimplesError {
        SimplesError { description: String::from_str(err.description) }
    }
}

impl<'a> FromError<&'a str> for SimplesError {
    fn from_error(err: &'a str) -> SimplesError {
        SimplesError { description: String::from_str(err) }
    }
}
<commit_msg>Convert FromBase64Error -> SimplesError.<commit_after>use std::error::{Error, FromError};
use std::fmt::{self, Display, Formatter};

use nanomsg;
use protobuf;
use rustc_serialize;

pub type SimplesResult<Msg> = Result<Msg, SimplesError>;

#[derive(Debug, Eq, PartialEq)]
pub struct SimplesError {
    description: String
}

impl SimplesError {
    pub fn new(description: &str) -> SimplesError {
        SimplesError { description: String::from_str(description) }
    }
}

impl Display for SimplesError {
    fn fmt(&self, formatter: &mut Formatter) -> Result<(), fmt::Error> {
        formatter.write_str(&self.description[])
    }
}

impl Error for SimplesError {
    fn description(&self) -> &str { &self.description[] }

    fn cause(&self) -> Option<&Error> { None }
}

// TODO: Use something like below (albeit with a SimplesErrorTrait)
//       once Rust gets negative trait bounds
//
// impl<Error: ::std::error::Error + !SimplesError>
//     FromError<Error> for SimplesError {
//
//     fn from_error(err: Error) -> SimplesError {
//         SimplesError { description: String::from_str(err.description()) }
//     }
// }

trait ConvertToSimplesError: Error {}
impl ConvertToSimplesError for protobuf::error::ProtobufError {}
impl ConvertToSimplesError for ::std::old_io::IoError {}
impl ConvertToSimplesError for rustc_serialize::json::EncoderError {}
impl ConvertToSimplesError for rustc_serialize::base64::FromBase64Error {}

impl<Err: ConvertToSimplesError> FromError<Err> for SimplesError {
    fn from_error(err: Err) -> SimplesError {
        SimplesError { description: String::from_str(err.description()) }
    }
}

impl FromError<nanomsg::NanoError> for SimplesError {
    fn from_error(err: nanomsg::NanoError) -> SimplesError {
        SimplesError { description: String::from_str(err.description) }
    }
}

impl<'a> FromError<&'a str> for SimplesError {
    fn from_error(err: &'a str) -> SimplesError {
        SimplesError { description: String::from_str(err) }
    }
}
<|endoftext|>


<commit_before>//! Errors for `frippy` crate using `failure`.

use std::io::Error as IoError;
use std::str::Utf8Error;
use irc::error::IrcError;
use reqwest::Error as ReqwestError;
use r2d2::Error as R2d2Error;

/// The main crate-wide error type.
#[derive(Debug, Fail)]
pub enum FrippyError {
    /// A plugin error
    #[fail(display = "A plugin error occured")]
    Plugin(#[cause] PluginError),

    /// An IRC error
    #[fail(display = "An IRC error occured")]
    Irc(#[cause] IrcError),

    /// Missing config error
    #[fail(display = "No config file was found")]
    MissingConfig,

    /// A reqwest error
    #[fail(display = "A reqwest error occured")]
    Reqwest(#[cause] ReqwestError),

    /// An I/O error
    #[fail(display = "An I/O error occured")]
    Io(#[cause] IoError),

    /// A UTF8 error
    #[fail(display = "A UTF8 error occured")]
    Utf8(#[cause] Utf8Error),

    /// An r2d2 error
    #[fail(display = "An r2d2 error occured")]
    R2d2(#[cause] R2d2Error),

    /// Reached download limit error
    #[fail(display = "Reached download limit of {} KiB", limit)]
    DownloadLimit { limit: usize },
}

/// Errors related to plugins
#[derive(Debug, Fail)]
pub enum PluginError {
    /// A Url error
    #[fail(display = "A Url error occured")]
    Url(#[cause] UrlError),

    /// A Factoids error
    #[fail(display = "{}", error)]
    Factoids { error: String },
}

/// A URL plugin error
#[derive(Debug, Fail)]
pub enum UrlError {
    /// Missing URL error
    #[fail(display = "No URL was found")]
    MissingUrl,

    /// Missing title error
    #[fail(display = "No title was found")]
    MissingTitle,
}

impl From<UrlError> for FrippyError {
    fn from(e: UrlError) -> FrippyError {
        FrippyError::Plugin(PluginError::Url(e))
    }
}

impl From<PluginError> for FrippyError {
    fn from(e: PluginError) -> FrippyError {
        FrippyError::Plugin(e)
    }
}

impl From<IrcError> for FrippyError {
    fn from(e: IrcError) -> FrippyError {
        FrippyError::Irc(e)
    }
}

impl From<ReqwestError> for FrippyError {
    fn from(e: ReqwestError) -> FrippyError {
        FrippyError::Reqwest(e)
    }
}

impl From<IoError> for FrippyError {
    fn from(e: IoError) -> FrippyError {
        FrippyError::Io(e)
    }
}

impl From<Utf8Error> for FrippyError {
    fn from(e: Utf8Error) -> FrippyError {
        FrippyError::Utf8(e)
    }
}

impl From<R2d2Error> for FrippyError {
    fn from(e: R2d2Error) -> FrippyError {
        FrippyError::R2d2(e)
    }
}
<commit_msg>Add the mysql error to the mysql feature<commit_after>//! Errors for `frippy` crate using `failure`.

use std::io::Error as IoError;
use std::str::Utf8Error;
use irc::error::IrcError;
use reqwest::Error as ReqwestError;
#[cfg(feature = "mysql")]
use r2d2::Error as R2d2Error;

/// The main crate-wide error type.
#[derive(Debug, Fail)]
pub enum FrippyError {
    /// A plugin error
    #[fail(display = "A plugin error occured")]
    Plugin(#[cause] PluginError),

    /// An IRC error
    #[fail(display = "An IRC error occured")]
    Irc(#[cause] IrcError),

    /// Missing config error
    #[fail(display = "No config file was found")]
    MissingConfig,

    /// A reqwest error
    #[fail(display = "A reqwest error occured")]
    Reqwest(#[cause] ReqwestError),

    /// An I/O error
    #[fail(display = "An I/O error occured")]
    Io(#[cause] IoError),

    /// A UTF8 error
    #[fail(display = "A UTF8 error occured")]
    Utf8(#[cause] Utf8Error),

    /// An r2d2 error
    #[cfg(feature = "mysql")]
    #[fail(display = "An r2d2 error occured")]
    R2d2(#[cause] R2d2Error),

    /// Reached download limit error
    #[fail(display = "Reached download limit of {} KiB", limit)]
    DownloadLimit { limit: usize },
}

/// Errors related to plugins
#[derive(Debug, Fail)]
pub enum PluginError {
    /// A Url error
    #[fail(display = "A Url error occured")]
    Url(#[cause] UrlError),

    /// A Factoids error
    #[fail(display = "{}", error)]
    Factoids { error: String },
}

/// A URL plugin error
#[derive(Debug, Fail)]
pub enum UrlError {
    /// Missing URL error
    #[fail(display = "No URL was found")]
    MissingUrl,

    /// Missing title error
    #[fail(display = "No title was found")]
    MissingTitle,
}

impl From<UrlError> for FrippyError {
    fn from(e: UrlError) -> FrippyError {
        FrippyError::Plugin(PluginError::Url(e))
    }
}

impl From<PluginError> for FrippyError {
    fn from(e: PluginError) -> FrippyError {
        FrippyError::Plugin(e)
    }
}

impl From<IrcError> for FrippyError {
    fn from(e: IrcError) -> FrippyError {
        FrippyError::Irc(e)
    }
}

impl From<ReqwestError> for FrippyError {
    fn from(e: ReqwestError) -> FrippyError {
        FrippyError::Reqwest(e)
    }
}

impl From<IoError> for FrippyError {
    fn from(e: IoError) -> FrippyError {
        FrippyError::Io(e)
    }
}

impl From<Utf8Error> for FrippyError {
    fn from(e: Utf8Error) -> FrippyError {
        FrippyError::Utf8(e)
    }
}

#[cfg(feature = "mysql")]
impl From<R2d2Error> for FrippyError {
    fn from(e: R2d2Error) -> FrippyError {
        FrippyError::R2d2(e)
    }
}
<|endoftext|>


<commit_before>// Copyright 2014 The CGMath Developers. For a full listing of the authors,
// refer to the AUTHORS file at the top-level directory of this distribution.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

extern crate cgmath;

use cgmath::{Aabb, Aabb2, Aabb3};
use cgmath::{Point2, Point3};
use cgmath::{Vector2, Vector3};
use cgmath::{Ray, Intersect};
use cgmath::{Plane, Bound, Relation};

#[test]
fn test_general() {
    let aabb = Aabb2::new(Point2::new(-20is, 30is), Point2::new(10is, -10is));
    assert_eq!(aabb.min(), &Point2::new(-20is, -10is));
    assert_eq!(aabb.max(), &Point2::new(10is, 30is));
    assert_eq!(aabb.dim(), Vector2::new(30is, 40is));
    assert_eq!(aabb.volume(), 30is * 40is);
    assert_eq!(aabb.center(), Point2::new(-5is, 10is));

    assert!(aabb.contains(&Point2::new(0is, 0is)));
    assert!(!aabb.contains(&Point2::new(-50is, -50is)));
    assert!(!aabb.contains(&Point2::new(50is, 50is)));

    assert_eq!(aabb.grow(&Point2::new(0is, 0is)), aabb);
    assert_eq!(aabb.grow(&Point2::new(100is, 100is)),
        Aabb2::new(Point2::new(-20is, -10is), Point2::new(100is, 100is)));
    assert_eq!(aabb.grow(&Point2::new(-100is, -100is)),
        Aabb2::new(Point2::new(-100is, -100is), Point2::new(10is, 30is)));

    let aabb = Aabb3::new(Point3::new(-20is, 30is, 5is), Point3::new(10is, -10is, -5is));
    assert_eq!(aabb.min(), &Point3::new(-20is, -10is, -5is));
    assert_eq!(aabb.max(), &Point3::new(10is, 30is, 5is));
    assert_eq!(aabb.dim(), Vector3::new(30is, 40is, 10is));
    assert_eq!(aabb.volume(), 30is * 40is * 10is);
    assert_eq!(aabb.center(), Point3::new(-5is, 10is, 0is));

    assert!(aabb.contains(&Point3::new(0is, 0is, 0is)));
    assert!(!aabb.contains(&Point3::new(-100is, 0is, 0is)));
    assert!(!aabb.contains(&Point3::new(100is, 0is, 0is)));
    assert!(aabb.contains(&Point3::new(9is, 29is, -1is)));
    assert!(!aabb.contains(&Point3::new(10is, 30is, 5is)));
    assert!(aabb.contains(&Point3::new(-20is, -10is, -5is)));
    assert!(!aabb.contains(&Point3::new(-21is, -11is, -6is)));

    assert_eq!(aabb.add_v(&Vector3::new(1is, 2is, 3is)),
        Aabb3::new(Point3::new(-19is, 32is, 8is), Point3::new(11is, -8is, -2is)));

    assert_eq!(aabb.mul_s(2is),
        Aabb3::new(Point3::new(-40is, -20is, -10is), Point3::new(20is, 60is, 10is)));

    assert_eq!(aabb.mul_v(&Vector3::new(1is, 2is, 3is)),
        Aabb3::new(Point3::new(-20is, -20is, -15is), Point3::new(10is, 60is, 15is)));
}

#[test]
fn test_ray_intersect() {
    let aabb = Aabb2::new(Point2::new(-5.0f32, 5.0), Point2::new(5.0, 10.0));
    let ray1 = Ray::new(Point2::new(0.0f32, 0.0), Vector2::new(0.0, 1.0));
    let ray2 = Ray::new(Point2::new(-10.0f32, 0.0), Vector2::new(2.5, 1.0));
    let ray3 = Ray::new(Point2::new(0.0f32, 0.0), Vector2::new(-1.0, -1.0));
    let ray4 = Ray::new(Point2::new(3.0f32, 7.0), Vector2::new(1.0, 1.0));

    assert_eq!((ray1, aabb).intersection(), Some(Point2::new(0.0, 5.0)));
    assert_eq!((ray2, aabb).intersection(), Some(Point2::new(2.5, 5.0)));
    assert_eq!((ray3, aabb).intersection(), None);
    assert_eq!((ray4, aabb).intersection(), Some(Point2::new(5.0, 9.0)));
}

#[test]
fn test_bound() {
    let aabb = Aabb3::new(Point3::new(-5.0f32, 5.0, 0.0), Point3::new(5.0, 10.0, 1.0));
    let plane1 = Plane::from_point_normal(Point3::new(0f32, 0.0, 0.0), Vector3::new(0f32, 0.0, 1.0));
    let plane2 = Plane::from_point_normal(Point3::new(-5.0f32, 4.0, 0.0), Vector3::new(0f32, 1.0, 0.0));
    let plane3 = Plane::from_point_normal(Point3::new(6.0f32, 0.0, 0.0), Vector3::new(1f32, 0.0, 0.0));
    assert_eq!(aabb.relate(&plane1), Relation::Cross);
    assert_eq!(aabb.relate(&plane2), Relation::In);
    assert_eq!(aabb.relate(&plane3), Relation::Out);
}
<commit_msg>Added tests for aabb to_corners(). Fixed test warnings.<commit_after>// Copyright 2014 The CGMath Developers. For a full listing of the authors,
// refer to the AUTHORS file at the top-level directory of this distribution.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASisize,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

extern crate cgmath;

use cgmath::{Aabb, Aabb2, Aabb3};
use cgmath::{Point2, Point3};
use cgmath::{Vector2, Vector3};
use cgmath::{Ray, Intersect};
use cgmath::{Plane, Bound, Relation};

#[test]
fn test_general() {
    let aabb = Aabb2::new(Point2::new(-20isize, 30isize), Point2::new(10isize, -10isize));
    assert_eq!(aabb.min(), &Point2::new(-20isize, -10isize));
    assert_eq!(aabb.max(), &Point2::new(10isize, 30isize));
    assert_eq!(aabb.dim(), Vector2::new(30isize, 40isize));
    assert_eq!(aabb.volume(), 30isize * 40isize);
    assert_eq!(aabb.center(), Point2::new(-5isize, 10isize));

    assert!(aabb.contains(&Point2::new(0isize, 0isize)));
    assert!(!aabb.contains(&Point2::new(-50isize, -50isize)));
    assert!(!aabb.contains(&Point2::new(50isize, 50isize)));

    assert_eq!(aabb.grow(&Point2::new(0isize, 0isize)), aabb);
    assert_eq!(aabb.grow(&Point2::new(100isize, 100isize)),
        Aabb2::new(Point2::new(-20isize, -10isize), Point2::new(100isize, 100isize)));
    assert_eq!(aabb.grow(&Point2::new(-100isize, -100isize)),
        Aabb2::new(Point2::new(-100isize, -100isize), Point2::new(10isize, 30isize)));

    let aabb = Aabb3::new(Point3::new(-20isize, 30isize, 5isize), Point3::new(10isize, -10isize, -5isize));
    assert_eq!(aabb.min(), &Point3::new(-20isize, -10isize, -5isize));
    assert_eq!(aabb.max(), &Point3::new(10isize, 30isize, 5isize));
    assert_eq!(aabb.dim(), Vector3::new(30isize, 40isize, 10isize));
    assert_eq!(aabb.volume(), 30isize * 40isize * 10isize);
    assert_eq!(aabb.center(), Point3::new(-5isize, 10isize, 0isize));

    assert!(aabb.contains(&Point3::new(0isize, 0isize, 0isize)));
    assert!(!aabb.contains(&Point3::new(-100isize, 0isize, 0isize)));
    assert!(!aabb.contains(&Point3::new(100isize, 0isize, 0isize)));
    assert!(aabb.contains(&Point3::new(9isize, 29isize, -1isize)));
    assert!(!aabb.contains(&Point3::new(10isize, 30isize, 5isize)));
    assert!(aabb.contains(&Point3::new(-20isize, -10isize, -5isize)));
    assert!(!aabb.contains(&Point3::new(-21isize, -11isize, -6isize)));

    assert_eq!(aabb.add_v(&Vector3::new(1isize, 2isize, 3isize)),
        Aabb3::new(Point3::new(-19isize, 32isize, 8isize), Point3::new(11isize, -8isize, -2isize)));

    assert_eq!(aabb.mul_s(2isize),
        Aabb3::new(Point3::new(-40isize, -20isize, -10isize), Point3::new(20isize, 60isize, 10isize)));

    assert_eq!(aabb.mul_v(&Vector3::new(1isize, 2isize, 3isize)),
        Aabb3::new(Point3::new(-20isize, -20isize, -15isize), Point3::new(10isize, 60isize, 15isize)));
}

#[test]
fn test_ray_intersect() {
    let aabb = Aabb2::new(Point2::new(-5.0f32, 5.0), Point2::new(5.0, 10.0));
    let ray1 = Ray::new(Point2::new(0.0f32, 0.0), Vector2::new(0.0, 1.0));
    let ray2 = Ray::new(Point2::new(-10.0f32, 0.0), Vector2::new(2.5, 1.0));
    let ray3 = Ray::new(Point2::new(0.0f32, 0.0), Vector2::new(-1.0, -1.0));
    let ray4 = Ray::new(Point2::new(3.0f32, 7.0), Vector2::new(1.0, 1.0));

    assert_eq!((ray1, aabb).intersection(), Some(Point2::new(0.0, 5.0)));
    assert_eq!((ray2, aabb).intersection(), Some(Point2::new(2.5, 5.0)));
    assert_eq!((ray3, aabb).intersection(), None);
    assert_eq!((ray4, aabb).intersection(), Some(Point2::new(5.0, 9.0)));
}

#[test]
fn test_corners() {
    let corners = Aabb2::new(Point2::new(-5.0f32, 5.0), Point2::new(5.0, 10.0))
                        .to_corners();
    assert!(corners.contains(&Point2::new(-5f32, 10.0)));
    assert!(corners.contains(&Point2::new(5f32, 5.0)));

    let corners = Aabb3::new(Point3::new(-20isize, 30isize, 5isize), Point3::new(10isize, -10isize, -5isize))
                        .to_corners();
    assert!(corners.contains(&Point3::new(-20isize, 30isize, -5isize)));
    assert!(corners.contains(&Point3::new(10isize, 30isize, 5isize)));
    assert!(corners.contains(&Point3::new(10isize, -10isize, 5isize)));
}

#[test]
fn test_bound() {
    let aabb = Aabb3::new(Point3::new(-5.0f32, 5.0, 0.0), Point3::new(5.0, 10.0, 1.0));
    let plane1 = Plane::from_point_normal(Point3::new(0f32, 0.0, 0.0), Vector3::new(0f32, 0.0, 1.0));
    let plane2 = Plane::from_point_normal(Point3::new(-5.0f32, 4.0, 0.0), Vector3::new(0f32, 1.0, 0.0));
    let plane3 = Plane::from_point_normal(Point3::new(6.0f32, 0.0, 0.0), Vector3::new(1f32, 0.0, 0.0));
    assert_eq!(aabb.relate(&plane1), Relation::Cross);
    assert_eq!(aabb.relate(&plane2), Relation::In);
    assert_eq!(aabb.relate(&plane3), Relation::Out);
}
<|endoftext|>


<commit_before>
extern crate nccl;

use nccl::value::Value;
use nccl::pair::Pair;

#[test]
fn from_vec() {
    assert_eq!(Value::from(vec![1, 2, 3]),
               Value::List(vec![Value::Integer(1),
                                Value::Integer(2),
                                Value::Integer(3)]));
}

#[test]
fn add() {
    let mut p = Pair::new("key");
    p.add("value");
    assert_eq!(p, Pair {
        key: "key".into(),
        value: vec![Pair {
            key: "value".into(),
            value: vec![]
        }]
    });
}

#[test]
fn get() {
    let mut p = Pair::new("key");
    p.add("value");
    p.add("testaroni");
    p.get_mut("value".into()).unwrap().add("Hello!");
    let v = p.get("value".into()).unwrap();
    assert_eq!(v, &Pair {
        key: "value".into(),
        value: vec![Pair {
            key: "Hello!".into(),
            value: vec![]
        }]
    });
}

#[test]
fn multi() {
    let mut p = Pair::new("key");
    p.add("value");
    p.add("dj khaled");
    p.get_mut("value".into()).unwrap().add("yes!");
    p.get_mut("dj khaled".into()).unwrap().add("you smart");
    p.get_mut("dj khaled".into()).unwrap().add("you loyal");
    assert_eq!(p, Pair {
        key: "key".into(),
        value: vec![Pair {
            key: "value".into(),
            value: vec![Pair {
                key: "yes!".into(),
                value: vec![]
            }]
        }, Pair {
            key: "dj khaled".into(),
            value: vec![Pair {
                key: "you smart".into(),
                value: vec![]
            }, Pair{
                key: "you loyal".into(),
                value: vec![]
            }]
        }]
    });
}

#[test]
fn index() {
    let mut p = Pair::new("key");
    p.add("hello");
    p["hello"].add("world");
    p["hello"]["world"].add("what's");
    p["hello"]["world"]["what's"].add("up?");
    assert_eq!(p, Pair {
        key: "key".into(),
        value: vec![Pair {
            key: "hello".into(),
            value: vec![Pair {
                key: "world".into(),
                value: vec![Pair {
                    key: "what's".into(),
                    value: vec![Pair {
                        key: "up?".into(),
                        value: vec![]
                    }]
                }]
            }]
        }]
    });
}

<commit_msg>update tests<commit_after>
extern crate nccl;

use nccl::value::Value;
use nccl::pair::Pair;

#[test]
fn from_vec() {
    assert_eq!(Value::from(vec![1, 2, 3]),
               Value::List(vec![Value::Integer(1),
                                Value::Integer(2),
                                Value::Integer(3)]));
}

#[test]
fn add() {
    let mut p = Pair::new("key");
    p.add("value");
    assert_eq!(p, Pair {
        key: "key".into(),
        value: vec![Pair {
            key: "value".into(),
            value: vec![]
        }]
    });
}

#[test]
fn get() {
    let mut p = Pair::new("key");
    p.add("value");
    p.add("testaroni");
    p.get_mut("value".into()).unwrap().add("Hello!");
    let v = p.get("value".into()).unwrap();
    assert_eq!(v, &Pair {
        key: "value".into(),
        value: vec![Pair {
            key: "Hello!".into(),
            value: vec![]
        }]
    });
}

#[test]
fn multi() {
    let mut p = Pair::new("key");
    p.add("value");
    p.add("dj khaled");
    p.get_mut("value".into()).unwrap().add("yes!");
    p.get_mut("dj khaled".into()).unwrap().add("you smart");
    p.get_mut("dj khaled".into()).unwrap().add("you loyal");
    assert_eq!(p, Pair {
        key: "key".into(),
        value: vec![Pair {
            key: "value".into(),
            value: vec![Pair {
                key: "yes!".into(),
                value: vec![]
            }]
        }, Pair {
            key: "dj khaled".into(),
            value: vec![Pair {
                key: "you smart".into(),
                value: vec![]
            }, Pair{
                key: "you loyal".into(),
                value: vec![]
            }]
        }]
    });
}

#[test]
fn index() {
    let mut p = Pair::new("key");
    p.add("hello");
    p["hello"].add("world");
    p["hello"]["world"].add("what's");
    p["hello"]["world"]["what's"].add("up?");
    assert_eq!(p, Pair {
        key: "key".into(),
        value: vec![Pair {
            key: "hello".into(),
            value: vec![Pair {
                key: "world".into(),
                value: vec![Pair {
                    key: "what's".into(),
                    value: vec![Pair {
                        key: "up?".into(),
                        value: vec![]
                    }]
                }]
            }]
        }]
    });
}

#[test]
fn index_pair() {
    let mut p1 = Pair::new("aaa");
    p1.add("hello");
    p1["hello"].add("everyone");
    let p2 = Pair::new("hello");
    assert_eq!(p1["hello"], p1[p2]);
}

#[test]
fn index_value() {
    let mut p = Pair::new("charles");
    p.add("fjfj");
    p["fjfj"].add(true);
    assert_eq!(p["fjfj"], p[Value::String("fjfj".into())]);
}

#[test]
fn overwrite_add() {
    let mut p = Pair::new("top");
    p.add("hello");
    p["hello"].add("everyone");
    p.add("hello");
    assert_eq!(p["hello"], Pair {
        key: "hello".into(),
        value: vec![]
    });
}

<|endoftext|>