<commit_before>use crate::context::ContextError;
use std::any::TypeId;
use std::error::Error as StdError;
use std::fmt::{self, Debug, Display};
use std::mem;
use std::ops::{Deref, DerefMut};
use std::ptr;

#[cfg(backtrace)]
use std::backtrace::{Backtrace, BacktraceStatus};

/// The `Error` type, a wrapper around a dynamic error type.
///
/// `Error` works a lot like `Box<dyn std::error::Error>`, but with these
/// differences:
///
/// - `Error` requires that the error is `Send`, `Sync`, and `'static`.
/// - `Error` guarantees that a backtrace is available, even if the underlying
///   error type does not provide one.
/// - `Error` is represented as a narrow pointer — exactly one word in
///   size instead of two.
pub struct Error {
    inner: Box<ErrorImpl<()>>,
}

impl Error {
    /// Create a new error object from any error type.
    ///
    /// The error type must be threadsafe and `'static`, so that the `Error`
    /// will be as well.
    ///
    /// If the error type does not provide a backtrace, a backtrace will be
    /// created here to ensure that a backtrace exists.
    pub fn new<E>(error: E) -> Self
    where
        E: StdError + Send + Sync + 'static,
    {
        // Captured here instead of in Error::construct to have one fewer layer
        // of wrapping visible in the backtrace.
        #[cfg(backtrace)]
        let backtrace = match error.backtrace() {
            Some(_) => None,
            None => Some(Backtrace::capture()),
        };

        #[cfg(not(backtrace))]
        let backtrace = None;

        Error::construct(error, TypeId::of::<E>(), backtrace)
    }

    pub(crate) fn new_adhoc<M>(message: M, backtrace: Option<Backtrace>) -> Self
    where
        M: Display + Debug + Send + Sync + 'static,
    {
        Error::construct(MessageError(message), TypeId::of::<M>(), backtrace)
    }

    fn construct<E>(error: E, type_id: TypeId, backtrace: Option<Backtrace>) -> Self
    where
        E: StdError + Send + Sync + 'static,
    {
        unsafe {
            let obj = mem::transmute::<&dyn StdError, TraitObject>(&error);
            let inner = Box::new(ErrorImpl {
                vtable: obj.vtable,
                type_id,
                backtrace,
                error,
            });
            Error {
                inner: mem::transmute::<Box<ErrorImpl<E>>, Box<ErrorImpl<()>>>(inner),
            }
        }
    }

    /// Wrap the error value with additional context.
    ///
    /// For attaching context to a `Result` as it is propagated, the
    /// [`Context`][crate::Context] extension trait may be more convenient than
    /// this function.
    ///
    /// The primary reason to use `error.context(...)` instead of
    /// `result.context(...)` via the `Context` trait would be if the context
    /// needs to depend on some data held by the underlying error:
    ///
    /// ```
    /// # use std::fmt::{self, Debug, Display};
    /// #
    /// # type T = ();
    /// #
    /// # impl std::error::Error for ParseError {}
    /// # impl Debug for ParseError {
    /// #     fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
    /// #         unimplemented!()
    /// #     }
    /// # }
    /// # impl Display for ParseError {
    /// #     fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
    /// #         unimplemented!()
    /// #     }
    /// # }
    /// #
    /// use std::fs::File;
    /// use std::path::Path;
    ///
    /// struct ParseError {
    ///     line: usize,
    ///     column: usize,
    /// }
    ///
    /// fn parse_impl(file: File) -> Result<T, ParseError> {
    ///     # const IGNORE: &str = stringify! {
    ///     ...
    ///     # };
    ///     # unimplemented!()
    /// }
    ///
    /// pub fn parse(path: impl AsRef<Path>) -> anyhow::Result<T> {
    ///     let file = File::open(&path)?;
    ///     parse_impl(file).map_err(|error| {
    ///         let context = format!(
    ///             "only the first {} lines of {} are valid",
    ///             error.line, path.as_ref().display(),
    ///         );
    ///         anyhow::Error::new(error).context(context)
    ///     })
    /// }
    /// ```
    pub fn context<C>(self, context: C) -> Self
    where
        C: Display + Send + Sync + 'static,
    {
        Error::from(ContextError {
            error: self,
            context,
        })
    }

    /// Get the backtrace for this Error.
    ///
    /// Backtraces are only available on the nightly channel. Tracking issue:
    /// [rust-lang/rust#53487][tracking].
    ///
    /// In order for the backtrace to be meaningful, the environment variable
    /// `RUST_LIB_BACKTRACE=1` must be defined. Backtraces are somewhat
    /// expensive to capture in Rust, so we don't necessarily want to be
    /// capturing them all over the place all the time.
    ///
    /// [tracking]: https://github.com/rust-lang/rust/issues/53487
    #[cfg(backtrace)]
    pub fn backtrace(&self) -> &Backtrace {
        // NB: this unwrap can only fail if the underlying error's backtrace
        // method is nondeterministic, which would only happen in maliciously
        // constructed code
        self.inner
            .backtrace
            .as_ref()
            .or_else(|| self.inner.error().backtrace())
            .expect("backtrace capture failed")
    }

    /// An iterator of the chain of source errors contained by this Error.
    ///
    /// This iterator will visit every error in the cause chain of this error
    /// object, beginning with the error that this error object was created
    /// from.
    pub fn chain(&self) -> Chain {
        Chain {
            next: Some(self.inner.error()),
        }
    }

    /// The lowest level cause of this error — this error's cause's
    /// cause's cause etc.
    ///
    /// The root cause is the last error in the iterator produced by
    /// [`chain()`][Error::chain].
    pub fn root_cause(&self) -> &(dyn StdError + 'static) {
        let mut chain = self.chain();
        let mut root_cause = chain.next().unwrap();
        for cause in chain {
            root_cause = cause;
        }
        root_cause
    }

    /// Returns `true` if `E` is the type wrapped by this error object.
    pub fn is<E>(&self) -> bool
    where
        E: Display + Debug + Send + Sync + 'static,
    {
        TypeId::of::<E>() == self.inner.type_id
    }

    /// Attempt to downcast the error object to a concrete type.
    pub fn downcast<E>(self) -> Result<E, Self>
    where
        E: Display + Debug + Send + Sync + 'static,
    {
        if let Some(error) = self.downcast_ref::<E>() {
            unsafe {
                let error = ptr::read(error);
                drop(ptr::read(&self.inner));
                mem::forget(self);
                Ok(error)
            }
        } else {
            Err(self)
        }
    }

    /// Downcast this error object by reference.
    ///
    /// # Example
    ///
    /// ```
    /// # use anyhow::anyhow;
    /// # use std::fmt::{self, Display};
    /// # use std::task::Poll;
    /// #
    /// # #[derive(Debug)]
    /// # enum DataStoreError {
    /// #     Censored(()),
    /// # }
    /// #
    /// # impl Display for DataStoreError {
    /// #     fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
    /// #         unimplemented!()
    /// #     }
    /// # }
    /// #
    /// # impl std::error::Error for DataStoreError {}
    /// #
    /// # const REDACTED_CONTENT: () = ();
    /// #
    /// # let error = anyhow!("...");
    /// # let root_cause = &error;
    /// #
    /// # let ret =
    /// // If the error was caused by redaction, then return a tombstone instead
    /// // of the content.
    /// match root_cause.downcast_ref::<DataStoreError>() {
    ///     Some(DataStoreError::Censored(_)) => Ok(Poll::Ready(REDACTED_CONTENT)),
    ///     None => Err(error),
    /// }
    /// # ;
    /// ```
    pub fn downcast_ref<E>(&self) -> Option<&E>
    where
        E: Display + Debug + Send + Sync + 'static,
    {
        if self.is::<E>() {
            unsafe { Some(&*(self.inner.error() as *const dyn StdError as *const E)) }
        } else {
            None
        }
    }

    /// Downcast this error object by mutable reference.
    pub fn downcast_mut<E>(&mut self) -> Option<&mut E>
    where
        E: Display + Debug + Send + Sync + 'static,
    {
        if self.is::<E>() {
            unsafe { Some(&mut *(self.inner.error_mut() as *mut dyn StdError as *mut E)) }
        } else {
            None
        }
    }
}

#[cfg(not(backtrace))]
pub(crate) enum Backtrace {}

impl<E> From<E> for Error
where
    E: StdError + Send + Sync + 'static,
{
    fn from(error: E) -> Self {
        Error::new(error)
    }
}

impl Deref for Error {
    type Target = dyn StdError + Send + Sync + 'static;

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

impl DerefMut for Error {
    fn deref_mut(&mut self) -> &mut Self::Target {
        self.inner.error_mut()
    }
}

impl Debug for Error {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        writeln!(f, "{}", self.inner.error())?;

        let mut chain = self.chain().skip(1).enumerate();
        if let Some((n, error)) = chain.next() {
            writeln!(f, "\ncaused by:")?;
            writeln!(f, "\t{}: {}", n, error)?;
            for (n, error) in chain {
                writeln!(f, "\t{}: {}", n, error)?;
            }
        }

        #[cfg(backtrace)]
        {
            let backtrace = self.backtrace();
            match backtrace.status() {
                BacktraceStatus::Captured => {
                    writeln!(f, "\n{}", backtrace)?;
                }
                BacktraceStatus::Disabled => {
                    writeln!(
                        f,
                        "\nbacktrace disabled; run with RUST_LIB_BACKTRACE=1 environment variable to display a backtrace"
                    )?;
                }
                _ => {}
            }
        }

        Ok(())
    }
}

impl Display for Error {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        write!(f, "{}", self.inner.error())
    }
}

unsafe impl Send for Error {}
unsafe impl Sync for Error {}

impl Drop for Error {
    fn drop(&mut self) {
        unsafe { ptr::drop_in_place(self.inner.error_mut()) }
    }
}

// repr C to ensure that `E` remains in the final position
#[repr(C)]
struct ErrorImpl<E> {
    vtable: *const (),
    type_id: TypeId,
    backtrace: Option<Backtrace>,
    error: E,
}

// repr C to ensure that transmuting from trait objects is safe
#[repr(C)]
struct TraitObject {
    data: *const (),
    vtable: *const (),
}

#[repr(transparent)]
struct MessageError<M>(M);

impl<M> Debug for MessageError<M>
where
    M: Display + Debug,
{
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        Debug::fmt(&self.0, f)
    }
}

impl<M> Display for MessageError<M>
where
    M: Display + Debug,
{
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        Display::fmt(&self.0, f)
    }
}

impl<M> StdError for MessageError<M> where M: Display + Debug + 'static {}

