<commit_before>//! Less used details of `CxxVector` are exposed in this module. `CxxVector`
//! itself is exposed at the crate root.

use crate::extern_type::ExternType;
use crate::kind::Trivial;
use crate::string::CxxString;
use core::ffi::c_void;
use core::fmt::{self, Debug, Display};
use core::iter::FusedIterator;
use core::marker::{PhantomData, PhantomPinned};
use core::mem;
use core::pin::Pin;
use core::ptr;
use core::slice;

#[doc(inline)]
pub use crate::Vector;

/// Binding to C++ `std::vector<T, std::allocator<T>>`.
///
/// # Invariants
///
/// As an invariant of this API and the static analysis of the cxx::bridge
/// macro, in Rust code we can never obtain a `CxxVector` by value. Instead in
/// Rust code we will only ever look at a vector behind a reference or smart
/// pointer, as in `&CxxVector<T>` or `UniquePtr<CxxVector<T>>`.
#[repr(C, packed)]
pub struct CxxVector<T> {
    _private: [T; 0],
    _pinned: PhantomData<PhantomPinned>,
}

impl<T> CxxVector<T>
where
    T: VectorElement,
{
    /// Returns the number of elements in the vector.
    ///
    /// Matches the behavior of C++ [std::vector\<T\>::size][size].
    ///
    /// [size]: https://en.cppreference.com/w/cpp/container/vector/size
    pub fn len(&self) -> usize {
        T::__vector_size(self)
    }

    /// Returns true if the vector contains no elements.
    ///
    /// Matches the behavior of C++ [std::vector\<T\>::empty][empty].
    ///
    /// [empty]: https://en.cppreference.com/w/cpp/container/vector/empty
    pub fn is_empty(&self) -> bool {
        self.len() == 0
    }

    /// Returns a reference to an element at the given position, or `None` if
    /// out of bounds.
    pub fn get(&self, pos: usize) -> Option<&T> {
        if pos < self.len() {
            Some(unsafe { self.get_unchecked(pos) })
        } else {
            None
        }
    }

    /// Returns a pinned mutable reference to an element at the given position,
    /// or `None` if out of bounds.
    pub fn index_mut(self: Pin<&mut Self>, pos: usize) -> Option<Pin<&mut T>> {
        if pos < self.len() {
            Some(unsafe { self.index_unchecked_mut(pos) })
        } else {
            None
        }
    }

    /// Returns a reference to an element without doing bounds checking.
    ///
    /// This is generally not recommended, use with caution! Calling this method
    /// with an out-of-bounds index is undefined behavior even if the resulting
    /// reference is not used.
    ///
    /// Matches the behavior of C++
    /// [std::vector\<T\>::operator\[\] const][operator_at].
    ///
    /// [operator_at]: https://en.cppreference.com/w/cpp/container/vector/operator_at
    pub unsafe fn get_unchecked(&self, pos: usize) -> &T {
        let this = self as *const CxxVector<T> as *mut CxxVector<T>;
        let ptr = T::__get_unchecked(this, pos) as *const T;
        &*ptr
    }

    /// Returns a pinned mutable reference to an element without doing bounds
    /// checking.
    ///
    /// This is generally not recommended, use with caution! Calling this method
    /// with an out-of-bounds index is undefined behavior even if the resulting
    /// reference is not used.
    ///
    /// Matches the behavior of C++
    /// [std::vector\<T\>::operator\[\]][operator_at].
    ///
    /// [operator_at]: https://en.cppreference.com/w/cpp/container/vector/operator_at
    pub unsafe fn index_unchecked_mut(self: Pin<&mut Self>, pos: usize) -> Pin<&mut T> {
        let ptr = T::__get_unchecked(self.get_unchecked_mut(), pos);
        Pin::new_unchecked(&mut *ptr)
    }

    /// Returns a slice to the underlying contiguous array of elements.
    pub fn as_slice(&self) -> &[T]
    where
        T: ExternType<Kind = Trivial>,
    {
        let len = self.len();
        if len == 0 {
            // The slice::from_raw_parts in the other branch requires a nonnull
            // and properly aligned data ptr. C++ standard does not guarantee
            // that data() on a vector with size 0 would return a nonnull
            // pointer or sufficiently aligned pointer, so using it would be
            // undefined behavior. Create our own empty slice in Rust instead
            // which upholds the invariants.
            &[]
        } else {
            let this = self as *const CxxVector<T> as *mut CxxVector<T>;
            let ptr = unsafe { T::__get_unchecked(this, 0) };
            unsafe { slice::from_raw_parts(ptr, len) }
        }
    }

    /// Returns an iterator over elements of type `&T`.
    pub fn iter(&self) -> Iter<T> {
        Iter { v: self, index: 0 }
    }

    /// Returns an iterator over elements of type `Pin<&mut T>`.
    pub fn iter_mut(self: Pin<&mut Self>) -> IterMut<T> {
        IterMut { v: self, index: 0 }
    }
}

/// Iterator over elements of a `CxxVector` by shared reference.
///
/// The iterator element type is `&'a T`.
pub struct Iter<'a, T> {
    v: &'a CxxVector<T>,
    index: usize,
}

impl<'a, T> IntoIterator for &'a CxxVector<T>
where
    T: VectorElement,
{
    type Item = &'a T;
    type IntoIter = Iter<'a, T>;

    fn into_iter(self) -> Self::IntoIter {
        self.iter()
    }
}

impl<'a, T> Iterator for Iter<'a, T>
where
    T: VectorElement,
{
    type Item = &'a T;

    fn next(&mut self) -> Option<Self::Item> {
        let next = self.v.get(self.index)?;
        self.index += 1;
        Some(next)
    }

    fn size_hint(&self) -> (usize, Option<usize>) {
        let len = self.len();
        (len, Some(len))
    }
}

impl<'a, T> ExactSizeIterator for Iter<'a, T>
where
    T: VectorElement,
{
    fn len(&self) -> usize {
        self.v.len() - self.index
    }
}

impl<'a, T> FusedIterator for Iter<'a, T> where T: VectorElement {}

/// Iterator over elements of a `CxxVector` by pinned mutable reference.
///
/// The iterator element type is `Pin<&'a mut T>`.
pub struct IterMut<'a, T> {
    v: Pin<&'a mut CxxVector<T>>,
    index: usize,
}

impl<'a, T> IntoIterator for Pin<&'a mut CxxVector<T>>
where
    T: VectorElement,
{
    type Item = Pin<&'a mut T>;
    type IntoIter = IterMut<'a, T>;

    fn into_iter(self) -> Self::IntoIter {
        self.iter_mut()
    }
}

impl<'a, T> Iterator for IterMut<'a, T>
where
    T: VectorElement,
{
    type Item = Pin<&'a mut T>;

    fn next(&mut self) -> Option<Self::Item> {
        let next = self.v.as_mut().index_mut(self.index)?;
        self.index += 1;
        // Extend lifetime to allow simultaneous holding of nonoverlapping
        // elements, analogous to slice::split_first_mut.
        unsafe {
            let ptr = Pin::into_inner_unchecked(next) as *mut T;
            Some(Pin::new_unchecked(&mut *ptr))
        }
    }

    fn size_hint(&self) -> (usize, Option<usize>) {
        let len = self.len();
        (len, Some(len))
    }
}

impl<'a, T> ExactSizeIterator for IterMut<'a, T>
where
    T: VectorElement,
{
    fn len(&self) -> usize {
        self.v.len() - self.index
    }
}

impl<'a, T> FusedIterator for IterMut<'a, T> where T: VectorElement {}

impl<T> Debug for CxxVector<T>
where
    T: VectorElement + Debug,
{
    fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
        formatter.debug_list().entries(self).finish()
    }
}

pub(crate) struct TypeName<T> {
    element: PhantomData<T>,
}

impl<T> TypeName<T> {
    pub const fn new() -> Self {
        TypeName {
            element: PhantomData,
        }
    }
}

impl<T> Display for TypeName<T>
where
    T: VectorElement,
{
    fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
        write!(formatter, "CxxVector<{}>", T::__NAME)
    }
}

// Methods are private; not intended to be implemented outside of cxxbridge
// codebase.
#[doc(hidden)]
pub unsafe trait VectorElement: Sized {
    const __NAME: &'static dyn Display;
    fn __vector_size(v: &CxxVector<Self>) -> usize;
    unsafe fn __get_unchecked(v: *mut CxxVector<Self>, pos: usize) -> *mut Self;
    fn __unique_ptr_null() -> *mut c_void;
    unsafe fn __unique_ptr_raw(raw: *mut CxxVector<Self>) -> *mut c_void;
    unsafe fn __unique_ptr_get(repr: *mut c_void) -> *const CxxVector<Self>;
    unsafe fn __unique_ptr_release(repr: *mut c_void) -> *mut CxxVector<Self>;
    unsafe fn __unique_ptr_drop(repr: *mut c_void);
}

macro_rules! impl_vector_element {
    ($segment:expr, $name:expr, $ty:ty) => {
        const_assert_eq!(1, mem::align_of::<CxxVector<$ty>>());

        unsafe impl VectorElement for $ty {
            const __NAME: &'static dyn Display = &$name;
            fn __vector_size(v: &CxxVector<$ty>) -> usize {
                extern "C" {
                    attr! {
                        #[link_name = concat!("cxxbridge1$std$vector$", $segment, "$size")]
                        fn __vector_size(_: &CxxVector<$ty>) -> usize;
                    }
                }
                unsafe { __vector_size(v) }
            }
            unsafe fn __get_unchecked(v: *mut CxxVector<$ty>, pos: usize) -> *mut $ty {
                extern "C" {
                    attr! {
                        #[link_name = concat!("cxxbridge1$std$vector$", $segment, "$get_unchecked")]
                        fn __get_unchecked(_: *mut CxxVector<$ty>, _: usize) -> *mut $ty;
                    }
                }
                __get_unchecked(v, pos)
            }
            fn __unique_ptr_null() -> *mut c_void {
                extern "C" {
                    attr! {
                        #[link_name = concat!("cxxbridge1$unique_ptr$std$vector$", $segment, "$null")]
                        fn __unique_ptr_null(this: *mut *mut c_void);
                    }
                }
                let mut repr = ptr::null_mut::<c_void>();
                unsafe { __unique_ptr_null(&mut repr) }
                repr
            }
            unsafe fn __unique_ptr_raw(raw: *mut CxxVector<Self>) -> *mut c_void {
                extern "C" {
                    attr! {
                        #[link_name = concat!("cxxbridge1$unique_ptr$std$vector$", $segment, "$raw")]
                        fn __unique_ptr_raw(this: *mut *mut c_void, raw: *mut CxxVector<$ty>);
                    }
                }
                let mut repr = ptr::null_mut::<c_void>();
                __unique_ptr_raw(&mut repr, raw);
                repr
            }
            unsafe fn __unique_ptr_get(repr: *mut c_void) -> *const CxxVector<Self> {
                extern "C" {
                    attr! {
                        #[link_name = concat!("cxxbridge1$unique_ptr$std$vector$", $segment, "$get")]
                        fn __unique_ptr_get(this: *const *mut c_void) -> *const CxxVector<$ty>;
                    }
                }
                __unique_ptr_get(&repr)
            }
            unsafe fn __unique_ptr_release(mut repr: *mut c_void) -> *mut CxxVector<Self> {
                extern "C" {
                    attr! {
                        #[link_name = concat!("cxxbridge1$unique_ptr$std$vector$", $segment, "$release")]
                        fn __unique_ptr_release(this: *mut *mut c_void) -> *mut CxxVector<$ty>;
                    }
                }
                __unique_ptr_release(&mut repr)
            }
            unsafe fn __unique_ptr_drop(mut repr: *mut c_void) {
                extern "C" {
                    attr! {
                        #[link_name = concat!("cxxbridge1$unique_ptr$std$vector$", $segment, "$drop")]
                        fn __unique_ptr_drop(this: *mut *mut c_void);
                    }
                }
                __unique_ptr_drop(&mut repr);
            }
        }
    };
}

