1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166
// Copyright Ⓒ 2019 David Kellum // // These _-v_ macros were co-developed with // https://github.com/rust-lang-nursery/log/pull/316 (by the same author) // // All original _log_ source is offered under the same Apache 2.0 or MIT // licenses, and is: // Copyright Ⓒ 2015 The Rust Project Developers /// Log a message at the error level, flush the logger, and then use the same /// message to panic. /// /// This will duplicate the message, once via the registered logger, then /// again via stderr for the panic (default handler). Since this is a fatal /// and presumably serious condition, potential duplication is of less concern /// than the risk of missing the message. This will always `panic!`, even if /// no logger is configured, or if error level messages aren't logged. /// /// # Example /// /// ```rust,should_panic /// # use std::time::{Duration, Instant}; /// use tao_log::fatal; /// /// # let td = Duration::new(0, 100_000_000); /// fatal!("shields compromised, core breach in {:?}!", td); /// // ^1 -- error level message: shields compromised, core breach in 100ms! /// // ^2 -- panic: shields compromised, core breach in 100ms! /// ``` #[macro_export] macro_rules! fatal { (target: $target:expr, $($arg:tt)+) => ( $crate::__tao_fatal!($target, $($arg)+) ); ($($arg:tt)+) => ( $crate::__tao_fatal!(module_path!(), $($arg)+) ); } /// Log an expression and its value at any specified level. /// /// Logs with the optional or default (module path of use) target, specified /// `Level`, optional prefix, and optional or default (`"{:?}"`) value format /// string, and a single expression. The expression argument is evaluated /// exactly once, regardless of if the logging level is enabled, and its /// value is returned from the macro. This is normally only used through the /// _-v_ macros like `debugv!` or `tracev!`. /// /// Note that the value is moved and then returned. If the type does not /// implement `Copy`, ownership may be retained by borrowing by reference /// e.g. `debugv!(&expr)`. /// /// # Examples /// /// ```rust /// use tao_log::*; /// /// #[derive(Debug)] /// struct Point { x: f32, y: f32 } /// /// fn circle(center: &Point, radius: f32) { /*...*/ } /// /// # fn main() { /// let center = Point { x: 3.234, y: -1.223 }; /// /// circle(logv!(log::Level::Trace, ¢er), 7.3); /// // ^-- trace level message: "¢er → Point { x: 3.234, y: -1.223 }" /// circle(tracev!(¢er), 8.0); /// // ^-- trace level message: "¢er → Point { x: 3.234, y: -1.223 }" /// # } /// ``` #[macro_export] macro_rules! logv { (target: $target:expr, $lvl:expr, $($arg:tt)+) => ( $crate::__tao_logv!($lvl, target: $target, $($arg)+) ); ($lvl:expr, $($arg:tt)+) => ( $crate::__tao_logv!($lvl, target: module_path!(), $($arg)+) ); } /// Log an expression at the error level, returning its value. #[macro_export] macro_rules! errorv { ($($arg:tt)+) => ($crate::__tao_logv!($crate::log::Level::Error, $($arg)+)) } /// Log an expression at the warn level, returning its value. #[macro_export] macro_rules! warnv { ($($arg:tt)+) => ($crate::__tao_logv!($crate::log::Level::Warn, $($arg)+)) } /// Log an expression at the info level, returning its value. #[macro_export] macro_rules! infov { ($($arg:tt)+) => ($crate::__tao_logv!($crate::log::Level::Info, $($arg)+)) } /// Log an expression at the debug level, returning its value. #[macro_export] macro_rules! debugv { ($($arg:tt)+) => ($crate::__tao_logv!($crate::log::Level::Debug, $($arg)+)) } /// Log an expression at the trace level, returning its value. #[macro_export] macro_rules! tracev { ($($arg:tt)+) => ($crate::__tao_logv!($crate::log::Level::Trace, $($arg)+)) } // Helper macro for `fatal!` #[doc(hidden)] #[macro_export] macro_rules! __tao_fatal { ($target:expr, $($arg:tt)+) => ( match format_args!($($arg)+) { args => { $crate::error!(target: $target, "{}", args); $crate::log::logger().flush(); panic!("{}", args); } } ); } // Helper macro for the -v macros, handling the permutations of optional // parameters. Note: The required level parameter is first here for // convenience of internal use with variable-args. #[doc(hidden)] #[macro_export] macro_rules! __tao_logv { ($lvl:expr, target: $tgt:expr, $pre:expr, $vfmt:expr, $exp:expr $(,)?) => ( $crate::__tao_v_eval!($tgt, $lvl, concat!($pre, " {} → ", $vfmt), $exp) ); ($lvl:expr, target: $tgt:expr, $pre:expr, $exp:expr $(,)?) => ( $crate::__tao_v_eval!($tgt, $lvl, concat!($pre, " {} → {:?}"), $exp) ); ($lvl:expr, target: $tgt:expr, $exp:expr $(,)?) => ( $crate::__tao_v_eval!($tgt, $lvl, "{} → {:?}", $exp) ); ($lvl:expr, $pre:expr, $vfmt:expr, $exp:expr $(,)?) => ( $crate::__tao_v_eval!(module_path!(), $lvl, concat!($pre, " {} → ", $vfmt), $exp) ); ($lvl:expr, $pre:expr, $exp:expr $(,)?) => ( $crate::__tao_v_eval!(module_path!(), $lvl, concat!($pre, " {} → {:?}"), $exp) ); ($lvl:expr, $exp:expr $(,)?) => ( $crate::__tao_v_eval!(module_path!(), $lvl, "{} → {:?}", $exp) ); } // Inner helper macro for __tao_logv. Evaluates expression exactly once, moves // value and returns it. #[doc(hidden)] #[macro_export] macro_rules! __tao_v_eval { ($tgt:expr, $lvl:expr, $fmt:expr, $exp:expr) => ( match $exp { vt => { $crate::log!(target: $tgt, $lvl, $fmt, stringify!($exp), &vt); vt } } ) }