impl ErrorImpl<()> {
    fn error(&self) -> &(dyn StdError + Send + Sync + 'static) {
        let object = TraitObject {
            data: &self.error,
            vtable: self.vtable,
        };

        unsafe { mem::transmute::<TraitObject, &(dyn StdError + Send + Sync + 'static)>(object) }
    }

    fn error_mut(&mut self) -> &mut (dyn StdError + Send + Sync + 'static) {
        let object = TraitObject {
            data: &mut self.error,
            vtable: self.vtable,
        };

        unsafe {
            mem::transmute::<TraitObject, &mut (dyn StdError + Send + Sync + 'static)>(object)
        }
    }
}

/// Iterator of a chain of source errors.
pub struct Chain<'a> {
    next: Option<&'a (dyn StdError + 'static)>,
}

impl<'a> Iterator for Chain<'a> {
    type Item = &'a (dyn StdError + 'static);

    fn next(&mut self) -> Option<Self::Item> {
        let next = self.next.take()?;
        self.next = next.source();
        Some(next)
    }
}

#[cfg(test)]
mod repr_correctness {
    use super::*;
    use std::marker::Unpin;
    use std::mem;
    use std::sync::atomic::AtomicBool;
    use std::sync::atomic::Ordering::SeqCst;
    use std::sync::Arc;

    #[test]
    fn size_of_error() {
        assert_eq!(mem::size_of::<Error>(), mem::size_of::<usize>());
    }

    #[test]
    fn error_autotraits() {
        fn assert<E: Unpin + Send + Sync + 'static>() {}
        assert::<Error>();
    }

    #[test]
    fn drop_works() {
        #[derive(Debug)]
        struct DetectDrop {
            has_dropped: Arc<AtomicBool>,
        }

        impl StdError for DetectDrop {}

        impl Display for DetectDrop {
            fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
                write!(f, "does something")
            }
        }

        impl Drop for DetectDrop {
            fn drop(&mut self) {
                let already_dropped = self.has_dropped.swap(true, SeqCst);
                assert!(!already_dropped);
            }
        }

        let has_dropped = Arc::new(AtomicBool::new(false));

        drop(Error::from(DetectDrop {
            has_dropped: has_dropped.clone(),
        }));

        assert!(has_dropped.load(SeqCst));
    }
}
<commit_msg>Add example of Error::chain<commit_after>use crate::context::ContextError;
use std::any::TypeId;
use std::error::Error as StdError;
use std::fmt::{self, Debug, Display};
use std::mem;
use std::ops::{Deref, DerefMut};
use std::ptr;

#[cfg(backtrace)]
use std::backtrace::{Backtrace, BacktraceStatus};

/// The `Error` type, a wrapper around a dynamic error type.
///
/// `Error` works a lot like `Box<dyn std::error::Error>`, but with these
/// differences:
///
/// - `Error` requires that the error is `Send`, `Sync`, and `'static`.
/// - `Error` guarantees that a backtrace is available, even if the underlying
///   error type does not provide one.
/// - `Error` is represented as a narrow pointer — exactly one word in
///   size instead of two.
pub struct Error {
    inner: Box<ErrorImpl<()>>,
}

impl Error {
    /// Create a new error object from any error type.
    ///
    /// The error type must be threadsafe and `'static`, so that the `Error`
    /// will be as well.
    ///
    /// If the error type does not provide a backtrace, a backtrace will be
    /// created here to ensure that a backtrace exists.
    pub fn new<E>(error: E) -> Self
    where
        E: StdError + Send + Sync + 'static,
    {
        // Captured here instead of in Error::construct to have one fewer layer
        // of wrapping visible in the backtrace.
        #[cfg(backtrace)]
        let backtrace = match error.backtrace() {
            Some(_) => None,
            None => Some(Backtrace::capture()),
        };

        #[cfg(not(backtrace))]
        let backtrace = None;

        Error::construct(error, TypeId::of::<E>(), backtrace)
    }

    pub(crate) fn new_adhoc<M>(message: M, backtrace: Option<Backtrace>) -> Self
    where
        M: Display + Debug + Send + Sync + 'static,
    {
        Error::construct(MessageError(message), TypeId::of::<M>(), backtrace)
    }

    fn construct<E>(error: E, type_id: TypeId, backtrace: Option<Backtrace>) -> Self
    where
        E: StdError + Send + Sync + 'static,
    {
        unsafe {
            let obj = mem::transmute::<&dyn StdError, TraitObject>(&error);
            let inner = Box::new(ErrorImpl {
                vtable: obj.vtable,
                type_id,
                backtrace,
                error,
            });
            Error {
                inner: mem::transmute::<Box<ErrorImpl<E>>, Box<ErrorImpl<()>>>(inner),
            }
        }
    }

    /// Wrap the error value with additional context.
    ///
    /// For attaching context to a `Result` as it is propagated, the
    /// [`Context`][crate::Context] extension trait may be more convenient than
    /// this function.
    ///
    /// The primary reason to use `error.context(...)` instead of
    /// `result.context(...)` via the `Context` trait would be if the context
    /// needs to depend on some data held by the underlying error:
    ///
    /// ```
    /// # use std::fmt::{self, Debug, Display};
    /// #
    /// # type T = ();
    /// #
    /// # impl std::error::Error for ParseError {}
    /// # impl Debug for ParseError {
    /// #     fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
    /// #         unimplemented!()
    /// #     }
    /// # }
    /// # impl Display for ParseError {
    /// #     fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
    /// #         unimplemented!()
    /// #     }
    /// # }
    /// #
    /// use std::fs::File;
    /// use std::path::Path;
    ///
    /// struct ParseError {
    ///     line: usize,
    ///     column: usize,
    /// }
    ///
    /// fn parse_impl(file: File) -> Result<T, ParseError> {
    ///     # const IGNORE: &str = stringify! {
    ///     ...
    ///     # };
    ///     # unimplemented!()
    /// }
    ///
    /// pub fn parse(path: impl AsRef<Path>) -> anyhow::Result<T> {
    ///     let file = File::open(&path)?;
    ///     parse_impl(file).map_err(|error| {
    ///         let context = format!(
    ///             "only the first {} lines of {} are valid",
    ///             error.line, path.as_ref().display(),
    ///         );
    ///         anyhow::Error::new(error).context(context)
    ///     })
    /// }
    /// ```
    pub fn context<C>(self, context: C) -> Self
    where
        C: Display + Send + Sync + 'static,
    {
        Error::from(ContextError {
            error: self,
            context,
        })
    }

    /// Get the backtrace for this Error.
    ///
    /// Backtraces are only available on the nightly channel. Tracking issue:
    /// [rust-lang/rust#53487][tracking].
    ///
    /// In order for the backtrace to be meaningful, the environment variable
    /// `RUST_LIB_BACKTRACE=1` must be defined. Backtraces are somewhat
    /// expensive to capture in Rust, so we don't necessarily want to be
    /// capturing them all over the place all the time.
    ///
    /// [tracking]: https://github.com/rust-lang/rust/issues/53487
    #[cfg(backtrace)]
    pub fn backtrace(&self) -> &Backtrace {
        // NB: this unwrap can only fail if the underlying error's backtrace
        // method is nondeterministic, which would only happen in maliciously
        // constructed code
        self.inner
            .backtrace
            .as_ref()
            .or_else(|| self.inner.error().backtrace())
            .expect("backtrace capture failed")
    }

    /// An iterator of the chain of source errors contained by this Error.
    ///
    /// This iterator will visit every error in the cause chain of this error
    /// object, beginning with the error that this error object was created
    /// from.
    ///
    /// # Example
    ///
    /// ```
    /// use anyhow::Error;
    /// use std::io;
    ///
    /// pub fn underlying_io_error_kind(error: &Error) -> Option<io::ErrorKind> {
    ///     for cause in error.chain() {
    ///         if let Some(io_error) = cause.downcast_ref::<io::Error>() {
    ///             return Some(io_error.kind());
    ///         }
    ///     }
    ///     None
    /// }
    /// ```
    pub fn chain(&self) -> Chain {
        Chain {
            next: Some(self.inner.error()),
        }
    }

    /// The lowest level cause of this error — this error's cause's
    /// cause's cause etc.
    ///
    /// The root cause is the last error in the iterator produced by
    /// [`chain()`][Error::chain].
    pub fn root_cause(&self) -> &(dyn StdError + 'static) {
        let mut chain = self.chain();
        let mut root_cause = chain.next().unwrap();
        for cause in chain {
            root_cause = cause;
        }
        root_cause
    }

    /// Returns `true` if `E` is the type wrapped by this error object.
    pub fn is<E>(&self) -> bool
    where
        E: Display + Debug + Send + Sync + 'static,
    {
        TypeId::of::<E>() == self.inner.type_id
    }

    /// Attempt to downcast the error object to a concrete type.
    pub fn downcast<E>(self) -> Result<E, Self>
    where
        E: Display + Debug + Send + Sync + 'static,
    {
        if let Some(error) = self.downcast_ref::<E>() {
            unsafe {
                let error = ptr::read(error);
                drop(ptr::read(&self.inner));
                mem::forget(self);
                Ok(error)
            }
        } else {
            Err(self)
        }
    }

    /// Downcast this error object by reference.
    ///
    /// # Example
    ///
    /// ```
    /// # use anyhow::anyhow;
    /// # use std::fmt::{self, Display};
    /// # use std::task::Poll;
    /// #
    /// # #[derive(Debug)]
    /// # enum DataStoreError {
    /// #     Censored(()),
    /// # }
    /// #
    /// # impl Display for DataStoreError {
    /// #     fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
    /// #         unimplemented!()
    /// #     }
    /// # }
    /// #
    /// # impl std::error::Error for DataStoreError {}
    /// #
    /// # const REDACTED_CONTENT: () = ();
    /// #
    /// # let error = anyhow!("...");
    /// # let root_cause = &error;
    /// #
    /// # let ret =
    /// // If the error was caused by redaction, then return a tombstone instead
    /// // of the content.
    /// match root_cause.downcast_ref::<DataStoreError>() {
    ///     Some(DataStoreError::Censored(_)) => Ok(Poll::Ready(REDACTED_CONTENT)),
    ///     None => Err(error),
    /// }
    /// # ;
    /// ```
    pub fn downcast_ref<E>(&self) -> Option<&E>
    where
        E: Display + Debug + Send + Sync + 'static,
    {
        if self.is::<E>() {
            unsafe { Some(&*(self.inner.error() as *const dyn StdError as *const E)) }
        } else {
            None
        }
    }

