use core::fmt::Display;

use {Compat, Context, Fail};

/// Extension methods for `Result`.
pub trait ResultExt<T, E> {
    /// Wraps the error in `Compat` to make it compatible with older error
    /// handling APIs that expect `std::error::Error`.
    ///
    /// # Examples
    ///
    /// ```
    /// # fn main() {
    /// #    tests::run_test();
    /// # }
    /// #
    /// # #[cfg(not(all(feature = "std", feature = "derive")))] mod tests { pub fn run_test() { } }
    /// #  
    /// # #[cfg(all(feature = "std", feature = "derive"))] mod tests {
    /// use std::error::Error;
    /// # use std::fmt;
    /// #
    /// # extern crate failure;
    /// #
    /// # use tests::failure::ResultExt;
    /// #
    /// # #[derive(Debug)]
    /// struct CustomError;
    ///
    /// impl Error for CustomError {
    ///     fn description(&self) -> &str {
    ///         "My custom error message"
    ///     }
    ///
    ///     fn cause(&self) -> Option<&Error> {
    ///         None
    ///     }
    /// }
    /// #
    /// # impl fmt::Display for CustomError {
    /// #     fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
    /// #         write!(f, "{}", self.description())
    /// #     }
    /// # }
    /// #
    /// # pub fn run_test() {
    ///
    /// let x = (|| -> Result<(), failure::Error> {
    ///     Err(CustomError).compat()?
    /// })().with_context(|e| {
    ///     format!("An error occured: {}", e)
    /// }).unwrap_err();
    ///
    /// let x = format!("{}", x);
    ///
    /// assert_eq!(x, "An error occured: My custom error message");
    /// # }
    ///
    /// # }
    /// ```
    fn compat(self) -> Result<T, Compat<E>>;

    /// Wraps the error type in a context type.
    ///
    /// # Examples
    ///
    /// ```
    /// # #[cfg(all(feature = "std", feature = "derive"))]
    /// # #[macro_use] extern crate failure;
    /// #
    /// # #[cfg(all(feature = "std", feature = "derive"))]
    /// # #[macro_use] extern crate failure_derive;
    /// #
    /// # fn main() {
    /// #    tests::run_test();
    /// # }
    /// #
    /// # #[cfg(not(all(feature = "std", feature = "derive")))] mod tests { pub fn run_test() { } }
    /// #
    /// # #[cfg(all(feature = "std", feature = "derive"))] mod tests {
    /// #
    /// # use failure::{self, ResultExt};
    /// #
    /// #[derive(Fail, Debug)]
    /// #[fail(display = "")]
    /// struct CustomError;
    /// #
    /// # pub fn run_test() {
    ///  
    /// let x = (|| -> Result<(), failure::Error> {
    ///     Err(CustomError)?
    /// })().context(format!("An error occured")).unwrap_err();
    ///
    /// let x = format!("{}", x);
    ///
    /// assert_eq!(x, "An error occured");
    /// # }
    ///
    /// # }
    /// ```
    fn context<D>(self, context: D) -> Result<T, Context<D>>
    where
        D: Display + Send + Sync + 'static;

    /// Wraps the error type in a context type generated by looking at the
    /// error value.
    ///
    /// # Examples
    ///
    /// ```
    /// # #[cfg(all(feature = "std", feature = "derive"))]
    /// # #[macro_use] extern crate failure;
    /// #
    /// # #[cfg(all(feature = "std", feature = "derive"))]
    /// # #[macro_use] extern crate failure_derive;
    /// #
    /// # fn main() {
    /// #    tests::run_test();
    /// # }
    /// #
    /// # #[cfg(not(all(feature = "std", feature = "derive")))] mod tests { pub fn run_test() { } }
    /// #
    /// # #[cfg(all(feature = "std", feature = "derive"))] mod tests {
    /// #
    /// # use failure::{self, ResultExt};
    /// #
    /// #[derive(Fail, Debug)]
    /// #[fail(display = "My custom error message")]
    /// struct CustomError;
    /// #
    /// # pub fn run_test() {
    ///
    /// let x = (|| -> Result<(), failure::Error> {
    ///     Err(CustomError)?
    /// })().with_context(|e| {
    ///     format!("An error occured: {}", e)
    /// }).unwrap_err();
    ///
    /// let x = format!("{}", x);
    ///
    /// assert_eq!(x, "An error occured: My custom error message");
    /// # }
    ///
    /// # }
    /// ```
    fn with_context<F, D>(self, f: F) -> Result<T, Context<D>>
    where
        F: FnOnce(&E) -> D,
        D: Display + Send + Sync + 'static;
}

impl<T, E> ResultExt<T, E> for Result<T, E>
where
    E: Fail,
{
    fn compat(self) -> Result<T, Compat<E>> {
        self.map_err(|err| err.compat())
    }

    fn context<D>(self, context: D) -> Result<T, Context<D>>
    where
        D: Display + Send + Sync + 'static,
    {
        self.map_err(|failure| failure.context(context))
    }

    fn with_context<F, D>(self, f: F) -> Result<T, Context<D>>
    where
        F: FnOnce(&E) -> D,
        D: Display + Send + Sync + 'static,
    {
        self.map_err(|failure| {
            let context = f(&failure);
            failure.context(context)
        })
    }
}

with_std! {
    use Error;

    impl<T> ResultExt<T, Error> for Result<T, Error> {
        fn compat(self) -> Result<T, Compat<Error>> {
            self.map_err(|err| err.compat())
        }

        fn context<D>(self, context: D) -> Result<T, Context<D>> where
            D: Display + Send + Sync + 'static
        {
            self.map_err(|failure| failure.context(context))
        }

        fn with_context<F, D>(self, f: F) -> Result<T, Context<D>> where
            F: FnOnce(&Error) -> D,
            D: Display + Send + Sync + 'static
        {
            self.map_err(|failure| {
                let context = f(&failure);
                failure.context(context)
            })
        }
    }
}
