<commit_before>//! Types which pin data to its location in memory
//!
//! It is sometimes useful to have objects that are guaranteed to not move,
//! in the sense that their placement in memory does not change, and can thus be relied upon.
//!
//! A prime example of such a scenario would be building self-referential structs,
//! since moving an object with pointers to itself will invalidate them,
//! which could cause undefined behavior.
//!
//! In order to prevent objects from moving, they must be pinned
//! by wrapping a pointer to the data in the [`Pin`] type. A pointer wrapped
//! in a `Pin` is otherwise equivalent to its normal version, e.g., `Pin<Box<T>>`
//! and `Box<T>` work the same way except that the first is pinning the value
//! of `T` in place.
//!
//! First of all, these are pointer types because pinned data mustn't be passed around by value
//! (that would change its location in memory).
//! Secondly, since data can be moved out of `&mut` and `Box` with functions such as [`swap`],
//! which causes their contents to swap places in memory,
//! we need dedicated types that prohibit such operations.
//!
//! However, these restrictions are usually not necessary,
//! so most types implement the [`Unpin`] auto-trait,
//! which indicates that the type can be moved out safely.
//! Doing so removes the limitations of pinning types,
//! making them the same as their non-pinning counterparts.
//!
//! [`Pin`]: struct.Pin.html
//! [`Unpin`]: trait.Unpin.html
//! [`swap`]: ../../std/mem/fn.swap.html
//! [`Box`]: ../../std/boxed/struct.Box.html
//!
//! # Examples
//!
//! ```rust
//! #![feature(pin)]
//!
//! use std::pin::Pin;
//! use std::marker::Pinned;
//! use std::ptr::NonNull;
//!
//! // This is a self-referential struct since the slice field points to the data field.
//! // We cannot inform the compiler about that with a normal reference,
//! // since this pattern cannot be described with the usual borrowing rules.
//! // Instead we use a raw pointer, though one which is known to not be null,
//! // since we know it's pointing at the string.
//! struct Unmovable {
//!     data: String,
//!     slice: NonNull<String>,
//!     _pin: Pinned,
//! }
//!
//! impl Unmovable {
//!     // To ensure the data doesn't move when the function returns,
//!     // we place it in the heap where it will stay for the lifetime of the object,
//!     // and the only way to access it would be through a pointer to it.
//!     fn new(data: String) -> Pin<Box<Self>> {
//!         let res = Unmovable {
//!             data,
//!             // we only create the pointer once the data is in place
//!             // otherwise it will have already moved before we even started
//!             slice: NonNull::dangling(),
//!             _pin: Pinned,
//!         };
//!         let mut boxed = Box::pinned(res);
//!
//!         let slice = NonNull::from(&boxed.data);
//!         // we know this is safe because modifying a field doesn't move the whole struct
//!         unsafe {
//!             let mut_ref: Pin<&mut Self> = Pin::as_mut(&mut boxed);
//!             Pin::get_mut_unchecked(mut_ref).slice = slice;
//!         }
//!         boxed
//!     }
//! }
//!
//! let unmoved = Unmovable::new("hello".to_string());
//! // The pointer should point to the correct location,
//! // so long as the struct hasn't moved.
//! // Meanwhile, we are free to move the pointer around.
//! # #[allow(unused_mut)]
//! let mut still_unmoved = unmoved;
//! assert_eq!(still_unmoved.slice, NonNull::from(&still_unmoved.data));
//!
//! // Since our type doesn't implement Unpin, this will fail to compile:
//! // let new_unmoved = Unmovable::new("world".to_string());
//! // std::mem::swap(&mut *still_unmoved, &mut *new_unmoved);
//! ```

#![unstable(feature = "pin", issue = "49150")]

use fmt;
use marker::Sized;
use ops::{Deref, DerefMut, CoerceUnsized, DispatchFromDyn};

#[doc(inline)]
pub use marker::Unpin;

/// A pinned pointer.
///
/// This is a wrapper around a kind of pointer which makes that pointer "pin" its
/// value in place, preventing the value referenced by that pointer from being moved
/// unless it implements [`Unpin`].
///
/// See the [`pin` module] documentation for further explanation on pinning.
///
/// [`Unpin`]: ../../std/marker/trait.Unpin.html
/// [`pin` module]: ../../std/pin/index.html
//
// Note: the derives below are allowed because they all only use `&P`, so they
// cannot move the value behind `pointer`.
#[unstable(feature = "pin", issue = "49150")]
#[fundamental]
#[derive(Copy, Clone, Hash, Eq, PartialEq, Ord, PartialOrd)]
pub struct Pin
 {
    pointer: P,
}

impl
 Pin

where
    P::Target: Unpin,
{
    /// Construct a new `Pin` around a pointer to some data of a type that
    /// implements `Unpin`.
    #[unstable(feature = "pin", issue = "49150")]
    #[inline(always)]
    pub fn new(pointer: P) -> Pin
 {
        // Safety: the value pointed to is `Unpin`, and so has no requirements
        // around pinning.
        unsafe { Pin::new_unchecked(pointer) }
    }
}

impl
 Pin
 {
    /// Construct a new `Pin` around a reference to some data of a type that
    /// may or may not implement `Unpin`.
    ///
    /// # Safety
    ///
    /// This constructor is unsafe because we cannot guarantee that the data
    /// pointed to by `pointer` is pinned. If the constructed `Pin<P>` does
    /// not guarantee that the data `P` points to is pinned, constructing a
    /// `Pin<P>` is undefined behavior.
    ///
    /// If `pointer` dereferences to an `Unpin` type, `Pin::new` should be used
    /// instead.
    #[unstable(feature = "pin", issue = "49150")]
    #[inline(always)]
    pub unsafe fn new_unchecked(pointer: P) -> Pin
 {
        Pin { pointer }
    }

    /// Get a pinned shared reference from this pinned pointer.
    #[unstable(feature = "pin", issue = "49150")]
    #[inline(always)]
    pub fn as_ref(self: &Pin
) -> Pin<&P::Target> {
        unsafe { Pin::new_unchecked(&*self.pointer) }
    }
}

impl
 Pin
 {
    /// Get a pinned mutable reference from this pinned pointer.
    #[unstable(feature = "pin", issue = "49150")]
    #[inline(always)]
    pub fn as_mut(self: &mut Pin
) -> Pin<&mut P::Target> {
        unsafe { Pin::new_unchecked(&mut *self.pointer) }
    }

    /// Assign a new value to the memory behind the pinned reference.
    #[unstable(feature = "pin", issue = "49150")]
    #[inline(always)]
    pub fn set(mut self: Pin
, value: P::Target)
    where
        P::Target: Sized,
    {
        *self.pointer = value;
    }
}