    /// Downcast this error object by mutable reference.
    pub fn downcast_mut<E>(&mut self) -> Option<&mut E>
    where
        E: Display + Debug + Send + Sync + 'static,
    {
        if self.is::<E>() {
            unsafe { Some(&mut *(self.inner.error_mut() as *mut dyn StdError as *mut E)) }
        } else {
            None
        }
    }
}

#[cfg(not(backtrace))]
pub(crate) enum Backtrace {}

impl<E> From<E> for Error
where
    E: StdError + Send + Sync + 'static,
{
    fn from(error: E) -> Self {
        Error::new(error)
    }
}

impl Deref for Error {
    type Target = dyn StdError + Send + Sync + 'static;

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

impl DerefMut for Error {
    fn deref_mut(&mut self) -> &mut Self::Target {
        self.inner.error_mut()
    }
}

impl Debug for Error {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        writeln!(f, "{}", self.inner.error())?;

        let mut chain = self.chain().skip(1).enumerate();
        if let Some((n, error)) = chain.next() {
            writeln!(f, "\ncaused by:")?;
            writeln!(f, "\t{}: {}", n, error)?;
            for (n, error) in chain {
                writeln!(f, "\t{}: {}", n, error)?;
            }
        }

        #[cfg(backtrace)]
        {
            let backtrace = self.backtrace();
            match backtrace.status() {
                BacktraceStatus::Captured => {
                    writeln!(f, "\n{}", backtrace)?;
                }
                BacktraceStatus::Disabled => {
                    writeln!(
                        f,
                        "\nbacktrace disabled; run with RUST_LIB_BACKTRACE=1 environment variable to display a backtrace"
                    )?;
                }
                _ => {}
            }
        }

        Ok(())
    }
}

impl Display for Error {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        write!(f, "{}", self.inner.error())
    }
}

unsafe impl Send for Error {}
unsafe impl Sync for Error {}

impl Drop for Error {
    fn drop(&mut self) {
        unsafe { ptr::drop_in_place(self.inner.error_mut()) }
    }
}

// repr C to ensure that `E` remains in the final position
#[repr(C)]
struct ErrorImpl<E> {
    vtable: *const (),
    type_id: TypeId,
    backtrace: Option<Backtrace>,
    error: E,
}

// repr C to ensure that transmuting from trait objects is safe
#[repr(C)]
struct TraitObject {
    data: *const (),
    vtable: *const (),
}

#[repr(transparent)]
struct MessageError<M>(M);

impl<M> Debug for MessageError<M>
where
    M: Display + Debug,
{
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        Debug::fmt(&self.0, f)
    }
}

impl<M> Display for MessageError<M>
where
    M: Display + Debug,
{
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        Display::fmt(&self.0, f)
    }
}

impl<M> StdError for MessageError<M> where M: Display + Debug + 'static {}

impl ErrorImpl<()> {
    fn error(&self) -> &(dyn StdError + Send + Sync + 'static) {
        let object = TraitObject {
            data: &self.error,
            vtable: self.vtable,
        };

        unsafe { mem::transmute::<TraitObject, &(dyn StdError + Send + Sync + 'static)>(object) }
    }

    fn error_mut(&mut self) -> &mut (dyn StdError + Send + Sync + 'static) {
        let object = TraitObject {
            data: &mut self.error,
            vtable: self.vtable,
        };

        unsafe {
            mem::transmute::<TraitObject, &mut (dyn StdError + Send + Sync + 'static)>(object)
        }
    }
}

/// Iterator of a chain of source errors.
pub struct Chain<'a> {
    next: Option<&'a (dyn StdError + 'static)>,
}

impl<'a> Iterator for Chain<'a> {
    type Item = &'a (dyn StdError + 'static);

    fn next(&mut self) -> Option<Self::Item> {
        let next = self.next.take()?;
        self.next = next.source();
        Some(next)
    }
}

#[cfg(test)]
mod repr_correctness {
    use super::*;
    use std::marker::Unpin;
    use std::mem;
    use std::sync::atomic::AtomicBool;
    use std::sync::atomic::Ordering::SeqCst;
    use std::sync::Arc;

    #[test]
    fn size_of_error() {
        assert_eq!(mem::size_of::<Error>(), mem::size_of::<usize>());
    }

    #[test]
    fn error_autotraits() {
        fn assert<E: Unpin + Send + Sync + 'static>() {}
        assert::<Error>();
    }

    #[test]
    fn drop_works() {
        #[derive(Debug)]
        struct DetectDrop {
            has_dropped: Arc<AtomicBool>,
        }

        impl StdError for DetectDrop {}

        impl Display for DetectDrop {
            fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
                write!(f, "does something")
            }
        }

        impl Drop for DetectDrop {
            fn drop(&mut self) {
                let already_dropped = self.has_dropped.swap(true, SeqCst);
                assert!(!already_dropped);
            }
        }

        let has_dropped = Arc::new(AtomicBool::new(false));

        drop(Error::from(DetectDrop {
            has_dropped: has_dropped.clone(),
        }));

        assert!(has_dropped.load(SeqCst));
    }
}
<|endoftext|>


<commit_before>use {HashSet, HashMap};
use std::collections::{RingBuf, Deque};
use std::fmt;

// call this Unigraph instead?
pub trait Graph<T> {
    /// Insert a new node, returning its index
    fn add_node(&mut self, val: T) -> NodeIndex;

    /// Insert a new edge, returning an error if one of the indices is invalid.
    /// Otherwise, return true if the edge was not already present.
    fn add_edge(&mut self, i: NodeIndex, j: NodeIndex) -> GraphResult<bool>;

    /// Remove a node, returning an error if the index is invalid.
    fn remove_node(&mut self, i: NodeIndex) -> GraphResult<()>;

    /// Return an iterator over the out-neighbors for a given node
    fn adj(&self, i: NodeIndex) -> NodeIndices;

    /// Return the number of nodes in the graph
    fn num_nodes(&self) -> uint;

    /// Returns an iterator over the indices of all the nodes in the graph
    fn node_indices(&self) -> NodeIndices;
}

struct GraphError {
    error_type: GraphErrorType,
}

impl GraphError {
    fn invalid_index(ind: NodeIndex) -> GraphError {
        GraphError { error_type: InvalidNodeIndex(ind) }
    }
}

type GraphResult<T> = Result<T, GraphError>;

enum GraphErrorType {
    InvalidNodeIndex(NodeIndex),
}

pub type NodeIndex = uint;
type NodeIndexSet = HashSet<NodeIndex>;

#[deriving(Show, Clone)]
struct Node<T> {
    data: T,
    index: NodeIndex,
}

/// Undirected graph. Allows loops.
pub struct Ungraph<T> {
    nodes: HashMap<NodeIndex, Node<T>>,
    adj: HashMap<NodeIndex, NodeIndexSet>,
    num_nodes: uint,
}

impl<T: fmt::Show> fmt::Show for Ungraph<T> {
    fn fmt(&self, fmt: &mut fmt::Formatter) -> Result<(), fmt::FormatError> {
        write!(fmt, "{{");
        for n in self.nodes.values() {
            write!(fmt, " {} ", n.data);
        }
        write!(fmt, "}}  ");

        for (&i, adj) in self.adj.iter() {
            for &j in adj.iter() {
                write!(fmt, "({}, {})", self.get_node(i).data,
                                        self.get_node(j).data);
            }
        }

        Ok(())
    }
}

/// Directed graph. Allows loops.
pub struct Digraph<T> {
    nodes: HashMap<NodeIndex, Node<T>>,
    in_adj: HashMap<NodeIndex, NodeIndexSet>,
    out_adj: HashMap<NodeIndex, NodeIndexSet>,
    num_nodes: uint,
}

impl<T: fmt::Show> fmt::Show for Digraph<T> {
    fn fmt(&self, fmt: &mut fmt::Formatter) -> Result<(), fmt::FormatError> {
        write!(fmt, "{{");
        for n in self.nodes.values() {
            write!(fmt, " {} ", n.data);
        }
        write!(fmt, "}}  ");

        for (&i, adj) in self.out_adj.iter() {
            for &j in adj.iter() {
                write!(fmt, "({}, {})", self.get_node(i).data,
                                        self.get_node(j).data);
            }
        }

        Ok(())
    }
}

impl<T> Ungraph<T> {
    pub fn new() -> Ungraph<T> {
        Ungraph { nodes: HashMap::new(), adj: HashMap::new(), num_nodes: 0 }
    }

    pub fn degree(&mut self, ind: NodeIndex) -> GraphResult<uint> {
        if !self.adj.contains_key(&ind) {
            Err(GraphError::invalid_index(ind))
        } else {
            Ok( self.get_adj(ind).len() )
        }
    }

    pub fn get_node<'a>(&'a self, i: NodeIndex) -> &'a Node<T> {
        self.nodes.find(&i).unwrap()
    }

    pub fn get_adj<'a>(&'a self, i: NodeIndex) -> &'a NodeIndexSet {
        self.adj.find(&i).unwrap()
    }
}

impl<T: Clone> Ungraph<T> {
    /// Returns a new graph induced by a set of node indices
    pub fn induced_subgraph(&self, nodes: &NodeIndexSet) -> Ungraph<T> {
        let mut new = Ungraph::new();
        let mut ind_map = HashMap::new(); // maps old indices to new

        for &ind in nodes.iter() {
            let new_ind = new.add_node(self.get_node(ind).data.clone());
            ind_map.insert(ind, new_ind);
        }

        for i in nodes.iter() {
            let actual_i = *ind_map.find(i).unwrap();
            for j in self.get_adj(*i).iter() {
                if nodes.contains(j) {
                    new.add_edge(actual_i, *ind_map.find(j).unwrap());
                }
            }
        }

        new
    }
}

impl<T> Graph<T> for Ungraph<T> {
    fn add_node(&mut self, val: T) -> NodeIndex {
        let ind = self.num_nodes;
        self.nodes.insert(ind, Node { data: val, index: ind });
        self.adj.insert(ind, HashSet::new());
        self.num_nodes += 1;
        ind
    }

    fn add_edge(&mut self, i: NodeIndex, j: NodeIndex) -> GraphResult<bool> {
        if !self.nodes.contains_key(&i) {
            Err(GraphError::invalid_index(i))
        } else if !self.nodes.contains_key(&j) {
            Err(GraphError::invalid_index(j))
        } else {
            if self.get_adj(i).contains(&j) {
                Ok(false)
            } else {
                self.adj.find_mut(&i).unwrap().insert(j);
                self.adj.find_mut(&j).unwrap().insert(i);
                Ok(true)
            }
        }
    }

    fn remove_node(&mut self, i: NodeIndex) -> GraphResult<()> {
        if !self.nodes.contains_key(&i) {
            Err(GraphError::invalid_index(i))
        } else {
            self.nodes.remove(&i);

            for j in self.adj(i) {
                self.adj.find_mut(&j).unwrap().remove(&i);
            }
            self.adj.remove(&i);
            self.num_nodes -= 1;
            Ok(())
        }
    }