macro_rules! impl_vector_element_for_primitive {
    ($ty:ident) => {
        impl_vector_element!(stringify!($ty), stringify!($ty), $ty);
    };
}

impl_vector_element_for_primitive!(u8);
impl_vector_element_for_primitive!(u16);
impl_vector_element_for_primitive!(u32);
impl_vector_element_for_primitive!(u64);
impl_vector_element_for_primitive!(usize);
impl_vector_element_for_primitive!(i8);
impl_vector_element_for_primitive!(i16);
impl_vector_element_for_primitive!(i32);
impl_vector_element_for_primitive!(i64);
impl_vector_element_for_primitive!(isize);
impl_vector_element_for_primitive!(f32);
impl_vector_element_for_primitive!(f64);

impl_vector_element!("string", "CxxString", CxxString);
<commit_msg>Add CxxVector::as_mut_slice<commit_after>//! Less used details of `CxxVector` are exposed in this module. `CxxVector`
//! itself is exposed at the crate root.

use crate::extern_type::ExternType;
use crate::kind::Trivial;
use crate::string::CxxString;
use core::ffi::c_void;
use core::fmt::{self, Debug, Display};
use core::iter::FusedIterator;
use core::marker::{PhantomData, PhantomPinned};
use core::mem;
use core::pin::Pin;
use core::ptr;
use core::slice;

#[doc(inline)]
pub use crate::Vector;

/// Binding to C++ `std::vector<T, std::allocator<T>>`.
///
/// # Invariants
///
/// As an invariant of this API and the static analysis of the cxx::bridge
/// macro, in Rust code we can never obtain a `CxxVector` by value. Instead in
/// Rust code we will only ever look at a vector behind a reference or smart
/// pointer, as in `&CxxVector<T>` or `UniquePtr<CxxVector<T>>`.
#[repr(C, packed)]
pub struct CxxVector<T> {
    _private: [T; 0],
    _pinned: PhantomData<PhantomPinned>,
}

impl<T> CxxVector<T>
where
    T: VectorElement,
{
    /// Returns the number of elements in the vector.
    ///
    /// Matches the behavior of C++ [std::vector\<T\>::size][size].
    ///
    /// [size]: https://en.cppreference.com/w/cpp/container/vector/size
    pub fn len(&self) -> usize {
        T::__vector_size(self)
    }

    /// Returns true if the vector contains no elements.
    ///
    /// Matches the behavior of C++ [std::vector\<T\>::empty][empty].
    ///
    /// [empty]: https://en.cppreference.com/w/cpp/container/vector/empty
    pub fn is_empty(&self) -> bool {
        self.len() == 0
    }

    /// Returns a reference to an element at the given position, or `None` if
    /// out of bounds.
    pub fn get(&self, pos: usize) -> Option<&T> {
        if pos < self.len() {
            Some(unsafe { self.get_unchecked(pos) })
        } else {
            None
        }
    }

    /// Returns a pinned mutable reference to an element at the given position,
    /// or `None` if out of bounds.
    pub fn index_mut(self: Pin<&mut Self>, pos: usize) -> Option<Pin<&mut T>> {
        if pos < self.len() {
            Some(unsafe { self.index_unchecked_mut(pos) })
        } else {
            None
        }
    }

    /// Returns a reference to an element without doing bounds checking.
    ///
    /// This is generally not recommended, use with caution! Calling this method
    /// with an out-of-bounds index is undefined behavior even if the resulting
    /// reference is not used.
    ///
    /// Matches the behavior of C++
    /// [std::vector\<T\>::operator\[\] const][operator_at].
    ///
    /// [operator_at]: https://en.cppreference.com/w/cpp/container/vector/operator_at
    pub unsafe fn get_unchecked(&self, pos: usize) -> &T {
        let this = self as *const CxxVector<T> as *mut CxxVector<T>;
        let ptr = T::__get_unchecked(this, pos) as *const T;
        &*ptr
    }

    /// Returns a pinned mutable reference to an element without doing bounds
    /// checking.
    ///
    /// This is generally not recommended, use with caution! Calling this method
    /// with an out-of-bounds index is undefined behavior even if the resulting
    /// reference is not used.
    ///
    /// Matches the behavior of C++
    /// [std::vector\<T\>::operator\[\]][operator_at].
    ///
    /// [operator_at]: https://en.cppreference.com/w/cpp/container/vector/operator_at
    pub unsafe fn index_unchecked_mut(self: Pin<&mut Self>, pos: usize) -> Pin<&mut T> {
        let ptr = T::__get_unchecked(self.get_unchecked_mut(), pos);
        Pin::new_unchecked(&mut *ptr)
    }

    /// Returns a slice to the underlying contiguous array of elements.
    pub fn as_slice(&self) -> &[T]
    where
        T: ExternType<Kind = Trivial>,
    {
        let len = self.len();
        if len == 0 {
            // The slice::from_raw_parts in the other branch requires a nonnull
            // and properly aligned data ptr. C++ standard does not guarantee
            // that data() on a vector with size 0 would return a nonnull
            // pointer or sufficiently aligned pointer, so using it would be
            // undefined behavior. Create our own empty slice in Rust instead
            // which upholds the invariants.
            &[]
        } else {
            let this = self as *const CxxVector<T> as *mut CxxVector<T>;
            let ptr = unsafe { T::__get_unchecked(this, 0) };
            unsafe { slice::from_raw_parts(ptr, len) }
        }
    }

    /// Returns a slice to the underlying contiguous array of elements by
    /// mutable reference.
    pub fn as_mut_slice(self: Pin<&mut Self>) -> &mut [T]
    where
        T: ExternType<Kind = Trivial>,
    {
        let len = self.len();
        if len == 0 {
            &mut []
        } else {
            let ptr = unsafe { T::__get_unchecked(self.get_unchecked_mut(), 0) };
            unsafe { slice::from_raw_parts_mut(ptr, len) }
        }
    }

    /// Returns an iterator over elements of type `&T`.
    pub fn iter(&self) -> Iter<T> {
        Iter { v: self, index: 0 }
    }

    /// Returns an iterator over elements of type `Pin<&mut T>`.
    pub fn iter_mut(self: Pin<&mut Self>) -> IterMut<T> {
        IterMut { v: self, index: 0 }
    }
}

/// Iterator over elements of a `CxxVector` by shared reference.
///
/// The iterator element type is `&'a T`.
pub struct Iter<'a, T> {
    v: &'a CxxVector<T>,
    index: usize,
}

impl<'a, T> IntoIterator for &'a CxxVector<T>
where
    T: VectorElement,
{
    type Item = &'a T;
    type IntoIter = Iter<'a, T>;

    fn into_iter(self) -> Self::IntoIter {
        self.iter()
    }
}

impl<'a, T> Iterator for Iter<'a, T>
where
    T: VectorElement,
{
    type Item = &'a T;

    fn next(&mut self) -> Option<Self::Item> {
        let next = self.v.get(self.index)?;
        self.index += 1;
        Some(next)
    }

    fn size_hint(&self) -> (usize, Option<usize>) {
        let len = self.len();
        (len, Some(len))
    }
}

impl<'a, T> ExactSizeIterator for Iter<'a, T>
where
    T: VectorElement,
{
    fn len(&self) -> usize {
        self.v.len() - self.index
    }
}

impl<'a, T> FusedIterator for Iter<'a, T> where T: VectorElement {}

/// Iterator over elements of a `CxxVector` by pinned mutable reference.
///
/// The iterator element type is `Pin<&'a mut T>`.
pub struct IterMut<'a, T> {
    v: Pin<&'a mut CxxVector<T>>,
    index: usize,
}

impl<'a, T> IntoIterator for Pin<&'a mut CxxVector<T>>
where
    T: VectorElement,
{
    type Item = Pin<&'a mut T>;
    type IntoIter = IterMut<'a, T>;

    fn into_iter(self) -> Self::IntoIter {
        self.iter_mut()
    }
}

impl<'a, T> Iterator for IterMut<'a, T>
where
    T: VectorElement,
{
    type Item = Pin<&'a mut T>;

    fn next(&mut self) -> Option<Self::Item> {
        let next = self.v.as_mut().index_mut(self.index)?;
        self.index += 1;
        // Extend lifetime to allow simultaneous holding of nonoverlapping
        // elements, analogous to slice::split_first_mut.
        unsafe {
            let ptr = Pin::into_inner_unchecked(next) as *mut T;
            Some(Pin::new_unchecked(&mut *ptr))
        }
    }

    fn size_hint(&self) -> (usize, Option<usize>) {
        let len = self.len();
        (len, Some(len))
    }
}

impl<'a, T> ExactSizeIterator for IterMut<'a, T>
where
    T: VectorElement,
{
    fn len(&self) -> usize {
        self.v.len() - self.index
    }
}

impl<'a, T> FusedIterator for IterMut<'a, T> where T: VectorElement {}

impl<T> Debug for CxxVector<T>
where
    T: VectorElement + Debug,
{
    fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
        formatter.debug_list().entries(self).finish()
    }
}

pub(crate) struct TypeName<T> {
    element: PhantomData<T>,
}

impl<T> TypeName<T> {
    pub const fn new() -> Self {
        TypeName {
            element: PhantomData,
        }
    }
}

impl<T> Display for TypeName<T>
where
    T: VectorElement,
{
    fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
        write!(formatter, "CxxVector<{}>", T::__NAME)
    }
}

// Methods are private; not intended to be implemented outside of cxxbridge
// codebase.
#[doc(hidden)]
pub unsafe trait VectorElement: Sized {
    const __NAME: &'static dyn Display;
    fn __vector_size(v: &CxxVector<Self>) -> usize;
    unsafe fn __get_unchecked(v: *mut CxxVector<Self>, pos: usize) -> *mut Self;
    fn __unique_ptr_null() -> *mut c_void;
    unsafe fn __unique_ptr_raw(raw: *mut CxxVector<Self>) -> *mut c_void;
    unsafe fn __unique_ptr_get(repr: *mut c_void) -> *const CxxVector<Self>;
    unsafe fn __unique_ptr_release(repr: *mut c_void) -> *mut CxxVector<Self>;
    unsafe fn __unique_ptr_drop(repr: *mut c_void);
}

macro_rules! impl_vector_element {
    ($segment:expr, $name:expr, $ty:ty) => {
        const_assert_eq!(1, mem::align_of::<CxxVector<$ty>>());

        unsafe impl VectorElement for $ty {
            const __NAME: &'static dyn Display = &$name;
            fn __vector_size(v: &CxxVector<$ty>) -> usize {
                extern "C" {
                    attr! {
                        #[link_name = concat!("cxxbridge1$std$vector$", $segment, "$size")]
                        fn __vector_size(_: &CxxVector<$ty>) -> usize;
                    }
                }
                unsafe { __vector_size(v) }
            }
            unsafe fn __get_unchecked(v: *mut CxxVector<$ty>, pos: usize) -> *mut $ty {
                extern "C" {
                    attr! {
                        #[link_name = concat!("cxxbridge1$std$vector$", $segment, "$get_unchecked")]
                        fn __get_unchecked(_: *mut CxxVector<$ty>, _: usize) -> *mut $ty;
                    }
                }
                __get_unchecked(v, pos)
            }
            fn __unique_ptr_null() -> *mut c_void {
                extern "C" {
                    attr! {
                        #[link_name = concat!("cxxbridge1$unique_ptr$std$vector$", $segment, "$null")]
                        fn __unique_ptr_null(this: *mut *mut c_void);
                    }
                }
                let mut repr = ptr::null_mut::<c_void>();
                unsafe { __unique_ptr_null(&mut repr) }
                repr
            }
            unsafe fn __unique_ptr_raw(raw: *mut CxxVector<Self>) -> *mut c_void {
                extern "C" {
                    attr! {
                        #[link_name = concat!("cxxbridge1$unique_ptr$std$vector$", $segment, "$raw")]
                        fn __unique_ptr_raw(this: *mut *mut c_void, raw: *mut CxxVector<$ty>);
                    }
                }
                let mut repr = ptr::null_mut::<c_void>();
                __unique_ptr_raw(&mut repr, raw);
                repr
            }
            unsafe fn __unique_ptr_get(repr: *mut c_void) -> *const CxxVector<Self> {
                extern "C" {
                    attr! {
                        #[link_name = concat!("cxxbridge1$unique_ptr$std$vector$", $segment, "$get")]
                        fn __unique_ptr_get(this: *const *mut c_void) -> *const CxxVector<$ty>;
                    }
                }
                __unique_ptr_get(&repr)
            }
            unsafe fn __unique_ptr_release(mut repr: *mut c_void) -> *mut CxxVector<Self> {
                extern "C" {
                    attr! {
                        #[link_name = concat!("cxxbridge1$unique_ptr$std$vector$", $segment, "$release")]
                        fn __unique_ptr_release(this: *mut *mut c_void) -> *mut CxxVector<$ty>;
                    }
                }
                __unique_ptr_release(&mut repr)
            }
            unsafe fn __unique_ptr_drop(mut repr: *mut c_void) {
                extern "C" {
                    attr! {
                        #[link_name = concat!("cxxbridge1$unique_ptr$std$vector$", $segment, "$drop")]
                        fn __unique_ptr_drop(this: *mut *mut c_void);
                    }
                }
                __unique_ptr_drop(&mut repr);
            }
        }
    };
}