impl<'a, T: ?Sized> Pin<&'a T> {
    /// Construct a new pin by mapping the interior value.
    ///
    /// For example, if you  wanted to get a `Pin` of a field of something,
    /// you could use this to get access to that field in one line of code.
    ///
    /// # Safety
    ///
    /// This function is unsafe. You must guarantee that the data you return
    /// will not move so long as the argument value does not move (for example,
    /// because it is one of the fields of that value), and also that you do
    /// not move out of the argument you receive to the interior function.
    #[unstable(feature = "pin", issue = "49150")]
    pub unsafe fn map_unchecked(this: Pin<&'a T>, func: F) -> Pin<&'a U> where
        F: FnOnce(&T) -> &U,
    {
        let pointer = &*this.pointer;
        let new_pointer = func(pointer);
        Pin::new_unchecked(new_pointer)
    }

    /// Get a shared reference out of a pin.
    ///
    /// Note: `Pin` also implements `Deref` to the target, which can be used
    /// to access the inner value. However, `Deref` only provides a reference
    /// that lives for as long as the borrow of the `Pin`, not the lifetime of
    /// the `Pin` itself. This method allows turning the `Pin` into a reference
    /// with the same lifetime as the original `Pin`.
    #[unstable(feature = "pin", issue = "49150")]
    #[inline(always)]
    pub fn get_ref(this: Pin<&'a T>) -> &'a T {
        this.pointer
    }
}

impl<'a, T: ?Sized> Pin<&'a mut T> {
    /// Convert this `Pin<&mut T>` into a `Pin<&T>` with the same lifetime.
    #[unstable(feature = "pin", issue = "49150")]
    #[inline(always)]
    pub fn into_ref(this: Pin<&'a mut T>) -> Pin<&'a T> {
        Pin { pointer: this.pointer }
    }

    /// Get a mutable reference to the data inside of this `Pin`.
    ///
    /// This requires that the data inside this `Pin` is `Unpin`.
    ///
    /// Note: `Pin` also implements `DerefMut` to the data, which can be used
    /// to access the inner value. However, `DerefMut` only provides a reference
    /// that lives for as long as the borrow of the `Pin`, not the lifetime of
    /// the `Pin` itself. This method allows turning the `Pin` into a reference
    /// with the same lifetime as the original `Pin`.
    #[unstable(feature = "pin", issue = "49150")]
    #[inline(always)]
    pub fn get_mut(this: Pin<&'a mut T>) -> &'a mut T
        where T: Unpin,
    {
        this.pointer
    }

    /// Get a mutable reference to the data inside of this `Pin`.
    ///
    /// # Safety
    ///
    /// This function is unsafe. You must guarantee that you will never move
    /// the data out of the mutable reference you receive when you call this
    /// function, so that the invariants on the `Pin` type can be upheld.
    ///
    /// If the underlying data is `Unpin`, `Pin::get_mut` should be used
    /// instead.
    #[unstable(feature = "pin", issue = "49150")]
    #[inline(always)]
    pub unsafe fn get_mut_unchecked(this: Pin<&'a mut T>) -> &'a mut T {
        this.pointer
    }

    /// Construct a new pin by mapping the interior value.
    ///
    /// For example, if you  wanted to get a `Pin` of a field of something,
    /// you could use this to get access to that field in one line of code.
    ///
    /// # Safety
    ///
    /// This function is unsafe. You must guarantee that the data you return
    /// will not move so long as the argument value does not move (for example,
    /// because it is one of the fields of that value), and also that you do
    /// not move out of the argument you receive to the interior function.
    #[unstable(feature = "pin", issue = "49150")]
    pub unsafe fn map_unchecked_mut(this: Pin<&'a mut T>, func: F) -> Pin<&'a mut U> where
        F: FnOnce(&mut T) -> &mut U,
    {
        let pointer = Pin::get_mut_unchecked(this);
        let new_pointer = func(pointer);
        Pin::new_unchecked(new_pointer)
    }
}

#[unstable(feature = "pin", issue = "49150")]
impl
 Deref for Pin
 {
    type Target = P::Target;
    fn deref(&self) -> &P::Target {
        Pin::get_ref(Pin::as_ref(self))
    }
}

#[unstable(feature = "pin", issue = "49150")]
impl
 DerefMut for Pin

where
    P::Target: Unpin
{
    fn deref_mut(&mut self) -> &mut P::Target {
        Pin::get_mut(Pin::as_mut(self))
    }
}

#[unstable(feature = "pin", issue = "49150")]
impl
 fmt::Debug for Pin
 {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        fmt::Debug::fmt(&self.pointer, f)
    }
}

#[unstable(feature = "pin", issue = "49150")]
impl
 fmt::Display for Pin
 {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        fmt::Display::fmt(&self.pointer, f)
    }
}

#[unstable(feature = "pin", issue = "49150")]
impl
 fmt::Pointer for Pin
 {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        fmt::Pointer::fmt(&self.pointer, f)
    }
}

// Note: this means that any impl of `CoerceUnsized` that allows coercing from
// a type that impls `Deref<Target=impl !Unpin>` to a type that impls
// `Deref<Target=Unpin>` is unsound. Any such impl would probably be unsound
// for other reasons, though, so we just need to take care not to allow such
// impls to land in std.
#[unstable(feature = "pin", issue = "49150")]
impl
 CoerceUnsized<Pin> for Pin

where
    P: CoerceUnsized,
{}

#[unstable(feature = "pin", issue = "49150")]
impl<'a, P, U> DispatchFromDyn<Pin> for Pin

where
    P: DispatchFromDyn,
{}

#[unstable(feature = "pin", issue = "49150")]
impl
 Unpin for Pin
 {}
<commit_msg>Expand documantation for std::pin module<commit_after>//! Types which pin data to its location in memory
//!
//! It is sometimes useful to have objects that are guaranteed to not move,
//! in the sense that their placement in memory does not change, and can thus be relied upon.
//!
//! A prime example of such a scenario would be building self-referential structs,
//! since moving an object with pointers to itself will invalidate them,
//! which could cause undefined behavior.
//!
//! By default, all types in Rust are movable. Rust allows passing all types by-value,
//! and common smart-pointer types such as `Box`, `Rc`, and `&mut` allow replacing and
//! moving the values they contain. In order to prevent objects from moving, they must
//! be pinned by wrapping a pointer to the data in the [`Pin`] type.
//! Doing this prohibits moving the value behind the pointer.
//! For example, `Pin<Box<T>>` functions much like a regular `Box<T>`,
//! but doesn't allow moving `T`. The pointer value itself (the `Box`) can still be moved,
//! but the value behind it cannot.
//!
//! Since data can be moved out of `&mut` and `Box` with functions such as [`swap`],
//! changing the location of the underlying data, [`Pin`] prohibits accessing the
//! underlying pointer type (the `&mut` or `Box`) directly, and provides its own set of
//! APIs for accessing and using the value.
//!
//! However, these restrictions are usually not necessary. Many types are always freely
//! movable. These types implement the [`Unpin`] auto-trait, which nullifies the affect
//! of [`Pin`]. For `T: Unpin`, `Pin<Box<T>>` and `Box<T>` function identically, as do
//! `Pin<&mut T>` and `&mut T`.
//!
//! Note that pinning and `Unpin` only affect the pointed-to type. For example, whether
//! or not `Box<T>` is `Unpin` has no affect on the behavior of `Pin<Box<T>>`. Similarly,
//! `Pin<Box<T>>` and `Pin<&mut T>` are always `Unpin` themselves, even though the
//! `T` underneath them isn't, because the pointers in `Pin<Box<_>>` and `Pin<&mut _>`
//! are always freely movable, even if the data they point to isn't.
//!
//! [`Pin`]: struct.Pin.html
//! [`Unpin`]: trait.Unpin.html
//! [`swap`]: ../../std/mem/fn.swap.html
//! [`Box`]: ../../std/boxed/struct.Box.html
//!
//! # Examples
//!
//! ```rust
//! #![feature(pin)]
//!
//! use std::pin::Pin;
//! use std::marker::Pinned;
//! use std::ptr::NonNull;
//!
//! // This is a self-referential struct since the slice field points to the data field.
//! // We cannot inform the compiler about that with a normal reference,
//! // since this pattern cannot be described with the usual borrowing rules.
//! // Instead we use a raw pointer, though one which is known to not be null,
//! // since we know it's pointing at the string.
//! struct Unmovable {
//!     data: String,
//!     slice: NonNull<String>,
//!     _pin: Pinned,
//! }
//!
//! impl Unmovable {
//!     // To ensure the data doesn't move when the function returns,
//!     // we place it in the heap where it will stay for the lifetime of the object,
//!     // and the only way to access it would be through a pointer to it.
//!     fn new(data: String) -> Pin<Box<Self>> {
//!         let res = Unmovable {
//!             data,
//!             // we only create the pointer once the data is in place
//!             // otherwise it will have already moved before we even started
//!             slice: NonNull::dangling(),
//!             _pin: Pinned,
//!         };
//!         let mut boxed = Box::pinned(res);
//!
//!         let slice = NonNull::from(&boxed.data);
//!         // we know this is safe because modifying a field doesn't move the whole struct
//!         unsafe {
//!             let mut_ref: Pin<&mut Self> = Pin::as_mut(&mut boxed);
//!             Pin::get_mut_unchecked(mut_ref).slice = slice;
//!         }
//!         boxed
//!     }
//! }
//!
//! let unmoved = Unmovable::new("hello".to_string());
//! // The pointer should point to the correct location,
//! // so long as the struct hasn't moved.
//! // Meanwhile, we are free to move the pointer around.
//! # #[allow(unused_mut)]
//! let mut still_unmoved = unmoved;
//! assert_eq!(still_unmoved.slice, NonNull::from(&still_unmoved.data));
//!
//! // Since our type doesn't implement Unpin, this will fail to compile:
//! // let new_unmoved = Unmovable::new("world".to_string());
//! // std::mem::swap(&mut *still_unmoved, &mut *new_unmoved);
//! ```

#![unstable(feature = "pin", issue = "49150")]

use fmt;
use marker::Sized;
use ops::{Deref, DerefMut, CoerceUnsized, DispatchFromDyn};

#[doc(inline)]
pub use marker::Unpin;

/// A pinned pointer.
///
/// This is a wrapper around a kind of pointer which makes that pointer "pin" its
/// value in place, preventing the value referenced by that pointer from being moved
/// unless it implements [`Unpin`].
///
/// See the [`pin` module] documentation for further explanation on pinning.
///
/// [`Unpin`]: ../../std/marker/trait.Unpin.html
/// [`pin` module]: ../../std/pin/index.html
//
// Note: the derives below are allowed because they all only use `&P`, so they
// cannot move the value behind `pointer`.
#[unstable(feature = "pin", issue = "49150")]
#[fundamental]
#[derive(Copy, Clone, Hash, Eq, PartialEq, Ord, PartialOrd)]
pub struct Pin
 {
    pointer: P,
}

impl
 Pin

where
    P::Target: Unpin,
{
    /// Construct a new `Pin` around a pointer to some data of a type that
    /// implements `Unpin`.
    #[unstable(feature = "pin", issue = "49150")]
    #[inline(always)]
    pub fn new(pointer: P) -> Pin
 {
        // Safety: the value pointed to is `Unpin`, and so has no requirements
        // around pinning.
        unsafe { Pin::new_unchecked(pointer) }
    }
}

impl
 Pin
 {
    /// Construct a new `Pin` around a reference to some data of a type that
    /// may or may not implement `Unpin`.
    ///
    /// # Safety
    ///
    /// This constructor is unsafe because we cannot guarantee that the data
    /// pointed to by `pointer` is pinned. If the constructed `Pin<P>` does
    /// not guarantee that the data `P` points to is pinned, constructing a
    /// `Pin<P>` is undefined behavior.
    ///
    /// If `pointer` dereferences to an `Unpin` type, `Pin::new` should be used
    /// instead.
    #[unstable(feature = "pin", issue = "49150")]
    #[inline(always)]
    pub unsafe fn new_unchecked(pointer: P) -> Pin
 {
        Pin { pointer }
    }

    /// Get a pinned shared reference from this pinned pointer.
    #[unstable(feature = "pin", issue = "49150")]
    #[inline(always)]
    pub fn as_ref(self: &Pin
) -> Pin<&P::Target> {
        unsafe { Pin::new_unchecked(&*self.pointer) }
    }
}

impl
 Pin
 {
    /// Get a pinned mutable reference from this pinned pointer.
    #[unstable(feature = "pin", issue = "49150")]
    #[inline(always)]
    pub fn as_mut(self: &mut Pin
) -> Pin<&mut P::Target> {
        unsafe { Pin::new_unchecked(&mut *self.pointer) }
    }

    /// Assign a new value to the memory behind the pinned reference.
    #[unstable(feature = "pin", issue = "49150")]
    #[inline(always)]
    pub fn set(mut self: Pin
, value: P::Target)
    where
        P::Target: Sized,
    {
        *self.pointer = value;
    }
}

impl<'a, T: ?Sized> Pin<&'a T> {
    /// Construct a new pin by mapping the interior value.
    ///
    /// For example, if you  wanted to get a `Pin` of a field of something,
    /// you could use this to get access to that field in one line of code.
    ///
    /// # Safety
    ///
    /// This function is unsafe. You must guarantee that the data you return
    /// will not move so long as the argument value does not move (for example,
    /// because it is one of the fields of that value), and also that you do
    /// not move out of the argument you receive to the interior function.
    #[unstable(feature = "pin", issue = "49150")]
    pub unsafe fn map_unchecked(this: Pin<&'a T>, func: F) -> Pin<&'a U> where
        F: FnOnce(&T) -> &U,
    {
        let pointer = &*this.pointer;
        let new_pointer = func(pointer);
        Pin::new_unchecked(new_pointer)
    }

    /// Get a shared reference out of a pin.
    ///
    /// Note: `Pin` also implements `Deref` to the target, which can be used
    /// to access the inner value. However, `Deref` only provides a reference
    /// that lives for as long as the borrow of the `Pin`, not the lifetime of
    /// the `Pin` itself. This method allows turning the `Pin` into a reference
    /// with the same lifetime as the original `Pin`.
    #[unstable(feature = "pin", issue = "49150")]
    #[inline(always)]
    pub fn get_ref(this: Pin<&'a T>) -> &'a T {
        this.pointer
    }
}

impl<'a, T: ?Sized> Pin<&'a mut T> {
    /// Convert this `Pin<&mut T>` into a `Pin<&T>` with the same lifetime.
    #[unstable(feature = "pin", issue = "49150")]
    #[inline(always)]
    pub fn into_ref(this: Pin<&'a mut T>) -> Pin<&'a T> {
        Pin { pointer: this.pointer }
    }

    /// Get a mutable reference to the data inside of this `Pin`.
    ///
    /// This requires that the data inside this `Pin` is `Unpin`.
    ///
    /// Note: `Pin` also implements `DerefMut` to the data, which can be used
    /// to access the inner value. However, `DerefMut` only provides a reference
    /// that lives for as long as the borrow of the `Pin`, not the lifetime of
    /// the `Pin` itself. This method allows turning the `Pin` into a reference
    /// with the same lifetime as the original `Pin`.
    #[unstable(feature = "pin", issue = "49150")]
    #[inline(always)]
    pub fn get_mut(this: Pin<&'a mut T>) -> &'a mut T
        where T: Unpin,
    {
        this.pointer
    }

    /// Get a mutable reference to the data inside of this `Pin`.
    ///
    /// # Safety
    ///
    /// This function is unsafe. You must guarantee that you will never move
    /// the data out of the mutable reference you receive when you call this
    /// function, so that the invariants on the `Pin` type can be upheld.
    ///
    /// If the underlying data is `Unpin`, `Pin::get_mut` should be used
    /// instead.
    #[unstable(feature = "pin", issue = "49150")]
    #[inline(always)]
    pub unsafe fn get_mut_unchecked(this: Pin<&'a mut T>) -> &'a mut T {
        this.pointer
    }

    /// Construct a new pin by mapping the interior value.
    ///
    /// For example, if you  wanted to get a `Pin` of a field of something,
    /// you could use this to get access to that field in one line of code.
    ///
    /// # Safety
    ///
    /// This function is unsafe. You must guarantee that the data you return
    /// will not move so long as the argument value does not move (for example,
    /// because it is one of the fields of that value), and also that you do
    /// not move out of the argument you receive to the interior function.
    #[unstable(feature = "pin", issue = "49150")]
    pub unsafe fn map_unchecked_mut(this: Pin<&'a mut T>, func: F) -> Pin<&'a mut U> where
        F: FnOnce(&mut T) -> &mut U,
    {
        let pointer = Pin::get_mut_unchecked(this);
        let new_pointer = func(pointer);
        Pin::new_unchecked(new_pointer)
    }
}

#[unstable(feature = "pin", issue = "49150")]
impl
 Deref for Pin
 {
    type Target = P::Target;
    fn deref(&self) -> &P::Target {
        Pin::get_ref(Pin::as_ref(self))
    }
}

#[unstable(feature = "pin", issue = "49150")]
impl
 DerefMut for Pin

where
    P::Target: Unpin
{
    fn deref_mut(&mut self) -> &mut P::Target {
        Pin::get_mut(Pin::as_mut(self))
    }
}

#[unstable(feature = "pin", issue = "49150")]
impl
 fmt::Debug for Pin
 {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        fmt::Debug::fmt(&self.pointer, f)
    }
}

#[unstable(feature = "pin", issue = "49150")]
impl
 fmt::Display for Pin
 {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        fmt::Display::fmt(&self.pointer, f)
    }
}

#[unstable(feature = "pin", issue = "49150")]
impl
 fmt::Pointer for Pin
 {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        fmt::Pointer::fmt(&self.pointer, f)
    }
}

// Note: this means that any impl of `CoerceUnsized` that allows coercing from
// a type that impls `Deref<Target=impl !Unpin>` to a type that impls
// `Deref<Target=Unpin>` is unsound. Any such impl would probably be unsound
// for other reasons, though, so we just need to take care not to allow such
// impls to land in std.
#[unstable(feature = "pin", issue = "49150")]
impl
 CoerceUnsized<Pin> for Pin

where
    P: CoerceUnsized,
{}

#[unstable(feature = "pin", issue = "49150")]
impl<'a, P, U> DispatchFromDyn<Pin> for Pin

where
    P: DispatchFromDyn,
{}

#[unstable(feature = "pin", issue = "49150")]
impl
 Unpin for Pin
 {}
<|endoftext|>


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

#![allow(missing_docs)]
#![unstable(feature = "core")]

//! Contains struct definitions for the layout of compiler built-in types.
//!
//! They can be used as targets of transmutes in unsafe code for manipulating
//! the raw representations directly.
//!
//! Their definition should always match the ABI defined in `rustc::back::abi`.

use marker::Copy;
use mem;

/// The representation of a Rust slice
#[repr(C)]
pub struct Slice<T> {
    pub data: *const T,
    pub len: uint,
}

impl<T> Copy for Slice<T> {}

/// The representation of a Rust closure
#[repr(C)]
#[derive(Copy)]
pub struct Closure {
    pub code: *mut (),
    pub env: *mut (),
}

/// The representation of a Rust trait object.
///
/// This struct does not have a `Repr` implementation
/// because there is no way to refer to all trait objects generically.
#[repr(C)]
#[derive(Copy)]
pub struct TraitObject {
    pub data: *mut (),
    pub vtable: *mut (),
}

/// This trait is meant to map equivalences between raw structs and their
/// corresponding rust values.
pub trait Repr<T> {
    /// This function "unwraps" a rust value (without consuming it) into its raw
    /// struct representation. This can be used to read/write different values
    /// for the struct. This is a safe method because by default it does not
    /// enable write-access to the fields of the return value in safe code.
    #[inline]
    fn repr(&self) -> T { unsafe { mem::transmute_copy(&self) } }
}

impl<T> Repr<Slice<T>> for [T] {}
impl Repr<Slice<u8>> for str {}
<commit_msg>core::raw: uint -> usize<commit_after>// Copyright 2013 The Rust Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution and at
// http://rust-lang.org/COPYRIGHT.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.

#![allow(missing_docs)]
#![unstable(feature = "core")]

//! Contains struct definitions for the layout of compiler built-in types.
//!
//! They can be used as targets of transmutes in unsafe code for manipulating
//! the raw representations directly.
//!
//! Their definition should always match the ABI defined in `rustc::back::abi`.

use marker::Copy;
use mem;

/// The representation of a Rust slice
#[repr(C)]
pub struct Slice<T> {
    pub data: *const T,
    pub len: usize,
}

impl<T> Copy for Slice<T> {}

/// The representation of a Rust closure
#[repr(C)]
#[derive(Copy)]
pub struct Closure {
    pub code: *mut (),
    pub env: *mut (),
}

/// The representation of a Rust trait object.
///
/// This struct does not have a `Repr` implementation
/// because there is no way to refer to all trait objects generically.
#[repr(C)]
#[derive(Copy)]
pub struct TraitObject {
    pub data: *mut (),
    pub vtable: *mut (),
}

/// This trait is meant to map equivalences between raw structs and their
/// corresponding rust values.
pub trait Repr<T> {
    /// This function "unwraps" a rust value (without consuming it) into its raw
    /// struct representation. This can be used to read/write different values
    /// for the struct. This is a safe method because by default it does not
    /// enable write-access to the fields of the return value in safe code.
    #[inline]
    fn repr(&self) -> T { unsafe { mem::transmute_copy(&self) } }
}

impl<T> Repr<Slice<T>> for [T] {}
impl Repr<Slice<u8>> for str {}
<|endoftext|>


<commit_before>#[link(name = "knob",
       vers = "1.0",
       uuid = "3299B6C2-99DE-44FD-8867-8EE7304959D7",
       url = "http://github.com/skade/knob")];

#[crate_type = "lib"];
#[comment = "A convenient Rust settings system"];
#[license = "MIT"];

//! A convenient structure to store and load settings.
//!
//! It is meant for items that are rarely read and stored, like command line flags or
//! application configuration.
//!
//! knob::Settings expects all values to implement ToStr + FromStr and stores them as
//! strings internally. This allows sideloading of settings through multiple means, e.g.
//! the command line or a simple config file. knob is not meant for structured data. If
//! you want to load such data, store the location of the data as a Knob setting and do
//! the loading parsing yourself.
//!
//! knob is typesafe in a sense that it will return you the type you wanted back if possible and
//! fails otherwise.
//!
//! knob allows you to decorate the Settings structure yourself for convenience (see examples).
//!
//! # Storing and fetching values
//!
//! The following example shows you how to store an ip in knob:
//!
//! ~~~{.rust}
//! extern mod knob;
//! use knob::*;
//! use std::rt::io::net::ip::IpAddr;
//!
//! fn main() {
//!   let settings = Settings::new();
//!   settings.set("ip", "0.0.0.0:4567");
//!   let socket: IpAddr = settings.socket();
//!   assert_eq!(socket.to_str(), ~"0.0.0.0:4567")
//! }
//! ~~~
//!
//! This works the same for IPv6 addresses:
//!
//! ~~~{.rust}
//! fn main() {
//!   let settings = Settings::new();
//!   settings.set("ip", "::0.0.0.1");
//!   let socket: IpAddr = settings.fetch("ip");
//!   assert_eq!(socket.to_str(), ~"::0.0.0.1")
//! }
//! ~~~
//!
//! # Providing your own keys
//!
//! You can use enums as keys, as long as they implement ToStr:
//!
//! ~~~{.rust}
//! enum Keys {
//!   Port,
//!   Ip,
//!   Addr,
//! }
//!
//! fn main() {
//!   let settings = Settings::new();
//!   settings.set(Ip, "::0.0.0.1");
//!   let socket: IpAddr = settings.fetch(Ip);
//!   assert_eq!(socket.to_str(), ~"::0.0.0.1")
//! }
//! ~~~
//!
//! # Registering command line options
//!
//! Knob allows you to register command line options to read from the command line later.
//!
//! The options are getopts option groups.
//!
//! If the loading of the command line args fails, an error will be returned.
//!
//! ~~~{.rust}
//! use extra::getopts::groups::*;
//!
//! fn main() {
//!   let settings = Settings::new();
//!   settings.opt(optopt("p", "port", "the port to bind to", "4000"))
//!   settings.opt(reqopt("e", "environment", "the environment to run in", ""));;
//!   let errors = settings.load_os_args();
//!   if errors.is_some() {
//!     println(settings.usage("Try one of these:"))
//!   }
//! }
//! ~~~
//!
//! # Decorating the settings struct
//!
//! To make matters more convenient, you can implement a decorator
//! to implement your own loading behaviour.
//!
//! ~~~{.rust}
//! enum Keys {
//!   Port,
//!   Ip,
//!   Addr,
//! }
//!
//! pub trait SocketSettings {
//!   fn socket(&self) -> SocketAddr;
//!   fn port(&self) -> u16;
//!   fn ip(&self) -> IpAddr;
//! }
//!
//! impl SocketSettings for Settings {
//!   fn socket(&self) -> SocketAddr {
//!     do self.fetch_with(Addr) |addr| {
//!       match addr {
//!         Some(socket_addr) => { socket_addr },
//!         None => {
//!           let port: u16 = self.port();
//!           let ip: IpAddr = self.ip();
//!           SocketAddr { ip: ip, port: port }
//!         }
//!       }
//!     }
//!   }
//!
//!   fn port(&self) -> u16 {
//!     self.fetch(Port).unwrap_or(8080)
//!   }
//!
//!   fn ip(&self) -> IpAddr {
//!     self.fetch(Ip).unwrap_or(Ipv4Addr(127,0,0,1))
//!   }
//! }
//! enum Keys {
//!   Port,
//!   Ip,
//! }
//!
//! fn main() {
//!   let settings = Settings::new();
//!   settings.set(Ip, "::0.0.0.1");
//!   let socket: IpAddr = settings.fetch(Ip);
//!   assert_eq!(socket.to_str(), ~"::0.0.0.1")
//! }
//! ~~~
//!
//! knob goes up to 11.

extern mod extra;

use std::hashmap::*;
use std::os;

use extra::getopts::groups::{OptGroup,getopts,usage};
use extra::getopts::Fail_;

/// The settings structure we save the options and settings in.
#[deriving(Clone)]
pub struct Settings {
  priv store: HashMap<~str,~str>,
  priv options: ~[OptGroup],
}

impl Settings {
  /// Create a new Settings struct.
  pub fn new() -> Settings {
    Settings { store: HashMap::new(), options: ~[] }
  }

  /// Set a settings key to a value. The value will be serialized.
  pub fn set<A: ToStr, T: ToStr>(&mut self, setting: A, value: T) {
    self.store.swap(setting.to_str(), value.to_str());
  }

  /// Set a value using an Option struct. The value will only be set if the
  /// Some value is given. This way, you can avoid unwrapping the result of a
  /// previous operation by yourself.
  pub fn set_opt<A: ToStr, T: ToStr>(&mut self, setting: A, value: Option<T>) {
    if !value.is_none() {
      self.store.swap(setting.to_str(), value.unwrap().to_str());
    }
  }

  /// Fetch a setting for a key. Fails if the setting is present but could not be
  /// parsed.
  pub fn fetch<A: ToStr, T: FromStr>(&self, setting: A) -> Option<T> {
    match self.store.find(&setting.to_str()) {
      Some(string) => {
        let value = from_str(string.to_owned());
        if value.is_none() {
          fail!("setting could not be parsed:" + setting.to_str())
        }
        value
      },
      None => { None }
    }
  }

  /// Fetch a setting for a key and pass it to given function. The result of the function
  /// will be returned.
  pub fn fetch_with<A: ToStr, T: FromStr>(&self, setting: A, f: &fn(Option<T>) -> T) -> T {
    let value = self.fetch(setting.to_str());
    f(value)
  }

  /// Register a commandline for laster use with load_args.
  ///
  /// Currently, only optopt and reqopt are properly supported.
  pub fn opt(&mut self, opt: OptGroup) {
    self.options.push(opt);
  }

  /// Load the command line argument given by the OS.
  ///
  /// Optionally returns failures.
  pub fn load_os_args(&mut self) -> Option<Fail_> {
    let args = os::args();
    self.load_args(args)
  }

  /// Load a list of command line arguments.
  ///
  /// Automatically sets "knob.progname" to the name of the program.
  ///
  /// Optionally returns failures.
  pub fn load_args(&mut self, args: ~[~str]) -> Option<Fail_> {
    let ref prog_name = args[0];

    self.set("knob.progname", prog_name.clone());

    let matches = match getopts(args.tail(), self.options) {
      Ok(m) => { m }
      Err(fail) => { return Some(fail) }
    };

    debug!(matches);

    let given_options = self.options.clone();
    for opt in given_options.iter() {
      let opt_strings = &[opt.short_name.clone(), opt.long_name.clone()];
      self.set_opt(opt.long_name.clone(), matches.opts_str(opt_strings))
    };
    None
  }

  /// Returns the usage string for the stored OptGroups. Pass `brief`
  /// to have it included.
  pub fn usage(&self, brief: &str) -> ~str {
    usage(brief, self.options)
  }
}

#[cfg(test)]
mod tests {
  use super::*;
  use std::rt::io::net::ip::{SocketAddr, IpAddr, Ipv4Addr};
  use extra::getopts::groups::*;

  #[deriving(ToStr)]
  enum Keys {
    Ip,
    Port,
    Addr
  }

  pub trait SocketSettings {
    fn socket(&self) -> SocketAddr;
    fn port(&self) -> u16;
    fn ip(&self) -> IpAddr;
  }

  impl SocketSettings for Settings {
    fn socket(&self) -> SocketAddr {
      do self.fetch_with(Addr) |addr| {
        match addr {
          Some(socket_addr) => { socket_addr },
          None => {
            let port: u16 = self.port();
            let ip: IpAddr = self.ip();
            SocketAddr { ip: ip, port: port }
          }
        }
      }
    }

    fn port(&self) -> u16 {
      self.fetch(Port).unwrap_or(8080)
    }

    fn ip(&self) -> IpAddr {
      self.fetch(Ip).unwrap_or(Ipv4Addr(127,0,0,1))
    }
  }

  #[test]
  fn test_simple_conversion() {
    let mut settings = Settings::new();
    settings.set("port", 12345);
    let settings = settings.fetch("port");
    assert_eq!(Some(12345), settings)
  }

  #[test]
  #[should_fail]
  fn test_should_fail_on_garbage() {
    let mut settings = Settings::new();
    settings.set("port", "foobar");
    let settings: Option<int> = settings.fetch("port");
    assert_eq!(Some(12345), settings)
  }

  #[test]
  fn test_enum() {
    let mut settings = Settings::new();
    settings.set(Port, 12345);
    let settings = settings.fetch(Port);
    assert_eq!(Some(12345), settings)
  }

  #[test]
  fn test_compound_socket_settings() {
    let mut settings = Settings::new();
    settings.set(Port, "12345");
    settings.set(Ip, "127.0.0.1");
    let socket = settings.socket();
    assert_eq!(socket.to_str(), ~"127.0.0.1:12345")
  }

  #[test]
  fn test_ipv6_addr() {
    let mut settings = Settings::new();
    settings.set(Ip, "::0.0.0.1");
    let ip = settings.ip();
    assert_eq!(ip.to_str(), ~"::0.0.0.1")
  }

  #[test]
  fn test_socket_overrides_port() {
    let mut settings = Settings::new();
    settings.set(Port, "12345");
    settings.set(Ip, "127.0.0.1");
    settings.set(Addr, "0.0.0.0:4567");
    let socket = settings.socket();
    assert_eq!(socket.to_str(), ~"0.0.0.0:4567")
  }

  #[test]
  fn test_opt_parse_optional() {
    let mut settings = Settings::new();
    settings.opt(optopt("p", "port", "The port to bind to", "eg: 4000"));

    let args = ~[~"myprog", ~"-p", ~"3000"];
    let error = settings.load_args(args);

    assert!(error.is_none());
    assert_eq!(settings.fetch("port"), Some(3000))
  }

  #[test]
  fn test_opt_parse_req_with_given() {
    let mut settings = Settings::new();
    settings.opt(reqopt("p", "port", "The port to bind to", "eg: 4000"));

    let args = ~[~"myprog", ~"-p", ~"3000"];
    let error = settings.load_args(args);

    assert!(error.is_none());
    assert_eq!(settings.fetch("port"), Some(3000))
  }

  #[test]
  fn test_opt_parse_req_without_given() {
    let mut settings = Settings::new();
    settings.opt(reqopt("p", "port", "The port to bind to", "eg: 4000"));

    let args = ~[~"myprog"];
    let error = settings.load_args(args);

    assert!(error.is_some());
    let port: Option<int> = settings.fetch("port");
    assert_eq!(port, None)
  }

  #[test]
  fn test_usage() {
    let mut settings = Settings::new();
    settings.opt(reqopt("p", "port", "The port to bind to", "eg: 4000"));
    let usage = settings.usage(&"this is how it works");

    assert!(usage.contains("this is how it works"))
    assert!(usage.contains("--port"))
  }

  #[test]
  fn test_goes_up_to_eleven() {
    let mut settings = Settings::new();
    settings.set("knob", 11);
    assert_eq!(settings.fetch("knob"), Some(11));
  }
}<commit_msg>Remove debug!, rustpkg barfs on it<commit_after>#[link(name = "knob",
       vers = "1.0",
       uuid = "3299B6C2-99DE-44FD-8867-8EE7304959D7",
       url = "http://github.com/skade/knob")];

#[crate_type = "lib"];
#[comment = "A convenient Rust settings system"];
#[license = "MIT"];

//! A convenient structure to store and load settings.
//!
//! It is meant for items that are rarely read and stored, like command line flags or
//! application configuration.
//!
//! knob::Settings expects all values to implement ToStr + FromStr and stores them as
//! strings internally. This allows sideloading of settings through multiple means, e.g.
//! the command line or a simple config file. knob is not meant for structured data. If
//! you want to load such data, store the location of the data as a Knob setting and do
//! the loading parsing yourself.
//!
//! knob is typesafe in a sense that it will return you the type you wanted back if possible and
//! fails otherwise.
//!
//! knob allows you to decorate the Settings structure yourself for convenience (see examples).
//!
//! # Storing and fetching values
//!
//! The following example shows you how to store an ip in knob:
//!
//! ~~~{.rust}
//! extern mod knob;
//! use knob::*;
//! use std::rt::io::net::ip::IpAddr;
//!
//! fn main() {
//!   let settings = Settings::new();
//!   settings.set("ip", "0.0.0.0:4567");
//!   let socket: IpAddr = settings.socket();
//!   assert_eq!(socket.to_str(), ~"0.0.0.0:4567")
//! }
//! ~~~
//!
//! This works the same for IPv6 addresses:
//!
//! ~~~{.rust}
//! fn main() {
//!   let settings = Settings::new();
//!   settings.set("ip", "::0.0.0.1");
//!   let socket: IpAddr = settings.fetch("ip");
//!   assert_eq!(socket.to_str(), ~"::0.0.0.1")
//! }
//! ~~~
//!
//! # Providing your own keys
//!
//! You can use enums as keys, as long as they implement ToStr:
//!
//! ~~~{.rust}
//! enum Keys {
//!   Port,
//!   Ip,
//!   Addr,
//! }
//!
//! fn main() {
//!   let settings = Settings::new();
//!   settings.set(Ip, "::0.0.0.1");
//!   let socket: IpAddr = settings.fetch(Ip);
//!   assert_eq!(socket.to_str(), ~"::0.0.0.1")
//! }
//! ~~~
//!
//! # Registering command line options
//!
//! Knob allows you to register command line options to read from the command line later.
//!
//! The options are getopts option groups.
//!
//! If the loading of the command line args fails, an error will be returned.
//!
//! ~~~{.rust}
//! use extra::getopts::groups::*;
//!
//! fn main() {
//!   let settings = Settings::new();
//!   settings.opt(optopt("p", "port", "the port to bind to", "4000"))
//!   settings.opt(reqopt("e", "environment", "the environment to run in", ""));;
//!   let errors = settings.load_os_args();
//!   if errors.is_some() {
//!     println(settings.usage("Try one of these:"))
//!   }
//! }
//! ~~~
//!
//! # Decorating the settings struct
//!
//! To make matters more convenient, you can implement a decorator
//! to implement your own loading behaviour.
//!
//! ~~~{.rust}
//! enum Keys {
//!   Port,
//!   Ip,
//!   Addr,
//! }
//!
//! pub trait SocketSettings {
//!   fn socket(&self) -> SocketAddr;
//!   fn port(&self) -> u16;
//!   fn ip(&self) -> IpAddr;
//! }
//!
//! impl SocketSettings for Settings {
//!   fn socket(&self) -> SocketAddr {
//!     do self.fetch_with(Addr) |addr| {
//!       match addr {
//!         Some(socket_addr) => { socket_addr },
//!         None => {
//!           let port: u16 = self.port();
//!           let ip: IpAddr = self.ip();
//!           SocketAddr { ip: ip, port: port }
//!         }
//!       }
//!     }
//!   }
//!
//!   fn port(&self) -> u16 {
//!     self.fetch(Port).unwrap_or(8080)
//!   }
//!
//!   fn ip(&self) -> IpAddr {
//!     self.fetch(Ip).unwrap_or(Ipv4Addr(127,0,0,1))
//!   }
//! }
//! enum Keys {
//!   Port,
//!   Ip,
//! }
//!
//! fn main() {
//!   let settings = Settings::new();
//!   settings.set(Ip, "::0.0.0.1");
//!   let socket: IpAddr = settings.fetch(Ip);
//!   assert_eq!(socket.to_str(), ~"::0.0.0.1")
//! }
//! ~~~
//!
//! knob goes up to 11.

extern mod extra;

use std::hashmap::*;
use std::os;

use extra::getopts::groups::{OptGroup,getopts,usage};
use extra::getopts::Fail_;

/// The settings structure we save the options and settings in.
#[deriving(Clone)]
pub struct Settings {
  priv store: HashMap<~str,~str>,
  priv options: ~[OptGroup],
}

impl Settings {
  /// Create a new Settings struct.
  pub fn new() -> Settings {
    Settings { store: HashMap::new(), options: ~[] }
  }

  /// Set a settings key to a value. The value will be serialized.
  pub fn set<A: ToStr, T: ToStr>(&mut self, setting: A, value: T) {
    self.store.swap(setting.to_str(), value.to_str());
  }

  /// Set a value using an Option struct. The value will only be set if the
  /// Some value is given. This way, you can avoid unwrapping the result of a
  /// previous operation by yourself.
  pub fn set_opt<A: ToStr, T: ToStr>(&mut self, setting: A, value: Option<T>) {
    if !value.is_none() {
      self.store.swap(setting.to_str(), value.unwrap().to_str());
    }
  }

  /// Fetch a setting for a key. Fails if the setting is present but could not be
  /// parsed.
  pub fn fetch<A: ToStr, T: FromStr>(&self, setting: A) -> Option<T> {
    match self.store.find(&setting.to_str()) {
      Some(string) => {
        let value = from_str(string.to_owned());
        if value.is_none() {
          fail!("setting could not be parsed:" + setting.to_str())
        }
        value
      },
      None => { None }
    }
  }

  /// Fetch a setting for a key and pass it to given function. The result of the function
  /// will be returned.
  pub fn fetch_with<A: ToStr, T: FromStr>(&self, setting: A, f: &fn(Option<T>) -> T) -> T {
    let value = self.fetch(setting.to_str());
    f(value)
  }

  /// Register a commandline for laster use with load_args.
  ///
  /// Currently, only optopt and reqopt are properly supported.
  pub fn opt(&mut self, opt: OptGroup) {
    self.options.push(opt);
  }

  /// Load the command line argument given by the OS.
  ///
  /// Optionally returns failures.
  pub fn load_os_args(&mut self) -> Option<Fail_> {
    let args = os::args();
    self.load_args(args)
  }

  /// Load a list of command line arguments.
  ///
  /// Automatically sets "knob.progname" to the name of the program.
  ///
  /// Optionally returns failures.
  pub fn load_args(&mut self, args: ~[~str]) -> Option<Fail_> {
    let ref prog_name = args[0];

    self.set("knob.progname", prog_name.clone());

    let matches = match getopts(args.tail(), self.options) {
      Ok(m) => { m }
      Err(fail) => { return Some(fail) }
    };

    let given_options = self.options.clone();
    for opt in given_options.iter() {
      let opt_strings = &[opt.short_name.clone(), opt.long_name.clone()];
      self.set_opt(opt.long_name.clone(), matches.opts_str(opt_strings))
    };
    None
  }

  /// Returns the usage string for the stored OptGroups. Pass `brief`
  /// to have it included.
  pub fn usage(&self, brief: &str) -> ~str {
    usage(brief, self.options)
  }
}

#[cfg(test)]
mod tests {
  use super::*;
  use std::rt::io::net::ip::{SocketAddr, IpAddr, Ipv4Addr};
  use extra::getopts::groups::*;

  #[deriving(ToStr)]
  enum Keys {
    Ip,
    Port,
    Addr
  }

  pub trait SocketSettings {
    fn socket(&self) -> SocketAddr;
    fn port(&self) -> u16;
    fn ip(&self) -> IpAddr;
  }

  impl SocketSettings for Settings {
    fn socket(&self) -> SocketAddr {
      do self.fetch_with(Addr) |addr| {
        match addr {
          Some(socket_addr) => { socket_addr },
          None => {
            let port: u16 = self.port();
            let ip: IpAddr = self.ip();
            SocketAddr { ip: ip, port: port }
          }
        }
      }
    }

    fn port(&self) -> u16 {
      self.fetch(Port).unwrap_or(8080)
    }

    fn ip(&self) -> IpAddr {
      self.fetch(Ip).unwrap_or(Ipv4Addr(127,0,0,1))
    }
  }

  #[test]
  fn test_simple_conversion() {
    let mut settings = Settings::new();
    settings.set("port", 12345);
    let settings = settings.fetch("port");
    assert_eq!(Some(12345), settings)
  }

  #[test]
  #[should_fail]
  fn test_should_fail_on_garbage() {
    let mut settings = Settings::new();
    settings.set("port", "foobar");
    let settings: Option<int> = settings.fetch("port");
    assert_eq!(Some(12345), settings)
  }

  #[test]
  fn test_enum() {
    let mut settings = Settings::new();
    settings.set(Port, 12345);
    let settings = settings.fetch(Port);
    assert_eq!(Some(12345), settings)
  }

  #[test]
  fn test_compound_socket_settings() {
    let mut settings = Settings::new();
    settings.set(Port, "12345");
    settings.set(Ip, "127.0.0.1");
    let socket = settings.socket();
    assert_eq!(socket.to_str(), ~"127.0.0.1:12345")
  }

  #[test]
  fn test_ipv6_addr() {
    let mut settings = Settings::new();
    settings.set(Ip, "::0.0.0.1");
    let ip = settings.ip();
    assert_eq!(ip.to_str(), ~"::0.0.0.1")
  }

  #[test]
  fn test_socket_overrides_port() {
    let mut settings = Settings::new();
    settings.set(Port, "12345");
    settings.set(Ip, "127.0.0.1");
    settings.set(Addr, "0.0.0.0:4567");
    let socket = settings.socket();
    assert_eq!(socket.to_str(), ~"0.0.0.0:4567")
  }

  #[test]
  fn test_opt_parse_optional() {
    let mut settings = Settings::new();
    settings.opt(optopt("p", "port", "The port to bind to", "eg: 4000"));

    let args = ~[~"myprog", ~"-p", ~"3000"];
    let error = settings.load_args(args);

    assert!(error.is_none());
    assert_eq!(settings.fetch("port"), Some(3000))
  }

  #[test]
  fn test_opt_parse_req_with_given() {
    let mut settings = Settings::new();
    settings.opt(reqopt("p", "port", "The port to bind to", "eg: 4000"));

    let args = ~[~"myprog", ~"-p", ~"3000"];
    let error = settings.load_args(args);

    assert!(error.is_none());
    assert_eq!(settings.fetch("port"), Some(3000))
  }

  #[test]
  fn test_opt_parse_req_without_given() {
    let mut settings = Settings::new();
    settings.opt(reqopt("p", "port", "The port to bind to", "eg: 4000"));

    let args = ~[~"myprog"];
    let error = settings.load_args(args);

    assert!(error.is_some());
    let port: Option<int> = settings.fetch("port");
    assert_eq!(port, None)
  }

  #[test]
  fn test_usage() {
    let mut settings = Settings::new();
    settings.opt(reqopt("p", "port", "The port to bind to", "eg: 4000"));
    let usage = settings.usage(&"this is how it works");

    assert!(usage.contains("this is how it works"))
    assert!(usage.contains("--port"))
  }

  #[test]
  fn test_goes_up_to_eleven() {
    let mut settings = Settings::new();
    settings.set("knob", 11);
    assert_eq!(settings.fetch("knob"), Some(11));
  }
}<|endoftext|>


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

/*!
Message passing
*/

#[allow(missing_doc)];

use clone::Clone;
use kinds::Send;
use option::Option;
use rtcomm = rt::comm;

/// A trait for things that can send multiple messages.
pub trait GenericChan<T> {
    /// Sends a message.
    fn send(&self, x: T);
}

/// Things that can send multiple messages and can detect when the receiver
/// is closed
pub trait GenericSmartChan<T> {
    /// Sends a message, or report if the receiver has closed the connection.
    fn try_send(&self, x: T) -> bool;
}

/// Trait for non-rescheduling send operations, similar to `send_deferred` on ChanOne.
pub trait SendDeferred<T> {
    fn send_deferred(&self, val: T);
    fn try_send_deferred(&self, val: T) -> bool;
}

/// A trait for things that can receive multiple messages.
pub trait GenericPort<T> {
    /// Receives a message, or fails if the connection closes.
    fn recv(&self) -> T;

    /** Receives a message, or returns `none` if
    the connection is closed or closes.
    */
    fn try_recv(&self) -> Option<T>;
}

/// Ports that can `peek`
pub trait Peekable<T> {
    /// Returns true if a message is available
    fn peek(&self) -> bool;
}

pub struct PortOne<T> { priv x: rtcomm::PortOne<T> }
pub struct ChanOne<T> { priv x: rtcomm::ChanOne<T> }

pub fn oneshot<T: Send>() -> (PortOne<T>, ChanOne<T>) {
    let (p, c) = rtcomm::oneshot();
    (PortOne { x: p }, ChanOne { x: c })
}

pub struct Port<T> { priv x: rtcomm::Port<T> }
pub struct Chan<T> { priv x: rtcomm::Chan<T> }

pub fn stream<T: Send>() -> (Port<T>, Chan<T>) {
    let (p, c) = rtcomm::stream();
    (Port { x: p }, Chan { x: c })
}

impl<T: Send> ChanOne<T> {
    pub fn send(self, val: T) {
        let ChanOne { x: c } = self;
        c.send(val)
    }

    pub fn try_send(self, val: T) -> bool {
        let ChanOne { x: c } = self;
        c.try_send(val)
    }

    pub fn send_deferred(self, val: T) {
        let ChanOne { x: c } = self;
        c.send_deferred(val)
    }

    pub fn try_send_deferred(self, val: T) -> bool {
        let ChanOne{ x: c } = self;
        c.try_send_deferred(val)
    }
}

impl<T: Send> PortOne<T> {
    pub fn recv(self) -> T {
        let PortOne { x: p } = self;
        p.recv()
    }

    pub fn try_recv(self) -> Option<T> {
        let PortOne { x: p } = self;
        p.try_recv()
    }
}

impl<T: Send> Peekable<T>  for PortOne<T> {
    fn peek(&self) -> bool {
        let &PortOne { x: ref p } = self;
        p.peek()
    }
}

impl<T: Send> GenericChan<T> for Chan<T> {
    fn send(&self, val: T) {
        let &Chan { x: ref c } = self;
        c.send(val)
    }
}

impl<T: Send> GenericSmartChan<T> for Chan<T> {
    fn try_send(&self, val: T) -> bool {
        let &Chan { x: ref c } = self;
        c.try_send(val)
    }
}

impl<T: Send> SendDeferred<T> for Chan<T> {
    fn send_deferred(&self, val: T) {
        let &Chan { x: ref c } = self;
        c.send_deferred(val)
    }

    fn try_send_deferred(&self, val: T) -> bool {
        let &Chan { x: ref c } = self;
        c.try_send_deferred(val)
    }
}

impl<T: Send> GenericPort<T> for Port<T> {
    fn recv(&self) -> T {
        let &Port { x: ref p } = self;
        p.recv()
    }

    fn try_recv(&self) -> Option<T> {
        let &Port { x: ref p } = self;
        p.try_recv()
    }
}

impl<T: Send> Peekable<T> for Port<T> {
    fn peek(&self) -> bool {
        let &Port { x: ref p } = self;
        p.peek()
    }
}

pub struct SharedChan<T> { priv x: rtcomm::SharedChan<T> }

impl<T: Send> SharedChan<T> {
    pub fn new(c: Chan<T>) -> SharedChan<T> {
        let Chan { x: c } = c;
        SharedChan { x: rtcomm::SharedChan::new(c) }
    }
}

impl<T: Send> GenericChan<T> for SharedChan<T> {
    fn send(&self, val: T) {
        let &SharedChan { x: ref c } = self;
        c.send(val)
    }
}

impl<T: Send> GenericSmartChan<T> for SharedChan<T> {
    fn try_send(&self, val: T) -> bool {
        let &SharedChan { x: ref c } = self;
        c.try_send(val)
    }
}

impl<T: Send> SendDeferred<T> for SharedChan<T> {
    fn send_deferred(&self, val: T) {
        let &SharedChan { x: ref c } = self;
        c.send_deferred(val)
    }

    fn try_send_deferred(&self, val: T) -> bool {
        let &SharedChan { x: ref c } = self;
        c.try_send_deferred(val)
    }
}

impl<T: Send> Clone for SharedChan<T> {
    fn clone(&self) -> SharedChan<T> {
        let &SharedChan { x: ref c } = self;
        SharedChan { x: c.clone() }
    }
}

pub struct SharedPort<T> { priv x: rtcomm::SharedPort<T> }

impl<T: Send> SharedPort<T> {
    pub fn new(p: Port<T>) -> SharedPort<T> {
        let Port { x: p } = p;
        SharedPort { x: rtcomm::SharedPort::new(p) }
    }
}

impl<T: Send> GenericPort<T> for SharedPort<T> {
    fn recv(&self) -> T {
        let &SharedPort { x: ref p } = self;
        p.recv()
    }

    fn try_recv(&self) -> Option<T> {
        let &SharedPort { x: ref p } = self;
        p.try_recv()
    }
}

impl<T: Send> Clone for SharedPort<T> {
    fn clone(&self) -> SharedPort<T> {
        let &SharedPort { x: ref p } = self;
        SharedPort { x: p.clone() }
    }
}
<commit_msg>auto merge of #10688 : bjz/rust/recv_iter, r=brson<commit_after>// Copyright 2012 The Rust Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution and at
// http://rust-lang.org/COPYRIGHT.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.

/*!
Message passing
*/

#[allow(missing_doc)];

use clone::Clone;
use iter::Iterator;
use kinds::Send;
use option::Option;
use rtcomm = rt::comm;

/// A trait for things that can send multiple messages.
pub trait GenericChan<T> {
    /// Sends a message.
    fn send(&self, x: T);
}

/// Things that can send multiple messages and can detect when the receiver
/// is closed
pub trait GenericSmartChan<T> {
    /// Sends a message, or report if the receiver has closed the connection.
    fn try_send(&self, x: T) -> bool;
}

/// Trait for non-rescheduling send operations, similar to `send_deferred` on ChanOne.
pub trait SendDeferred<T> {
    fn send_deferred(&self, val: T);
    fn try_send_deferred(&self, val: T) -> bool;
}

/// A trait for things that can receive multiple messages.
pub trait GenericPort<T> {
    /// Receives a message, or fails if the connection closes.
    fn recv(&self) -> T;

    /// Receives a message, or returns `none` if
    /// the connection is closed or closes.
    fn try_recv(&self) -> Option<T>;

    /// Returns an iterator that breaks once the connection closes.
    ///
    /// # Example
    ///
    /// ~~~rust
    /// do spawn {
    ///     for x in port.recv_iter() {
    ///         if pred(x) { break; }
    ///         println!("{}", x);
    ///     }
    /// }
    /// ~~~
    fn recv_iter<'a>(&'a self) -> RecvIterator<'a, Self> {
        RecvIterator { port: self }
    }
}

