summaryrefslogtreecommitdiff
path: root/vendor/miette/src/eyreish/mod.rs
diff options
context:
space:
mode:
authorValentin Popov <valentin@popov.link>2024-01-08 00:21:28 +0300
committerValentin Popov <valentin@popov.link>2024-01-08 00:21:28 +0300
commit1b6a04ca5504955c571d1c97504fb45ea0befee4 (patch)
tree7579f518b23313e8a9748a88ab6173d5e030b227 /vendor/miette/src/eyreish/mod.rs
parent5ecd8cf2cba827454317368b68571df0d13d7842 (diff)
downloadfparkan-1b6a04ca5504955c571d1c97504fb45ea0befee4.tar.xz
fparkan-1b6a04ca5504955c571d1c97504fb45ea0befee4.zip
Initial vendor packages
Signed-off-by: Valentin Popov <valentin@popov.link>
Diffstat (limited to 'vendor/miette/src/eyreish/mod.rs')
-rw-r--r--vendor/miette/src/eyreish/mod.rs485
1 files changed, 485 insertions, 0 deletions
diff --git a/vendor/miette/src/eyreish/mod.rs b/vendor/miette/src/eyreish/mod.rs
new file mode 100644
index 0000000..0efceed
--- /dev/null
+++ b/vendor/miette/src/eyreish/mod.rs
@@ -0,0 +1,485 @@
+#![cfg_attr(doc_cfg, feature(doc_cfg))]
+#![allow(
+ clippy::needless_doctest_main,
+ clippy::new_ret_no_self,
+ clippy::wrong_self_convention
+)]
+use core::fmt::Display;
+
+use std::error::Error as StdError;
+
+use once_cell::sync::OnceCell;
+
+#[allow(unreachable_pub)]
+pub use into_diagnostic::*;
+#[doc(hidden)]
+#[allow(unreachable_pub)]
+pub use Report as ErrReport;
+/// Compatibility re-export of `Report` for interop with `anyhow`
+#[allow(unreachable_pub)]
+pub use Report as Error;
+#[doc(hidden)]
+#[allow(unreachable_pub)]
+pub use ReportHandler as EyreContext;
+/// Compatibility re-export of `WrapErr` for interop with `anyhow`
+#[allow(unreachable_pub)]
+pub use WrapErr as Context;
+
+#[cfg(not(feature = "fancy-no-backtrace"))]
+use crate::DebugReportHandler;
+use crate::Diagnostic;
+#[cfg(feature = "fancy-no-backtrace")]
+use crate::MietteHandler;
+
+use error::ErrorImpl;
+
+use self::ptr::Own;
+
+mod context;
+mod error;
+mod fmt;
+mod into_diagnostic;
+mod kind;
+mod macros;
+mod ptr;
+mod wrapper;
+
+/**
+Core Diagnostic wrapper type.
+
+## `eyre` Users
+
+You can just replace `use`s of `eyre::Report` with `miette::Report`.
+*/
+pub struct Report {
+ inner: Own<ErrorImpl<()>>,
+}
+
+unsafe impl Sync for Report {}
+unsafe impl Send for Report {}
+
+///
+pub type ErrorHook =
+ Box<dyn Fn(&(dyn Diagnostic + 'static)) -> Box<dyn ReportHandler> + Sync + Send + 'static>;
+
+static HOOK: OnceCell<ErrorHook> = OnceCell::new();
+
+/// Error indicating that [`set_hook()`] was unable to install the provided
+/// [`ErrorHook`].
+#[derive(Debug)]
+pub struct InstallError;
+
+impl core::fmt::Display for InstallError {
+ fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
+ f.write_str("cannot install provided ErrorHook, a hook has already been installed")
+ }
+}
+
+impl StdError for InstallError {}
+impl Diagnostic for InstallError {}
+
+/**
+Set the error hook.
+*/
+pub fn set_hook(hook: ErrorHook) -> Result<(), InstallError> {
+ HOOK.set(hook).map_err(|_| InstallError)
+}
+
+#[cfg_attr(track_caller, track_caller)]
+#[cfg_attr(not(track_caller), allow(unused_mut))]
+fn capture_handler(error: &(dyn Diagnostic + 'static)) -> Box<dyn ReportHandler> {
+ let hook = HOOK.get_or_init(|| Box::new(get_default_printer)).as_ref();
+
+ #[cfg(track_caller)]
+ {
+ let mut handler = hook(error);
+ handler.track_caller(std::panic::Location::caller());
+ handler
+ }
+ #[cfg(not(track_caller))]
+ {
+ hook(error)
+ }
+}
+
+fn get_default_printer(_err: &(dyn Diagnostic + 'static)) -> Box<dyn ReportHandler + 'static> {
+ #[cfg(feature = "fancy-no-backtrace")]
+ return Box::new(MietteHandler::new());
+ #[cfg(not(feature = "fancy-no-backtrace"))]
+ return Box::new(DebugReportHandler::new());
+}
+
+impl dyn ReportHandler {
+ ///
+ pub fn is<T: ReportHandler>(&self) -> bool {
+ // Get `TypeId` of the type this function is instantiated with.
+ let t = core::any::TypeId::of::<T>();
+
+ // Get `TypeId` of the type in the trait object (`self`).
+ let concrete = self.type_id();
+
+ // Compare both `TypeId`s on equality.
+ t == concrete
+ }
+
+ ///
+ pub fn downcast_ref<T: ReportHandler>(&self) -> Option<&T> {
+ if self.is::<T>() {
+ unsafe { Some(&*(self as *const dyn ReportHandler as *const T)) }
+ } else {
+ None
+ }
+ }
+
+ ///
+ pub fn downcast_mut<T: ReportHandler>(&mut self) -> Option<&mut T> {
+ if self.is::<T>() {
+ unsafe { Some(&mut *(self as *mut dyn ReportHandler as *mut T)) }
+ } else {
+ None
+ }
+ }
+}
+
+/// Error Report Handler trait for customizing `miette::Report`
+pub trait ReportHandler: core::any::Any + Send + Sync {
+ /// Define the report format
+ ///
+ /// Used to override the report format of `miette::Report`
+ ///
+ /// # Example
+ ///
+ /// ```rust
+ /// use indenter::indented;
+ /// use miette::{Diagnostic, ReportHandler};
+ ///
+ /// pub struct Handler;
+ ///
+ /// impl ReportHandler for Handler {
+ /// fn debug(
+ /// &self,
+ /// error: &dyn Diagnostic,
+ /// f: &mut core::fmt::Formatter<'_>,
+ /// ) -> core::fmt::Result {
+ /// use core::fmt::Write as _;
+ ///
+ /// if f.alternate() {
+ /// return core::fmt::Debug::fmt(error, f);
+ /// }
+ ///
+ /// write!(f, "{}", error)?;
+ ///
+ /// Ok(())
+ /// }
+ /// }
+ /// ```
+ fn debug(
+ &self,
+ error: &(dyn Diagnostic),
+ f: &mut core::fmt::Formatter<'_>,
+ ) -> core::fmt::Result;
+
+ /// Override for the `Display` format
+ fn display(
+ &self,
+ error: &(dyn StdError + 'static),
+ f: &mut core::fmt::Formatter<'_>,
+ ) -> core::fmt::Result {
+ write!(f, "{}", error)?;
+
+ if f.alternate() {
+ for cause in crate::chain::Chain::new(error).skip(1) {
+ write!(f, ": {}", cause)?;
+ }
+ }
+
+ Ok(())
+ }
+
+ /// Store the location of the caller who constructed this error report
+ #[allow(unused_variables)]
+ fn track_caller(&mut self, location: &'static std::panic::Location<'static>) {}
+}
+
+/// type alias for `Result<T, Report>`
+///
+/// This is a reasonable return type to use throughout your application but also
+/// for `main()`. If you do, failures will be printed along with a backtrace if
+/// one was captured.
+///
+/// `miette::Result` may be used with one *or* two type parameters.
+///
+/// ```rust
+/// use miette::Result;
+///
+/// # const IGNORE: &str = stringify! {
+/// fn demo1() -> Result<T> {...}
+/// // ^ equivalent to std::result::Result<T, miette::Error>
+///
+/// fn demo2() -> Result<T, OtherError> {...}
+/// // ^ equivalent to std::result::Result<T, OtherError>
+/// # };
+/// ```
+///
+/// # Example
+///
+/// ```
+/// # pub trait Deserialize {}
+/// #
+/// # mod serde_json {
+/// # use super::Deserialize;
+/// # use std::io;
+/// #
+/// # pub fn from_str<T: Deserialize>(json: &str) -> io::Result<T> {
+/// # unimplemented!()
+/// # }
+/// # }
+/// #
+/// # #[derive(Debug)]
+/// # struct ClusterMap;
+/// #
+/// # impl Deserialize for ClusterMap {}
+/// #
+/// use miette::{IntoDiagnostic, Result};
+///
+/// fn main() -> Result<()> {
+/// # return Ok(());
+/// let config = std::fs::read_to_string("cluster.json").into_diagnostic()?;
+/// let map: ClusterMap = serde_json::from_str(&config).into_diagnostic()?;
+/// println!("cluster info: {:#?}", map);
+/// Ok(())
+/// }
+/// ```
+///
+/// ## `anyhow`/`eyre` Users
+///
+/// You can just replace `use`s of `anyhow::Result`/`eyre::Result` with
+/// `miette::Result`.
+pub type Result<T, E = Report> = core::result::Result<T, E>;
+
+/// Provides the [`wrap_err()`](WrapErr::wrap_err) method for [`Result`].
+///
+/// This trait is sealed and cannot be implemented for types outside of
+/// `miette`.
+///
+/// # Example
+///
+/// ```
+/// use miette::{WrapErr, IntoDiagnostic, Result};
+/// use std::{fs, path::PathBuf};
+///
+/// pub struct ImportantThing {
+/// path: PathBuf,
+/// }
+///
+/// impl ImportantThing {
+/// # const IGNORE: &'static str = stringify! {
+/// pub fn detach(&mut self) -> Result<()> {...}
+/// # };
+/// # fn detach(&mut self) -> Result<()> {
+/// # unimplemented!()
+/// # }
+/// }
+///
+/// pub fn do_it(mut it: ImportantThing) -> Result<Vec<u8>> {
+/// it.detach().wrap_err("Failed to detach the important thing")?;
+///
+/// let path = &it.path;
+/// let content = fs::read(path)
+/// .into_diagnostic()
+/// .wrap_err_with(|| format!(
+/// "Failed to read instrs from {}",
+/// path.display())
+/// )?;
+///
+/// Ok(content)
+/// }
+/// ```
+///
+/// When printed, the outermost error would be printed first and the lower
+/// level underlying causes would be enumerated below.
+///
+/// ```console
+/// Error: Failed to read instrs from ./path/to/instrs.json
+///
+/// Caused by:
+/// No such file or directory (os error 2)
+/// ```
+///
+/// # Wrapping Types That Do Not Implement `Error`
+///
+/// For example `&str` and `Box<dyn Error>`.
+///
+/// Due to restrictions for coherence `Report` cannot implement `From` for types
+/// that don't implement `Error`. Attempts to do so will give `"this type might
+/// implement Error in the future"` as an error. As such, `wrap_err()`, which
+/// uses `From` under the hood, cannot be used to wrap these types. Instead we
+/// encourage you to use the combinators provided for `Result` in `std`/`core`.
+///
+/// For example, instead of this:
+///
+/// ```rust,compile_fail
+/// use std::error::Error;
+/// use miette::{WrapErr, Report};
+///
+/// fn wrap_example(err: Result<(), Box<dyn Error + Send + Sync + 'static>>)
+/// -> Result<(), Report>
+/// {
+/// err.wrap_err("saw a downstream error")
+/// }
+/// ```
+///
+/// We encourage you to write this:
+///
+/// ```rust
+/// use miette::{miette, Report, WrapErr};
+/// use std::error::Error;
+///
+/// fn wrap_example(err: Result<(), Box<dyn Error + Send + Sync + 'static>>) -> Result<(), Report> {
+/// err.map_err(|e| miette!(e))
+/// .wrap_err("saw a downstream error")
+/// }
+/// ```
+///
+/// # Effect on Downcasting
+///
+/// After attaching a message of type `D` onto an error of type `E`, the
+/// resulting `miette::Error` may be downcast to `D` **or** to `E`.
+///
+/// That is, in codebases that rely on downcasting, `miette`'s `wrap_err()`
+/// supports both of the following use cases:
+///
+/// - **Attaching messages whose type is insignificant onto errors whose type
+/// is used in downcasts.**
+///
+/// In other error libraries whose `wrap_err()` is not designed this way, it
+/// can be risky to introduce messages to existing code because new message
+/// might break existing working downcasts. In miette, any downcast that
+/// worked before adding the message will continue to work after you add a
+/// message, so you should freely wrap errors wherever it would be helpful.
+///
+/// ```
+/// # use miette::bail;
+/// # use thiserror::Error;
+/// #
+/// # #[derive(Error, Debug)]
+/// # #[error("???")]
+/// # struct SuspiciousError;
+/// #
+/// # fn helper() -> Result<()> {
+/// # bail!(SuspiciousError);
+/// # }
+/// #
+/// use miette::{WrapErr, Result};
+///
+/// fn do_it() -> Result<()> {
+/// helper().wrap_err("Failed to complete the work")?;
+/// # const IGNORE: &str = stringify! {
+/// ...
+/// # };
+/// # unreachable!()
+/// }
+///
+/// fn main() {
+/// let err = do_it().unwrap_err();
+/// if let Some(e) = err.downcast_ref::<SuspiciousError>() {
+/// // If helper() returned SuspiciousError, this downcast will
+/// // correctly succeed even with the message in between.
+/// # return;
+/// }
+/// # panic!("expected downcast to succeed");
+/// }
+/// ```
+///
+/// - **Attaching message whose type is used in downcasts onto errors whose
+/// type is insignificant.**
+///
+/// Some codebases prefer to use machine-readable messages to categorize
+/// lower level errors in a way that will be actionable to higher levels of
+/// the application.
+///
+/// ```
+/// # use miette::bail;
+/// # use thiserror::Error;
+/// #
+/// # #[derive(Error, Debug)]
+/// # #[error("???")]
+/// # struct HelperFailed;
+/// #
+/// # fn helper() -> Result<()> {
+/// # bail!("no such file or directory");
+/// # }
+/// #
+/// use miette::{WrapErr, Result};
+///
+/// fn do_it() -> Result<()> {
+/// helper().wrap_err(HelperFailed)?;
+/// # const IGNORE: &str = stringify! {
+/// ...
+/// # };
+/// # unreachable!()
+/// }
+///
+/// fn main() {
+/// let err = do_it().unwrap_err();
+/// if let Some(e) = err.downcast_ref::<HelperFailed>() {
+/// // If helper failed, this downcast will succeed because
+/// // HelperFailed is the message that has been attached to
+/// // that error.
+/// # return;
+/// }
+/// # panic!("expected downcast to succeed");
+/// }
+/// ```
+pub trait WrapErr<T, E>: context::private::Sealed {
+ /// Wrap the error value with a new adhoc error
+ #[cfg_attr(track_caller, track_caller)]
+ fn wrap_err<D>(self, msg: D) -> Result<T, Report>
+ where
+ D: Display + Send + Sync + 'static;
+
+ /// Wrap the error value with a new adhoc error that is evaluated lazily
+ /// only once an error does occur.
+ #[cfg_attr(track_caller, track_caller)]
+ fn wrap_err_with<D, F>(self, f: F) -> Result<T, Report>
+ where
+ D: Display + Send + Sync + 'static,
+ F: FnOnce() -> D;
+
+ /// Compatibility re-export of `wrap_err()` for interop with `anyhow`
+ #[cfg_attr(track_caller, track_caller)]
+ fn context<D>(self, msg: D) -> Result<T, Report>
+ where
+ D: Display + Send + Sync + 'static;
+
+ /// Compatibility re-export of `wrap_err_with()` for interop with `anyhow`
+ #[cfg_attr(track_caller, track_caller)]
+ fn with_context<D, F>(self, f: F) -> Result<T, Report>
+ where
+ D: Display + Send + Sync + 'static,
+ F: FnOnce() -> D;
+}
+
+// Private API. Referenced by macro-generated code.
+#[doc(hidden)]
+pub mod private {
+ use super::Report;
+ use core::fmt::{Debug, Display};
+
+ pub use core::result::Result::Err;
+
+ #[doc(hidden)]
+ pub mod kind {
+ pub use super::super::kind::{AdhocKind, TraitKind};
+
+ pub use super::super::kind::BoxedKind;
+ }
+
+ #[cfg_attr(track_caller, track_caller)]
+ pub fn new_adhoc<M>(message: M) -> Report
+ where
+ M: Display + Debug + Send + Sync + 'static,
+ {
+ Report::from_adhoc(message)
+ }
+}