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 $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#[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;