pub struct RecvIterator<'a, P> {
    priv port: &'a P,
}

impl<'a, T, P: GenericPort<T>> Iterator<T> for RecvIterator<'a, P> {
    fn next(&mut self) -> Option<T> {
        self.port.try_recv()
    }
}

/// Ports that can `peek`
pub trait Peekable<T> {
    /// Returns true if a message is available
    fn peek(&self) -> bool;
}

pub struct PortOne<T> { priv x: rtcomm::PortOne<T> }
pub struct ChanOne<T> { priv x: rtcomm::ChanOne<T> }

pub fn oneshot<T: Send>() -> (PortOne<T>, ChanOne<T>) {
    let (p, c) = rtcomm::oneshot();
    (PortOne { x: p }, ChanOne { x: c })
}

pub struct Port<T> { priv x: rtcomm::Port<T> }
pub struct Chan<T> { priv x: rtcomm::Chan<T> }

pub fn stream<T: Send>() -> (Port<T>, Chan<T>) {
    let (p, c) = rtcomm::stream();
    (Port { x: p }, Chan { x: c })
}

impl<T: Send> ChanOne<T> {
    pub fn send(self, val: T) {
        let ChanOne { x: c } = self;
        c.send(val)
    }

    pub fn try_send(self, val: T) -> bool {
        let ChanOne { x: c } = self;
        c.try_send(val)
    }

