|  | /// Return early with an error. | 
|  | /// | 
|  | /// This macro is equivalent to `return Err(From::from($err))`. | 
|  | /// | 
|  | /// # Example | 
|  | /// | 
|  | /// ``` | 
|  | /// # use miette::{bail, Result}; | 
|  | /// # | 
|  | /// # fn has_permission(user: usize, resource: usize) -> bool { | 
|  | /// #     true | 
|  | /// # } | 
|  | /// # | 
|  | /// # fn main() -> Result<()> { | 
|  | /// #     let user = 0; | 
|  | /// #     let resource = 0; | 
|  | /// # | 
|  | /// if !has_permission(user, resource) { | 
|  | #[cfg_attr( | 
|  | not(feature = "no-format-args-capture"), | 
|  | doc = r#"     bail!("permission denied for accessing {resource}");"# | 
|  | )] | 
|  | #[cfg_attr( | 
|  | feature = "no-format-args-capture", | 
|  | doc = r#"     bail!("permission denied for accessing {}", resource);"# | 
|  | )] | 
|  | /// } | 
|  | /// #     Ok(()) | 
|  | /// # } | 
|  | /// ``` | 
|  | /// | 
|  | /// ``` | 
|  | /// # use miette::{bail, Result}; | 
|  | /// # use thiserror::Error; | 
|  | /// # | 
|  | /// # const MAX_DEPTH: usize = 1; | 
|  | /// # | 
|  | /// #[derive(Error, Debug)] | 
|  | /// enum ScienceError { | 
|  | ///     #[error("recursion limit exceeded")] | 
|  | ///     RecursionLimitExceeded, | 
|  | ///     # #[error("...")] | 
|  | ///     # More = (stringify! { | 
|  | ///     ... | 
|  | ///     # }, 1).1, | 
|  | /// } | 
|  | /// | 
|  | /// # fn main() -> Result<()> { | 
|  | /// #     let depth = 0; | 
|  | /// #     let err: &'static dyn std::error::Error = &ScienceError::RecursionLimitExceeded; | 
|  | /// # | 
|  | /// if depth > MAX_DEPTH { | 
|  | ///     bail!(ScienceError::RecursionLimitExceeded); | 
|  | /// } | 
|  | /// #     Ok(()) | 
|  | /// # } | 
|  | /// ``` | 
|  | /// | 
|  | /// ``` | 
|  | /// use miette::{bail, Result, Severity}; | 
|  | /// | 
|  | /// fn divide(x: f64, y: f64) -> Result<f64> { | 
|  | ///     if y.abs() < 1e-3 { | 
|  | ///         bail!( | 
|  | ///             severity = Severity::Warning, | 
|  | #[cfg_attr( | 
|  | not(feature = "no-format-args-capture"), | 
|  | doc = r#"             "dividing by value ({y}) close to 0""# | 
|  | )] | 
|  | #[cfg_attr( | 
|  | feature = "no-format-args-capture", | 
|  | doc = r#"             "dividing by value ({}) close to 0", y"# | 
|  | )] | 
|  | ///         ); | 
|  | ///     } | 
|  | ///     Ok(x / y) | 
|  | /// } | 
|  | /// ``` | 
|  | #[macro_export] | 
|  | macro_rules! bail { | 
|  | ($($key:ident = $value:expr,)* $fmt:literal $($arg:tt)*) => { | 
|  | return $crate::private::Err( | 
|  | $crate::miette!($($key = $value,)* $fmt $($arg)*) | 
|  | ); | 
|  | }; | 
|  | ($err:expr $(,)?) => { | 
|  | return $crate::private::Err($crate::miette!($err)); | 
|  | }; | 
|  | } | 
|  |  | 
|  | /// Return early with an error if a condition is not satisfied. | 
|  | /// | 
|  | /// This macro is equivalent to `if !$cond { return Err(From::from($err)); }`. | 
|  | /// | 
|  | /// Analogously to `assert!`, `ensure!` takes a condition and exits the function | 
|  | /// if the condition fails. Unlike `assert!`, `ensure!` returns an `Error` | 
|  | /// rather than panicking. | 
|  | /// | 
|  | /// # Example | 
|  | /// | 
|  | /// ``` | 
|  | /// # use miette::{ensure, Result}; | 
|  | /// # | 
|  | /// # fn main() -> Result<()> { | 
|  | /// #     let user = 0; | 
|  | /// # | 
|  | /// ensure!(user == 0, "only user 0 is allowed"); | 
|  | /// #     Ok(()) | 
|  | /// # } | 
|  | /// ``` | 
|  | /// | 
|  | /// ``` | 
|  | /// # use miette::{ensure, Result}; | 
|  | /// # use thiserror::Error; | 
|  | /// # | 
|  | /// # const MAX_DEPTH: usize = 1; | 
|  | /// # | 
|  | /// #[derive(Error, Debug)] | 
|  | /// enum ScienceError { | 
|  | ///     #[error("recursion limit exceeded")] | 
|  | ///     RecursionLimitExceeded, | 
|  | ///     # #[error("...")] | 
|  | ///     # More = (stringify! { | 
|  | ///     ... | 
|  | ///     # }, 1).1, | 
|  | /// } | 
|  | /// | 
|  | /// # fn main() -> Result<()> { | 
|  | /// #     let depth = 0; | 
|  | /// # | 
|  | /// ensure!(depth <= MAX_DEPTH, ScienceError::RecursionLimitExceeded); | 
|  | /// #     Ok(()) | 
|  | /// # } | 
|  | /// ``` | 
|  | /// | 
|  | /// ``` | 
|  | /// use miette::{ensure, Result, Severity}; | 
|  | /// | 
|  | /// fn divide(x: f64, y: f64) -> Result<f64> { | 
|  | ///     ensure!( | 
|  | ///         y.abs() >= 1e-3, | 
|  | ///         severity = Severity::Warning, | 
|  | #[cfg_attr( | 
|  | not(feature = "no-format-args-capture"), | 
|  | doc = r#"             "dividing by value ({y}) close to 0""# | 
|  | )] | 
|  | #[cfg_attr( | 
|  | feature = "no-format-args-capture", | 
|  | doc = r#"             "dividing by value ({}) close to 0", y"# | 
|  | )] | 
|  | ///     ); | 
|  | ///     Ok(x / y) | 
|  | /// } | 
|  | /// ``` | 
|  | #[macro_export] | 
|  | macro_rules! ensure { | 
|  | ($cond:expr, $($key:ident = $value:expr,)* $fmt:literal $($arg:tt)*) => { | 
|  | if !$cond { | 
|  | return $crate::private::Err( | 
|  | $crate::miette!($($key = $value,)* $fmt $($arg)*) | 
|  | ); | 
|  | } | 
|  | }; | 
|  | ($cond:expr, $err:expr $(,)?) => { | 
|  | if !$cond { | 
|  | return $crate::private::Err($crate::miette!($err)); | 
|  | } | 
|  | }; | 
|  | } | 
|  |  | 
|  | /// Construct an ad-hoc [`Report`]. | 
|  | /// | 
|  | /// # Examples | 
|  | /// | 
|  | /// With string literal and interpolation: | 
|  | /// ``` | 
|  | /// # use miette::miette; | 
|  | /// let x = 1; | 
|  | /// let y = 2; | 
|  | #[cfg_attr( | 
|  | not(feature = "no-format-args-capture"), | 
|  | doc = r#"let report = miette!("{x} + {} = {z}", y, z = x + y);"# | 
|  | )] | 
|  | #[cfg_attr( | 
|  | feature = "no-format-args-capture", | 
|  | doc = r#"let report = miette!("{} + {} = {z}", x, y, z = x + y);"# | 
|  | )] | 
|  | /// | 
|  | /// assert_eq!(report.to_string().as_str(), "1 + 2 = 3"); | 
|  | /// | 
|  | /// let z = x + y; | 
|  | #[cfg_attr( | 
|  | not(feature = "no-format-args-capture"), | 
|  | doc = r#"let report = miette!("{x} + {y} = {z}");"# | 
|  | )] | 
|  | #[cfg_attr( | 
|  | feature = "no-format-args-capture", | 
|  | doc = r#"let report = miette!("{} + {} = {}", x, y, z);"# | 
|  | )] | 
|  | /// assert_eq!(report.to_string().as_str(), "1 + 2 = 3"); | 
|  | /// ``` | 
|  | /// | 
|  | /// With [`diagnostic!`]-like arguments: | 
|  | /// ``` | 
|  | /// use miette::{miette, LabeledSpan, Severity}; | 
|  | /// | 
|  | /// let source = "(2 + 2".to_string(); | 
|  | /// let report = miette!( | 
|  | ///     // Those fields are optional | 
|  | ///     severity = Severity::Error, | 
|  | ///     code = "expected::rparen", | 
|  | ///     help = "always close your parens", | 
|  | ///     labels = vec![LabeledSpan::at_offset(6, "here")], | 
|  | ///     url = "https://example.com", | 
|  | ///     // Rest of the arguments are passed to `format!` | 
|  | ///     // to form diagnostic message | 
|  | ///     "expected closing ')'" | 
|  | /// ) | 
|  | /// .with_source_code(source); | 
|  | /// ``` | 
|  | /// | 
|  | /// ## `anyhow`/`eyre` Users | 
|  | /// | 
|  | /// You can just replace `use`s of the `anyhow!`/`eyre!` macros with `miette!`. | 
|  | /// | 
|  | /// [`diagnostic!`]: crate::diagnostic! | 
|  | /// [`Report`]: crate::Report | 
|  | #[macro_export] | 
|  | macro_rules! miette { | 
|  | ($($key:ident = $value:expr,)* $fmt:literal $($arg:tt)*) => { | 
|  | $crate::Report::from( | 
|  | $crate::diagnostic!($($key = $value,)* $fmt $($arg)*) | 
|  | ) | 
|  | }; | 
|  | ($err:expr $(,)?) => ({ | 
|  | use $crate::private::kind::*; | 
|  | let error = $err; | 
|  | (&error).miette_kind().new(error) | 
|  | }); | 
|  | } | 
|  |  | 
|  | /// Construct a [`MietteDiagnostic`] in more user-friendly way. | 
|  | /// | 
|  | /// # Examples | 
|  | /// ``` | 
|  | /// use miette::{diagnostic, LabeledSpan, Severity}; | 
|  | /// | 
|  | /// let source = "(2 + 2".to_string(); | 
|  | /// let diag = diagnostic!( | 
|  | ///     // Those fields are optional | 
|  | ///     severity = Severity::Error, | 
|  | ///     code = "expected::rparen", | 
|  | ///     help = "always close your parens", | 
|  | ///     labels = vec![LabeledSpan::at_offset(6, "here")], | 
|  | ///     url = "https://example.com", | 
|  | ///     // Rest of the arguments are passed to `format!` | 
|  | ///     // to form diagnostic message | 
|  | ///     "expected closing ')'", | 
|  | /// ); | 
|  | /// ``` | 
|  | /// Diagnostic without any fields: | 
|  | /// ``` | 
|  | /// # use miette::diagnostic; | 
|  | /// let x = 1; | 
|  | /// let y = 2; | 
|  | /// | 
|  | #[cfg_attr( | 
|  | not(feature = "no-format-args-capture"), | 
|  | doc = r#" let diag = diagnostic!("{x} + {} = {z}", y, z = x + y);"# | 
|  | )] | 
|  | #[cfg_attr( | 
|  | feature = "no-format-args-capture", | 
|  | doc = r#" let diag = diagnostic!("{} + {} = {z}", x, y, z = x + y);"# | 
|  | )] | 
|  | /// assert_eq!(diag.message, "1 + 2 = 3"); | 
|  | /// | 
|  | /// let z = x + y; | 
|  | #[cfg_attr( | 
|  | not(feature = "no-format-args-capture"), | 
|  | doc = r#"let diag = diagnostic!("{x} + {y} = {z}");"# | 
|  | )] | 
|  | #[cfg_attr( | 
|  | feature = "no-format-args-capture", | 
|  | doc = r#"let diag = diagnostic!("{} + {} = {}", x, y, z);"# | 
|  | )] | 
|  | /// assert_eq!(diag.message, "1 + 2 = 3"); | 
|  | /// ``` | 
|  | /// | 
|  | /// [`MietteDiagnostic`]: crate::MietteDiagnostic | 
|  | #[macro_export] | 
|  | macro_rules! diagnostic { | 
|  | ($fmt:literal $($arg:tt)*) => {{ | 
|  | $crate::MietteDiagnostic::new(format!($fmt $($arg)*)) | 
|  | }}; | 
|  | ($($key:ident = $value:expr,)+ $fmt:literal $($arg:tt)*) => {{ | 
|  | let mut diag = $crate::MietteDiagnostic::new(format!($fmt $($arg)*)); | 
|  | $(diag.$key = Some($value.into());)* | 
|  | diag | 
|  | }}; | 
|  | } |