aboutsummaryrefslogtreecommitdiff
path: root/src/log.rs
blob: d25d2105b6cf77ea1e6619bfd07ad32e7a5cfd14 (plain)
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
//! Logging abstraction that works with both defmt and tracing.
//!
//! This module provides logging macros that can use either `defmt` (for embedded targets)
//! or `tracing` (for desktop/testing) depending on the enabled cargo features.
//!
//! ## Features
//!
//! - `defmt`: Use defmt for logging
//! - `tracing`: Use tracing for logging
//! - Neither: Logging is compiled out (no-op)
//!
//! ## Usage
//!
//! ```rust,ignore
//! use crate::log::{trace, debug, info, warn, error};
//!
//! info!("Application started");
//! debug!("Value: {}", 42);
//! warn!("Something unexpected: {:?}", some_value);
//! ```

// Re-export Format trait when using defmt
#[cfg(feature = "defmt")]
pub use defmt::Format;

// For tracing or no logging, we provide a stub Format trait
#[cfg(not(feature = "defmt"))]
pub trait Format {}

// When using defmt, also provide Debug2Format for std types
#[cfg(feature = "defmt")]
pub use defmt::Debug2Format;

// For tracing or no logging, Debug2Format is a passthrough
#[cfg(not(feature = "defmt"))]
#[inline]
pub fn Debug2Format<T>(value: &T) -> &T {
    value
}

// Logging macros that dispatch to the appropriate backend or no-op
// If both features are enabled, defmt takes precedence

#[macro_export]
macro_rules! trace {
    ($($arg:tt)*) => {
        #[cfg(feature = "defmt")]
        defmt::trace!($($arg)*);

        #[cfg(all(feature = "tracing", not(feature = "defmt")))]
        tracing::trace!($($arg)*);

        #[cfg(not(any(feature = "defmt", feature = "tracing")))]
        { let _ = (); } // no-op
    };
}

#[macro_export]
macro_rules! debug {
    ($($arg:tt)*) => {
        #[cfg(feature = "defmt")]
        defmt::debug!($($arg)*);

        #[cfg(all(feature = "tracing", not(feature = "defmt")))]
        tracing::debug!($($arg)*);

        #[cfg(not(any(feature = "defmt", feature = "tracing")))]
        { let _ = (); } // no-op
    };
}

#[macro_export]
macro_rules! info {
    ($($arg:tt)*) => {
        #[cfg(feature = "defmt")]
        defmt::info!($($arg)*);

        #[cfg(all(feature = "tracing", not(feature = "defmt")))]
        tracing::info!($($arg)*);

        #[cfg(not(any(feature = "defmt", feature = "tracing")))]
        { let _ = (); } // no-op
    };
}

#[macro_export]
macro_rules! warn {
    ($($arg:tt)*) => {
        #[cfg(feature = "defmt")]
        defmt::warn!($($arg)*);

        #[cfg(all(feature = "tracing", not(feature = "defmt")))]
        tracing::warn!($($arg)*);

        #[cfg(not(any(feature = "defmt", feature = "tracing")))]
        { let _ = (); } // no-op
    };
}

#[macro_export]
macro_rules! error {
    ($($arg:tt)*) => {
        #[cfg(feature = "defmt")]
        defmt::error!($($arg)*);

        #[cfg(all(feature = "tracing", not(feature = "defmt")))]
        tracing::error!($($arg)*);

        #[cfg(not(any(feature = "defmt", feature = "tracing")))]
        { let _ = (); } // no-op
    };
}

// Re-export the macros at the module level for easier use
pub use crate::{debug, error, info, trace, warn};