macro_rules! impl_vector_element_for_primitive {
    ($ty:ident) => {
        impl_vector_element!(stringify!($ty), stringify!($ty), $ty);
    };
}

impl_vector_element_for_primitive!(u8);
impl_vector_element_for_primitive!(u16);
impl_vector_element_for_primitive!(u32);
impl_vector_element_for_primitive!(u64);
impl_vector_element_for_primitive!(usize);
impl_vector_element_for_primitive!(i8);
impl_vector_element_for_primitive!(i16);
impl_vector_element_for_primitive!(i32);
impl_vector_element_for_primitive!(i64);
impl_vector_element_for_primitive!(isize);
impl_vector_element_for_primitive!(f32);
impl_vector_element_for_primitive!(f64);

impl_vector_element!("string", "CxxString", CxxString);
<|endoftext|>


<commit_before>extern crate syn;

use std::env;
use std::fs::File;
use std::io::{Write, BufWriter};
use syn::DeriveInput;

pub fn generate_elm(ast: &DeriveInput) {
    let mut path = env::current_dir().unwrap();
    let name = &ast.ident;
    path.push(format!("generated/{}.elm", name));

    let file = File::create(path).unwrap();
    let ref mut w = BufWriter::new(file);
    w.write("Hello, World!".as_bytes()).unwrap();
}
<commit_msg>Create generated directory unless it is already created<commit_after>extern crate syn;

use std::env;
use std::fs::{File, create_dir};
use std::io::{Write, BufWriter};
use syn::DeriveInput;

pub fn generate_elm(ast: &DeriveInput) {
    let mut path = env::current_dir().unwrap();
    path.push("generated");
    if path.exists() && path.is_file() { panic!("expecting \"generated\" to be a directory"); }
    if !path.exists() { create_dir(path.clone()).expect("problem creating \"generated\" directory") }
    let name = &ast.ident;
    path.push(format!("{}.elm", name));

    let file = File::create(path).unwrap();
    let ref mut w = BufWriter::new(file);
    w.write("Hello, World!".as_bytes()).unwrap();
}
<|endoftext|>


<commit_before>// Kevin Cantu
// additional vector functions

use std;

fn windowed <copy TT> (nn: uint, xx: [TT]) -> [[TT]] {
   let ww = [];

   assert 1u <= nn;

   vec::iteri (xx, {|ii, _x|
      let len = vec::len(xx);

      if ii+nn <= len {
         let w = vec::slice ( xx, ii, ii+nn );
         vec::push (ww, w);
      }
   });

   ret ww;
}

#[test]
fn windowed_test_3of6 () {
   assert [[1u,2u,3u],[2u,3u,4u],[3u,4u,5u],[4u,5u,6u]]
          == windowed (3u, [1u,2u,3u,4u,5u,6u]);
}

#[test]
fn windowed_test_4of6 () {
   assert [[1u,2u,3u,4u],[2u,3u,4u,5u],[3u,4u,5u,6u]]
          == windowed (4u, [1u,2u,3u,4u,5u,6u]);
}

#[test]
#[should_fail]
fn windowed_test_0of6 () {
   let _x = windowed (0u, [1u,2u,3u,4u,5u,6u]);
}

#[test]
fn windowed_test_7of6 () {
   assert [] == windowed (7u, [1u,2u,3u,4u,5u,6u]);
}

fn splitAt <copy TT> (nn: uint, xx: [TT]) -> ([TT],[TT]) {
   assert 0u <= nn;
   assert nn <= vec::len(xx);
   (vec::slice(xx,0u,nn), vec::slice(xx,nn,vec::len(xx)))
}

#[test]
fn splitAt_test_a () {
   let temp: ([u8],[u8]) = splitAt(0u, []);
   assert ([],[]) == temp;
}

#[test]
fn splitAt_test_b () {
   assert ([],[1u]) == splitAt(0u, [1u]);
}

#[test]
fn splitAt_test_c () {
   assert ([1u],[]) == splitAt(1u, [1u]);
}

#[test]
#[should_fail]
fn splitAt_test_d () {
   let temp: ([u8],[u8]) = splitAt(7u, []);
   assert ([],[]) == temp;
}

fn take <copy TT> (nn: uint, xx: [TT]) -> [TT] {
   ret vec::slice (xx, 0u, nn);
}

<commit_msg>vec2::show() added<commit_after>// Kevin Cantu
// additional vector functions

use std;

fn windowed <copy TT> (nn: uint, xx: [TT]) -> [[TT]] {
   let ww = [];

   assert 1u <= nn;

   vec::iteri (xx, {|ii, _x|
      let len = vec::len(xx);

      if ii+nn <= len {
         let w = vec::slice ( xx, ii, ii+nn );
         vec::push (ww, w);
      }
   });

   ret ww;
}

#[test]
fn windowed_test_3of6 () {
   assert [[1u,2u,3u],[2u,3u,4u],[3u,4u,5u],[4u,5u,6u]]
          == windowed (3u, [1u,2u,3u,4u,5u,6u]);
}

#[test]
fn windowed_test_4of6 () {
   assert [[1u,2u,3u,4u],[2u,3u,4u,5u],[3u,4u,5u,6u]]
          == windowed (4u, [1u,2u,3u,4u,5u,6u]);
}

#[test]
#[should_fail]
fn windowed_test_0of6 () {
   let _x = windowed (0u, [1u,2u,3u,4u,5u,6u]);
}

#[test]
fn windowed_test_7of6 () {
   assert [] == windowed (7u, [1u,2u,3u,4u,5u,6u]);
}

fn splitAt <copy TT> (nn: uint, xx: [TT]) -> ([TT],[TT]) {
   assert 0u <= nn;
   assert nn <= vec::len(xx);
   (vec::slice(xx,0u,nn), vec::slice(xx,nn,vec::len(xx)))
}

#[test]
fn splitAt_test_a () {
   let temp: ([u8],[u8]) = splitAt(0u, []);
   assert ([],[]) == temp;
}

#[test]
fn splitAt_test_b () {
   assert ([],[1u]) == splitAt(0u, [1u]);
}

#[test]
fn splitAt_test_c () {
   assert ([1u],[]) == splitAt(1u, [1u]);
}

#[test]
#[should_fail]
fn splitAt_test_d () {
   let temp: ([u8],[u8]) = splitAt(7u, []);
   assert ([],[]) == temp;
}

fn take <copy TT> (nn: uint, xx: [TT]) -> [TT] {
   assert nn < vec::len(xx);
   ret vec::slice (xx, 0u, nn);
}

#[test]
fn take_test_a () {
   assert [] == take(0u, [8u,9u]);
}

#[test]
#[should_fail]
fn take_test_b () {
   let _xyz = take(6u, [8u,9u]);
}

// given a function to stringify an element
// make a pretty string of a vector
fn show <copy TT> ( vv: [TT],
                    showTT: block(TT)->str ) -> str {

   let strings = vec::map (vv, showTT);

   check vec::is_not_empty(strings);  // satisfy the typesystem

   let with_commas = vec::foldl ( vec::head(strings),
                                  vec::tail(strings),
                                  {|w,s| w + "," + s});

   ret "[" + with_commas + "]";
}

#[test]
fn show_test_a () {
   assert "[3,56,62,2,4]"
         == show ([3u,56u,62u,2u,4u], {|x| #fmt("%u", x)});
}

#[test]
fn show_test_b () {
   let vv   =  [[ "abc",  "def",  "ghi" ],[ "jkl",  "mno" ]];
   let ref  = "[[\"abc\",\"def\",\"ghi\"],[\"jkl\",\"mno\"]]";

   // this is a bit fragile, but works ok for now...
   let test = show (vv, {|xs|
                 show (xs, {|x| "\"" + x + "\"" })
              });

   assert ref == test;
}

<|endoftext|>


<commit_before>/*===============================================================================================*/
// Copyright 2016 Kyle Finlay
//
// 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.
/*===============================================================================================*/

use ::engine::AppInfo;
use ::resource::ResourceManager;
use ::window::WindowManager;
use ::util::{Version, Logger};

use std::cell::RefCell;
use std::rc::Rc;
use std::boxed::Box;
use std::process;

/*===============================================================================================*/
/*------STATIC VARIABLES-------------------------------------------------------------------------*/
/*===============================================================================================*/

pub static mut APP_POINTER: Option <*mut App> = None;

/*===============================================================================================*/
/*------APP STRUCT-------------------------------------------------------------------------------*/
/*===============================================================================================*/

/// The app
///
/// This is the main control center of ionCore.
/// It is in charge of initialization, updating, and shutdown of all modules,
/// as well as the handing of any inter-module communication.
pub struct App {

    // Public
    /// The application info.
    pub app_info: AppInfo,
    /// The resource manager.
    pub resource_mgr: Rc<RefCell<ResourceManager>>,
    /// The window manager.
    pub window_mgr: Rc<RefCell<WindowManager>>,

    // Private
    _is_in_main_loop: bool,
    _should_exit: bool,
}

/*===============================================================================================*/
/*------APP PUBLIC METHODS-----------------------------------------------------------------------*/
/*===============================================================================================*/

impl App {

    /// The main app loop.
    pub fn run (&mut self) {

        self._is_in_main_loop = true;

        loop {

            let should_exit = self._should_exit;

            if !should_exit {

                self._on_pre_render ();
                self._on_render ();
                self._on_post_render ();
            }

            else {

                self._is_in_main_loop = false;
                return;
            }
        }
    }

/*-----------------------------------------------------------------------------------------------*/

    /// Releases all resources, and exits the application.
    pub fn exit (&mut self) {

        // Check if in main loop
        if self._is_in_main_loop {

            info! ("Exiting main loop.");
            self._should_exit = true;
        }

        else {

            info! ("Shutting down ion Core.");

            // Release the managers, and release self
            self._release_managers ();
            App::_terminate ();
        }
    }

/*-----------------------------------------------------------------------------------------------*/

    /// Initializes the app
    pub fn init (&self) {

        Logger::init ("./ionCore.log", true).unwrap ();
        info! ("Initializing ionCore | Version: {}", env! ("CARGO_PKG_VERSION"));

        // Init the managers
        self._init_managers ();
    }

/*===============================================================================================*/
/*------APP PUBLIC STATIC METHODS----------------------------------------------------------------*/
/*===============================================================================================*/

    /// Returns a new App Builder.
    pub fn builder () -> AppBuilder {
        AppBuilder::new ()
    }

/*-----------------------------------------------------------------------------------------------*/

    /// Checks if the app has been initialized.
    ///
    /// # Return value
    /// A bool returning whether the app has been initialized.
    pub fn is_initialized () -> bool {

        unsafe {

            match APP_POINTER {

                Some (pointer) => !pointer.is_null (),
                None => false
            }
        }
    }

/*-----------------------------------------------------------------------------------------------*/

    /// Returns a reference to the app instance.
    pub fn get_instance () -> Result<&'static App, ()> {

        if App::is_initialized () {
            return Ok (unsafe {&*APP_POINTER.unwrap ()});
        }

        Err (())
    }

/*-----------------------------------------------------------------------------------------------*/

    /// Returns a mutable reference to the app instance.
    pub fn get_instance_mut () -> Result<&'static mut App, ()> {

        if App::is_initialized () {
            return Ok (unsafe {&mut *APP_POINTER.unwrap ()});
        }

        Err (())
    }

/*===============================================================================================*/
/*------APP PRIVATE METHODS----------------------------------------------------------------------*/
/*===============================================================================================*/

    // Initializes the various managers.
    fn _init_managers (&self) {

        self.resource_mgr.borrow_mut ().init ();
        self.window_mgr.borrow_mut   ().init ();
    }

/*-----------------------------------------------------------------------------------------------*/

    // TODO: Finish me
    // On pre render
    fn _on_pre_render (&self) {
        self.window_mgr.borrow_mut ().on_pre_render ();
    }

/*-----------------------------------------------------------------------------------------------*/

    // TODO: Finish me
    // On render
    fn _on_render (&self) {
        self.window_mgr.borrow_mut ().on_render ();
    }

/*-----------------------------------------------------------------------------------------------*/

    // TODO: Finish me
    // On post render
    fn _on_post_render (&self) {
        self.window_mgr.borrow_mut ().on_post_render ();
    }

/*-----------------------------------------------------------------------------------------------*/

    // Releases the managers
    fn _release_managers (&self) {
        self.window_mgr.borrow_mut ().release ();
    }

/*===============================================================================================*/
/*------APP PRIVATE STATIC METHODS---------------------------------------------------------------*/
/*===============================================================================================*/

    // Release the app pointer, and terminate the application.
    fn _terminate () {

        unsafe {

            drop (Box::from_raw (APP_POINTER.unwrap ()));
            APP_POINTER = None;
        };

        // Release the logger, and shutdown the application
        info! ("Terminating the application.");
        Logger::release ();

        process::exit (0);
    }
}