    fn adj(&self, i: NodeIndex) -> NodeIndices {
        FromIterator::from_iter(self.get_adj(i).iter().map(|&x| x))
    }

    fn num_nodes(&self) -> uint {
        self.num_nodes
    }

    fn node_indices(&self) -> NodeIndices {
        FromIterator::from_iter(self.nodes.keys().map(|&x| x))
    }
}

impl<T> Digraph<T> {
    pub fn new() -> Digraph<T> {
        Digraph { nodes: HashMap::new(),
                  in_adj: HashMap::new(),
                  out_adj: HashMap::new(),
                  num_nodes: 0 }
    }

    pub fn out_degree(&mut self, ind: NodeIndex) -> GraphResult<uint> {
        if !self.nodes.contains_key(&ind) {
            Err(GraphError::invalid_index(ind))
        } else {
            Ok(self.get_out_adj(ind).len())
        }
    }

    pub fn in_degree(&mut self, ind: NodeIndex) -> GraphResult<uint> {
        if ind >= self.num_nodes {
            Err(GraphError::invalid_index(ind))
        } else {
            Ok(self.get_in_adj(ind).len())
        }
    }

    fn in_adj(&self, i: NodeIndex) -> NodeIndices {
        FromIterator::from_iter(self.get_in_adj(i).iter().map(|&x| x))
    }

    pub fn is_dag(&self) -> bool {
        false
    }

    pub fn get_node<'a>(&'a self, i: NodeIndex) -> &'a Node<T> {
        self.nodes.find(&i).unwrap()
    }

    pub fn get_in_adj<'a>(&'a self, i: NodeIndex) -> &'a NodeIndexSet {
        self.in_adj.find(&i).unwrap()
    }

    pub fn get_out_adj<'a>(&'a self, i: NodeIndex) -> &'a NodeIndexSet {
        self.out_adj.find(&i).unwrap()
    }
}

impl<T: Clone> Digraph<T> {
    /// Returns a new graph induced by a set of node indices
    pub fn induced_subgraph(&self, nodes: &NodeIndexSet) -> Digraph<T> {
        let mut new = Digraph::new();
        let mut ind_map = HashMap::new(); // maps old indices to new

        for &ind in nodes.iter() {
            let new_ind = new.add_node(self.get_node(ind).data.clone());
            ind_map.insert(ind, new_ind);
        }

        for i in nodes.iter() {
            let actual_i = *ind_map.find(i).unwrap();
            for j in self.get_in_adj(*i).iter() {
                if nodes.contains(j) {
                    new.add_edge(*ind_map.find(j).unwrap(), actual_i);
                }
            }

            for j in self.get_out_adj(*i).iter() {
                if nodes.contains(j) {
                    new.add_edge(actual_i, *ind_map.find(j).unwrap());
                }
            }
        }

        new
    }

    // Returns the transpose of the graph
    pub fn transpose(&self) -> Digraph<T> {
        let mut new = Digraph::new();
        let mut ind_map = HashMap::new(); // maps old indices to new

        for n in self.nodes.values() {
            let new_ind = new.add_node(n.data.clone());
            ind_map.insert(n.index, new_ind);
        }

        for &i in self.nodes.keys() {
            let actual_i = *ind_map.find(&i).unwrap();

            for j in self.get_in_adj(i).iter() {
                new.add_edge(actual_i, *ind_map.find(j).unwrap());
            }

            for j in self.get_out_adj(i).iter() {
                new.add_edge(*ind_map.find(j).unwrap(), actual_i);
            }
        }
        new
    }
}

impl<T> Graph<T> for Digraph<T> {
    fn add_node(&mut self, val: T) -> NodeIndex {
        let ind = self.num_nodes;
        self.nodes.insert(ind, Node { data: val, index: ind });
        self.in_adj.insert(ind, HashSet::new());
        self.out_adj.insert(ind, HashSet::new());
        self.num_nodes += 1;
        ind
    }

    fn add_edge(&mut self, i: NodeIndex, j: NodeIndex) -> GraphResult<bool> {
        if !self.nodes.contains_key(&i) {
            Err(GraphError::invalid_index(i))
        } else if !self.nodes.contains_key(&j) {
            Err(GraphError::invalid_index(j))
        } else {
            if self.get_out_adj(i).contains(&j) {
                Ok(false)
            } else {
                self.out_adj.find_mut(&i).unwrap().insert(j);
                self.in_adj.find_mut(&j).unwrap().insert(i);
                Ok(true)
            }
        }
    }

    fn remove_node(&mut self, i: NodeIndex) -> GraphResult<()> {
        if !self.nodes.contains_key(&i) {
            Err(GraphError::invalid_index(i))
        } else {
            self.nodes.remove(&i);

            for j in self.adj(i) {
                self.in_adj.find_mut(&j).unwrap().remove(&i);
            }
            self.out_adj.remove(&i);

            for j in self.in_adj(i) {
                self.out_adj.find_mut(&j).unwrap().remove(&i);
            }
            self.in_adj.remove(&i);

            self.num_nodes -= 1;
            Ok(())
        }
    }

    fn adj(&self, i: NodeIndex) -> NodeIndices {
        FromIterator::from_iter(self.get_out_adj(i).iter().map(|&x| x))
    }

    fn num_nodes(&self) -> uint {
        self.num_nodes
    }

    fn node_indices(&self) -> NodeIndices {
        FromIterator::from_iter(self.nodes.keys().map(|&x| x))
    }
}

struct NodeIndices {
    indices: Vec<NodeIndex>,
    curr: uint,
}

impl Iterator<NodeIndex> for NodeIndices {
    fn next(&mut self) -> Option<NodeIndex> {
        if self.curr < self.indices.len() {
            self.curr += 1;
            Some(self.indices[self.curr - 1])
        } else {
            None
        }
    }
}

impl FromIterator<NodeIndex> for NodeIndices {
    fn from_iter<T: Iterator<NodeIndex>>(mut it: T) -> NodeIndices {
        let mut vec = vec!();
        for i in it {
            vec.push(i);
        }
        NodeIndices { indices: vec, curr: 0 }
    }
}
<commit_msg>Add remove_edge() to Graph trait, implement for Ungraph and Digraph<commit_after>use {HashSet, HashMap};
use std::collections::{RingBuf, Deque};
use std::fmt;

// call this Unigraph instead?
pub trait Graph<T> {
    /// Insert a new node, returning its index
    fn add_node(&mut self, val: T) -> NodeIndex;

    /// Insert a new edge, returning an error if one of the indices is invalid.
    /// Otherwise, return true if the edge was not already present.
    fn add_edge(&mut self, i: NodeIndex, j: NodeIndex) -> GraphResult<bool>;

    /// Remove a node, returning an error if the index is invalid.
    fn remove_node(&mut self, i: NodeIndex) -> GraphResult<()>;

    /// Remove an edge, returning an error if one of the indices is invalid
    /// Otherwise, return true if the edge was already present.
    fn remove_edge(&mut self, i: NodeIndex, j: NodeIndex) -> GraphResult<bool>;

    /// Return an iterator over the out-neighbors for a given node
    fn adj(&self, i: NodeIndex) -> NodeIndices;

    /// Return the number of nodes in the graph
    fn num_nodes(&self) -> uint;

    /// Returns an iterator over the indices of all the nodes in the graph
    fn node_indices(&self) -> NodeIndices;
}

struct GraphError {
    error_type: GraphErrorType,
}

impl GraphError {
    fn invalid_index(ind: NodeIndex) -> GraphError {
        GraphError { error_type: InvalidNodeIndex(ind) }
    }
}

type GraphResult<T> = Result<T, GraphError>;

enum GraphErrorType {
    InvalidNodeIndex(NodeIndex),
}

pub type NodeIndex = uint;
type NodeIndexSet = HashSet<NodeIndex>;

#[deriving(Show, Clone)]
struct Node<T> {
    data: T,
    index: NodeIndex,
}

/// Undirected graph. Allows loops.
pub struct Ungraph<T> {
    nodes: HashMap<NodeIndex, Node<T>>,
    adj: HashMap<NodeIndex, NodeIndexSet>,
    num_nodes: uint,
}

impl<T: fmt::Show> fmt::Show for Ungraph<T> {
    fn fmt(&self, fmt: &mut fmt::Formatter) -> Result<(), fmt::FormatError> {
        write!(fmt, "{{");
        for n in self.nodes.values() {
            write!(fmt, " {} ", n.data);
        }
        write!(fmt, "}}  ");

        for (&i, adj) in self.adj.iter() {
            for &j in adj.iter() {
                write!(fmt, "({}, {})", self.get_node(i).data,
                                        self.get_node(j).data);
            }
        }

        Ok(())
    }
}

/// Directed graph. Allows loops.
pub struct Digraph<T> {
    nodes: HashMap<NodeIndex, Node<T>>,
    in_adj: HashMap<NodeIndex, NodeIndexSet>,
    out_adj: HashMap<NodeIndex, NodeIndexSet>,
    num_nodes: uint,
}

impl<T: fmt::Show> fmt::Show for Digraph<T> {
    fn fmt(&self, fmt: &mut fmt::Formatter) -> Result<(), fmt::FormatError> {
        write!(fmt, "{{");
        for n in self.nodes.values() {
            write!(fmt, " {} ", n.data);
        }
        write!(fmt, "}}  ");

        for (&i, adj) in self.out_adj.iter() {
            for &j in adj.iter() {
                write!(fmt, "({}, {})", self.get_node(i).data,
                                        self.get_node(j).data);
            }
        }

        Ok(())
    }
}

impl<T> Ungraph<T> {
    pub fn new() -> Ungraph<T> {
        Ungraph { nodes: HashMap::new(), adj: HashMap::new(), num_nodes: 0 }
    }

    pub fn degree(&mut self, ind: NodeIndex) -> GraphResult<uint> {
        if !self.adj.contains_key(&ind) {
            Err(GraphError::invalid_index(ind))
        } else {
            Ok( self.get_adj(ind).len() )
        }
    }

    pub fn get_node<'a>(&'a self, i: NodeIndex) -> &'a Node<T> {
        self.nodes.find(&i).unwrap()
    }

    pub fn get_adj<'a>(&'a self, i: NodeIndex) -> &'a NodeIndexSet {
        self.adj.find(&i).unwrap()
    }

    // return true if the nodes i and j are adjacent, and false otherwise
    pub fn are_adj(&self, i: NodeIndex, j: NodeIndex) -> bool {
        self.get_adj(i).contains(&j)
    }
}