    pub fn send_deferred(self, val: T) {
        let ChanOne { x: c } = self;
        c.send_deferred(val)
    }

    pub fn try_send_deferred(self, val: T) -> bool {
        let ChanOne{ x: c } = self;
        c.try_send_deferred(val)
    }
}

impl<T: Send> PortOne<T> {
    pub fn recv(self) -> T {
        let PortOne { x: p } = self;
        p.recv()
    }

    pub fn try_recv(self) -> Option<T> {
        let PortOne { x: p } = self;
        p.try_recv()
    }
}

impl<T: Send> Peekable<T>  for PortOne<T> {
    fn peek(&self) -> bool {
        let &PortOne { x: ref p } = self;
        p.peek()
    }
}

impl<T: Send> GenericChan<T> for Chan<T> {
    fn send(&self, val: T) {
        let &Chan { x: ref c } = self;
        c.send(val)
    }
}

impl<T: Send> GenericSmartChan<T> for Chan<T> {
    fn try_send(&self, val: T) -> bool {
        let &Chan { x: ref c } = self;
        c.try_send(val)
    }
}

impl<T: Send> SendDeferred<T> for Chan<T> {
    fn send_deferred(&self, val: T) {
        let &Chan { x: ref c } = self;
        c.send_deferred(val)
    }