/*===============================================================================================*/
/*------APP BUILDER STRUCT-----------------------------------------------------------------------*/
/*===============================================================================================*/

/// Used for building a new, static app instance.
pub struct AppBuilder {

    // Private
    _app_name: String,
    _app_developer: String,
    _app_publisher: String,
    _app_version: Version,
}

/*===============================================================================================*/
/*------APP BUILDER PUBLIC METHODS---------------------------------------------------------------*/
/*===============================================================================================*/

impl AppBuilder {

    /// Sets the app name.
    pub fn name (&mut self, name: &str) -> &mut Self {

        self._app_name = name.to_string ();
        self
    }

/*-----------------------------------------------------------------------------------------------*/

    /// Sets the app developer.
    pub fn developer (&mut self, developer: &str) -> &mut Self {

        self._app_developer = developer.to_string ();
        self
    }

/*-----------------------------------------------------------------------------------------------*/

    /// Sets the app publisher
    pub fn publisher (&mut self, publisher: &str) -> &mut Self {

        self._app_publisher = publisher.to_string ();
        self
    }

/*-----------------------------------------------------------------------------------------------*/

    /// Sets the app version
    pub fn version (&mut self, version: Version) -> &mut Self {

        self._app_version = version;
        self
    }

/*-----------------------------------------------------------------------------------------------*/

    /// Builds the app.
    pub fn build (&self) -> Result<&'static mut App, ()> {

        // Check if initialized
        if !App::is_initialized () {

            let app_info = AppInfo {

                app_name: self._app_name.clone (),
                app_developer: self._app_developer.clone (),
                app_publisher: self._app_publisher.clone (),
                app_version: self._app_version
            };

            let ab = Box::new (App {

                app_info: app_info,
                resource_mgr: Rc::new (RefCell::new (ResourceManager::new ())),
                window_mgr: Rc::new (RefCell::new (WindowManager::new ())),
                _is_in_main_loop: false,
                _should_exit: false,
            });

            unsafe {APP_POINTER = Some (Box::into_raw (ab))};
        }

        App::get_instance_mut ()
    }

/*===============================================================================================*/
/*------APP BUILDER PUBLIC STATIC METHODS--------------------------------------------------------*/
/*===============================================================================================*/

    /// Returns a new app builder instance.
    pub fn new () -> AppBuilder {

        AppBuilder {

            _app_name: "Unknown".to_string (),
            _app_developer: "Unknown".to_string (),
            _app_publisher: "Unknown".to_string (),
            _app_version: Version::new ()
        }
    }
}

/*-----------------------------------------------------------------------------------------------*/

impl Default for AppBuilder {

    fn default () -> AppBuilder {
        AppBuilder::new ()
    }
}
<commit_msg>Moved init method, and removed pub from APP_POINTER<commit_after>/*===============================================================================================*/
// Copyright 2016 Kyle Finlay
//
// 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.
/*===============================================================================================*/

use ::engine::AppInfo;
use ::resource::ResourceManager;
use ::window::WindowManager;
use ::util::{Version, Logger};

use std::cell::RefCell;
use std::rc::Rc;
use std::boxed::Box;
use std::process;

/*===============================================================================================*/
/*------STATIC VARIABLES-------------------------------------------------------------------------*/
/*===============================================================================================*/

static mut APP_POINTER: Option <*mut App> = None;

/*===============================================================================================*/
/*------APP STRUCT-------------------------------------------------------------------------------*/
/*===============================================================================================*/

/// The app
///
/// This is the main control center of ionCore.
/// It is in charge of initialization, updating, and shutdown of all modules,
/// as well as the handing of any inter-module communication.
pub struct App {

    // Public
    /// The application info.
    pub app_info: AppInfo,
    /// The resource manager.
    pub resource_mgr: Rc<RefCell<ResourceManager>>,
    /// The window manager.
    pub window_mgr: Rc<RefCell<WindowManager>>,

    // Private
    _is_in_main_loop: bool,
    _should_exit: bool,
}

/*===============================================================================================*/
/*------APP PUBLIC METHODS-----------------------------------------------------------------------*/
/*===============================================================================================*/

impl App {

    /// Initializes the app
    pub fn init (&self) {

        Logger::init ("./ionCore.log", true).unwrap ();
        info! ("Initializing ionCore | Version: {}", env! ("CARGO_PKG_VERSION"));

        // Init the managers
        self._init_managers ();
    }

/*-----------------------------------------------------------------------------------------------*/

    /// The main app loop.
    pub fn run (&mut self) {

        self._is_in_main_loop = true;

        loop {

            let should_exit = self._should_exit;

            if !should_exit {

                self._on_pre_render ();
                self._on_render ();
                self._on_post_render ();
            }

            else {

                self._is_in_main_loop = false;
                return;
            }
        }
    }

/*-----------------------------------------------------------------------------------------------*/

    /// Releases all resources, and exits the application.
    pub fn exit (&mut self) {

        // Check if in main loop
        if self._is_in_main_loop {

            info! ("Exiting main loop.");
            self._should_exit = true;
        }

        else {

            info! ("Shutting down ion Core.");

            // Release the managers, and release self
            self._release_managers ();
            App::_terminate ();
        }
    }

/*===============================================================================================*/
/*------APP PUBLIC STATIC METHODS----------------------------------------------------------------*/
/*===============================================================================================*/

    /// Returns a new App Builder.
    pub fn builder () -> AppBuilder {
        AppBuilder::new ()
    }

/*-----------------------------------------------------------------------------------------------*/

    /// Checks if the app has been initialized.
    ///
    /// # Return value
    /// A bool returning whether the app has been initialized.
    pub fn is_initialized () -> bool {

        unsafe {

            match APP_POINTER {

                Some (pointer) => !pointer.is_null (),
                None => false
            }
        }
    }

/*-----------------------------------------------------------------------------------------------*/

    /// Returns a reference to the app instance.
    pub fn get_instance () -> Result<&'static App, ()> {

        if App::is_initialized () {
            return Ok (unsafe {&*APP_POINTER.unwrap ()});
        }

        Err (())
    }

/*-----------------------------------------------------------------------------------------------*/

    /// Returns a mutable reference to the app instance.
    pub fn get_instance_mut () -> Result<&'static mut App, ()> {

        if App::is_initialized () {
            return Ok (unsafe {&mut *APP_POINTER.unwrap ()});
        }

        Err (())
    }

/*===============================================================================================*/
/*------APP PRIVATE METHODS----------------------------------------------------------------------*/
/*===============================================================================================*/

    // Initializes the various managers.
    fn _init_managers (&self) {

        self.resource_mgr.borrow_mut ().init ();
        self.window_mgr.borrow_mut   ().init ();
    }

/*-----------------------------------------------------------------------------------------------*/

    // TODO: Finish me
    // On pre render
    fn _on_pre_render (&self) {
        self.window_mgr.borrow_mut ().on_pre_render ();
    }

/*-----------------------------------------------------------------------------------------------*/

    // TODO: Finish me
    // On render
    fn _on_render (&self) {
        self.window_mgr.borrow_mut ().on_render ();
    }

/*-----------------------------------------------------------------------------------------------*/

    // TODO: Finish me
    // On post render
    fn _on_post_render (&self) {
        self.window_mgr.borrow_mut ().on_post_render ();
    }

/*-----------------------------------------------------------------------------------------------*/

    // Releases the managers
    fn _release_managers (&self) {
        self.window_mgr.borrow_mut ().release ();
    }

/*===============================================================================================*/
/*------APP PRIVATE STATIC METHODS---------------------------------------------------------------*/
/*===============================================================================================*/

    // Release the app pointer, and terminate the application.
    fn _terminate () {

        unsafe {

            drop (Box::from_raw (APP_POINTER.unwrap ()));
            APP_POINTER = None;
        };

        // Release the logger, and shutdown the application
        info! ("Terminating the application.");
        Logger::release ();

        process::exit (0);
    }
}

/*===============================================================================================*/
/*------APP BUILDER STRUCT-----------------------------------------------------------------------*/
/*===============================================================================================*/

/// Used for building a new, static app instance.
pub struct AppBuilder {

    // Private
    _app_name: String,
    _app_developer: String,
    _app_publisher: String,
    _app_version: Version,
}

/*===============================================================================================*/
/*------APP BUILDER PUBLIC METHODS---------------------------------------------------------------*/
/*===============================================================================================*/

impl AppBuilder {

    /// Sets the app name.
    pub fn name (&mut self, name: &str) -> &mut Self {

        self._app_name = name.to_string ();
        self
    }

/*-----------------------------------------------------------------------------------------------*/

    /// Sets the app developer.
    pub fn developer (&mut self, developer: &str) -> &mut Self {

        self._app_developer = developer.to_string ();
        self
    }

/*-----------------------------------------------------------------------------------------------*/

    /// Sets the app publisher
    pub fn publisher (&mut self, publisher: &str) -> &mut Self {

        self._app_publisher = publisher.to_string ();
        self
    }

/*-----------------------------------------------------------------------------------------------*/

    /// Sets the app version
    pub fn version (&mut self, version: Version) -> &mut Self {

        self._app_version = version;
        self
    }

/*-----------------------------------------------------------------------------------------------*/

    /// Builds the app.
    pub fn build (&self) -> Result<&'static mut App, ()> {

        // Check if initialized
        if !App::is_initialized () {

            let app_info = AppInfo {

                app_name: self._app_name.clone (),
                app_developer: self._app_developer.clone (),
                app_publisher: self._app_publisher.clone (),
                app_version: self._app_version
            };

            let ab = Box::new (App {

                app_info: app_info,
                resource_mgr: Rc::new (RefCell::new (ResourceManager::new ())),
                window_mgr: Rc::new (RefCell::new (WindowManager::new ())),
                _is_in_main_loop: false,
                _should_exit: false,
            });

            unsafe {APP_POINTER = Some (Box::into_raw (ab))};
        }

        App::get_instance_mut ()
    }