impl<T: Clone> Ungraph<T> {
    /// Returns a new graph induced by a set of node indices
    pub fn induced_subgraph(&self, nodes: &NodeIndexSet) -> Ungraph<T> {
        let mut new = Ungraph::new();
        let mut ind_map = HashMap::new(); // maps old indices to new

        for &ind in nodes.iter() {
            let new_ind = new.add_node(self.get_node(ind).data.clone());
            ind_map.insert(ind, new_ind);
        }

        for i in nodes.iter() {
            let actual_i = *ind_map.find(i).unwrap();
            for j in self.get_adj(*i).iter() {
                if nodes.contains(j) {
                    new.add_edge(actual_i, *ind_map.find(j).unwrap());
                }
            }
        }

        new
    }
}

impl<T> Graph<T> for Ungraph<T> {
    fn add_node(&mut self, val: T) -> NodeIndex {
        let ind = self.num_nodes;
        self.nodes.insert(ind, Node { data: val, index: ind });
        self.adj.insert(ind, HashSet::new());
        self.num_nodes += 1;
        ind
    }

    fn add_edge(&mut self, i: NodeIndex, j: NodeIndex) -> GraphResult<bool> {
        if !self.nodes.contains_key(&i) {
            Err(GraphError::invalid_index(i))
        } else if !self.nodes.contains_key(&j) {
            Err(GraphError::invalid_index(j))
        } else {
            if self.get_adj(i).contains(&j) {
                Ok(false)
            } else {
                self.adj.find_mut(&i).unwrap().insert(j);
                self.adj.find_mut(&j).unwrap().insert(i);
                Ok(true)
            }
        }
    }

    fn remove_node(&mut self, i: NodeIndex) -> GraphResult<()> {
        if !self.nodes.contains_key(&i) {
            Err(GraphError::invalid_index(i))
        } else {
            self.nodes.remove(&i);

            for j in self.adj(i) {
                self.adj.find_mut(&j).unwrap().remove(&i);
            }
            self.adj.remove(&i);
            self.num_nodes -= 1;
            Ok(())
        }
    }

    fn remove_edge(&mut self, i: NodeIndex, j: NodeIndex) -> GraphResult<bool> {
        if !self.nodes.contains_key(&i) {
            Err(GraphError::invalid_index(i))
        } else if !self.nodes.contains_key(&j) {
            Err(GraphError::invalid_index(j))
        } else {
            Ok(self.are_adj(i, j))
        }
    }

    fn adj(&self, i: NodeIndex) -> NodeIndices {
        FromIterator::from_iter(self.get_adj(i).iter().map(|&x| x))
    }

    fn num_nodes(&self) -> uint {
        self.num_nodes
    }

    fn node_indices(&self) -> NodeIndices {
        FromIterator::from_iter(self.nodes.keys().map(|&x| x))
    }
}

impl<T> Digraph<T> {
    pub fn new() -> Digraph<T> {
        Digraph { nodes: HashMap::new(),
                  in_adj: HashMap::new(),
                  out_adj: HashMap::new(),
                  num_nodes: 0 }
    }

    pub fn out_degree(&mut self, ind: NodeIndex) -> GraphResult<uint> {
        if !self.nodes.contains_key(&ind) {
            Err(GraphError::invalid_index(ind))
        } else {
            Ok(self.get_out_adj(ind).len())
        }
    }

    pub fn in_degree(&mut self, ind: NodeIndex) -> GraphResult<uint> {
        if ind >= self.num_nodes {
            Err(GraphError::invalid_index(ind))
        } else {
            Ok(self.get_in_adj(ind).len())
        }
    }

    fn in_adj(&self, i: NodeIndex) -> NodeIndices {
        FromIterator::from_iter(self.get_in_adj(i).iter().map(|&x| x))
    }

    pub fn get_node<'a>(&'a self, i: NodeIndex) -> &'a Node<T> {
        self.nodes.find(&i).unwrap()
    }

    pub fn get_in_adj<'a>(&'a self, i: NodeIndex) -> &'a NodeIndexSet {
        self.in_adj.find(&i).unwrap()
    }

    pub fn get_out_adj<'a>(&'a self, i: NodeIndex) -> &'a NodeIndexSet {
        self.out_adj.find(&i).unwrap()
    }

    // return true if j is an out-neighbor of i, and false otherwise
    pub fn is_out_adj_to(&self, i: NodeIndex, j: NodeIndex) -> bool {
        self.get_out_adj(i).contains(&j)
    }
}

impl<T: Clone> Digraph<T> {
    /// Returns a new graph induced by a set of node indices
    pub fn induced_subgraph(&self, nodes: &NodeIndexSet) -> Digraph<T> {
        let mut new = Digraph::new();
        let mut ind_map = HashMap::new(); // maps old indices to new

        for &ind in nodes.iter() {
            let new_ind = new.add_node(self.get_node(ind).data.clone());
            ind_map.insert(ind, new_ind);
        }

        for i in nodes.iter() {
            let actual_i = *ind_map.find(i).unwrap();
            for j in self.get_in_adj(*i).iter() {
                if nodes.contains(j) {
                    new.add_edge(*ind_map.find(j).unwrap(), actual_i);
                }
            }

            for j in self.get_out_adj(*i).iter() {
                if nodes.contains(j) {
                    new.add_edge(actual_i, *ind_map.find(j).unwrap());
                }
            }
        }

        new
    }

    // Returns the transpose of the graph
    pub fn transpose(&self) -> Digraph<T> {
        let mut new = Digraph::new();
        let mut ind_map = HashMap::new(); // maps old indices to new

        for n in self.nodes.values() {
            let new_ind = new.add_node(n.data.clone());
            ind_map.insert(n.index, new_ind);
        }

        for &i in self.nodes.keys() {
            let actual_i = *ind_map.find(&i).unwrap();

            for j in self.get_in_adj(i).iter() {
                new.add_edge(actual_i, *ind_map.find(j).unwrap());
            }

            for j in self.get_out_adj(i).iter() {
                new.add_edge(*ind_map.find(j).unwrap(), actual_i);
            }
        }
        new
    }
}

impl<T> Graph<T> for Digraph<T> {
    fn add_node(&mut self, val: T) -> NodeIndex {
        let ind = self.num_nodes;
        self.nodes.insert(ind, Node { data: val, index: ind });
        self.in_adj.insert(ind, HashSet::new());
        self.out_adj.insert(ind, HashSet::new());
        self.num_nodes += 1;
        ind
    }

    fn add_edge(&mut self, i: NodeIndex, j: NodeIndex) -> GraphResult<bool> {
        if !self.nodes.contains_key(&i) {
            Err(GraphError::invalid_index(i))
        } else if !self.nodes.contains_key(&j) {
            Err(GraphError::invalid_index(j))
        } else {
            if self.get_out_adj(i).contains(&j) {
                Ok(false)
            } else {
                self.out_adj.find_mut(&i).unwrap().insert(j);
                self.in_adj.find_mut(&j).unwrap().insert(i);
                Ok(true)
            }
        }
    }

    fn remove_node(&mut self, i: NodeIndex) -> GraphResult<()> {
        if !self.nodes.contains_key(&i) {
            Err(GraphError::invalid_index(i))
        } else {
            self.nodes.remove(&i);

            for j in self.adj(i) {
                self.in_adj.find_mut(&j).unwrap().remove(&i);
            }
            self.out_adj.remove(&i);

            for j in self.in_adj(i) {
                self.out_adj.find_mut(&j).unwrap().remove(&i);
            }
            self.in_adj.remove(&i);

            self.num_nodes -= 1;
            Ok(())
        }
    }

    fn remove_edge(&mut self, i: NodeIndex, j: NodeIndex) -> GraphResult<bool> {
        if !self.nodes.contains_key(&i) {
            Err(GraphError::invalid_index(i))
        } else if !self.nodes.contains_key(&j) {
            Err(GraphError::invalid_index(j))
        } else {
            Ok(self.is_out_adj_to(i, j))
        }
    }

    fn adj(&self, i: NodeIndex) -> NodeIndices {
        FromIterator::from_iter(self.get_out_adj(i).iter().map(|&x| x))
    }

    fn num_nodes(&self) -> uint {
        self.num_nodes
    }

    fn node_indices(&self) -> NodeIndices {
        FromIterator::from_iter(self.nodes.keys().map(|&x| x))
    }
}

struct NodeIndices {
    indices: Vec<NodeIndex>,
    curr: uint,
}

impl Iterator<NodeIndex> for NodeIndices {
    fn next(&mut self) -> Option<NodeIndex> {
        if self.curr < self.indices.len() {
            self.curr += 1;
            Some(self.indices[self.curr - 1])
        } else {
            None
        }
    }
}

impl FromIterator<NodeIndex> for NodeIndices {
    fn from_iter<T: Iterator<NodeIndex>>(mut it: T) -> NodeIndices {
        let mut vec = vec!();
        for i in it {
            vec.push(i);
        }
        NodeIndices { indices: vec, curr: 0 }
    }
}
<|endoftext|>


<commit_before>use colortype::ColorType;

/// An enumeration of Image Errors
#[deriving(Show, PartialEq, Eq)]
pub enum ImageError {
        ///The Image is not formatted properly
	FormatError,

        ///The Image's dimensions are either too small or too large
	DimensionError,

        ///The Decoder does not support this image format
	UnsupportedError,

        ///The Decoder does not support this color type
	UnsupportedColor,

        ///Not enough data was provided to the Decoder
        ///to decode the image
	NotEnoughData,

        ///An I/O Error occurred while decoding the image
	IoError,

        ///The end of the image has been reached
        ImageEnd
}

/// The trait that all decoders implement
pub trait ImageDecoder {
        ///Return a tuple containing the width and height of the image
        fn dimensions(&mut self) -> ImageResult<(u32, u32)>;

        ///Return the color type of the image e.g RGB(8) (8bit RGB)
        fn colortype(&mut self) -> ImageResult<ColorType>;

        ///Returns the length in bytes of one decoded row of the image
        fn row_len(&mut self) -> ImageResult<uint>;

        ///Read one row from the image into buf
        ///Returns the row index
        fn read_scanline(&mut self, buf: &mut [u8]) -> ImageResult<u32>;

        ///Decode the entire image and return it as a Vector
        fn read_image(&mut self) -> ImageResult<Vec<u8>>;
}

pub type ImageResult<T> = Result<T, ImageError>;<commit_msg>Add a method for loading a section of an image<commit_after>use std::slice;

use colortype;
use colortype::ColorType;

/// An enumeration of Image Errors
#[deriving(Show, PartialEq, Eq)]
pub enum ImageError {
        ///The Image is not formatted properly
	FormatError,