    fn try_send_deferred(&self, val: T) -> bool {
        let &Chan { x: ref c } = self;
        c.try_send_deferred(val)
    }
}

impl<T: Send> GenericPort<T> for Port<T> {
    fn recv(&self) -> T {
        let &Port { x: ref p } = self;
        p.recv()
    }

    fn try_recv(&self) -> Option<T> {
        let &Port { x: ref p } = self;
        p.try_recv()
    }
}

impl<T: Send> Peekable<T> for Port<T> {
    fn peek(&self) -> bool {
        let &Port { x: ref p } = self;
        p.peek()
    }
}

pub struct SharedChan<T> { priv x: rtcomm::SharedChan<T> }

impl<T: Send> SharedChan<T> {
    pub fn new(c: Chan<T>) -> SharedChan<T> {
        let Chan { x: c } = c;
        SharedChan { x: rtcomm::SharedChan::new(c) }
    }
}

impl<T: Send> GenericChan<T> for SharedChan<T> {
    fn send(&self, val: T) {
        let &SharedChan { x: ref c } = self;
        c.send(val)
    }
}

impl<T: Send> GenericSmartChan<T> for SharedChan<T> {
    fn try_send(&self, val: T) -> bool {
        let &SharedChan { x: ref c } = self;
        c.try_send(val)
    }
}