/*===============================================================================================*/
/*------APP BUILDER PUBLIC STATIC METHODS--------------------------------------------------------*/
/*===============================================================================================*/

    /// Returns a new app builder instance.
    pub fn new () -> AppBuilder {

        AppBuilder {

            _app_name: "Unknown".to_string (),
            _app_developer: "Unknown".to_string (),
            _app_publisher: "Unknown".to_string (),
            _app_version: Version::new ()
        }
    }
}

/*-----------------------------------------------------------------------------------------------*/

impl Default for AppBuilder {

    fn default () -> AppBuilder {
        AppBuilder::new ()
    }
}
<|endoftext|>


<commit_before>use engine::{IntoMap, Tile};
use util::units::{Point, Size};

use std::path::AsPath;
use std::fs::File;
use std::io::Read;

pub struct Map {
    pub tiles: Vec<Vec<Tile>>,
    pub size: Size,
}

impl Map {

    pub fn new<T>(maplike: T) -> Map where T: IntoMap {
        let result = maplike.as_map();

        let map = match result {
            Ok(map) => map,
            Err(msg) => {
                panic!(msg);
            }
        };

        map
    }

    pub fn from_file<T>(path: T) -> Map where T: AsPath {
        let mut level_file = File::open(&path).ok().expect("Could not find level file");
        let mut level_string = String::new();

        level_file.read_to_string(&mut level_string).ok().expect("Could not read from level file");

        Map::new(level_string)
    }

    pub fn at(&self, loc: Point) -> Tile {
        self.tiles[loc.y as usize][loc.x as usize]
    }

    pub fn is_walkable(&self, loc: Point) -> bool {
        self.at(loc).is_walkable()
    }

    pub fn set_tile(&mut self, loc: Point, tile: Tile) {
        self.tiles[loc.y as usize][loc.x as usize] = tile;
    }

    pub fn height(&self) -> i32 {
        self.tiles.len() as i32
    }

    pub fn width(&self) -> i32 {
        self.tiles[0].len() as i32
    }

}
<commit_msg>Remove an antipattern better represented with 'unwrap'<commit_after>use engine::{IntoMap, Tile};
use util::units::{Point, Size};

use std::path::AsPath;
use std::fs::File;
use std::io::Read;

pub struct Map {
    pub tiles: Vec<Vec<Tile>>,
    pub size: Size,
}

impl Map {

    pub fn new<T>(maplike: T) -> Map where T: IntoMap {
        maplike.as_map().unwrap()
    }

    pub fn from_file<T>(path: T) -> Map where T: AsPath {
        let mut level_file = File::open(&path).ok().expect("Could not find level file");
        let mut level_string = String::new();

        level_file.read_to_string(&mut level_string).ok().expect("Could not read from level file");

        Map::new(level_string)
    }

    pub fn at(&self, loc: Point) -> Tile {
        self.tiles[loc.y as usize][loc.x as usize]
    }

    pub fn is_walkable(&self, loc: Point) -> bool {
        self.at(loc).is_walkable()
    }

    pub fn set_tile(&mut self, loc: Point, tile: Tile) {
        self.tiles[loc.y as usize][loc.x as usize] = tile;
    }

    pub fn height(&self) -> i32 {
        self.tiles.len() as i32
    }

    pub fn width(&self) -> i32 {
        self.tiles[0].len() as i32
    }

}
<|endoftext|>


<commit_before>// Copyright (c) 2016 Fabian Schuiki

//! Utilities to implement diagnostics and error reporting facilities.

use source::Span;
use std::fmt;

/// A handler deals with errors.
#[derive(Debug)]
pub struct Handler {
}

pub static DUMMY_HANDLER: Handler = Handler{};

/// Used to emit structured error messages.
#[must_use]
#[derive(Clone, Debug)]
pub struct DiagnosticBuilder<'a> {
	pub handler: &'a Handler,
	pub message: String,
}

/// A diagnostic result type. Either carries the result `T` in the Ok variant,
/// or an assembled diagnostic in the Err variant.
pub type DiagResult<'a, T> = Result<T, DiagnosticBuilder<'a>>;

#[must_use]
#[derive(Clone, Debug)]
pub struct DiagBuilder2 {
	pub severity: Severity,
	pub message: String,
	pub span: Option<Span>,
}

/// A diagnostic result type. Either carries the result `T` in the Ok variant,
/// or an assembled diagnostic in the Err variant.
pub type DiagResult2<T> = Result<T, DiagBuilder2>;

impl DiagBuilder2 {
	pub fn fatal<S: Into<String>>(message: S) -> DiagBuilder2 {
		DiagBuilder2 {
			severity: Severity::Fatal,
			message: message.into(),
			span: None,
		}
	}

	pub fn error<S: Into<String>>(message: S) -> DiagBuilder2 {
		DiagBuilder2 {
			severity: Severity::Error,
			message: message.into(),
			span: None,
		}
	}

	pub fn warning<S: Into<String>>(message: S) -> DiagBuilder2 {
		DiagBuilder2 {
			severity: Severity::Warning,
			message: message.into(),
			span: None,
		}
	}

	pub fn span<S: Into<Span>>(self, span: S) -> DiagBuilder2 {
		DiagBuilder2 {
			span: Some(span.into()),
			..self
		}
	}

	pub fn get_severity(&self) -> Severity {
		self.severity
	}

	pub fn get_message(&self) -> &String {
		&self.message
	}

	pub fn get_span(&self) -> Option<Span> {
		self.span
	}
}

#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Debug)]
pub enum Severity {
	Fatal,
	Error,
	Warning,
	Note,
}

impl Severity {
	pub fn to_str(self) -> &'static str {
		match self {
			Severity::Fatal => "fatal",
			Severity::Error => "error",
			Severity::Warning => "warning",
			Severity::Note => "note",
		}
	}
}

impl fmt::Display for Severity {
	fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
		write!(f, "{}", self.to_str())
	}
}
<commit_msg>errors: add support for `note` severity<commit_after>// Copyright (c) 2016 Fabian Schuiki

//! Utilities to implement diagnostics and error reporting facilities.

use source::Span;
use std::fmt;

/// A handler deals with errors.
#[derive(Debug)]
pub struct Handler {
}

pub static DUMMY_HANDLER: Handler = Handler{};

/// Used to emit structured error messages.
#[must_use]
#[derive(Clone, Debug)]
pub struct DiagnosticBuilder<'a> {
	pub handler: &'a Handler,
	pub message: String,
}

/// A diagnostic result type. Either carries the result `T` in the Ok variant,
/// or an assembled diagnostic in the Err variant.
pub type DiagResult<'a, T> = Result<T, DiagnosticBuilder<'a>>;

#[must_use]
#[derive(Clone, Debug)]
pub struct DiagBuilder2 {
	pub severity: Severity,
	pub message: String,
	pub span: Option<Span>,
}

/// A diagnostic result type. Either carries the result `T` in the Ok variant,
/// or an assembled diagnostic in the Err variant.
pub type DiagResult2<T> = Result<T, DiagBuilder2>;

impl DiagBuilder2 {
	pub fn fatal<S: Into<String>>(message: S) -> DiagBuilder2 {
		DiagBuilder2 {
			severity: Severity::Fatal,
			message: message.into(),
			span: None,
		}
	}

	pub fn error<S: Into<String>>(message: S) -> DiagBuilder2 {
		DiagBuilder2 {
			severity: Severity::Error,
			message: message.into(),
			span: None,
		}
	}

	pub fn warning<S: Into<String>>(message: S) -> DiagBuilder2 {
		DiagBuilder2 {
			severity: Severity::Warning,
			message: message.into(),
			span: None,
		}
	}

	pub fn note<S: Into<String>>(message: S) -> DiagBuilder2 {
		DiagBuilder2 {
			severity: Severity::Note,
			message: message.into(),
			span: None,
		}
	}

	pub fn span<S: Into<Span>>(self, span: S) -> DiagBuilder2 {
		DiagBuilder2 {
			span: Some(span.into()),
			..self
		}
	}

	pub fn get_severity(&self) -> Severity {
		self.severity
	}

	pub fn get_message(&self) -> &String {
		&self.message
	}

	pub fn get_span(&self) -> Option<Span> {
		self.span
	}
}

#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Debug)]
pub enum Severity {
	Fatal,
	Error,
	Warning,
	Note,
}

impl Severity {
	pub fn to_str(self) -> &'static str {
		match self {
			Severity::Fatal => "fatal",
			Severity::Error => "error",
			Severity::Warning => "warning",
			Severity::Note => "note",
		}
	}
}

impl fmt::Display for Severity {
	fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
		write!(f, "{}", self.to_str())
	}
}
<|endoftext|>


<commit_before>use self::airport::Runway;
use ::rocket::http::RawStr;
use ::rocket::request::FromFormValue;
use ::std::ops::Deref;
use util::StringUtil;

pub mod airport;
pub mod data;
pub mod route;

macro_rules! gen_filter_type {
    ($name:ident, $form_ty:ty,
        $($struct_variant:ident => $enum_variant:ident($type:ty),)*) => {

        #[derive(Debug)]
        pub enum $name {
            $($enum_variant($type),)*
        }

        impl $name {
            fn from_form(form: &$form_ty) -> Vec<$name> {
                let mut found = Vec::new();

                $(match form.$struct_variant {
                    Some(ref v) => found.push($name::$enum_variant(v.clone())),
                    None => (),
                })*

                found
            }
        }
    };
}

#[derive(FromForm, Debug)]
pub struct DataForm {
    pub mach:           f32,
    pub dep_icao:       Option<ICAO>,
    pub dep_type:       Option<airport::Type>,
    pub dep_runway_len: Option<RunwayLength>,
    pub dep_country:    Option<String>,
    pub arr_icao:       Option<ICAO>,
    pub arr_type:       Option<airport::Type>,
    pub arr_runway_len: Option<RunwayLength>,
    pub arr_country:    Option<String>,
    pub min_time:       Option<Time>,
    pub max_time:       Option<Time>,
}

gen_filter_type!(AirportFilter, DataForm,
    dep_type       => Type(airport::Type),
    dep_runway_len => RunwayLength(RunwayLength),
    dep_country    => Country(String),
);

gen_filter_type!(RouteFilter, DataForm,
    arr_type       => ArrType(airport::Type),
    arr_runway_len => ArrRunwayLength(RunwayLength),
    arr_country    => ArrCountry(String),
    min_time       => MinTime(Time),
    max_time       => MaxTime(Time),
);

#[derive(Debug, Serialize, Clone)]
pub struct ICAO(pub String);

impl<'v> FromFormValue<'v> for ICAO {
    type Error = &'v RawStr;

    fn from_form_value(form_value: &'v RawStr) -> Result<ICAO, &'v RawStr> {
        if form_value != "" {
            Ok(ICAO(form_value.as_str().into()))
        } else {
            Err(form_value)
        }
    }
}

impl Deref for ICAO {
    type Target = String;

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

#[derive(Debug, Clone)]
pub struct Time(pub f32);

impl<'v> FromFormValue<'v> for Time {
    type Error = &'v RawStr;

    fn from_form_value(form_value: &'v RawStr) -> Result<Time, &'v RawStr> {
        let value = form_value.as_str();
        let split = value.splitn(2, "%3A") // %3A = :
                         .collect::<Vec<_>>();

        if split.len() < 2 {
            match value.parse::<f32>() {
                Ok(v)  => Ok(Time(v)),
                Err(_) => Err(form_value),
            }
        } else {
            let hour   = split[0].parse::<i32>().map_err(|_| form_value)?;
            let minute = split[1].parse::<i32>().map_err(|_| form_value)?;

            Ok(Time(hour as f32 + (minute as f32 / 60.0)))
        }
    }
}

type Length    = u32;
type MinLength = Length;
type MaxLength = Length;

#[derive(Debug, Clone)]
pub enum RunwayLength {
    LessThan(Length),
    GreaterThan(Length),
    EqualTo(Length),
    Between(MinLength, MaxLength),
}

impl RunwayLength {
    fn parse_single(input_str: &RawStr) -> Result<RunwayLength, &RawStr> {
        if input_str.len() > 3 {
            use self::RunwayLength::*;
            let value = input_str[3..].parse().map_err(|_| input_str)?;

            match &input_str[..3] {
                "%3C" => Ok(LessThan(value)),    // <
                "%3E" => Ok(GreaterThan(value)), // >
                "%3D" => Ok(EqualTo(value)),     // =
                _     => Err(input_str),
            }
        } else {
            Err(input_str)
        }
    }

