From 1b6a04ca5504955c571d1c97504fb45ea0befee4 Mon Sep 17 00:00:00 2001 From: Valentin Popov Date: Mon, 8 Jan 2024 01:21:28 +0400 Subject: Initial vendor packages Signed-off-by: Valentin Popov --- vendor/miette/src/panic.rs | 86 ++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 86 insertions(+) create mode 100644 vendor/miette/src/panic.rs (limited to 'vendor/miette/src/panic.rs') diff --git a/vendor/miette/src/panic.rs b/vendor/miette/src/panic.rs new file mode 100644 index 0000000..ad98cac --- /dev/null +++ b/vendor/miette/src/panic.rs @@ -0,0 +1,86 @@ +use backtrace::Backtrace; +use thiserror::Error; + +use crate::{self as miette, Context, Diagnostic, Result}; + +/// Tells miette to render panics using its rendering engine. +pub fn set_panic_hook() { + std::panic::set_hook(Box::new(move |info| { + let mut message = "Something went wrong".to_string(); + let payload = info.payload(); + if let Some(msg) = payload.downcast_ref::<&str>() { + message = msg.to_string(); + } + if let Some(msg) = payload.downcast_ref::() { + message = msg.clone(); + } + let mut report: Result<()> = Err(Panic(message).into()); + if let Some(loc) = info.location() { + report = report + .with_context(|| format!("at {}:{}:{}", loc.file(), loc.line(), loc.column())); + } + if let Err(err) = report.with_context(|| "Main thread panicked.".to_string()) { + eprintln!("Error: {:?}", err); + } + })); +} + +#[derive(Debug, Error, Diagnostic)] +#[error("{0}{}", Panic::backtrace())] +#[diagnostic(help("set the `RUST_BACKTRACE=1` environment variable to display a backtrace."))] +struct Panic(String); + +impl Panic { + fn backtrace() -> String { + use std::fmt::Write; + if let Ok(var) = std::env::var("RUST_BACKTRACE") { + if !var.is_empty() && var != "0" { + const HEX_WIDTH: usize = std::mem::size_of::() + 2; + // Padding for next lines after frame's address + const NEXT_SYMBOL_PADDING: usize = HEX_WIDTH + 6; + let mut backtrace = String::new(); + let trace = Backtrace::new(); + let frames = backtrace_ext::short_frames_strict(&trace).enumerate(); + for (idx, (frame, sub_frames)) in frames { + let ip = frame.ip(); + let _ = write!(backtrace, "\n{:4}: {:2$?}", idx, ip, HEX_WIDTH); + + let symbols = frame.symbols(); + if symbols.is_empty() { + let _ = write!(backtrace, " - "); + continue; + } + + for (idx, symbol) in symbols[sub_frames].iter().enumerate() { + // Print symbols from this address, + // if there are several addresses + // we need to put it on next line + if idx != 0 { + let _ = write!(backtrace, "\n{:1$}", "", NEXT_SYMBOL_PADDING); + } + + if let Some(name) = symbol.name() { + let _ = write!(backtrace, " - {}", name); + } else { + let _ = write!(backtrace, " - "); + } + + // See if there is debug information with file name and line + if let (Some(file), Some(line)) = (symbol.filename(), symbol.lineno()) { + let _ = write!( + backtrace, + "\n{:3$}at {}:{}", + "", + file.display(), + line, + NEXT_SYMBOL_PADDING + ); + } + } + } + return backtrace; + } + } + "".into() + } +} -- cgit v1.2.3