impl<T: Send> SendDeferred<T> for SharedChan<T> {
    fn send_deferred(&self, val: T) {
        let &SharedChan { x: ref c } = self;
        c.send_deferred(val)
    }

    fn try_send_deferred(&self, val: T) -> bool {
        let &SharedChan { x: ref c } = self;
        c.try_send_deferred(val)
    }
}

impl<T: Send> Clone for SharedChan<T> {
    fn clone(&self) -> SharedChan<T> {
        let &SharedChan { x: ref c } = self;
        SharedChan { x: c.clone() }
    }
}

pub struct SharedPort<T> { priv x: rtcomm::SharedPort<T> }

impl<T: Send> SharedPort<T> {
    pub fn new(p: Port<T>) -> SharedPort<T> {
        let Port { x: p } = p;
        SharedPort { x: rtcomm::SharedPort::new(p) }
    }
}

impl<T: Send> GenericPort<T> for SharedPort<T> {
    fn recv(&self) -> T {
        let &SharedPort { x: ref p } = self;
        p.recv()
    }

    fn try_recv(&self) -> Option<T> {
        let &SharedPort { x: ref p } = self;
        p.try_recv()
    }
}

impl<T: Send> Clone for SharedPort<T> {
    fn clone(&self) -> SharedPort<T> {
        let &SharedPort { x: ref p } = self;
        SharedPort { x: p.clone() }
    }
}

#[cfg(test)]
mod tests {
    use comm::*;
    use prelude::*;

    #[test]
    fn test_nested_recv_iter() {
        let (port, chan) = stream::<int>();
        let (total_port, total_chan) = oneshot::<int>();

        do spawn {
            let mut acc = 0;
            for x in port.recv_iter() {
                acc += x;
                for x in port.recv_iter() {
                    acc += x;
                    for x in port.try_recv().move_iter() {
                        acc += x;
                        total_chan.send(acc);
                    }
                }
            }
        }

        chan.send(3);
        chan.send(1);
        chan.send(2);
        assert_eq!(total_port.recv(), 6);
    }

    #[test]
    fn test_recv_iter_break() {
        let (port, chan) = stream::<int>();
        let (count_port, count_chan) = oneshot::<int>();

        do spawn {
            let mut count = 0;
            for x in port.recv_iter() {
                if count >= 3 {
                    count_chan.send(count);
                    break;
                } else {
                    count += x;
                }
            }
        }

        chan.send(2);
        chan.send(2);
        chan.send(2);
        chan.send(2);
        assert_eq!(count_port.recv(), 4);
    }
}
<|endoftext|>


<commit_before>// Anima Engine. The quirky game engine
// Copyright (C) 2016  Dragoș Tiselice
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU Lesser General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public License
// along with this program.  If not, see <http://www.gnu.org/licenses/>.

use math::Quaternion;

/// A simple vector `struct` tailored specifically for graphics.
#[derive(Clone, Copy, Debug, PartialEq)]
pub struct Vector {
    /// `f32` *x* coordinate value
    pub x: f32,
    /// `f32` *y* coordinate value
    pub y: f32,
    /// `f32` *z* coordinate value
    pub z: f32
}

impl Vector {
    /// Creates a vector using 3 values.
    ///
    /// # Example
    ///
    /// ```
    /// # use anima::math::Vector;
    /// let v = Vector::new(0.0, 1.0, 2.0);
    ///
    /// assert_eq!(v, Vector { x: 0.0, y: 1.0, z: 2.0 });
    /// ```
    pub fn new(x: f32, y: f32, z: f32) -> Vector {
        Vector { x: x, y: y, z: z }
    }

    /// Creates a vector using an array.
    ///
    /// # Example
    ///
    /// ```
    /// # use anima::math::Vector;
    /// let v = Vector::new_arr([0.0, 1.0, 2.0]);
    ///
    /// assert_eq!(v, Vector { x: 0.0, y: 1.0, z: 2.0 });
    /// ```
    pub fn new_arr(array: [f32; 3]) -> Vector {
        Vector { x: array[0], y: array[1], z: array[2] }
    }

    /// Creates a uniform vector using 1 value.
    ///
    /// # Example
    ///
    /// ```
    /// # use anima::math::Vector;
    /// let v = Vector::new_unf(1.0);
    ///
    /// assert_eq!(v, Vector { x: 1.0, y: 1.0, z: 1.0 });
    /// ```
    pub fn new_unf(v: f32) -> Vector {
        Vector { x: v, y: v, z: v }
    }

    /// Creates a zero (0.0, 0.0, 0.0) Vector.
    ///
    /// # Example
    ///
    /// ```
    /// # use anima::math::Vector;
    /// assert_eq!(Vector::zero(), Vector { x: 0.0, y: 0.0, z: 0.0 });
    /// ```
    pub fn zero() -> Vector {
        Vector { x: 0.0, y: 0.0, z: 0.0 }
    }

    /// Creates a one (1.0, 1.0, 1.0) Vector.
    ///
    /// # Example
    ///
    /// ```
    /// # use anima::math::Vector;
    /// assert_eq!(Vector::one(), Vector { x: 1.0, y: 1.0, z: 1.0 });
    /// ```
    pub fn one() -> Vector {
        Vector { x: 1.0, y: 1.0, z: 1.0 }
    }

    /// Creates a back (0.0, 0.0, -1.0) Vector.
    ///
    /// # Example
    ///
    /// ```
    /// # use anima::math::Vector;
    /// assert_eq!(Vector::back(), Vector { x: 0.0, y: 0.0, z: -1.0 });
    /// ```
    pub fn back() -> Vector {
        Vector { x: 0.0, y: 0.0, z: -1.0 }
    }

    /// Creates a down (0.0, -1.0, 0.0) Vector.
    ///
    /// # Example
    ///
    /// ```
    /// # use anima::math::Vector;
    /// assert_eq!(Vector::down(), Vector { x: 0.0, y: -1.0, z: 0.0 });
    /// ```
    pub fn down() -> Vector {
        Vector { x: 0.0, y: -1.0, z: 0.0 }
    }

    /// Creates a forward (0.0, 0.0, 1.0) Vector.
    ///
    /// # Example
    ///
    /// ```
    /// # use anima::math::Vector;
    /// assert_eq!(Vector::forward(), Vector { x: 0.0, y: 0.0, z: 1.0 });
    /// ```
    pub fn forward() -> Vector {
        Vector { x: 0.0, y: 0.0, z: 1.0 }
    }

    /// Creates a left (-1.0, 0.0, 0.0) Vector.
    ///
    /// # Example
    ///
    /// ```
    /// # use anima::math::Vector;
    /// assert_eq!(Vector::left(), Vector { x: -1.0, y: 0.0, z: 0.0 });
    /// ```
    pub fn left() -> Vector {
        Vector { x: -1.0, y: 0.0, z: 0.0 }
    }

    /// Creates a right (1.0, 0.0, 0.0) Vector.
    ///
    /// # Example
    ///
    /// ```
    /// # use anima::math::Vector;
    /// assert_eq!(Vector::right(), Vector { x: 1.0, y: 0.0, z: 0.0 });
    /// ```
    pub fn right() -> Vector {
        Vector { x: 1.0, y: 0.0, z: 0.0 }
    }

    /// Creates an up (0.0, 1.0, 0.0) Vector.
    ///
    /// # Example
    ///
    /// ```
    /// # use anima::math::Vector;
    /// assert_eq!(Vector::up(), Vector { x: 0.0, y: 1.0, z: 0.0 });
    /// ```
    pub fn up() -> Vector {
        Vector { x: 0.0, y: 1.0, z: 0.0 }
    }

    /// Computes the length of a vector.
    ///
    /// # Example
    ///
    /// ```
    /// # use anima::math::Vector;
    /// let v = Vector::new(1.0, 2.0, 2.0);
    ///
    /// assert_eq!(v.length(), 3.0);
    /// ```
    pub fn length(&self) -> f32 {
        (self.x.powi(2) + self.y.powi(2) + self.z.powi(2)).sqrt()
    }

    /// Computes the normalized version of a vector.
    ///
    /// # Example
    ///
    /// ```
    /// # use anima::math::Vector;
    /// let v = Vector::new(1.0, 2.0, 2.0);
    /// let n = v.norm();
    ///
    /// assert_eq!(n.length(), 1.0); // Keep precision in mind when comparing floats.
    /// ```
    pub fn norm(&self) -> Vector {
        let length = self.length();

        Vector {
            x: self.x / length,
            y: self.y / length,
            z: self.z / length
        }
    }

    /// Computes the dot product between two vectors.
    ///
    /// # Example
    ///
    /// ```
    /// # use anima::math::Vector;
    /// let v1 = Vector::new(1.0, 2.0, 2.0);
    /// let v2 = Vector::new(3.0, 3.0, 1.0);
    ///
    /// assert_eq!(v1.dot(v2), 11.0);
    /// ```
    pub fn dot(&self, other: Vector) -> f32 {
        self.x * other.x +
        self.y * other.y +
        self.z * other.z
    }

    /// Computes the cross product between two vectors.
    ///
    /// # Example
    ///
    /// ```
    /// # use anima::math::Vector;
    /// let v1 = Vector::new(1.0, 2.0, 2.0);
    /// let v2 = Vector::new(3.0, 3.0, 1.0);
    ///
    /// assert_eq!(v1.cross(v2), Vector { x: -4.0, y: 5.0, z: -3.0 });
    /// ```
    pub fn cross(&self, other: Vector) -> Vector {
        Vector {
            x: self.y * other.z - self.z * other.y,
            y: self.z * other.x - self.x * other.z,
            z: self.x * other.y - self.y * other.x
        }
    }

    /// Rotates a vector according to the rotation represented by a quaternion.
    ///
    /// # Example
    ///
    /// ```
    /// # use anima::math::Vector;
    /// # use anima::math::Quaternion;
    /// let q = Quaternion::new(0.0, 1.0, 0.0, 0.0);
    /// let v = Vector::new(1.0, 0.0, 0.0);
    ///
    /// assert_eq!(v.rot(q), Vector { x: -1.0, y: 0.0, z: 0.0 });
    /// ```
    pub fn rot(&self, quaternion: Quaternion) -> Vector {
        let conjugate = quaternion.conj();
        let result = quaternion *
                     Quaternion::new(self.x, self.y, self.z, 0.0) *
                     conjugate;

        Vector { x: result.x, y: result.y, z: result.z }
    }

    /// Rotates a vector according to the rotation represented by the quaternion around a point.
    ///
    /// # Example
    ///
    /// ```
    /// # use anima::math::Vector;
    /// # use anima::math::Quaternion;
    /// let q = Quaternion::new(0.0, 1.0, 0.0, 0.0);
    /// let v = Vector::new(1.0, 0.0, 0.0);
    /// let p = Vector::new(2.0, 0.0, 0.0);
    ///
    /// assert_eq!(v.rot_around(q, p), Vector { x: 3.0, y: 0.0, z: 0.0 });
    /// ```
    pub fn rot_around(self, quaternion: Quaternion, point: Vector) -> Vector {
        (self - point).rot(quaternion) + point
    }