    fn parse_between(input_str: &RawStr) -> Result<RunwayLength, &RawStr> {
        let values = input_str.splitn(2, '+')
                              .collect::<Vec<_>>();

        if values.len() == 2 {
            let min = values[0].parse().map_err(|_| input_str)?;
            let max = values[1].parse().map_err(|_| input_str)?;

            Ok(RunwayLength::Between(min, max))
        } else {
            Err(input_str)
        }
    }

    pub fn parse(input_str: &RawStr) -> Result<RunwayLength, &RawStr> {
        // Since slices are invovled in parsing, accepting non-ascii strings
        // can cause a panic from going out of bounds
        if input_str.is_ascii() {
            RunwayLength::parse_between(input_str)
                .or(RunwayLength::parse_single(input_str))
        } else {
            println!("non");
            Err(input_str)
        }
    }

    pub fn is_match(&self, runway: &Runway) -> bool {
        match runway.length {
            Some(run_len) => {
                use self::RunwayLength::*;
                match *self {
                    LessThan(len)             => run_len <= len,
                    GreaterThan(len)          => run_len >= len,
                    EqualTo(len)              => run_len == len,
                    Between(min_len, max_len) => run_len >= min_len && run_len <= max_len,
                }
            },
            None => false,
        }
    }

    pub fn any_match(&self, runways: &Option<Vec<Runway>>) -> bool {
        match *runways {
            Some(ref runways) => runways.iter().any(|r| self.is_match(r)),
            None => false,
        }
    }
}

impl<'v> FromFormValue<'v> for RunwayLength {
    type Error = &'v RawStr;

    fn from_form_value(form_value: &'v RawStr) -> Result<RunwayLength, &'v RawStr> {
        RunwayLength::parse(form_value)
    }
}<commit_msg>... nothing to see here<commit_after>use self::airport::Runway;
use ::rocket::http::RawStr;
use ::rocket::request::FromFormValue;
use ::std::ops::Deref;
use util::StringUtil;

pub mod airport;
pub mod data;
pub mod route;

macro_rules! gen_filter_type {
    ($name:ident, $form_ty:ty,
        $($struct_variant:ident => $enum_variant:ident($type:ty),)*) => {

        #[derive(Debug)]
        pub enum $name {
            $($enum_variant($type),)*
        }

        impl $name {
            fn from_form(form: &$form_ty) -> Vec<$name> {
                let mut found = Vec::new();

                $(match form.$struct_variant {
                    Some(ref v) => found.push($name::$enum_variant(v.clone())),
                    None => (),
                })*

                found
            }
        }
    };
}

#[derive(FromForm, Debug)]
pub struct DataForm {
    pub mach:           f32,
    pub dep_icao:       Option<ICAO>,
    pub dep_type:       Option<airport::Type>,
    pub dep_runway_len: Option<RunwayLength>,
    pub dep_country:    Option<String>,
    pub arr_icao:       Option<ICAO>,
    pub arr_type:       Option<airport::Type>,
    pub arr_runway_len: Option<RunwayLength>,
    pub arr_country:    Option<String>,
    pub min_time:       Option<Time>,
    pub max_time:       Option<Time>,
}

gen_filter_type!(AirportFilter, DataForm,
    dep_type       => Type(airport::Type),
    dep_runway_len => RunwayLength(RunwayLength),
    dep_country    => Country(String),
);

gen_filter_type!(RouteFilter, DataForm,
    arr_type       => ArrType(airport::Type),
    arr_runway_len => ArrRunwayLength(RunwayLength),
    arr_country    => ArrCountry(String),
    min_time       => MinTime(Time),
    max_time       => MaxTime(Time),
);

#[derive(Debug, Serialize, Clone)]
pub struct ICAO(pub String);

impl<'v> FromFormValue<'v> for ICAO {
    type Error = &'v RawStr;

    fn from_form_value(form_value: &'v RawStr) -> Result<ICAO, &'v RawStr> {
        if form_value != "" {
            Ok(ICAO(form_value.as_str().into()))
        } else {
            Err(form_value)
        }
    }
}

impl Deref for ICAO {
    type Target = String;

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

#[derive(Debug, Clone)]
pub struct Time(pub f32);

impl<'v> FromFormValue<'v> for Time {
    type Error = &'v RawStr;

    fn from_form_value(form_value: &'v RawStr) -> Result<Time, &'v RawStr> {
        let value = form_value.as_str();
        let split = value.splitn(2, "%3A") // %3A = :
                         .collect::<Vec<_>>();

        if split.len() < 2 {
            match value.parse::<f32>() {
                Ok(v)  => Ok(Time(v)),
                Err(_) => Err(form_value),
            }
        } else {
            let hour   = split[0].parse::<i32>().map_err(|_| form_value)?;
            let minute = split[1].parse::<i32>().map_err(|_| form_value)?;

            Ok(Time(hour as f32 + (minute as f32 / 60.0)))
        }
    }
}

type Length    = u32;
type MinLength = Length;
type MaxLength = Length;

#[derive(Debug, Clone)]
pub enum RunwayLength {
    LessThan(Length),
    GreaterThan(Length),
    EqualTo(Length),
    Between(MinLength, MaxLength),
}

impl RunwayLength {
    fn parse_single(input_str: &RawStr) -> Result<RunwayLength, &RawStr> {
        if input_str.len() > 3 {
            use self::RunwayLength::*;
            let value = input_str[3..].parse().map_err(|_| input_str)?;

            match &input_str[..3] {
                "%3C" => Ok(LessThan(value)),    // <
                "%3E" => Ok(GreaterThan(value)), // >
                "%3D" => Ok(EqualTo(value)),     // =
                _     => Err(input_str),
            }
        } else {
            Err(input_str)
        }
    }

    fn parse_between(input_str: &RawStr) -> Result<RunwayLength, &RawStr> {
        let values = input_str.splitn(2, '+')
                              .collect::<Vec<_>>();

        if values.len() == 2 {
            let min = values[0].parse().map_err(|_| input_str)?;
            let max = values[1].parse().map_err(|_| input_str)?;

            Ok(RunwayLength::Between(min, max))
        } else {
            Err(input_str)
        }
    }

    pub fn parse(input_str: &RawStr) -> Result<RunwayLength, &RawStr> {
        // Since slices are invovled in parsing, accepting non-ascii strings
        // can cause a panic from going out of bounds
        if input_str.is_ascii() {
            RunwayLength::parse_between(input_str)
                .or(RunwayLength::parse_single(input_str))
        } else {
            Err(input_str)
        }
    }

    pub fn is_match(&self, runway: &Runway) -> bool {
        match runway.length {
            Some(run_len) => {
                use self::RunwayLength::*;
                match *self {
                    LessThan(len)             => run_len <= len,
                    GreaterThan(len)          => run_len >= len,
                    EqualTo(len)              => run_len == len,
                    Between(min_len, max_len) => run_len >= min_len && run_len <= max_len,
                }
            },
            None => false,
        }
    }

    pub fn any_match(&self, runways: &Option<Vec<Runway>>) -> bool {
        match *runways {
            Some(ref runways) => runways.iter().any(|r| self.is_match(r)),
            None => false,
        }
    }
}

impl<'v> FromFormValue<'v> for RunwayLength {
    type Error = &'v RawStr;