        ///The Image's dimensions are either too small or too large
	DimensionError,

        ///The Decoder does not support this image format
	UnsupportedError,

        ///The Decoder does not support this color type
	UnsupportedColor,

        ///Not enough data was provided to the Decoder
        ///to decode the image
	NotEnoughData,

        ///An I/O Error occurred while decoding the image
	IoError,

        ///The end of the image has been reached
        ImageEnd
}

pub type ImageResult<T> = Result<T, ImageError>;

/// The trait that all decoders implement
pub trait ImageDecoder {
        ///Return a tuple containing the width and height of the image
        fn dimensions(&mut self) -> ImageResult<(u32, u32)>;

        ///Return the color type of the image e.g RGB(8) (8bit RGB)
        fn colortype(&mut self) -> ImageResult<ColorType>;

        ///Returns the length in bytes of one decoded row of the image
        fn row_len(&mut self) -> ImageResult<uint>;

        ///Read one row from the image into buf
        ///Returns the row index
        fn read_scanline(&mut self, buf: &mut [u8]) -> ImageResult<u32>;

        ///Decode the entire image and return it as a Vector
        fn read_image(&mut self) -> ImageResult<Vec<u8>>;

        ///Decode a specific region of the image, represented by the rectangle
        ///starting from ```x``` and ```y``` and having ```length``` and ```width```
        fn load_rect(&mut self, x: u32, y: u32, length: u32, width: u32) -> ImageResult<Vec<u8>> {
                let (w, h) = try!(self.dimensions());

                if length > h || width > w || x > w || y > h {
                        return Err(DimensionError)
                }

                let c = try!(self.colortype());

                let bpp = colortype::bits_per_pixel(c) / 8;
                let rowlen  = try!(self.row_len());

                let mut buf = Vec::from_elem(length as uint * width as uint * bpp, 0u8);
                let mut tmp = Vec::from_elem(rowlen, 0u8);

                loop {
                        let row = try!(self.read_scanline(tmp.as_mut_slice()));
                        if row - 1 == y {
                                break
                        }
                }

                for i in range(0, length as uint) {
                        {
                                let from = tmp.slice_from(x as uint * bpp)
                                              .slice_to(width as uint * bpp);

                                let to   = buf.mut_slice_from(i * width as uint * bpp)
                                              .mut_slice_to(width as uint * bpp);

                                slice::bytes::copy_memory(to, from);
                        }

                        let _ = try!(self.read_scanline(tmp.as_mut_slice()));
                }

                Ok(buf)
        }
}<|endoftext|>


<commit_before>//! An abstract input state object that gets fed user
//! events and updates itself based on a set of key
//! bindings.
//! The idea is threefold:
//!
//! * Have a layer of abstract key bindings rather than
//! looking at concrete event types
//! * Use this to be able to abstract away differences
//! between keyboards, joysticks and game controllers
//! (rather based on Unity3D),
//! * Do some tweening of input axes and stuff just for
//! fun maybe.
//!
//! Right now ggez doesn't handle joysticks or controllers
//! anyway, so.

use std::hash::Hash;
use std::collections::HashMap;
use ggez::event::*;

// Okay, but how does it actually work?
// Basically we have to bind input events to buttons and axes.
// Input events can be keys, mouse buttons/motion, or eventually
// joystick/controller inputs.  Mouse delta can be mapped to axes too.
//
// https://docs.unity3d.com/Manual/ConventionalGameInput.html has useful
// descriptions of the exact behavior of axes.
//
// So to think about this more clearly, here are the default bindings:
//
// W, ↑: +Y axis
// A, ←: -X axis
// S, ↓: -Y axis
// D, →: +X axis
// Enter, z, LMB: Button 1
// Shift, x, MMB: Button 2
// Ctrl,  c, RMB: Button 3
//
// Easy way?  Hash map of event -> axis/button bindings.

#[derive(Debug, Hash, Eq, PartialEq, Copy, Clone)]
enum InputEvent {
    KeyEvent(Keycode), // MouseButtonEvent,
}

#[derive(Debug, Copy, Clone)]
enum InputEffect<Axes, Buttons>
    where Axes: Eq + Hash + Clone,
          Buttons: Eq + Hash + Clone
{
    Axis(Axes, bool),
    Button(Buttons),
}

#[derive(Debug)]
struct AxisStatus {
    // Where the axis currently is, in [-1, 1]
    position: f64,
    // Where the axis is moving towards.  Possible
    // values are -1, 0, +1
    // (or a continuous range for analog devices I guess)
    direction: f64,
    // Speed in units per second that the axis
    // moves towards the target value.
    acceleration: f64,
    // Speed in units per second that the axis will
    // fall back toward 0 if the input stops.
    gravity: f64,
}

impl Default for AxisStatus {
    fn default() -> Self {
        AxisStatus {
            position: 0.0,
            direction: 0.0,
            acceleration: 4.0,
            gravity: 3.0,
        }
    }
}

#[derive(Debug)]
pub struct InputManager<Axes, Buttons>
    where Axes: Hash + Eq + Clone,
          Buttons: Hash + Eq + Clone
{
    // Once EnumSet is stable it should be used for these
    // instead of BTreeMap. ♥?
    // Binding of keys to input values.
    bindings: HashMap<InputEvent, InputEffect<Axes, Buttons>>,
    // Input state for axes
    axes: HashMap<Axes, AxisStatus>,
    // Input states for buttons
    buttons: HashMap<Buttons, bool>,
}

impl<Axes, Buttons> InputManager<Axes, Buttons>
    where Axes: Eq + Hash + Clone,
          Buttons: Eq + Hash + Clone
{
    pub fn new() -> Self {
        InputManager {
            bindings: HashMap::new(),
            axes: HashMap::new(),
            buttons: HashMap::new(),
        }
    }

    /// Adds a key binding connecting the given keycode to the given
    /// logical axis.
    pub fn bind_key_to_axis(mut self, keycode: Keycode, axis: Axes, positive: bool) -> Self {

        self.bindings.insert(InputEvent::KeyEvent(keycode),
                             InputEffect::Axis(axis.clone(), positive));
        self.axes.insert(axis, AxisStatus::default());
        self
    }

    /// Adds a key binding connecting the given keycode to the given
    /// logical button.
    pub fn bind_key_to_button(mut self, keycode: Keycode, button: Buttons) -> Self {
        self.bindings.insert(InputEvent::KeyEvent(keycode),
                             InputEffect::Button(button.clone()));
        self.buttons.insert(button, false);
        self
    }

    /// Updates the logical input state based on the actual
    /// physical input state.  Should be called in your update()
    /// handler.
    /// So, it will do things like move the axes and so on.
    pub fn update(&mut self, dt: f64) {
        for (_axis, axis_status) in self.axes.iter_mut() {
            if axis_status.direction != 0.0 {
                // Accelerate the axis towards the
                // input'ed direction.
                let abs_dx = f64::min(axis_status.acceleration * dt,
                                      1.0 - f64::abs(axis_status.position));
                let dx = if axis_status.direction > 0.0 {
                    abs_dx
                } else {
                    -abs_dx
                };
                axis_status.position += dx;
            } else {
                // Gravitate back towards 0.
                let abs_dx = f64::min(axis_status.gravity * dt, f64::abs(axis_status.position));
                let dx = if axis_status.position > 0.0 {
                    -abs_dx
                } else {
                    abs_dx
                };
                axis_status.position += dx;
            }
        }
    }

    /// This method should get called by your key_down_event handler.
    pub fn update_keydown(&mut self, keycode: Option<Keycode>) {
        if let Some(keycode) = keycode {
            let effect = {
                if let Some(e) = self.bindings.get(&InputEvent::KeyEvent(keycode)) {
                    e.clone()
                } else {
                    return;
                }
            };
            self.update_effect(effect, true);
        }
    }

    /// This method should get called by your key_up_event handler.
    pub fn update_keyup(&mut self, keycode: Option<Keycode>) {
        if let Some(keycode) = keycode {
            let effect = {
                if let Some(e) = self.bindings.get(&InputEvent::KeyEvent(keycode)) {
                    e.clone()
                } else {
                    return;
                }
            };
            self.update_effect(effect, false);
        }
    }

    /// Takes an InputEffect and actually applies it.
    fn update_effect(&mut self, effect: InputEffect<Axes, Buttons>, started: bool) {
        match effect {
            InputEffect::Axis(axis, direction) => {
                let f = || AxisStatus::default();
                let axis_status = self.axes.entry(axis).or_insert_with(f);
                if started {
                    let direction_float = if direction { 1.0 } else { -1.0 };
                    axis_status.direction = direction_float;
                } else {
                    axis_status.direction = 0.0;
                }
            }
            InputEffect::Button(button) => {
                let button_pressed = self.buttons.entry(button).or_insert(started);
                *button_pressed = started;

            }
        }
    }

    pub fn get_axis(&mut self, axis: Axes) -> f64 {
        let f = || AxisStatus::default();
        let axis_status = self.axes.entry(axis).or_insert_with(f);
        axis_status.position
    }

    pub fn get_axis_raw(&mut self, axis: Axes) -> f64 {
        let f = || AxisStatus::default();
        let axis_status = self.axes.entry(axis).or_insert_with(f);
        axis_status.direction
    }

    pub fn get_button(&self, axis: Buttons) -> bool {
        if let Some(pressed) = self.buttons.get(&axis) {
            *pressed
        } else {
            false
        }
    }

    pub fn get_button_down(&self, axis: Buttons) -> bool {
        self.get_button(axis)
    }

    pub fn get_button_up(&self, axis: Buttons) -> bool {
        !self.get_button(axis)
    }

    pub fn mouse_position() {}

    pub fn mouse_scroll_delta() {}

    pub fn get_mouse_button() {}

    pub fn get_mouse_button_down() {}

    pub fn get_mouse_button_up() {}

    pub fn reset_input_axes(&mut self) {
        for (_axis, axis_status) in self.axes.iter_mut() {
            axis_status.position = 0.0;
            axis_status.direction = 0.0;
        }
    }
}

#[cfg(test)]
mod tests {
    use ggez::event::*;
    use super::*;

    #[derive(Hash, Eq, PartialEq, Copy, Clone, Debug)]
    enum Buttons {
        A,
        B,
        Select,
        Start,
    }

