support field values in err! macro
Signed-off-by: Jason Volk <jason@zemos.net>
This commit is contained in:
parent
5b1642f641
commit
5add9a8c34
4 changed files with 127 additions and 31 deletions
|
@ -14,7 +14,7 @@ pub use crate::utils::debug::*;
|
|||
#[macro_export]
|
||||
macro_rules! debug_event {
|
||||
( $level:expr, $($x:tt)+ ) => {
|
||||
if cfg!(debug_assertions) && cfg!(not(feature = "dev_release_log_level")) {
|
||||
if $crate::debug::logging() {
|
||||
::tracing::event!( $level, $($x)+ )
|
||||
} else {
|
||||
::tracing::debug!( $($x)+ )
|
||||
|
@ -88,3 +88,7 @@ pub fn panic_str(p: &Box<dyn Any + Send>) -> &'static str { p.downcast_ref::<&st
|
|||
#[inline(always)]
|
||||
#[must_use]
|
||||
pub fn type_name<T>(_: &T) -> &'static str { std::any::type_name::<T>() }
|
||||
|
||||
#[must_use]
|
||||
#[inline]
|
||||
pub const fn logging() -> bool { cfg!(debug_assertions) && cfg!(not(feature = "dev_release_log_level")) }
|
||||
|
|
|
@ -41,60 +41,149 @@ macro_rules! Err {
|
|||
|
||||
#[macro_export]
|
||||
macro_rules! err {
|
||||
(Config($item:literal, $($args:expr),*)) => {{
|
||||
$crate::error!(config = %$item, $($args),*);
|
||||
$crate::error::Error::Config($item, $crate::format_maybe!($($args),*))
|
||||
}};
|
||||
|
||||
(Request(Forbidden($level:ident!($($args:expr),*)))) => {{
|
||||
$crate::$level!($($args),*);
|
||||
(Request(Forbidden($level:ident!($($args:tt)+)))) => {{
|
||||
let mut buf = String::new();
|
||||
$crate::error::Error::Request(
|
||||
::ruma::api::client::error::ErrorKind::forbidden(),
|
||||
$crate::format_maybe!($($args),*),
|
||||
$crate::err_log!(buf, $level, $($args)+),
|
||||
::http::StatusCode::BAD_REQUEST
|
||||
)
|
||||
}};
|
||||
|
||||
(Request(Forbidden($($args:expr),*))) => {
|
||||
(Request(Forbidden($($args:tt)+))) => {
|
||||
$crate::error::Error::Request(
|
||||
::ruma::api::client::error::ErrorKind::forbidden(),
|
||||
$crate::format_maybe!($($args),*),
|
||||
$crate::format_maybe!($($args)+),
|
||||
::http::StatusCode::BAD_REQUEST
|
||||
)
|
||||
};
|
||||
|
||||
(Request($variant:ident($level:ident!($($args:expr),*)))) => {{
|
||||
$crate::$level!($($args),*);
|
||||
(Request($variant:ident($level:ident!($($args:tt)+)))) => {{
|
||||
let mut buf = String::new();
|
||||
$crate::error::Error::Request(
|
||||
::ruma::api::client::error::ErrorKind::$variant,
|
||||
$crate::format_maybe!($($args),*),
|
||||
$crate::err_log!(buf, $level, $($args)+),
|
||||
::http::StatusCode::BAD_REQUEST
|
||||
)
|
||||
}};
|
||||
|
||||
(Request($variant:ident($($args:expr),*))) => {
|
||||
(Request($variant:ident($($args:tt)+))) => {
|
||||
$crate::error::Error::Request(
|
||||
::ruma::api::client::error::ErrorKind::$variant,
|
||||
$crate::format_maybe!($($args),*),
|
||||
$crate::format_maybe!($($args)+),
|
||||
::http::StatusCode::BAD_REQUEST
|
||||
)
|
||||
};
|
||||
|
||||
($variant:ident($level:ident!($($args:expr),*))) => {{
|
||||
$crate::$level!($($args),*);
|
||||
$crate::error::Error::$variant($crate::format_maybe!($($args),*))
|
||||
(Config($item:literal, $($args:tt)+)) => {{
|
||||
let mut buf = String::new();
|
||||
$crate::error::Error::Config($item, $crate::err_log!(buf, error, config = %$item, $($args)+))
|
||||
}};
|
||||
|
||||
($variant:ident($($args:expr),*)) => {
|
||||
$crate::error::Error::$variant($crate::format_maybe!($($args),*))
|
||||
($variant:ident($level:ident!($($args:tt)+))) => {{
|
||||
let mut buf = String::new();
|
||||
$crate::error::Error::$variant($crate::err_log!(buf, $level, $($args)+))
|
||||
}};
|
||||
|
||||
($variant:ident($($args:tt)+)) => {
|
||||
$crate::error::Error::$variant($crate::format_maybe!($($args)+))
|
||||
};
|
||||
|
||||
($level:ident!($($args:expr),*)) => {{
|
||||
$crate::$level!($($args),*);
|
||||
$crate::error::Error::Err($crate::format_maybe!($($args),*))
|
||||
($level:ident!($($args:tt)+)) => {{
|
||||
let mut buf = String::new();
|
||||
$crate::error::Error::Err($crate::err_log!(buf, $level, $($args)+))
|
||||
}};
|
||||
|
||||
($($args:expr),*) => {
|
||||
$crate::error::Error::Err($crate::format_maybe!($($args),*))
|
||||
($($args:tt)+) => {
|
||||
$crate::error::Error::Err($crate::format_maybe!($($args)+))
|
||||
};
|
||||
}
|
||||
|
||||
/// A trinity of integration between tracing, logging, and Error. This is a
|
||||
/// customization of tracing::event! with the primary purpose of sharing the
|
||||
/// error string, fieldset parsing and formatting. An added benefit is that we
|
||||
/// can share the same callsite metadata for the source of our Error and the
|
||||
/// associated logging and tracing event dispatches.
|
||||
#[macro_export]
|
||||
macro_rules! err_log {
|
||||
($out:ident, $level:ident, $($fields:tt)+) => {{
|
||||
use std::{fmt, fmt::Write};
|
||||
|
||||
use ::tracing::{
|
||||
callsite, callsite2, level_enabled, metadata, valueset, Callsite, Event, __macro_support,
|
||||
__tracing_log,
|
||||
field::{Field, ValueSet, Visit},
|
||||
Level,
|
||||
};
|
||||
|
||||
const LEVEL: Level = $crate::err_lev!($level);
|
||||
static __CALLSITE: callsite::DefaultCallsite = callsite2! {
|
||||
name: std::concat! {
|
||||
"event ",
|
||||
std::file!(),
|
||||
":",
|
||||
std::line!(),
|
||||
},
|
||||
kind: metadata::Kind::EVENT,
|
||||
target: std::module_path!(),
|
||||
level: LEVEL,
|
||||
fields: $($fields)+,
|
||||
};
|
||||
|
||||
let visit = &mut |vs: ValueSet<'_>| {
|
||||
struct Visitor<'a>(&'a mut String);
|
||||
impl Visit for Visitor<'_> {
|
||||
fn record_debug(&mut self, field: &Field, val: &dyn fmt::Debug) {
|
||||
if field.name() == "message" {
|
||||
write!(self.0, "{:?}", val).expect("stream error");
|
||||
} else {
|
||||
write!(self.0, " {}={:?}", field.name(), val).expect("stream error");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
let meta = __CALLSITE.metadata();
|
||||
let enabled = level_enabled!(LEVEL) && {
|
||||
let interest = __CALLSITE.interest();
|
||||
!interest.is_never() && __macro_support::__is_enabled(meta, interest)
|
||||
};
|
||||
|
||||
if enabled {
|
||||
Event::dispatch(meta, &vs);
|
||||
}
|
||||
|
||||
__tracing_log!(LEVEL, __CALLSITE, &vs);
|
||||
vs.record(&mut Visitor(&mut $out));
|
||||
};
|
||||
|
||||
(visit)(valueset!(__CALLSITE.metadata().fields(), $($fields)+));
|
||||
($out).into()
|
||||
}}
|
||||
}
|
||||
|
||||
#[macro_export]
|
||||
macro_rules! err_lev {
|
||||
(debug_warn) => {
|
||||
if $crate::debug::logging() {
|
||||
::tracing::Level::WARN
|
||||
} else {
|
||||
::tracing::Level::DEBUG
|
||||
}
|
||||
};
|
||||
|
||||
(debug_error) => {
|
||||
if $crate::debug::logging() {
|
||||
::tracing::Level::ERROR
|
||||
} else {
|
||||
::tracing::Level::DEBUG
|
||||
}
|
||||
};
|
||||
|
||||
(warn) => {
|
||||
::tracing::Level::WARN
|
||||
};
|
||||
|
||||
(error) => {
|
||||
::tracing::Level::ERROR
|
||||
};
|
||||
}
|
||||
|
|
|
@ -5,8 +5,7 @@ mod response;
|
|||
|
||||
use std::{any::Any, borrow::Cow, convert::Infallible, fmt};
|
||||
|
||||
pub use log::*;
|
||||
|
||||
pub use self::log::*;
|
||||
use crate::error;
|
||||
|
||||
#[derive(thiserror::Error)]
|
||||
|
|
|
@ -8,12 +8,12 @@ pub const EMPTY: &str = "";
|
|||
/// arguments are provided the first is assumed to be a format string.
|
||||
#[macro_export]
|
||||
macro_rules! format_maybe {
|
||||
($s:literal) => {
|
||||
($s:literal $(,)?) => {
|
||||
if $crate::is_format!($s) { std::format!($s).into() } else { $s.into() }
|
||||
};
|
||||
|
||||
($($args:expr),*) => {
|
||||
std::format!($($args),*).into()
|
||||
($s:literal, $($args:tt)+) => {
|
||||
std::format!($s, $($args)+).into()
|
||||
};
|
||||
}
|
||||
|
||||
|
@ -24,6 +24,10 @@ macro_rules! is_format {
|
|||
($s:literal) => {
|
||||
::const_str::contains!($s, "{") && ::const_str::contains!($s, "}")
|
||||
};
|
||||
|
||||
($($s:tt)+) => {
|
||||
false
|
||||
};
|
||||
}
|
||||
|
||||
#[inline]
|
||||
|
|
Loading…
Add table
Reference in a new issue