    fn from_form_value(form_value: &'v RawStr) -> Result<RunwayLength, &'v RawStr> {
        RunwayLength::parse(form_value)
    }
}<|endoftext|>


<commit_before>use float::Float;
use int::Int;

macro_rules! int_to_float {
    ($intrinsic:ident: $ity:ty, $fty:ty) => {
        int_to_float!($intrinsic: $ity, $fty, "C");
    };
    ($intrinsic:ident: $ity:ty, $fty:ty, $abi:tt) => {

    pub extern $abi fn $intrinsic(i: $ity) -> $fty {
        if i == 0 {
            return 0.0
        }

        let mant_dig = <$fty>::significand_bits() + 1;
        let exponent_bias = <$fty>::exponent_bias();

        let n = <$ity>::bits();
        let (s, a) = i.extract_sign();
        let mut a = a;

        // number of significant digits
        let sd = n - a.leading_zeros();

        // exponent
        let mut e = sd - 1;

        if <$ity>::bits() < mant_dig {
            return <$fty>::from_parts(s,
                (e + exponent_bias) as <$fty as Float>::Int,
                (a as <$fty as Float>::Int) << (mant_dig - e - 1))
        }

        a = if sd > mant_dig {
            /* start:  0000000000000000000001xxxxxxxxxxxxxxxxxxxxxxPQxxxxxxxxxxxxxxxxxx
            *  finish: 000000000000000000000000000000000000001xxxxxxxxxxxxxxxxxxxxxxPQR
            *                                                12345678901234567890123456
            *  1 = msb 1 bit
            *  P = bit MANT_DIG-1 bits to the right of 1
            *  Q = bit MANT_DIG bits to the right of 1
            *  R = "or" of all bits to the right of Q
            */
            let mant_dig_plus_one = mant_dig + 1;
            let mant_dig_plus_two = mant_dig + 2;
            a = if sd == mant_dig_plus_one {
                a << 1
            } else if sd == mant_dig_plus_two {
                a
            } else {
                (a >> (sd - mant_dig_plus_two)) as <$ity as Int>::UnsignedInt |
                ((a & <$ity as Int>::UnsignedInt::max_value()).wrapping_shl((n + mant_dig_plus_two) - sd) != 0) as <$ity as Int>::UnsignedInt
            };

            /* finish: */
            a |= ((a & 4) != 0) as <$ity as Int>::UnsignedInt; /* Or P into R */
            a += 1; /* round - this step may add a significant bit */
            a >>= 2; /* dump Q and R */

            /* a is now rounded to mant_dig or mant_dig+1 bits */
            if (a & (1 << mant_dig)) != 0 {
                a >>= 1; e += 1;
            }
            a
            /* a is now rounded to mant_dig bits */
        } else {
            a.wrapping_shl(mant_dig - sd)
            /* a is now rounded to mant_dig bits */
        };

        <$fty>::from_parts(s,
            (e + exponent_bias) as <$fty as Float>::Int,
            a as <$fty as Float>::Int)
    }
    }
}

macro_rules! int_to_float_unadj_on_win {
    ($intrinsic:ident: $ity:ty, $fty:ty) => {
        #[cfg(all(windows, target_pointer_width="64"))]
        int_to_float!($intrinsic: $ity, $fty, "unadjusted");
        #[cfg(not(all(windows, target_pointer_width="64")))]
        int_to_float!($intrinsic: $ity, $fty, "C");
    };
}

int_to_float!(__floatsisf: i32, f32);
int_to_float!(__floatsidf: i32, f64);
int_to_float!(__floatdidf: i64, f64);
int_to_float_unadj_on_win!(__floattisf: i128, f32);
int_to_float_unadj_on_win!(__floattidf: i128, f64);
int_to_float!(__floatunsisf: u32, f32);
int_to_float!(__floatunsidf: u32, f64);
int_to_float!(__floatundidf: u64, f64);
int_to_float_unadj_on_win!(__floatuntisf: u128, f32);
int_to_float_unadj_on_win!(__floatuntidf: u128, f64);

#[derive(PartialEq, Debug)]
enum Sign {
    Positive,
    Negative
}

macro_rules! float_to_int {
    ($intrinsic:ident: $fty:ty, $ity:ty) => {
        float_to_int!($intrinsic: $fty, $ity, "C");
    };
    ($intrinsic:ident: $fty:ty, $ity:ty, $abi:tt) => {
        pub extern $abi fn $intrinsic(f: $fty) -> $ity {
            let fixint_min = <$ity>::min_value();
            let fixint_max = <$ity>::max_value();
            let fixint_bits = <$ity>::bits() as usize;
            let fixint_unsigned = fixint_min == 0;

            let sign_bit = <$fty>::sign_mask();
            let significand_bits = <$fty>::significand_bits() as usize;
            let exponent_bias = <$fty>::exponent_bias() as usize;
            //let exponent_max = <$fty>::exponent_max() as usize;

            // Break a into sign, exponent, significand
            let a_rep = <$fty>::repr(f);
            let a_abs = a_rep & !sign_bit;

            // this is used to work around -1 not being available for unsigned
            let sign = if (a_rep & sign_bit) == 0 { Sign::Positive } else { Sign::Negative };
            let mut exponent = (a_abs >> significand_bits) as usize;
            let significand = (a_abs & <$fty>::significand_mask()) | <$fty>::implicit_bit();

            // if < 1 or unsigned & negative
            if  exponent < exponent_bias ||
                fixint_unsigned && sign == Sign::Negative {
                return 0
            }
            exponent -= exponent_bias;

            // If the value is infinity, saturate.
            // If the value is too large for the integer type, 0.
            if exponent >= (if fixint_unsigned {fixint_bits} else {fixint_bits -1}) {
                return if sign == Sign::Positive {fixint_max} else {fixint_min}
            }
            // If 0 <= exponent < significand_bits, right shift to get the result.
            // Otherwise, shift left.
            // (sign - 1) will never overflow as negative signs are already returned as 0 for unsigned
            let r = if exponent < significand_bits {
                (significand >> (significand_bits - exponent)) as $ity
            } else {
                (significand as $ity) << (exponent - significand_bits)
            };

            if sign == Sign::Negative {
                (!r).wrapping_add(1)
            } else {
                r
            }
        }
    }
}

macro_rules! float_to_int_unadj_on_win {
    ($intrinsic:ident: $fty:ty, $ity:ty) => {
        #[cfg(all(windows, target_pointer_width="64"))]
        float_to_int!($intrinsic: $fty, $ity, "unadjusted");
        #[cfg(not(all(windows, target_pointer_width="64")))]
        float_to_int!($intrinsic: $fty, $ity, "C");
    };
}

float_to_int!(__fixsfsi: f32, i32);
float_to_int!(__fixsfdi: f32, i64);
float_to_int_unadj_on_win!(__fixsfti: f32, i128);
float_to_int!(__fixdfsi: f64, i32);
float_to_int!(__fixdfdi: f64, i64);
float_to_int_unadj_on_win!(__fixdfti: f64, i128);

float_to_int!(__fixunssfsi: f32, u32);
float_to_int!(__fixunssfdi: f32, u64);
float_to_int_unadj_on_win!(__fixunssfti: f32, u128);
float_to_int!(__fixunsdfsi: f64, u32);
float_to_int!(__fixunsdfdi: f64, u64);
float_to_int_unadj_on_win!(__fixunsdfti: f64, u128);
<commit_msg>Remove executable bit from conv.rs<commit_after>use float::Float;
use int::Int;

macro_rules! int_to_float {
    ($intrinsic:ident: $ity:ty, $fty:ty) => {
        int_to_float!($intrinsic: $ity, $fty, "C");
    };
    ($intrinsic:ident: $ity:ty, $fty:ty, $abi:tt) => {

    pub extern $abi fn $intrinsic(i: $ity) -> $fty {
        if i == 0 {
            return 0.0
        }

        let mant_dig = <$fty>::significand_bits() + 1;
        let exponent_bias = <$fty>::exponent_bias();

        let n = <$ity>::bits();
        let (s, a) = i.extract_sign();
        let mut a = a;

        // number of significant digits
        let sd = n - a.leading_zeros();

        // exponent
        let mut e = sd - 1;

        if <$ity>::bits() < mant_dig {
            return <$fty>::from_parts(s,
                (e + exponent_bias) as <$fty as Float>::Int,
                (a as <$fty as Float>::Int) << (mant_dig - e - 1))
        }

        a = if sd > mant_dig {
            /* start:  0000000000000000000001xxxxxxxxxxxxxxxxxxxxxxPQxxxxxxxxxxxxxxxxxx
            *  finish: 000000000000000000000000000000000000001xxxxxxxxxxxxxxxxxxxxxxPQR
            *                                                12345678901234567890123456
            *  1 = msb 1 bit
            *  P = bit MANT_DIG-1 bits to the right of 1
            *  Q = bit MANT_DIG bits to the right of 1
            *  R = "or" of all bits to the right of Q
            */
            let mant_dig_plus_one = mant_dig + 1;
            let mant_dig_plus_two = mant_dig + 2;
            a = if sd == mant_dig_plus_one {
                a << 1
            } else if sd == mant_dig_plus_two {
                a
            } else {
                (a >> (sd - mant_dig_plus_two)) as <$ity as Int>::UnsignedInt |
                ((a & <$ity as Int>::UnsignedInt::max_value()).wrapping_shl((n + mant_dig_plus_two) - sd) != 0) as <$ity as Int>::UnsignedInt
            };

            /* finish: */
            a |= ((a & 4) != 0) as <$ity as Int>::UnsignedInt; /* Or P into R */
            a += 1; /* round - this step may add a significant bit */
            a >>= 2; /* dump Q and R */

            /* a is now rounded to mant_dig or mant_dig+1 bits */
            if (a & (1 << mant_dig)) != 0 {
                a >>= 1; e += 1;
            }
            a
            /* a is now rounded to mant_dig bits */
        } else {
            a.wrapping_shl(mant_dig - sd)
            /* a is now rounded to mant_dig bits */
        };

        <$fty>::from_parts(s,
            (e + exponent_bias) as <$fty as Float>::Int,
            a as <$fty as Float>::Int)
    }
    }
}

macro_rules! int_to_float_unadj_on_win {
    ($intrinsic:ident: $ity:ty, $fty:ty) => {
        #[cfg(all(windows, target_pointer_width="64"))]
        int_to_float!($intrinsic: $ity, $fty, "unadjusted");
        #[cfg(not(all(windows, target_pointer_width="64")))]
        int_to_float!($intrinsic: $ity, $fty, "C");
    };
}

int_to_float!(__floatsisf: i32, f32);
int_to_float!(__floatsidf: i32, f64);
int_to_float!(__floatdidf: i64, f64);
int_to_float_unadj_on_win!(__floattisf: i128, f32);
int_to_float_unadj_on_win!(__floattidf: i128, f64);
int_to_float!(__floatunsisf: u32, f32);
int_to_float!(__floatunsidf: u32, f64);
int_to_float!(__floatundidf: u64, f64);
int_to_float_unadj_on_win!(__floatuntisf: u128, f32);
int_to_float_unadj_on_win!(__floatuntidf: u128, f64);

#[derive(PartialEq, Debug)]
enum Sign {
    Positive,
    Negative
}

macro_rules! float_to_int {
    ($intrinsic:ident: $fty:ty, $ity:ty) => {
        float_to_int!($intrinsic: $fty, $ity, "C");
    };
    ($intrinsic:ident: $fty:ty, $ity:ty, $abi:tt) => {
        pub extern $abi fn $intrinsic(f: $fty) -> $ity {
            let fixint_min = <$ity>::min_value();
            let fixint_max = <$ity>::max_value();
            let fixint_bits = <$ity>::bits() as usize;
            let fixint_unsigned = fixint_min == 0;

            let sign_bit = <$fty>::sign_mask();
            let significand_bits = <$fty>::significand_bits() as usize;
            let exponent_bias = <$fty>::exponent_bias() as usize;
            //let exponent_max = <$fty>::exponent_max() as usize;

            // Break a into sign, exponent, significand
            let a_rep = <$fty>::repr(f);
            let a_abs = a_rep & !sign_bit;

            // this is used to work around -1 not being available for unsigned
            let sign = if (a_rep & sign_bit) == 0 { Sign::Positive } else { Sign::Negative };
            let mut exponent = (a_abs >> significand_bits) as usize;
            let significand = (a_abs & <$fty>::significand_mask()) | <$fty>::implicit_bit();

            // if < 1 or unsigned & negative
            if  exponent < exponent_bias ||
                fixint_unsigned && sign == Sign::Negative {
                return 0
            }
            exponent -= exponent_bias;

            // If the value is infinity, saturate.
            // If the value is too large for the integer type, 0.
            if exponent >= (if fixint_unsigned {fixint_bits} else {fixint_bits -1}) {
                return if sign == Sign::Positive {fixint_max} else {fixint_min}
            }
            // If 0 <= exponent < significand_bits, right shift to get the result.
            // Otherwise, shift left.
            // (sign - 1) will never overflow as negative signs are already returned as 0 for unsigned
            let r = if exponent < significand_bits {
                (significand >> (significand_bits - exponent)) as $ity
            } else {
                (significand as $ity) << (exponent - significand_bits)
            };

            if sign == Sign::Negative {
                (!r).wrapping_add(1)
            } else {
                r
            }
        }
    }
}

macro_rules! float_to_int_unadj_on_win {
    ($intrinsic:ident: $fty:ty, $ity:ty) => {
        #[cfg(all(windows, target_pointer_width="64"))]
        float_to_int!($intrinsic: $fty, $ity, "unadjusted");
        #[cfg(not(all(windows, target_pointer_width="64")))]
        float_to_int!($intrinsic: $fty, $ity, "C");
    };
}

float_to_int!(__fixsfsi: f32, i32);
float_to_int!(__fixsfdi: f32, i64);
float_to_int_unadj_on_win!(__fixsfti: f32, i128);
float_to_int!(__fixdfsi: f64, i32);
float_to_int!(__fixdfdi: f64, i64);
float_to_int_unadj_on_win!(__fixdfti: f64, i128);

float_to_int!(__fixunssfsi: f32, u32);
float_to_int!(__fixunssfdi: f32, u64);
float_to_int_unadj_on_win!(__fixunssfti: f32, u128);
float_to_int!(__fixunsdfsi: f64, u32);
float_to_int!(__fixunsdfdi: f64, u64);
float_to_int_unadj_on_win!(__fixunsdfti: f64, u128);
<|endoftext|>


<commit_before>pub use self::Color::{White,Black};

#[derive(PartialEq, Eq, Copy, Clone, Show)]
pub enum Color {
    White,
    Black,
}

impl Color {
    pub fn invert(&self) -> Color {
        match *self {
            White => Black,
            Black => White,
        }
    }
}
<commit_msg>Make Color::invert() take self by value<commit_after>pub use self::Color::{White,Black};

#[derive(PartialEq, Eq, Copy, Clone, Show)]
pub enum Color {
    White,
    Black,
}

impl Color {
    pub fn invert(self) -> Color {
        match self {
            White => Black,
            Black => White,
        }
    }
}
<|endoftext|>


<commit_before>// Copyright (c) 2017-2018 Rene van der Meer
//
// Permission is hereby granted, free of charge, to any person obtaining a
// copy of this software and associated documentation files (the "Software"),
// to deal in the Software without restriction, including without limitation
// the rights to use, copy, modify, merge, publish, distribute, sublicense,
// and/or sell copies of the Software, and to permit persons to whom the
// Software is furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
// DEALINGS IN THE SOFTWARE.

// NOTE: This is currently experimental, and may be removed at any point.

#![allow(dead_code)]

use libc::{c_int, c_ulong, ioctl};
use std::io;
use std::mem::size_of;
use std::result;

pub type Result<T> = result::Result<T, io::Error>;

fn parse_retval(retval: c_int) -> Result<i32> {
    if retval == -1 {
        Err(io::Error::last_os_error())
    } else {
        Ok(retval)
    }
}

#[repr(C)]
struct ChipInfo {
    name: [u8; 32],
    label: [u8; 32],
    lines: u32,
}

const LINE_FLAG_KERNEL: u32 = 1;
const LINE_FLAG_IS_OUT: u32 = 1 << 1;
const LINE_FLAG_ACTIVE_LOW: u32 = 1 << 2;
const LINE_FLAG_OPEN_DRAIN: u32 = 1 << 3;
const LINE_FLAG_OPEN_SOURCE: u32 = 1 << 4;

#[repr(C)]
struct LineInfo {
    line_offset: u32,
    flags: u32,
    name: [u8; 32],
    consumer: [u8; 32],
}

const HANDLES_MAX: usize = 64;
const HANDLE_FLAG_INPUT: u32 = 1;
const HANDLE_FLAG_OUTPUT: u32 = 1 << 1;
const HANDLE_FLAG_ACTIVE_LOW: u32 = 1 << 2;
const HANDLE_FLAG_OPEN_DRAIN: u32 = 1 << 3;
const HANDLE_FLAG_OPEN_SOURCE: u32 = 1 << 4;

#[repr(C)]
struct HandleRequest {
    line_offets: [u32; HANDLES_MAX],
    flags: u32,
    default_values: [u8; HANDLES_MAX],
    consumer_label: [u8; 32],
    lines: u32,
    fd: c_int,
}

#[repr(C)]
struct HandleData {
    values: [u8; HANDLES_MAX],
}

const EVENT_FLAG_RISING_EDGE: u32 = 1;
const EVENT_FLAG_FALLING_EDGE: u32 = 1 << 1;
const EVENT_FLAG_BOTH_EDGES: u32 = EVENT_FLAG_RISING_EDGE | EVENT_FLAG_FALLING_EDGE;

#[repr(C)]
struct EventRequest {
    line_offset: u32,
    handle_flags: u32,
    event_flags: u32,
    consumer_label: [u8; 32],
    fd: c_int,
}

const EVENT_TYPE_RISING_EDGE: u32 = 0x01;
const EVENT_TYPE_FALLING_EDGE: u32 = 0x02;

#[repr(C)]
struct EventData {
    timestamp: u64,
    id: u32,
}

const NRBITS: u8 = 8;
const TYPEBITS: u8 = 8;
const SIZEBITS: u8 = 14;
const DIRBITS: u8 = 2;

const NRSHIFT: u8 = 0;
const TYPESHIFT: u8 = (NRSHIFT + NRBITS);
const SIZESHIFT: u8 = (TYPESHIFT + TYPEBITS);
const DIRSHIFT: u8 = (SIZESHIFT + SIZEBITS);

const NR_GET_CHIPINFO: c_ulong = 0x01 << NRSHIFT;
const NR_GET_LINEINFO: c_ulong = 0x02 << NRSHIFT;
const NR_GET_LINEHANDLE: c_ulong = 0x03 << NRSHIFT;
const NR_GET_LINEEVENT: c_ulong = 0x04 << NRSHIFT;
const NR_GET_LINE_VALUES: c_ulong = 0x08 << NRSHIFT;
const NR_SET_LINE_VALUES: c_ulong = 0x09 << NRSHIFT;

const TYPE_GPIO: c_ulong = (0xB4 as c_ulong) << TYPESHIFT;

const SIZE_CHIPINFO: c_ulong = (size_of::<ChipInfo>() as c_ulong) << SIZESHIFT;
const SIZE_LINEINFO: c_ulong = (size_of::<LineInfo>() as c_ulong) << SIZESHIFT;
const SIZE_HANDLEREQUEST: c_ulong = (size_of::<HandleRequest>() as c_ulong) << SIZESHIFT;
const SIZE_EVENTREQUEST: c_ulong = (size_of::<EventRequest>() as c_ulong) << SIZESHIFT;
const SIZE_HANDLEDATA: c_ulong = (size_of::<HandleData>() as c_ulong) << SIZESHIFT;

const DIR_NONE: c_ulong = 0;
const DIR_WRITE: c_ulong = 1 << DIRSHIFT;
const DIR_READ: c_ulong = 2 << DIRSHIFT;
const DIR_READ_WRITE: c_ulong = DIR_READ | DIR_WRITE;

const REQ_GET_CHIPINFO: c_ulong = DIR_READ | TYPE_GPIO | NR_GET_CHIPINFO | SIZE_CHIPINFO;
const REQ_GET_LINEINFO: c_ulong = DIR_READ_WRITE | TYPE_GPIO | NR_GET_LINEINFO | SIZE_LINEINFO;
const REQ_GET_LINEHANDLE: c_ulong =
    DIR_READ_WRITE | TYPE_GPIO | NR_GET_LINEHANDLE | SIZE_HANDLEREQUEST;
const REQ_GET_LINEEVENT: c_ulong =
    DIR_READ_WRITE | TYPE_GPIO | NR_GET_LINEEVENT | SIZE_EVENTREQUEST;
const REQ_GET_LINE_VALUES: c_ulong =
    DIR_READ_WRITE | TYPE_GPIO | NR_GET_LINE_VALUES | SIZE_HANDLEDATA;
const REQ_SET_LINE_VALUES: c_ulong =
    DIR_READ_WRITE | TYPE_GPIO | NR_SET_LINE_VALUES | SIZE_HANDLEDATA;
<commit_msg>Implement find_driver()<commit_after>// Copyright (c) 2017-2018 Rene van der Meer
//
// Permission is hereby granted, free of charge, to any person obtaining a
// copy of this software and associated documentation files (the "Software"),
// to deal in the Software without restriction, including without limitation
// the rights to use, copy, modify, merge, publish, distribute, sublicense,
// and/or sell copies of the Software, and to permit persons to whom the
// Software is furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
// DEALINGS IN THE SOFTWARE.

// NOTE: This is currently experimental, and may be removed at any point.

#![allow(dead_code)]

use libc::{c_int, c_ulong, ioctl};
use std::fs::{File, OpenOptions};
use std::io;
use std::mem::size_of;
use std::os::unix::io::AsRawFd;
use std::result;
use std::ffi::CStr;

pub type Result<T> = result::Result<T, io::Error>;

fn parse_retval(retval: c_int) -> Result<i32> {
    if retval == -1 {
        Err(io::Error::last_os_error())
    } else {
        Ok(retval)
    }
}

#[repr(C)]
struct ChipInfo {
    name: [u8; 32],
    label: [u8; 32],
    lines: u32,
}

const LINE_FLAG_KERNEL: u32 = 1;
const LINE_FLAG_IS_OUT: u32 = 1 << 1;
const LINE_FLAG_ACTIVE_LOW: u32 = 1 << 2;
const LINE_FLAG_OPEN_DRAIN: u32 = 1 << 3;
const LINE_FLAG_OPEN_SOURCE: u32 = 1 << 4;

#[repr(C)]
struct LineInfo {
    line_offset: u32,
    flags: u32,
    name: [u8; 32],
    consumer: [u8; 32],
}

const HANDLES_MAX: usize = 64;
const HANDLE_FLAG_INPUT: u32 = 1;
const HANDLE_FLAG_OUTPUT: u32 = 1 << 1;
const HANDLE_FLAG_ACTIVE_LOW: u32 = 1 << 2;
const HANDLE_FLAG_OPEN_DRAIN: u32 = 1 << 3;
const HANDLE_FLAG_OPEN_SOURCE: u32 = 1 << 4;

#[repr(C)]
struct HandleRequest {
    line_offets: [u32; HANDLES_MAX],
    flags: u32,
    default_values: [u8; HANDLES_MAX],
    consumer_label: [u8; 32],
    lines: u32,
    fd: c_int,
}

#[repr(C)]
struct HandleData {
    values: [u8; HANDLES_MAX],
}

const EVENT_FLAG_RISING_EDGE: u32 = 1;
const EVENT_FLAG_FALLING_EDGE: u32 = 1 << 1;
const EVENT_FLAG_BOTH_EDGES: u32 = EVENT_FLAG_RISING_EDGE | EVENT_FLAG_FALLING_EDGE;

#[repr(C)]
struct EventRequest {
    line_offset: u32,
    handle_flags: u32,
    event_flags: u32,
    consumer_label: [u8; 32],
    fd: c_int,
}

const EVENT_TYPE_RISING_EDGE: u32 = 0x01;
const EVENT_TYPE_FALLING_EDGE: u32 = 0x02;

#[repr(C)]
struct EventData {
    timestamp: u64,
    id: u32,
}

const NRBITS: u8 = 8;
const TYPEBITS: u8 = 8;
const SIZEBITS: u8 = 14;
const DIRBITS: u8 = 2;

const NRSHIFT: u8 = 0;
const TYPESHIFT: u8 = (NRSHIFT + NRBITS);
const SIZESHIFT: u8 = (TYPESHIFT + TYPEBITS);
const DIRSHIFT: u8 = (SIZESHIFT + SIZEBITS);

const NR_GET_CHIPINFO: c_ulong = 0x01 << NRSHIFT;
const NR_GET_LINEINFO: c_ulong = 0x02 << NRSHIFT;
const NR_GET_LINEHANDLE: c_ulong = 0x03 << NRSHIFT;
const NR_GET_LINEEVENT: c_ulong = 0x04 << NRSHIFT;
const NR_GET_LINE_VALUES: c_ulong = 0x08 << NRSHIFT;
const NR_SET_LINE_VALUES: c_ulong = 0x09 << NRSHIFT;

const TYPE_GPIO: c_ulong = (0xB4 as c_ulong) << TYPESHIFT;

const SIZE_CHIPINFO: c_ulong = (size_of::<ChipInfo>() as c_ulong) << SIZESHIFT;
const SIZE_LINEINFO: c_ulong = (size_of::<LineInfo>() as c_ulong) << SIZESHIFT;
const SIZE_HANDLEREQUEST: c_ulong = (size_of::<HandleRequest>() as c_ulong) << SIZESHIFT;
const SIZE_EVENTREQUEST: c_ulong = (size_of::<EventRequest>() as c_ulong) << SIZESHIFT;
const SIZE_HANDLEDATA: c_ulong = (size_of::<HandleData>() as c_ulong) << SIZESHIFT;

const DIR_NONE: c_ulong = 0;
const DIR_WRITE: c_ulong = 1 << DIRSHIFT;
const DIR_READ: c_ulong = 2 << DIRSHIFT;
const DIR_READ_WRITE: c_ulong = DIR_READ | DIR_WRITE;

const REQ_GET_CHIPINFO: c_ulong = DIR_READ | TYPE_GPIO | NR_GET_CHIPINFO | SIZE_CHIPINFO;
const REQ_GET_LINEINFO: c_ulong = DIR_READ_WRITE | TYPE_GPIO | NR_GET_LINEINFO | SIZE_LINEINFO;
const REQ_GET_LINEHANDLE: c_ulong =
    DIR_READ_WRITE | TYPE_GPIO | NR_GET_LINEHANDLE | SIZE_HANDLEREQUEST;
const REQ_GET_LINEEVENT: c_ulong =
    DIR_READ_WRITE | TYPE_GPIO | NR_GET_LINEEVENT | SIZE_EVENTREQUEST;
const REQ_GET_LINE_VALUES: c_ulong =
    DIR_READ_WRITE | TYPE_GPIO | NR_GET_LINE_VALUES | SIZE_HANDLEDATA;
const REQ_SET_LINE_VALUES: c_ulong =
    DIR_READ_WRITE | TYPE_GPIO | NR_SET_LINE_VALUES | SIZE_HANDLEDATA;

// I'm not sure the GPIO header is always available through /dev/gpiochip0, so searching for
// the corresponding driver name in the label field seems like a more reliable option.
pub unsafe fn find_driver() -> Result<Option<File>> {
    let driver_name = b"pinctrl-bcm2835\0";

    let mut chip_info = ChipInfo {
        name: [0u8; 32],
        label: [0u8; 32],
        lines: 0,
    };

    for idx in 0..=255 {
        let gpiochip = OpenOptions::new()
            .read(true)
            .write(true)
            .open(format!("/dev/gpiochip{}", idx))?;

        parse_retval(ioctl(gpiochip.as_raw_fd(), REQ_GET_CHIPINFO, &mut chip_info))?;
        if &chip_info.label[0..driver_name.len()] == &driver_name[..] {
            return Ok(Some(gpiochip));
        }
    }

    Ok(None)
}
<|endoftext|>