//! Keyfork Bug Reporting Utilities. //! //! # Examples //! //! ```rust //! use std::{fs::File, io::Write}; //! use keyfork_bug as bug; //! //! let option = Some("hello world!"); //! let value = option.expect(bug::bug!("missing str value!")); //! //! let mut output_file = File::create("/dev/null").expect(bug::bug!("can't open /dev/null")); //! output_file //! .write_all(value.as_bytes()) //! .unwrap_or_else(bug::panic!("Can't write to file: {}", value)); //! ``` //! //! ```rust,should_panic //! use std::fs::File; //! use keyfork_bug as bug; //! //! let mut output_file = File::open("/dev/nukk").expect(bug::bug!("can't open /dev/null")); //! ``` /// The mutex was poisoned and is unusable. pub const POISONED_MUTEX: &str = "The mutex was poisoned and is unusable"; /// Automatically generate a bug report message for Keyfork. This macro is intended to use when /// using `Result::expect()` or `Option::expect()` to retrieve information about the callsite where /// the bug was located. /// /// # Examples /// ```rust /// use keyfork_bug::bug; /// /// let option = Some(0u32); /// let value = option.expect(bug!("missing u32 value!")); /// ``` /// /// ```rust /// use keyfork_bug::bug; /// /// let error_message = "This is a really long error message that should not be in the macro."; /// let option = Some(0u32); /// let value = option.expect(bug!(error_message)); /// ``` /// /// ```rust,should_panic /// use keyfork_bug::bug; /// /// let option: Option = None; /// let value = option.expect(bug!("missing u32 value!")); /// ``` #[macro_export] macro_rules! bug { ($input:literal) => { concat!( "Keyfork encountered a BUG at: [", file!(), ":", line!(), ":", column!(), "]: ", $input, "\n\nReport this bug to , this behavior is unexpected!" ) }; ($input:ident) => { format!( concat!("Keyfork encountered a BUG at: [{file}:{line}:{column}]: {input}\n\n", "Report this bug to , this behavior is unexpected!" ), file=file!(), line=line!(), column=column!(), input=$input, ).as_str() }; ($($arg:tt)*) => {{ let message = format!($($arg)*); $crate::bug!(message) }}; } /// Return a closure that, when called, panics with a bug report message for Keyfork. Returning a /// closure can help handle the `clippy::expect_fun_call` lint. The closure accepts an error /// argument, so it is suitable for being used with [`Result`] types instead of [`Option`] types. /// /// # Examples /// ```rust /// use std::fs::File; /// use keyfork_bug as bug; /// /// let file = File::open("/dev/null").unwrap_or_else(bug::panic!("couldn't open /dev/null")); /// ``` #[macro_export] macro_rules! panic { ($input:literal) => { |e| { std::panic!("{}\n{}", $crate::bug!($input), e) }}; ($input:ident) => { |e| { std::panic!("{}\n{}", $crate::bug!($input), e) }}; ($($arg:tt)*) => { |e| { std::panic!("{}\n{}", $crate::bug!($($arg)*), e) }}; }