    /// Computes the angle in radians between two vectors.
    ///
    /// # Example
    ///
    /// ```
    /// # use anima::math::Vector;
    /// # use std::f32::consts;
    /// let v1 = Vector::new(1.0, 0.0, 0.0);
    /// let v2 = Vector::new(0.0, 1.0, 0.0);
    ///
    /// assert_eq!(v1.angle(v2), consts::PI / 2.0);
    /// ```
    pub fn angle(&self, other: Vector) -> f32 {
        self.dot(other).acos()
    }

    /// Computes the distance between two vectors.
    ///
    /// # Example
    ///
    /// ```
    /// # use anima::math::Vector;
    /// let v1 = Vector::new(0.0, 0.0, 0.0);
    /// let v2 = Vector::new(0.0, 1.0, 0.0);
    ///
    /// assert_eq!(v1.dist(v2), 1.0);
    /// ```
    pub fn dist(self, other: Vector) -> f32 {
        (self - other).length()
    }
}

use std::ops::Add;
use std::ops::Sub;
use std::ops::Mul;
use std::ops::Neg;
use std::cmp::Ordering;

impl Add for Vector {
    type Output = Vector;

    fn add(self, other: Vector) -> Vector {
        Vector {
            x: self.x + other.x,
            y: self.y + other.y,
            z: self.z + other.z
        }
    }
}

impl Sub for Vector {
    type Output = Vector;

    fn sub(self, other: Vector) -> Vector {
        Vector {
            x: self.x - other.x,
            y: self.y - other.y,
            z: self.z - other.z
        }
    }
}

impl Mul<Vector> for Vector {
    type Output = Vector;

    fn mul(self, other: Vector) -> Vector {
        Vector {
            x: self.x * other.x,
            y: self.y * other.y,
            z: self.z * other.z
        }
    }
}

impl Mul<f32> for Vector {
    type Output = Vector;

    fn mul(self, scalar: f32) -> Vector {
        Vector {
            x: self.x * scalar,
            y: self.y * scalar,
            z: self.z * scalar
        }
    }
}

impl Mul<Vector> for f32 {
    type Output = Vector;

    fn mul(self, vector: Vector) -> Vector {
        Vector {
            x: vector.x * self,
            y: vector.y * self,
            z: vector.z * self
        }
    }
}

impl Neg for Vector {
    type Output = Vector;

    fn neg(self) -> Vector {
        Vector {
            x: -self.x,
            y: -self.y,
            z: -self.z
        }
    }
}

impl PartialOrd for Vector {
    fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
        self.length().partial_cmp(&other.length())
    }
}
<commit_msg>Changed left/right to right-handed coordinate system.<commit_after>// Anima Engine. The quirky game engine
// Copyright (C) 2016  Dragoș Tiselice
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU Lesser General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public License
// along with this program.  If not, see <http://www.gnu.org/licenses/>.

use math::Quaternion;

/// A simple vector `struct` tailored specifically for graphics.
#[derive(Clone, Copy, Debug, PartialEq)]
pub struct Vector {
    /// `f32` *x* coordinate value
    pub x: f32,
    /// `f32` *y* coordinate value
    pub y: f32,
    /// `f32` *z* coordinate value
    pub z: f32
}

impl Vector {
    /// Creates a vector using 3 values.
    ///
    /// # Example
    ///
    /// ```
    /// # use anima::math::Vector;
    /// let v = Vector::new(0.0, 1.0, 2.0);
    ///
    /// assert_eq!(v, Vector { x: 0.0, y: 1.0, z: 2.0 });
    /// ```
    pub fn new(x: f32, y: f32, z: f32) -> Vector {
        Vector { x: x, y: y, z: z }
    }

    /// Creates a vector using an array.
    ///
    /// # Example
    ///
    /// ```
    /// # use anima::math::Vector;
    /// let v = Vector::new_arr([0.0, 1.0, 2.0]);
    ///
    /// assert_eq!(v, Vector { x: 0.0, y: 1.0, z: 2.0 });
    /// ```
    pub fn new_arr(array: [f32; 3]) -> Vector {
        Vector { x: array[0], y: array[1], z: array[2] }
    }

    /// Creates a uniform vector using 1 value.
    ///
    /// # Example
    ///
    /// ```
    /// # use anima::math::Vector;
    /// let v = Vector::new_unf(1.0);
    ///
    /// assert_eq!(v, Vector { x: 1.0, y: 1.0, z: 1.0 });
    /// ```
    pub fn new_unf(v: f32) -> Vector {
        Vector { x: v, y: v, z: v }
    }

    /// Creates a zero (0.0, 0.0, 0.0) Vector.
    ///
    /// # Example
    ///
    /// ```
    /// # use anima::math::Vector;
    /// assert_eq!(Vector::zero(), Vector { x: 0.0, y: 0.0, z: 0.0 });
    /// ```
    pub fn zero() -> Vector {
        Vector { x: 0.0, y: 0.0, z: 0.0 }
    }

    /// Creates a one (1.0, 1.0, 1.0) Vector.
    ///
    /// # Example
    ///
    /// ```
    /// # use anima::math::Vector;
    /// assert_eq!(Vector::one(), Vector { x: 1.0, y: 1.0, z: 1.0 });
    /// ```
    pub fn one() -> Vector {
        Vector { x: 1.0, y: 1.0, z: 1.0 }
    }

    /// Creates a back (0.0, 0.0, -1.0) Vector.
    ///
    /// # Example
    ///
    /// ```
    /// # use anima::math::Vector;
    /// assert_eq!(Vector::back(), Vector { x: 0.0, y: 0.0, z: -1.0 });
    /// ```
    pub fn back() -> Vector {
        Vector { x: 0.0, y: 0.0, z: -1.0 }
    }

    /// Creates a down (0.0, -1.0, 0.0) Vector.
    ///
    /// # Example
    ///
    /// ```
    /// # use anima::math::Vector;
    /// assert_eq!(Vector::down(), Vector { x: 0.0, y: -1.0, z: 0.0 });
    /// ```
    pub fn down() -> Vector {
        Vector { x: 0.0, y: -1.0, z: 0.0 }
    }

    /// Creates a forward (0.0, 0.0, 1.0) Vector.
    ///
    /// # Example
    ///
    /// ```
    /// # use anima::math::Vector;
    /// assert_eq!(Vector::forward(), Vector { x: 0.0, y: 0.0, z: 1.0 });
    /// ```
    pub fn forward() -> Vector {
        Vector { x: 0.0, y: 0.0, z: 1.0 }
    }

    /// Creates a left (-1.0, 0.0, 0.0) Vector.
    ///
    /// # Example
    ///
    /// ```
    /// # use anima::math::Vector;
    /// assert_eq!(Vector::left(), Vector { x: 1.0, y: 0.0, z: 0.0 });
    /// ```
    pub fn left() -> Vector {
        Vector { x: 1.0, y: 0.0, z: 0.0 }
    }

    /// Creates a right (1.0, 0.0, 0.0) Vector.
    ///
    /// # Example
    ///
    /// ```
    /// # use anima::math::Vector;
    /// assert_eq!(Vector::right(), Vector { x: -1.0, y: 0.0, z: 0.0 });
    /// ```
    pub fn right() -> Vector {
        Vector { x: -1.0, y: 0.0, z: 0.0 }
    }

    /// Creates an up (0.0, 1.0, 0.0) Vector.
    ///
    /// # Example
    ///
    /// ```
    /// # use anima::math::Vector;
    /// assert_eq!(Vector::up(), Vector { x: 0.0, y: 1.0, z: 0.0 });
    /// ```
    pub fn up() -> Vector {
        Vector { x: 0.0, y: 1.0, z: 0.0 }
    }

    /// Computes the length of a vector.
    ///
    /// # Example
    ///
    /// ```
    /// # use anima::math::Vector;
    /// let v = Vector::new(1.0, 2.0, 2.0);
    ///
    /// assert_eq!(v.length(), 3.0);
    /// ```
    pub fn length(&self) -> f32 {
        (self.x.powi(2) + self.y.powi(2) + self.z.powi(2)).sqrt()
    }

    /// Computes the normalized version of a vector.
    ///
    /// # Example
    ///
    /// ```
    /// # use anima::math::Vector;
    /// let v = Vector::new(1.0, 2.0, 2.0);
    /// let n = v.norm();
    ///
    /// assert_eq!(n.length(), 1.0); // Keep precision in mind when comparing floats.
    /// ```
    pub fn norm(&self) -> Vector {
        let length = self.length();

        Vector {
            x: self.x / length,
            y: self.y / length,
            z: self.z / length
        }
    }

    /// Computes the dot product between two vectors.
    ///
    /// # Example
    ///
    /// ```
    /// # use anima::math::Vector;
    /// let v1 = Vector::new(1.0, 2.0, 2.0);
    /// let v2 = Vector::new(3.0, 3.0, 1.0);
    ///
    /// assert_eq!(v1.dot(v2), 11.0);
    /// ```
    pub fn dot(&self, other: Vector) -> f32 {
        self.x * other.x +
        self.y * other.y +
        self.z * other.z
    }

    /// Computes the cross product between two vectors.
    ///
    /// # Example
    ///
    /// ```
    /// # use anima::math::Vector;
    /// let v1 = Vector::new(1.0, 2.0, 2.0);
    /// let v2 = Vector::new(3.0, 3.0, 1.0);
    ///
    /// assert_eq!(v1.cross(v2), Vector { x: -4.0, y: 5.0, z: -3.0 });
    /// ```
    pub fn cross(&self, other: Vector) -> Vector {
        Vector {
            x: self.y * other.z - self.z * other.y,
            y: self.z * other.x - self.x * other.z,
            z: self.x * other.y - self.y * other.x
        }
    }

    /// Rotates a vector according to the rotation represented by a quaternion.
    ///
    /// # Example
    ///
    /// ```
    /// # use anima::math::Vector;
    /// # use anima::math::Quaternion;
    /// let q = Quaternion::new(0.0, 1.0, 0.0, 0.0);
    /// let v = Vector::new(1.0, 0.0, 0.0);
    ///
    /// assert_eq!(v.rot(q), Vector { x: -1.0, y: 0.0, z: 0.0 });
    /// ```
    pub fn rot(&self, quaternion: Quaternion) -> Vector {
        let conjugate = quaternion.conj();
        let result = quaternion *
                     Quaternion::new(self.x, self.y, self.z, 0.0) *
                     conjugate;

        Vector { x: result.x, y: result.y, z: result.z }
    }

    /// Rotates a vector according to the rotation represented by the quaternion around a point.
    ///
    /// # Example
    ///
    /// ```
    /// # use anima::math::Vector;
    /// # use anima::math::Quaternion;
    /// let q = Quaternion::new(0.0, 1.0, 0.0, 0.0);
    /// let v = Vector::new(1.0, 0.0, 0.0);
    /// let p = Vector::new(2.0, 0.0, 0.0);
    ///
    /// assert_eq!(v.rot_around(q, p), Vector { x: 3.0, y: 0.0, z: 0.0 });
    /// ```
    pub fn rot_around(self, quaternion: Quaternion, point: Vector) -> Vector {
        (self - point).rot(quaternion) + point
    }

    /// Computes the angle in radians between two vectors.
    ///
    /// # Example
    ///
    /// ```
    /// # use anima::math::Vector;
    /// # use std::f32::consts;
    /// let v1 = Vector::new(1.0, 0.0, 0.0);
    /// let v2 = Vector::new(0.0, 1.0, 0.0);
    ///
    /// assert_eq!(v1.angle(v2), consts::PI / 2.0);
    /// ```
    pub fn angle(&self, other: Vector) -> f32 {
        self.dot(other).acos()
    }

    /// Computes the distance between two vectors.
    ///
    /// # Example
    ///
    /// ```
    /// # use anima::math::Vector;
    /// let v1 = Vector::new(0.0, 0.0, 0.0);
    /// let v2 = Vector::new(0.0, 1.0, 0.0);
    ///
    /// assert_eq!(v1.dist(v2), 1.0);
    /// ```
    pub fn dist(self, other: Vector) -> f32 {
        (self - other).length()
    }
}

use std::ops::Add;
use std::ops::Sub;
use std::ops::Mul;
use std::ops::Neg;
use std::cmp::Ordering;

impl Add for Vector {
    type Output = Vector;

    fn add(self, other: Vector) -> Vector {
        Vector {
            x: self.x + other.x,
            y: self.y + other.y,
            z: self.z + other.z
        }
    }
}

impl Sub for Vector {
    type Output = Vector;

