summaryrefslogtreecommitdiff
path: root/vendor/miette/src/eyreish/macros.rs
diff options
context:
space:
mode:
Diffstat (limited to 'vendor/miette/src/eyreish/macros.rs')
-rw-r--r--vendor/miette/src/eyreish/macros.rs300
1 files changed, 300 insertions, 0 deletions
diff --git a/vendor/miette/src/eyreish/macros.rs b/vendor/miette/src/eyreish/macros.rs
new file mode 100644
index 0000000..e13309f
--- /dev/null
+++ b/vendor/miette/src/eyreish/macros.rs
@@ -0,0 +1,300 @@
+/// 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
+ }};
+}