use core::fmt::{Display, Formatter};
use proc_macro2::Span;
use thiserror::Error;
pub type Result<T> = core::result::Result<T, SecureFmtError>;
#[derive(Error, Debug)]
pub struct SecureFmtError {
pub call_site: Span,
pub message: String,
}
impl Display for SecureFmtError {
fn fmt(&self, f: &mut Formatter<'_>) -> core::fmt::Result {
write!(f, "{}", self.message)
}
}
macro_rules! secure_fmt_error {
($call_site:expr, $($arg:tt)+) => {{
let message = std::fmt::format(std::format_args!($($arg)*));
Err($crate::errors::SecureFmtError { call_site: $call_site, message })
}}
}
#[cfg(test)]
mod tests {
use super::Result;
use pretty_assertions::assert_eq;
use proc_macro2::Span;
#[test]
fn should_create_secure_fmt_error_with_message() {
let result: Result<()> = secure_fmt_error!(Span::call_site(), "Bad stuff: {}", 42);
let err = result.expect_err("Should have been an error");
assert_eq!(
format!("{:?}", err.call_site),
format!("{:?}", Span::call_site())
);
assert_eq!(err.message, "Bad stuff: 42");
}
}