    fn sub(self, other: Vector) -> Vector {
        Vector {
            x: self.x - other.x,
            y: self.y - other.y,
            z: self.z - other.z
        }
    }
}

impl Mul<Vector> for Vector {
    type Output = Vector;

    fn mul(self, other: Vector) -> Vector {
        Vector {
            x: self.x * other.x,
            y: self.y * other.y,
            z: self.z * other.z
        }
    }
}

impl Mul<f32> for Vector {
    type Output = Vector;

    fn mul(self, scalar: f32) -> Vector {
        Vector {
            x: self.x * scalar,
            y: self.y * scalar,
            z: self.z * scalar
        }
    }
}

impl Mul<Vector> for f32 {
    type Output = Vector;

    fn mul(self, vector: Vector) -> Vector {
        Vector {
            x: vector.x * self,
            y: vector.y * self,
            z: vector.z * self
        }
    }
}

impl Neg for Vector {
    type Output = Vector;

    fn neg(self) -> Vector {
        Vector {
            x: -self.x,
            y: -self.y,
            z: -self.z
        }
    }
}

impl PartialOrd for Vector {
    fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
        self.length().partial_cmp(&other.length())
    }
}
<|endoftext|>


<commit_before>/// a very small mod just for ui data send by net. It is important to
/// not send all discovery blindly (e.g. duplicates)
use libp2p_core::{Multiaddr, PeerId};
use std::{collections::HashMap, sync::mpsc::Sender};

use super::super::ctrl::{self, ForwardNetMessage, UiPeer, UiUpdateMsg};

pub struct UiData {
    sender: Option<Sender<UiUpdateMsg>>,
    // todo: use, fill () with some nice data for webui functionality, etc.
    ui_shown_peers: HashMap<PeerId, ()>,
}
impl UiData {
    pub fn new(sender: Option<Sender<UiUpdateMsg>>) -> Self {
        Self {
            sender,
            ui_shown_peers: HashMap::new(),
        }
    }

    pub fn has_peer(&mut self, peer_id: &PeerId) -> bool {
        let ref collection = self.ui_shown_peers;
        collection.get(peer_id).is_some()
    }

    pub fn register_address(&mut self, peer_id: &PeerId, multi_addresses: &Multiaddr) {
        let ref mut collection = self.ui_shown_peers;
        if collection.get(peer_id).is_none() {
            // add
            collection.insert(peer_id.clone(), ());
            trace!("found new peer {}", peer_id.to_string());
            // and send
            if let Some(ctrl_sender) = &self.sender {
                let addr_as_string = multi_addresses.iter().map(|x| x.to_string()).collect();

                ctrl_sender
                    .send(ctrl::UiUpdateMsg::NetUpdate(ForwardNetMessage::Add(
                        UiPeer {
                            id: peer_id.clone(),
                            addresses: addr_as_string,
                        },
                    )))
                    .unwrap_or_else(|e| error!("use one: {}", e));
            }
        } else {
            error!("Hey, the StateMachine should have made this impossible!!!");
        }
    }
    pub fn unregister_address(&mut self, peer_id: &PeerId) {
        let ref mut collection = self.ui_shown_peers;
        if collection.remove(peer_id).is_some() {
            trace!("removed peer {}", peer_id.to_string());
            if let Some(ctrl_sender) = &self.sender {
                ctrl_sender
                    .send(ctrl::UiUpdateMsg::NetUpdate(ForwardNetMessage::Delete(
                        peer_id.clone(),
                    )))
                    .unwrap_or_else(|e| error!("use one: {}", e));
            }
        } else {
            warn!("Trying to remove something which wasn't there ...");
        }
    }
}
<commit_msg>[clean-up] peer ids hash also in logs, to be comparable<commit_after>/// a very small mod just for ui data send by net. It is important to
/// not send all discovery blindly (e.g. duplicates)
use libp2p_core::{Multiaddr, PeerId};
use std::{collections::HashMap, sync::mpsc::Sender};

use super::super::ctrl::{self, ForwardNetMessage, UiPeer, UiUpdateMsg};

pub struct UiData {
    sender: Option<Sender<UiUpdateMsg>>,
    // todo: use, fill () with some nice data for webui functionality, etc.
    ui_shown_peers: HashMap<PeerId, ()>,
}
impl UiData {
    pub fn new(sender: Option<Sender<UiUpdateMsg>>) -> Self {
        Self {
            sender,
            ui_shown_peers: HashMap::new(),
        }
    }

    pub fn has_peer(&mut self, peer_id: &PeerId) -> bool {
        let ref collection = self.ui_shown_peers;
        collection.get(peer_id).is_some()
    }

    pub fn register_address(&mut self, peer_id: &PeerId, multi_addresses: &Multiaddr) {
        let ref mut collection = self.ui_shown_peers;
        if collection.get(peer_id).is_none() {
            // add
            collection.insert(peer_id.clone(), ());
            trace!("found new peer {}", ctrl::peer_hash(peer_id));
            // and send
            if let Some(ctrl_sender) = &self.sender {
                let addr_as_string = multi_addresses.iter().map(|x| x.to_string()).collect();

                ctrl_sender
                    .send(ctrl::UiUpdateMsg::NetUpdate(ForwardNetMessage::Add(
                        UiPeer {
                            id: peer_id.clone(),
                            addresses: addr_as_string,
                        },
                    )))
                    .unwrap_or_else(|e| error!("use one: {}", e));
            }
        } else {
            error!("Hey, the StateMachine should have made this impossible!!!");
        }
    }
    pub fn unregister_address(&mut self, peer_id: &PeerId) {
        let ref mut collection = self.ui_shown_peers;
        if collection.remove(peer_id).is_some() {
            trace!("removed peer {}", ctrl::peer_hash(peer_id));
            if let Some(ctrl_sender) = &self.sender {
                ctrl_sender
                    .send(ctrl::UiUpdateMsg::NetUpdate(ForwardNetMessage::Delete(
                        peer_id.clone(),
                    )))
                    .unwrap_or_else(|e| error!("use one: {}", e));
            }
        } else {
            warn!("Trying to remove something which wasn't there ...");
        }
    }
}
<|endoftext|>


<commit_before>use parser::combinators::{Parser, ParseTo, Consumer, token};
use parser::lexer::{Token};
use parser::lexer::Token::{Identifier};
use ast::{Typ};
use ast::Typ::{F32, F64, I32, I64};

#[derive(Clone, Eq, PartialEq, Hash, Ord, PartialOrd, Debug)]
pub enum ParseError {
    ExpectingTyp(String),
}

pub trait ParserConsumer<D> where D: Consumer<Result<Typ,ParseError>> {
    fn accept<P>(self, parser: P) where P: for<'a> ParseTo<&'a[Token<'a>],D>;
}

fn is_identifier<'a>(tok: Token<'a>) -> bool {
    match tok {
        Identifier(_) => true,
        _             => false,
    }
}

fn mk_typ<'a>(tok: Token<'a>) -> Result<Typ,ParseError> {
    match tok {
        Identifier("f32") => Ok(F32),
        Identifier("f64") => Ok(F64),
        Identifier("i32") => Ok(I32),
        Identifier("i64") => Ok(I64),
        _                 => Err(ParseError::ExpectingTyp(String::from(tok))),
    }
}

pub fn parser<C,D>(consumer: C) where C: ParserConsumer<D>, D: Consumer<Result<Typ,ParseError>> {
    let typ = token(is_identifier).map(mk_typ);
    consumer.accept(typ);
}

#[test]
fn test_typ() {
    use parser::combinators::MatchResult::{Matched,Failed};
    use parser::lexer::Token::{LParen};
    struct TestConsumer;
    impl ParserConsumer<Vec<Result<Typ,ParseError>>> for TestConsumer {
        fn accept<P>(self, mut parser: P) where P: for<'a> ParseTo<&'a[Token<'a>],Vec<Result<Typ,ParseError>>> {
            let mut results = Vec::new();
            assert_eq!(parser.push_to(&[Identifier("f32")], &mut results), Matched(None));
            assert_eq!(parser.done_to(&mut results), true);
            assert_eq!(results, [Ok(F32)]);
            results.clear();
            assert_eq!(parser.push_to(&[Identifier("f64")], &mut results), Matched(None));
            assert_eq!(parser.done_to(&mut results), true);
            assert_eq!(results, [Ok(F64)]);
            results.clear();
            assert_eq!(parser.push_to(&[Identifier("i32")], &mut results), Matched(None));
            assert_eq!(parser.done_to(&mut results), true);
            assert_eq!(results, [Ok(I32)]);
            results.clear();
            assert_eq!(parser.push_to(&[Identifier("i64")], &mut results), Matched(None));
            assert_eq!(parser.done_to(&mut results), true);
            assert_eq!(results, [Ok(I64)]);
            results.clear();
            assert_eq!(parser.push_to(&[LParen], &mut results), Failed(Some(&[LParen][..])));
            assert_eq!(parser.done_to(&mut results), false);
            assert_eq!(results, []);
            results.clear();
            assert_eq!(parser.push_to(&[Identifier("foo")], &mut results), Matched(None));
            assert_eq!(parser.done_to(&mut results), true);
            assert_eq!(results, [Err(ParseError::ExpectingTyp(String::from("foo")))]);
            results.clear();
        }
    }
    parser(TestConsumer);
}
<commit_msg>Renaming.<commit_after>use parser::combinators::{Parser, ParseTo, Consumer, token};
use parser::lexer::{Token};
use parser::lexer::Token::{Identifier};
use ast::{Typ};
use ast::Typ::{F32, F64, I32, I64};

#[derive(Clone, Eq, PartialEq, Hash, Ord, PartialOrd, Debug)]
pub enum ParseError {
    ExpectingTyp(String),
}

pub trait ParserConsumer<T,D> where D: Consumer<Result<T,ParseError>> {
    fn accept<P>(self, parser: P) where P: for<'a> ParseTo<&'a[Token<'a>],D>;
}

fn is_identifier<'a>(tok: Token<'a>) -> bool {
    match tok {
        Identifier(_) => true,
        _             => false,
    }
}

fn mk_typ<'a>(tok: Token<'a>) -> Result<Typ,ParseError> {
    match tok {
        Identifier("f32") => Ok(F32),
        Identifier("f64") => Ok(F64),
        Identifier("i32") => Ok(I32),
        Identifier("i64") => Ok(I64),
        _                 => Err(ParseError::ExpectingTyp(String::from(tok))),
    }
}

pub fn typ_parser<C,D>(consumer: C) where C: ParserConsumer<Typ,D>, D: Consumer<Result<Typ,ParseError>> {
    consumer.accept(token(is_identifier).map(mk_typ));
}

#[test]
fn test_typ() {
    use parser::combinators::MatchResult::{Matched,Failed};
    use parser::lexer::Token::{LParen};
    struct TestConsumer;
    impl ParserConsumer<Typ,Vec<Result<Typ,ParseError>>> for TestConsumer {
        fn accept<P>(self, mut parser: P) where P: for<'a> ParseTo<&'a[Token<'a>],Vec<Result<Typ,ParseError>>> {
            let mut results = Vec::new();
            assert_eq!(parser.push_to(&[Identifier("f32")], &mut results), Matched(None));
            assert_eq!(parser.done_to(&mut results), true);
            assert_eq!(results, [Ok(F32)]);
            results.clear();
            assert_eq!(parser.push_to(&[Identifier("f64")], &mut results), Matched(None));
            assert_eq!(parser.done_to(&mut results), true);
            assert_eq!(results, [Ok(F64)]);
            results.clear();
            assert_eq!(parser.push_to(&[Identifier("i32")], &mut results), Matched(None));
            assert_eq!(parser.done_to(&mut results), true);
            assert_eq!(results, [Ok(I32)]);
            results.clear();
            assert_eq!(parser.push_to(&[Identifier("i64")], &mut results), Matched(None));
            assert_eq!(parser.done_to(&mut results), true);
            assert_eq!(results, [Ok(I64)]);
            results.clear();
            assert_eq!(parser.push_to(&[LParen], &mut results), Failed(Some(&[LParen][..])));
            assert_eq!(parser.done_to(&mut results), false);
            assert_eq!(results, []);
            results.clear();
            assert_eq!(parser.push_to(&[Identifier("foo")], &mut results), Matched(None));
            assert_eq!(parser.done_to(&mut results), true);
            assert_eq!(results, [Err(ParseError::ExpectingTyp(String::from("foo")))]);
            results.clear();
        }
    }
    typ_parser(TestConsumer);
}
<|endoftext|>