    #[derive(Hash, Eq, PartialEq, Copy, Clone, Debug)]
    enum Axes {
        Horz,
        Vert,
    }
    #[test]
    fn test_input_events() {
        let mut im = InputManager::<Axes, Buttons>::new()
            .bind_key_to_button(Keycode::Z, Buttons::A)
            .bind_key_to_button(Keycode::X, Buttons::B)
            .bind_key_to_button(Keycode::Return, Buttons::Start)
            .bind_key_to_button(Keycode::RShift, Buttons::Select)
            .bind_key_to_axis(Keycode::Up, Axes::Vert, true)
            .bind_key_to_axis(Keycode::Down, Axes::Vert, false)
            .bind_key_to_axis(Keycode::Left, Axes::Horz, false)
            .bind_key_to_axis(Keycode::Right, Axes::Horz, true);

        im.update_keydown(Some(Keycode::Z));
        assert!(im.get_button(&Buttons::A));
        assert!(im.get_button_down(&Buttons::A));
        im.update_keyup(Some(Keycode::Z));
        assert!(!im.get_button(&Buttons::A));
        assert!(im.get_button_up(&Buttons::A));

        // Push the 'up' button, watch the axis
        // increase to 1.0 but not beyond
        im.update_keydown(Some(Keycode::Up));
        assert!(im.get_axis_raw(Axes::Vert) > 0.0);
        while im.get_axis(Axes::Vert) < 0.99 {
            im.update(0.16);
            assert!(im.get_axis(Axes::Vert) >= 0.0);
            assert!(im.get_axis(Axes::Vert) <= 1.0);
        }
        // Release it, watch it wind down
        im.update_keyup(Some(Keycode::Up));
        while im.get_axis(Axes::Vert) > 0.01 {
            im.update(0.16);
            assert!(im.get_axis(Axes::Vert) >= 0.0)
        }

        // Do the same with the 'down' button.
        im.update_keydown(Some(Keycode::Down));
        while im.get_axis(Axes::Vert) > -0.99 {
            im.update(0.16);
            assert!(im.get_axis(Axes::Vert) <= 0.0);
            assert!(im.get_axis(Axes::Vert) >= -1.0);
        }
    }
}
<commit_msg>Updated tests slightly<commit_after>//! An abstract input state object that gets fed user
//! events and updates itself based on a set of key
//! bindings.
//! The idea is threefold:
//!
//! * Have a layer of abstract key bindings rather than
//! looking at concrete event types
//! * Use this to be able to abstract away differences
//! between keyboards, joysticks and game controllers
//! (rather based on Unity3D),
//! * Do some tweening of input axes and stuff just for
//! fun maybe.
//!
//! Right now ggez doesn't handle joysticks or controllers
//! anyway, so.

use std::hash::Hash;
use std::collections::HashMap;
use ggez::event::*;

// Okay, but how does it actually work?
// Basically we have to bind input events to buttons and axes.
// Input events can be keys, mouse buttons/motion, or eventually
// joystick/controller inputs.  Mouse delta can be mapped to axes too.
//
// https://docs.unity3d.com/Manual/ConventionalGameInput.html has useful
// descriptions of the exact behavior of axes.
//
// So to think about this more clearly, here are the default bindings:
//
// W, ↑: +Y axis
// A, ←: -X axis
// S, ↓: -Y axis
// D, →: +X axis
// Enter, z, LMB: Button 1
// Shift, x, MMB: Button 2
// Ctrl,  c, RMB: Button 3
//
// Easy way?  Hash map of event -> axis/button bindings.

#[derive(Debug, Hash, Eq, PartialEq, Copy, Clone)]
enum InputEvent {
    KeyEvent(Keycode), // MouseButtonEvent,
}

#[derive(Debug, Copy, Clone)]
enum InputEffect<Axes, Buttons>
    where Axes: Eq + Hash + Clone,
          Buttons: Eq + Hash + Clone
{
    Axis(Axes, bool),
    Button(Buttons),
}

#[derive(Debug)]
struct AxisStatus {
    // Where the axis currently is, in [-1, 1]
    position: f64,
    // Where the axis is moving towards.  Possible
    // values are -1, 0, +1
    // (or a continuous range for analog devices I guess)
    direction: f64,
    // Speed in units per second that the axis
    // moves towards the target value.
    acceleration: f64,
    // Speed in units per second that the axis will
    // fall back toward 0 if the input stops.
    gravity: f64,
}

impl Default for AxisStatus {
    fn default() -> Self {
        AxisStatus {
            position: 0.0,
            direction: 0.0,
            acceleration: 4.0,
            gravity: 3.0,
        }
    }
}

#[derive(Debug)]
pub struct InputManager<Axes, Buttons>
    where Axes: Hash + Eq + Clone,
          Buttons: Hash + Eq + Clone
{
    // Once EnumSet is stable it should be used for these
    // instead of BTreeMap. ♥?
    // Binding of keys to input values.
    bindings: HashMap<InputEvent, InputEffect<Axes, Buttons>>,
    // Input state for axes
    axes: HashMap<Axes, AxisStatus>,
    // Input states for buttons
    buttons: HashMap<Buttons, bool>,
}

impl<Axes, Buttons> InputManager<Axes, Buttons>
    where Axes: Eq + Hash + Clone,
          Buttons: Eq + Hash + Clone
{
    pub fn new() -> Self {
        InputManager {
            bindings: HashMap::new(),
            axes: HashMap::new(),
            buttons: HashMap::new(),
        }
    }

    /// Adds a key binding connecting the given keycode to the given
    /// logical axis.
    pub fn bind_key_to_axis(mut self, keycode: Keycode, axis: Axes, positive: bool) -> Self {

        self.bindings.insert(InputEvent::KeyEvent(keycode),
                             InputEffect::Axis(axis.clone(), positive));
        self.axes.insert(axis, AxisStatus::default());
        self
    }

    /// Adds a key binding connecting the given keycode to the given
    /// logical button.
    pub fn bind_key_to_button(mut self, keycode: Keycode, button: Buttons) -> Self {
        self.bindings.insert(InputEvent::KeyEvent(keycode),
                             InputEffect::Button(button.clone()));
        self.buttons.insert(button, false);
        self
    }

    /// Updates the logical input state based on the actual
    /// physical input state.  Should be called in your update()
    /// handler.
    /// So, it will do things like move the axes and so on.
    pub fn update(&mut self, dt: f64) {
        for (_axis, axis_status) in self.axes.iter_mut() {
            if axis_status.direction != 0.0 {
                // Accelerate the axis towards the
                // input'ed direction.
                let abs_dx = f64::min(axis_status.acceleration * dt,
                                      1.0 - f64::abs(axis_status.position));
                let dx = if axis_status.direction > 0.0 {
                    abs_dx
                } else {
                    -abs_dx
                };
                axis_status.position += dx;
            } else {
                // Gravitate back towards 0.
                let abs_dx = f64::min(axis_status.gravity * dt, f64::abs(axis_status.position));
                let dx = if axis_status.position > 0.0 {
                    -abs_dx
                } else {
                    abs_dx
                };
                axis_status.position += dx;
            }
        }
    }

    /// This method should get called by your key_down_event handler.
    pub fn update_keydown(&mut self, keycode: Option<Keycode>) {
        if let Some(keycode) = keycode {
            let effect = {
                if let Some(e) = self.bindings.get(&InputEvent::KeyEvent(keycode)) {
                    e.clone()
                } else {
                    return;
                }
            };
            self.update_effect(effect, true);
        }
    }

    /// This method should get called by your key_up_event handler.
    pub fn update_keyup(&mut self, keycode: Option<Keycode>) {
        if let Some(keycode) = keycode {
            let effect = {
                if let Some(e) = self.bindings.get(&InputEvent::KeyEvent(keycode)) {
                    e.clone()
                } else {
                    return;
                }
            };
            self.update_effect(effect, false);
        }
    }

    /// Takes an InputEffect and actually applies it.
    fn update_effect(&mut self, effect: InputEffect<Axes, Buttons>, started: bool) {
        match effect {
            InputEffect::Axis(axis, direction) => {
                let f = || AxisStatus::default();
                let axis_status = self.axes.entry(axis).or_insert_with(f);
                if started {
                    let direction_float = if direction { 1.0 } else { -1.0 };
                    axis_status.direction = direction_float;
                } else {
                    axis_status.direction = 0.0;
                }
            }
            InputEffect::Button(button) => {
                let button_pressed = self.buttons.entry(button).or_insert(started);
                *button_pressed = started;

            }
        }
    }

    pub fn get_axis(&mut self, axis: Axes) -> f64 {
        let f = || AxisStatus::default();
        let axis_status = self.axes.entry(axis).or_insert_with(f);
        axis_status.position
    }

    pub fn get_axis_raw(&mut self, axis: Axes) -> f64 {
        let f = || AxisStatus::default();
        let axis_status = self.axes.entry(axis).or_insert_with(f);
        axis_status.direction
    }

    pub fn get_button(&self, axis: Buttons) -> bool {
        if let Some(pressed) = self.buttons.get(&axis) {
            *pressed
        } else {
            false
        }
    }

    pub fn get_button_down(&self, axis: Buttons) -> bool {
        self.get_button(axis)
    }

    pub fn get_button_up(&self, axis: Buttons) -> bool {
        !self.get_button(axis)
    }

    pub fn mouse_position() {}

    pub fn mouse_scroll_delta() {}

    pub fn get_mouse_button() {}

    pub fn get_mouse_button_down() {}

    pub fn get_mouse_button_up() {}

    pub fn reset_input_axes(&mut self) {
        for (_axis, axis_status) in self.axes.iter_mut() {
            axis_status.position = 0.0;
            axis_status.direction = 0.0;
        }
    }
}

#[cfg(test)]
mod tests {
    use ggez::event::*;
    use super::*;

    #[derive(Hash, Eq, PartialEq, Copy, Clone, Debug)]
    enum Buttons {
        A,
        B,
        Select,
        Start,
    }

