flipperzero/furi/log/
mod.rs

1//! Furi Logging system.
2
3pub(crate) mod metadata;
4
5pub use metadata::{Level, LevelFilter};
6
7/// The standard logging macro.
8///
9/// This macro will generically log with the specified `Level` and `format!` based
10/// argument list.
11///
12/// # Examples
13///
14/// ```
15/// use flipperzero::{log, furi::log::Level};
16///
17/// # fn main() {
18/// let error_code = 42;
19///
20/// log!(Level::ERROR, "Failed to handle the florp: {}", error_code);
21/// log!(target: "events", Level::INFO, "Finished the documentation!");
22/// # }
23/// ```
24#[macro_export]
25macro_rules! log {
26    (target: $target:expr, $lvl:expr, $msg:expr $(, $arg:expr)*) => ({
27        // The `uwrite!` macro expects `ufmt` in scope
28        use $crate::__macro_support::ufmt;
29
30        if $lvl <= $crate::furi::log::LevelFilter::current() {
31            const TARGET: *const ::core::ffi::c_char =
32                match ::core::ffi::CStr::from_bytes_with_nul(
33                    ::core::concat!($target, "\0").as_bytes(),
34                ) {
35                    Ok(cstr) => cstr.as_ptr(),
36                    Err(_error) => panic!("target contains NULs"),
37                };
38
39            let mut buf = $crate::__macro_support::FuriString::new();
40            $crate::__macro_support::ufmt::uwrite!(&mut buf, $msg $(, $arg)*)
41                .expect("can append to FuriString");
42            // don't pass raw expression to the internal `unsafe` block
43            let lvl = $crate::__macro_support::__level_to_furi($lvl);
44            let buf = buf.as_c_ptr();
45            unsafe {
46                $crate::__macro_support::__sys::furi_log_print_format(lvl, TARGET, buf);
47            };
48        }
49    });
50
51    ($lvl:expr, $msg:expr $(, $arg:expr)*) => (
52        $crate::log!(target: module_path!(), $lvl, $msg $(, $arg)*)
53    );
54}
55
56/// Logs a message at the error level.
57///
58/// # Examples
59///
60/// ```
61/// use flipperzero::error;
62///
63/// # fn main() {
64/// let error_code = 42;
65/// let name = "Flipper";
66///
67/// error!("Failed to handle the florp: {}", error_code);
68/// error!(target: "events", "Missed birthday party for {}", name);
69/// # }
70/// ```
71#[macro_export]
72macro_rules! error {
73    (target: $target:expr, $msg:expr $(, $arg:expr)*) => (
74        $crate::log!(target: $target, $crate::furi::log::Level::ERROR, $msg $(, $arg)*)
75    );
76
77    ($msg:expr $(, $arg:expr)*) => (
78        $crate::log!($crate::furi::log::Level::ERROR, $msg $(, $arg)*)
79    );
80}
81
82/// Logs a message at the warn level.
83///
84/// # Examples
85///
86/// ```
87/// use flipperzero::warn;
88///
89/// # fn main() {
90/// let name = "Flipper";
91///
92/// warn!("Event almost started!");
93/// warn!(target: "events", "About to miss the birthday party for {}", name);
94/// # }
95/// ```
96#[macro_export]
97macro_rules! warn {
98    (target: $target:expr, $msg:expr $(, $arg:expr)*) => (
99        $crate::log!(target: $target, $crate::furi::log::Level::WARN, $msg $(, $arg)*)
100    );
101
102    ($msg:expr $(, $arg:expr)*) => (
103        $crate::log!($crate::furi::log::Level::WARN, $msg $(, $arg)*)
104    );
105}
106
107/// Logs a message at the info level.
108///
109/// # Examples
110///
111/// ```
112/// use flipperzero::info;
113///
114/// # fn main() {
115/// let name = "Flipper";
116///
117/// info!("It's {}'s birthday today!", name);
118/// info!(target: "events", "Birthday party today: {}", name);
119/// # }
120/// ```
121#[macro_export]
122macro_rules! info {
123    (target: $target:expr, $msg:expr $(, $arg:expr)*) => (
124        $crate::log!(target: $target, $crate::furi::log::Level::INFO, $msg $(, $arg)*)
125    );
126
127    ($msg:expr $(, $arg:expr)*) => (
128        $crate::log!($crate::furi::log::Level::INFO, $msg $(, $arg)*)
129    );
130}
131
132/// Logs a message at the debug level.
133///
134/// # Examples
135///
136/// ```
137/// use flipperzero::debug;
138///
139/// # fn main() {
140/// let name = "Flipper";
141///
142/// debug!("Creating {} event", 1);
143/// debug!(target: "events", "New event created: birthday party for {}", name);
144/// # }
145/// ```
146#[macro_export]
147macro_rules! debug {
148    (target: $target:expr, $msg:expr $(, $arg:expr)*) => (
149        $crate::log!(target: $target, $crate::furi::log::Level::DEBUG, $msg $(, $arg)*)
150    );
151
152    ($msg:expr $(, $arg:expr)*) => (
153        $crate::log!($crate::furi::log::Level::DEBUG, $msg $(, $arg)*)
154    );
155}
156
157/// Logs a message at the trace level.
158///
159/// # Examples
160///
161/// ```
162/// use flipperzero::trace;
163///
164/// # fn main() {
165/// let name = "Flipper";
166///
167/// trace!("About to show how the target field works");
168/// trace!(target: "events", "Scanning for events involving {}", name);
169/// # }
170/// ```
171#[macro_export]
172macro_rules! trace {
173    (target: $target:expr, $msg:expr $(, $arg:expr)*) => (
174        $crate::log!(target: $target, $crate::furi::log::Level::TRACE, $msg $(, $arg)*)
175    );
176
177    ($msg:expr $(, $arg:expr)*) => (
178        $crate::log!($crate::furi::log::Level::TRACE, $msg $(, $arg)*)
179    );
180}