cvlr_log/
log.rs

1use crate::CvlrLogger;
2
3pub trait CvlrLog {
4    fn log(&self, tag: &str, logger: &mut CvlrLogger);
5}
6
7#[inline(always)]
8pub fn cvlr_log_with<T: CvlrLog>(tag: &str, val: &T, logger: &mut CvlrLogger) {
9    val.log(tag, logger);
10}
11
12#[inline(always)]
13pub fn cvlr_log<T: CvlrLog>(tag: &str, val: &T) {
14    let mut logger = CvlrLogger::new();
15    val.log(tag, &mut logger);
16}
17
18#[macro_export]
19macro_rules! cvlr_log {
20    () => {
21        $crate::log_loc(core::file!(), core::line!());
22    };
23
24    ($v:expr => $t:expr) => {
25        // TODO: enable when this becomes stable
26        // $crate::add_loc(core::file!(), core::line!());
27        $crate::cvlr_log($t, &($v));
28    };
29
30    ($v:expr => $t:expr ; $l:ident) => {
31        $crate::cvlr_log_with($t, &($v), $l)
32    };
33
34    ($v:expr $(,)?) => {
35        $crate::cvlr_log! { $v => stringify!($v) }
36    };
37
38    ($v:expr, $( $vs:expr ),+ $(,)?) => {
39        $crate::cvlr_log! { $v }
40        $crate::cvlr_log! { $( $vs ),+ }
41    };
42}
43
44pub use cvlr_log as clog;
45
46macro_rules! impl_cvlr_log_for_uint {
47    ($t:ty) => {
48        impl CvlrLog for $t {
49            #[inline(always)]
50            fn log(&self, tag: &str, logger: &mut CvlrLogger) {
51                logger.log_u64(tag, *self as u64);
52            }
53        }
54    };
55}
56
57impl_cvlr_log_for_uint!(bool);
58impl_cvlr_log_for_uint!(u8);
59impl_cvlr_log_for_uint!(u16);
60impl_cvlr_log_for_uint!(u32);
61impl_cvlr_log_for_uint!(u64);
62impl_cvlr_log_for_uint!(usize);
63
64impl CvlrLog for u128 {
65    #[inline(always)]
66    fn log(&self, tag: &str, logger: &mut CvlrLogger) {
67        logger.log_u128(tag, *self);
68    }
69}
70
71macro_rules! impl_cvlr_log_for_int {
72    ($t:ty) => {
73        impl CvlrLog for $t {
74            #[inline(always)]
75            fn log(&self, tag: &str, logger: &mut CvlrLogger) {
76                logger.log_i64(tag, *self as i64);
77            }
78        }
79    };
80}
81
82impl_cvlr_log_for_int!(i8);
83impl_cvlr_log_for_int!(i16);
84impl_cvlr_log_for_int!(i32);
85impl_cvlr_log_for_int!(i64);
86
87impl CvlrLog for i128 {
88    #[inline(always)]
89    fn log(&self, tag: &str, logger: &mut CvlrLogger) {
90        logger.log_i128(tag, *self);
91    }
92}
93
94impl<T: CvlrLog> CvlrLog for &T {
95    #[inline(always)]
96    fn log(&self, tag: &str, logger: &mut CvlrLogger) {
97        (**self).log(tag, logger);
98    }
99}
100
101impl CvlrLog for &str {
102    #[inline(always)]
103    fn log(&self, _tag: &str, logger: &mut CvlrLogger) {
104        logger.log(self);
105    }
106}
107
108impl CvlrLog for () {
109    #[inline(always)]
110    fn log(&self, tag: &str, logger: &mut CvlrLogger) {
111        logger.log_str(tag, "()");
112    }
113}
114
115impl<T: CvlrLog> CvlrLog for Option<T> {
116    #[inline(always)]
117    fn log(&self, tag: &str, logger: &mut CvlrLogger) {
118        if let Some(v) = self {
119            v.log(tag, logger);
120        } else {
121            logger.log_str(tag, "None");
122        }
123    }
124}
125
126impl<T: CvlrLog, E: CvlrLog> CvlrLog for Result<T, E> {
127    #[inline(always)]
128    fn log(&self, tag: &str, logger: &mut CvlrLogger) {
129        match self {
130            Ok(v) => {
131                logger.log("Ok");
132                v.log(tag, logger)
133            }
134            Err(v) => {
135                logger.log("Err");
136                v.log(tag, logger)
137            }
138        }
139    }
140}
141
142#[cfg(feature = "mathint")]
143impl CvlrLog for cvlr_mathint::NativeInt {
144    #[inline(always)]
145    fn log(&self, tag: &str, logger: &mut CvlrLogger) {
146        logger.log_u64(tag, self.as_internal());
147    }
148}
149
150/// Implements CvlrLog trait given a struct and a list of fields
151///
152/// Example usage
153/// ```
154/// use cvlr_log::impl_cvlr_log_for_struct;
155/// struct Foo {
156///     x: u64,
157///     y: u64,
158/// }
159/// impl_cvlr_log_for_struct!(Foo, x, y,);
160/// ```
161#[macro_export]
162macro_rules! impl_cvlr_log_for_struct {
163    ($prop:path $(, $field:ident)* $(,)?) => {
164        impl $crate::CvlrLog for $prop {
165            fn log(&self, tag: &str, logger: &mut $crate::CvlrLogger) {
166                logger.log_scope_start(tag);
167                let __self = self;
168                $(impl_cvlr_log_for_struct!(@field __self, logger, $field);)*
169                logger.log_scope_end(tag);
170            }
171        }
172    };
173
174    (@field $self:ident, $logger:ident, $field:ident) => {
175        $crate::cvlr_log_with(stringify!($field), &$self.$field, $logger);
176    };
177}
178
179pub use impl_cvlr_log_for_struct as impl_clog_for_struct;