anystack 0.6.0-alpha.3

Flexible and comprehensive error handling.
Documentation
/// Creates a [`Report`] from the given parameters.
///
/// The parameters may either be [`Error`] or a [`Report`]. The returned [`Report`] will use the
/// the provided type as context.
///
/// [`Report`]: crate::Report
/// [`Error`]: core::error::Error
///
/// # Examples
///
/// Create a [`Report`] from [`Error`]:
///
/// ```rust
/// # #![expect(deprecated, reason = "`report!` is deprecated")]
/// use std::fs;
///
/// use anystack::report;
///
/// # fn wrapper() -> Result<(), anystack::Report<impl core::fmt::Debug>> {
/// match fs::read_to_string("/path/to/file") {
///     Ok(content) => println!("file contents: {content}"),
///     Err(err) => return Err(report!(err)),
/// }
/// # Ok(()) }
/// # assert!(wrapper().unwrap_err().contains::<std::io::Error>());
/// ```
///
/// ```rust
/// # #![expect(deprecated, reason = "`report!` is deprecated")]
/// # fn has_permission(_: &u32, _: &u32) -> bool { true }
/// # type User = u32;
/// # let user = 0;
/// # type Resource = u32;
/// # let resource = 0;
/// use core::error::Error;
/// use core::fmt;
///
/// use anystack::report;
///
/// #[derive(Debug)]
/// # #[allow(dead_code)]
/// struct PermissionDenied(User, Resource);
///
/// impl fmt::Display for PermissionDenied {
///     # #[allow(unused_variables)]
///     fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
///         # const _: &str = stringify! {
///         ...
///         # }; Ok(())}
/// }
///
/// impl Error for PermissionDenied {}
///
/// if !has_permission(&user, &resource) {
///     return Err(report!(PermissionDenied(user, resource)));
/// }
/// # Ok(())
/// ```
#[deprecated(since = "0.6.0", note = "use `IntoReport::into_report` instead")]
#[macro_export]
macro_rules! report {
    ($err:expr $(,)?) => {{
        $crate::IntoReport::into_report($err)
    }};
}

/// Creates a [`Report`] and returns it as [`Result`].
///
/// Shorthand for `return Err(report!(..))`.
///
/// [`Report`]: crate::Report
/// [`report!(...)`]: report
///
/// # Examples
///
/// Create a [`Report`] from [`Error`]:
///
/// [`Error`]: core::error::Error
///
/// ```rust
/// # #![expect(deprecated, reason = "`anystack::Result` is deprecated")]
/// use std::fs;
///
/// use anystack::bail;
/// # fn wrapper() -> anystack::Result<(), impl core::fmt::Debug> {
/// match fs::read_to_string("/path/to/file") {
///     Ok(content) => println!("file contents: {content}"),
///     Err(err) => bail!(err),
/// }
/// # Ok(()) }
/// # assert!(wrapper().unwrap_err().contains::<std::io::Error>());
/// ```
///
/// Create a [`Report`] from [`Context`]:
///
/// [`Context`]: crate::Context
///
/// ```rust
/// # #![expect(deprecated, reason = "`anystack::Context` is deprecated")]
/// # fn has_permission(_: &u32, _: &u32) -> bool { true }
/// # type User = u32;
/// # let user = 0;
/// # type Resource = u32;
/// # let resource = 0;
/// use core::fmt;
///
/// use anystack::{bail, Context};
///
/// #[derive(Debug)]
/// # #[allow(dead_code)]
/// struct PermissionDenied(User, Resource);
///
/// impl fmt::Display for PermissionDenied {
///     # #[allow(unused_variables)]
///     fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
///         # const _: &str = stringify! {
///         ...
///         # }; Ok(())}
/// }
///
/// impl Context for PermissionDenied {}
///
/// if !has_permission(&user, &resource) {
///     bail!(PermissionDenied(user, resource));
/// }
/// # Ok(())
/// ```
#[macro_export]
macro_rules! bail {
    ($err:expr) => {{
        return ::core::result::Result::Err($crate::IntoReport::into_report($err));
    }};
}

/// Ensures `$cond` is met, otherwise return an error.
///
/// Shorthand for <code>if !$cond { [bail!(..)]) }</code>
///
/// [`Report`]: crate::Report
/// [bail!(..)]: bail
///
/// # Examples
///
/// Create a [`Report`] from an [`Error`]:
///
/// [`Error`]: core::error::Error
///
/// ```rust
/// # fn has_permission(_: &u32, _: &u32) -> bool { true }
/// # type User = u32;
/// # let user = 0;
/// # type Resource = u32;
/// # let resource = 0;
/// use core::error::Error;
/// use core::fmt;
///
/// use anystack::ensure;
///
/// #[derive(Debug)]
/// # #[allow(dead_code)]
/// struct PermissionDenied(User, Resource);
///
/// impl fmt::Display for PermissionDenied {
///     # #[allow(unused_variables)]
///     fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
///         # const _: &str = stringify! {
///         ...
///         # };
///         Ok(())
///     }
/// }
///
/// impl Error for PermissionDenied {}
///
/// ensure!(
///     has_permission(&user, &resource),
///     PermissionDenied(user, resource)
/// );
/// # Ok(())
/// ```
#[macro_export]
macro_rules! ensure {
    ($cond:expr, $err:expr $(,)?) => {{
        if !bool::from($cond) {
            $crate::bail!($err)
        }
    }};
}