    #[derive(Hash, Eq, PartialEq, Copy, Clone, Debug)]
    enum Axes {
        Horz,
        Vert,
    }
    #[test]
    fn test_input_events() {
        let mut im = InputManager::<Axes, Buttons>::new()
            .bind_key_to_button(Keycode::Z, Buttons::A)
            .bind_key_to_button(Keycode::X, Buttons::B)
            .bind_key_to_button(Keycode::Return, Buttons::Start)
            .bind_key_to_button(Keycode::RShift, Buttons::Select)
            .bind_key_to_axis(Keycode::Up, Axes::Vert, true)
            .bind_key_to_axis(Keycode::Down, Axes::Vert, false)
            .bind_key_to_axis(Keycode::Left, Axes::Horz, false)
            .bind_key_to_axis(Keycode::Right, Axes::Horz, true);

        im.update_keydown(Some(Keycode::Z));
        assert!(im.get_button(Buttons::A));
        assert!(im.get_button_down(Buttons::A));
        im.update_keyup(Some(Keycode::Z));
        assert!(!im.get_button(Buttons::A));
        assert!(im.get_button_up(Buttons::A));

        // Push the 'up' button, watch the axis
        // increase to 1.0 but not beyond
        im.update_keydown(Some(Keycode::Up));
        assert!(im.get_axis_raw(Axes::Vert) > 0.0);
        while im.get_axis(Axes::Vert) < 0.99 {
            im.update(0.16);
            assert!(im.get_axis(Axes::Vert) >= 0.0);
            assert!(im.get_axis(Axes::Vert) <= 1.0);
        }
        // Release it, watch it wind down
        im.update_keyup(Some(Keycode::Up));
        while im.get_axis(Axes::Vert) > 0.01 {
            im.update(0.16);
            assert!(im.get_axis(Axes::Vert) >= 0.0)
        }

        // Do the same with the 'down' button.
        im.update_keydown(Some(Keycode::Down));
        while im.get_axis(Axes::Vert) > -0.99 {
            im.update(0.16);
            assert!(im.get_axis(Axes::Vert) <= 0.0);
            assert!(im.get_axis(Axes::Vert) >= -1.0);
        }
    }
}
<|endoftext|>


<commit_before>use libc::{c_char, c_ulong, c_int, c_uint, O_RDONLY, read, strerror};
use std::ffi::{CStr, CString};
use std::{mem, os, str};

pub static MAX_JOYSTICK_VALUE:i16 = 32767;
pub static MIN_JOYSTICK_VALUE:i16 = -32767;

static JSIOCGAXES: c_uint = 2147576337;
static JSIOCGBUTTONS: c_uint = 2147576338;
static JSIOCGID: c_uint = 2151705107;
static JSIOCGID_LEN: usize = 64;
extern {
	fn open(path: *const c_char, oflag: c_int) -> c_int;
	fn close(fd: c_int) -> c_int;
	fn ioctl(fd: c_uint, op: c_uint, result: *mut c_char);
}
fn os_error() -> &'static str {
	unsafe {
		let num = os::errno() as c_int;
		let c_error = CStr::from_ptr(strerror(num) as *const i8);
		str::from_utf8(c_error.to_bytes()).unwrap()
	}
}
#[derive(Debug)]
/// Represents a system joystick
pub struct Joystick {
	index: u8,
	fd: c_int,
	connected: bool
}
impl Joystick {
	/// Create a joystick from its index
	///
	/// This tries to open the interface `/dev/input/js...` and will return the
	/// OS-level error if it fails to open this
	pub fn new(index: u8) -> Result<Joystick, &'static str> {
		let path = format!("/dev/input/js{}", index);
		unsafe {
			let c_path = CString::new(path.as_bytes()).unwrap();
			let fd =  open(c_path.as_ptr(), O_RDONLY | 0x800);
			if fd == -1 {
				Err(os_error())
			} else {
				Ok(Joystick {
					index: index,
					fd: fd,
					connected: true
				})
			}
		}
	}
	/// Poll this joystick for events
	///
	/// This reads from the interface in non-blocking mode and converts the native
	/// event into a Reminisce event
	pub fn poll(&mut self) -> Option<::Event> {
		use ::IntoEvent;
		unsafe {
			let mut event:LinuxEvent = mem::uninitialized();
			loop {
				let event_size = mem::size_of::<LinuxEvent>() as c_ulong;
				if read(self.fd, mem::transmute(&mut event), event_size) == -1 {
					match os::errno() {
						19 => self.connected = false,
						11 => (),
						code =>
							panic!("Error while polling joystick {} - {} - {}", self.index, code, os_error())
					}
					return None
				} else if event._type & 0x80 == 0 {
					return Some(event.into_event())
				}
			}
		}
	}
	/// Check if this joystick is still connected
	pub fn is_connected(&self) -> bool {
		self.connected
	}
	/// Get the number of axes supported by this joystick
	pub fn get_num_axes(&self) -> u8 {
		unsafe {
			let mut num_axes: c_char = mem::uninitialized();
			ioctl(self.fd as u32, JSIOCGAXES, &mut num_axes as *mut i8);
			num_axes as u8
		}
	}
	/// Get the number of buttons supported by this joystick
	pub fn get_num_buttons(&self) -> u8 {
		unsafe {
			let mut num_buttons: c_char = mem::uninitialized();
			ioctl(self.fd as u32, JSIOCGBUTTONS, &mut num_buttons as *mut i8);
			num_buttons as u8
		}
	}
	/// Get the product / driver identifier of this joystick
	pub fn get_id(&self) -> String {
		unsafe {
			let text = String::with_capacity(JSIOCGID_LEN);
			ioctl(self.fd as u32, JSIOCGID, text.as_ptr() as *mut i8);
			let new_text = String::from_raw_parts(text.as_ptr() as *mut u8, JSIOCGID_LEN, JSIOCGID_LEN);
			mem::forget(text);
			new_text
		}
	}
	/// Get the index of this joystick
	pub fn get_index(&self) -> u8 {
		self.index
	}
}
impl Drop for Joystick {
	/// Close the joystick's file descriptor
	fn drop(&mut self) {
		unsafe {
			if close(self.fd) == -1 {
				panic!("Failed to close joystick {} due to {}", self.index, os_error())
			}
		}
	}
}
#[repr(C)]
struct LinuxEvent {
	/// timestamp in milleseconds
	time: u32,
	/// value
	value: i16,
	/// event type
	_type: u8,
	/// axis / button number
	number: u8
}
impl ::IntoEvent for LinuxEvent {
	fn into_event(self) -> ::Event {
		match (self._type, self.value) {
			(1, 0) => ::Event::ButtonReleased(self.number),
			(1, 1) => ::Event::ButtonPressed(self.number),
			(2, _) => ::Event::JoystickMoved(self.number, self.value),
			_ => panic!("Bad type and value {} {} for joystick", self._type, self.value)
		}
	}
}
<commit_msg>Document statics<commit_after>use libc::{c_char, c_ulong, c_int, c_uint, O_RDONLY, read, strerror};
use std::ffi::{CStr, CString};
use std::{mem, os, str};

/// The maximum axis value
pub static MAX_JOYSTICK_VALUE:i16 = 32767;
/// The minimum axis value
pub static MIN_JOYSTICK_VALUE:i16 = -32767;

static JSIOCGAXES: c_uint = 2147576337;
static JSIOCGBUTTONS: c_uint = 2147576338;
static JSIOCGID: c_uint = 2151705107;
static JSIOCGID_LEN: usize = 64;
extern {
	fn open(path: *const c_char, oflag: c_int) -> c_int;
	fn close(fd: c_int) -> c_int;
	fn ioctl(fd: c_uint, op: c_uint, result: *mut c_char);
}
fn os_error() -> &'static str {
	unsafe {
		let num = os::errno() as c_int;
		let c_error = CStr::from_ptr(strerror(num) as *const i8);
		str::from_utf8(c_error.to_bytes()).unwrap()
	}
}
#[derive(Debug)]
/// Represents a system joystick
pub struct Joystick {
	index: u8,
	fd: c_int,
	connected: bool
}
impl Joystick {
	/// Create a joystick from its index
	///
	/// This tries to open the interface `/dev/input/js...` and will return the
	/// OS-level error if it fails to open this
	pub fn new(index: u8) -> Result<Joystick, &'static str> {
		let path = format!("/dev/input/js{}", index);
		unsafe {
			let c_path = CString::new(path.as_bytes()).unwrap();
			let fd =  open(c_path.as_ptr(), O_RDONLY | 0x800);
			if fd == -1 {
				Err(os_error())
			} else {
				Ok(Joystick {
					index: index,
					fd: fd,
					connected: true
				})
			}
		}
	}
	/// Poll this joystick for events
	///
	/// This reads from the interface in non-blocking mode and converts the native
	/// event into a Reminisce event
	pub fn poll(&mut self) -> Option<::Event> {
		use ::IntoEvent;
		unsafe {
			let mut event:LinuxEvent = mem::uninitialized();
			loop {
				let event_size = mem::size_of::<LinuxEvent>() as c_ulong;
				if read(self.fd, mem::transmute(&mut event), event_size) == -1 {
					match os::errno() {
						19 => self.connected = false,
						11 => (),
						code =>
							panic!("Error while polling joystick {} - {} - {}", self.index, code, os_error())
					}
					return None
				} else if event._type & 0x80 == 0 {
					return Some(event.into_event())
				}
			}
		}
	}
	/// Check if this joystick is still connected
	pub fn is_connected(&self) -> bool {
		self.connected
	}
	/// Get the number of axes supported by this joystick
	pub fn get_num_axes(&self) -> u8 {
		unsafe {
			let mut num_axes: c_char = mem::uninitialized();
			ioctl(self.fd as u32, JSIOCGAXES, &mut num_axes as *mut i8);
			num_axes as u8
		}
	}
	/// Get the number of buttons supported by this joystick
	pub fn get_num_buttons(&self) -> u8 {
		unsafe {
			let mut num_buttons: c_char = mem::uninitialized();
			ioctl(self.fd as u32, JSIOCGBUTTONS, &mut num_buttons as *mut i8);
			num_buttons as u8
		}
	}
	/// Get the product / driver identifier of this joystick
	pub fn get_id(&self) -> String {
		unsafe {
			let text = String::with_capacity(JSIOCGID_LEN);
			ioctl(self.fd as u32, JSIOCGID, text.as_ptr() as *mut i8);
			let new_text = String::from_raw_parts(text.as_ptr() as *mut u8, JSIOCGID_LEN, JSIOCGID_LEN);
			mem::forget(text);
			new_text
		}
	}
	/// Get the index of this joystick
	pub fn get_index(&self) -> u8 {
		self.index
	}
}
impl Drop for Joystick {
	/// Close the joystick's file descriptor
	fn drop(&mut self) {
		unsafe {
			if close(self.fd) == -1 {
				panic!("Failed to close joystick {} due to {}", self.index, os_error())
			}
		}
	}
}
#[repr(C)]
struct LinuxEvent {
	/// timestamp in milleseconds
	time: u32,
	/// value
	value: i16,
	/// event type
	_type: u8,
	/// axis / button number
	number: u8
}
impl ::IntoEvent for LinuxEvent {
	fn into_event(self) -> ::Event {
		match (self._type, self.value) {
			(1, 0) => ::Event::ButtonReleased(self.number),
			(1, 1) => ::Event::ButtonPressed(self.number),
			(2, _) => ::Event::JoystickMoved(self.number, self.value),
			_ => panic!("Bad type and value {} {} for joystick", self._type, self.value)
		}
	}
}
<|endoftext|>