Skip to content

Commit 66de3db

Browse files
committed
defmt
1 parent 13ee557 commit 66de3db

File tree

43 files changed

+3020
-225
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

43 files changed

+3020
-225
lines changed

Cargo.toml

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,8 @@ async-io-mini = ["std", "edge-nal-std/async-io-mini"]
1717
std = ["io", "edge-captive/std", "edge-dhcp/std", "edge-http/std", "edge-mdns/std", "edge-raw/std", "edge-mqtt", "edge-ws/std", "edge-nal-std"]
1818
embassy = ["io", "edge-nal-embassy"]
1919
io = ["edge-captive/io", "edge-dhcp/io", "edge-http/io", "edge-mdns/io", "edge-raw/io", "edge-ws/io", "edge-nal"]
20+
log = ["edge-captive/log", "edge-dhcp/log", "edge-http/log", "edge-mdns/log", "edge-raw/log", "edge-ws/log", "edge-nal-embassy?/log"]
21+
defmt = ["edge-captive/defmt", "edge-dhcp/defmt", "edge-http/defmt", "edge-mdns/defmt", "edge-raw/defmt", "edge-ws/defmt", "edge-nal-embassy?/defmt"]
2022
embedded-svc = ["edge-http/embedded-svc", "edge-mqtt/embedded-svc", "edge-ws/embedded-svc"]
2123
nightly = []
2224

@@ -111,7 +113,6 @@ embassy-sync = { version = "0.6", default-features = false }
111113
embassy-time = { version = "0.4", default-features = false }
112114
embedded-io-async = { version = "0.6", default-features = false }
113115
embedded-svc = { version = "0.28", default-features = false }
114-
log = { version = "0.4", default-features = false }
115116
heapless = { version = "0.8", default-features = false }
116117
domain = { version = "0.10", default-features = false, features = ["heapless"] }
117118

edge-captive/Cargo.toml

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ std = ["io"]
2020
io = ["edge-nal"]
2121

2222
[dependencies]
23-
log = { workspace = true }
23+
log = { version = "0.4", default-features = false, optional = true }
24+
defmt = { version = "0.3", optional = true }
2425
domain = { workspace = true }
2526
edge-nal = { workspace = true, optional = true }

edge-captive/src/fmt.rs

Lines changed: 340 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,340 @@
1+
//! A module that re-exports the `log` macros if `defmt` is not enabled, or `defmt` macros if `defmt` is enabled.
2+
//!
3+
//! The module also defines:
4+
//! - Custom versions of the core assert macros (`assert!`, `assert_eq!`, etc.) that use the `defmt` macros if the `defmt` feature is enabled.
5+
//! - Custom versions of the `panic!`, `todo!`, and `unreachable!` macros that use the `defmt` macros if the `defmt` feature is enabled.
6+
//! - A custom `unwrap!` macro that uses the `defmt` macros if the `defmt` feature is enabled, otherwise it uses the standard library's `unwrap` method.
7+
//! - A custom `Bytes` struct that formats byte slices as hex in a way compatible with `defmt`.
8+
#![macro_use]
9+
#![allow(unused)]
10+
11+
use core::fmt::{Debug, Display, LowerHex};
12+
13+
#[collapse_debuginfo(yes)]
14+
macro_rules! assert {
15+
($($x:tt)*) => {
16+
{
17+
#[cfg(not(feature = "defmt"))]
18+
::core::assert!($($x)*);
19+
#[cfg(feature = "defmt")]
20+
::defmt::assert!($($x)*);
21+
}
22+
};
23+
}
24+
25+
#[collapse_debuginfo(yes)]
26+
macro_rules! assert_eq {
27+
($($x:tt)*) => {
28+
{
29+
#[cfg(not(feature = "defmt"))]
30+
::core::assert_eq!($($x)*);
31+
#[cfg(feature = "defmt")]
32+
::defmt::assert_eq!($($x)*);
33+
}
34+
};
35+
}
36+
37+
#[collapse_debuginfo(yes)]
38+
macro_rules! assert_ne {
39+
($($x:tt)*) => {
40+
{
41+
#[cfg(not(feature = "defmt"))]
42+
::core::assert_ne!($($x)*);
43+
#[cfg(feature = "defmt")]
44+
::defmt::assert_ne!($($x)*);
45+
}
46+
};
47+
}
48+
49+
#[collapse_debuginfo(yes)]
50+
macro_rules! debug_assert {
51+
($($x:tt)*) => {
52+
{
53+
#[cfg(not(feature = "defmt"))]
54+
::core::debug_assert!($($x)*);
55+
#[cfg(feature = "defmt")]
56+
::defmt::debug_assert!($($x)*);
57+
}
58+
};
59+
}
60+
61+
#[collapse_debuginfo(yes)]
62+
macro_rules! debug_assert_eq {
63+
($($x:tt)*) => {
64+
{
65+
#[cfg(not(feature = "defmt"))]
66+
::core::debug_assert_eq!($($x)*);
67+
#[cfg(feature = "defmt")]
68+
::defmt::debug_assert_eq!($($x)*);
69+
}
70+
};
71+
}
72+
73+
#[collapse_debuginfo(yes)]
74+
macro_rules! debug_assert_ne {
75+
($($x:tt)*) => {
76+
{
77+
#[cfg(not(feature = "defmt"))]
78+
::core::debug_assert_ne!($($x)*);
79+
#[cfg(feature = "defmt")]
80+
::defmt::debug_assert_ne!($($x)*);
81+
}
82+
};
83+
}
84+
85+
#[collapse_debuginfo(yes)]
86+
macro_rules! todo {
87+
($($x:tt)*) => {
88+
{
89+
#[cfg(not(feature = "defmt"))]
90+
::core::todo!($($x)*);
91+
#[cfg(feature = "defmt")]
92+
::defmt::todo!($($x)*);
93+
}
94+
};
95+
}
96+
97+
#[collapse_debuginfo(yes)]
98+
macro_rules! unreachable {
99+
($($x:tt)*) => {
100+
{
101+
#[cfg(not(feature = "defmt"))]
102+
::core::unreachable!($($x)*);
103+
#[cfg(feature = "defmt")]
104+
::defmt::unreachable!($($x)*);
105+
}
106+
};
107+
}
108+
109+
#[collapse_debuginfo(yes)]
110+
macro_rules! panic {
111+
($($x:tt)*) => {
112+
{
113+
#[cfg(not(feature = "defmt"))]
114+
::core::panic!($($x)*);
115+
#[cfg(feature = "defmt")]
116+
::defmt::panic!($($x)*);
117+
}
118+
};
119+
}
120+
121+
#[collapse_debuginfo(yes)]
122+
macro_rules! trace {
123+
($s:literal $(, $x:expr)* $(,)?) => {
124+
{
125+
#[cfg(feature = "log")]
126+
::log::trace!($s $(, $x)*);
127+
#[cfg(feature = "defmt")]
128+
::defmt::trace!($s $(, $x)*);
129+
#[cfg(not(any(feature = "log", feature="defmt")))]
130+
let _ = ($( & $x ),*);
131+
}
132+
};
133+
}
134+
135+
#[collapse_debuginfo(yes)]
136+
macro_rules! debug {
137+
($s:literal $(, $x:expr)* $(,)?) => {
138+
{
139+
#[cfg(feature = "log")]
140+
::log::debug!($s $(, $x)*);
141+
#[cfg(feature = "defmt")]
142+
::defmt::debug!($s $(, $x)*);
143+
#[cfg(not(any(feature = "log", feature="defmt")))]
144+
let _ = ($( & $x ),*);
145+
}
146+
};
147+
}
148+
149+
#[collapse_debuginfo(yes)]
150+
macro_rules! info {
151+
($s:literal $(, $x:expr)* $(,)?) => {
152+
{
153+
#[cfg(feature = "log")]
154+
::log::info!($s $(, $x)*);
155+
#[cfg(feature = "defmt")]
156+
::defmt::info!($s $(, $x)*);
157+
#[cfg(not(any(feature = "log", feature="defmt")))]
158+
let _ = ($( & $x ),*);
159+
}
160+
};
161+
}
162+
163+
#[collapse_debuginfo(yes)]
164+
macro_rules! warn {
165+
($s:literal $(, $x:expr)* $(,)?) => {
166+
{
167+
#[cfg(feature = "log")]
168+
::log::warn!($s $(, $x)*);
169+
#[cfg(feature = "defmt")]
170+
::defmt::warn!($s $(, $x)*);
171+
#[cfg(not(any(feature = "log", feature="defmt")))]
172+
let _ = ($( & $x ),*);
173+
}
174+
};
175+
}
176+
177+
#[collapse_debuginfo(yes)]
178+
macro_rules! error {
179+
($s:literal $(, $x:expr)* $(,)?) => {
180+
{
181+
#[cfg(feature = "log")]
182+
::log::error!($s $(, $x)*);
183+
#[cfg(feature = "defmt")]
184+
::defmt::error!($s $(, $x)*);
185+
#[cfg(not(any(feature = "log", feature="defmt")))]
186+
let _ = ($( & $x ),*);
187+
}
188+
};
189+
}
190+
191+
#[cfg(feature = "defmt")]
192+
#[collapse_debuginfo(yes)]
193+
macro_rules! unwrap {
194+
($($x:tt)*) => {
195+
::defmt::unwrap!($($x)*)
196+
};
197+
}
198+
199+
#[cfg(not(feature = "defmt"))]
200+
#[collapse_debuginfo(yes)]
201+
macro_rules! unwrap {
202+
($arg:expr) => {
203+
match $crate::fmt::Try::into_result($arg) {
204+
::core::result::Result::Ok(t) => t,
205+
::core::result::Result::Err(e) => {
206+
::core::panic!("unwrap of `{}` failed: {:?}", ::core::stringify!($arg), e);
207+
}
208+
}
209+
};
210+
($arg:expr, $($msg:expr),+ $(,)? ) => {
211+
match $crate::fmt::Try::into_result($arg) {
212+
::core::result::Result::Ok(t) => t,
213+
::core::result::Result::Err(e) => {
214+
::core::panic!("unwrap of `{}` failed: {}: {:?}", ::core::stringify!($arg), ::core::format_args!($($msg,)*), e);
215+
}
216+
}
217+
}
218+
}
219+
220+
#[cfg(feature = "defmt")]
221+
#[collapse_debuginfo(yes)]
222+
macro_rules! write_unwrap {
223+
($f:expr, $s:literal $(, $x:expr)* $(,)?) => {
224+
{
225+
unwrap!(write!($f, $s $(, $x)*).map_err($crate::fmt::FmtError));
226+
}
227+
};
228+
}
229+
230+
#[cfg(not(feature = "defmt"))]
231+
#[collapse_debuginfo(yes)]
232+
macro_rules! write_unwrap {
233+
($f:expr, $s:literal $(, $x:expr)* $(,)?) => {
234+
{
235+
unwrap!(write!($f, $s $(, $x)*));
236+
}
237+
};
238+
}
239+
240+
#[cfg(feature = "defmt")]
241+
#[collapse_debuginfo(yes)]
242+
macro_rules! display2format {
243+
($arg:expr) => {
244+
::defmt::Display2Format(&$arg)
245+
};
246+
}
247+
248+
#[cfg(not(feature = "defmt"))]
249+
#[collapse_debuginfo(yes)]
250+
macro_rules! display2format {
251+
($arg:expr) => {
252+
$arg
253+
};
254+
}
255+
256+
#[cfg(feature = "defmt")]
257+
#[collapse_debuginfo(yes)]
258+
macro_rules! debug2format {
259+
($arg:expr) => {
260+
::defmt::Debug2Format(&$arg)
261+
};
262+
}
263+
264+
#[cfg(not(feature = "defmt"))]
265+
#[collapse_debuginfo(yes)]
266+
macro_rules! debug2format {
267+
($arg:expr) => {
268+
$arg
269+
};
270+
}
271+
272+
/// A way to `{:x?}` format a byte slice which is compatible with `defmt`
273+
pub struct Bytes<'a>(pub &'a [u8]);
274+
275+
impl Debug for Bytes<'_> {
276+
fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
277+
write!(f, "{:#02x?}", self.0)
278+
}
279+
}
280+
281+
impl Display for Bytes<'_> {
282+
fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
283+
write!(f, "{:#02x?}", self.0)
284+
}
285+
}
286+
287+
impl LowerHex for Bytes<'_> {
288+
fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
289+
write!(f, "{:#02x?}", self.0)
290+
}
291+
}
292+
293+
#[cfg(feature = "defmt")]
294+
impl defmt::Format for Bytes<'_> {
295+
fn format(&self, fmt: defmt::Formatter) {
296+
defmt::write!(fmt, "{:02x}", self.0)
297+
}
298+
}
299+
300+
/// Support for the `unwrap!` macro for `Option` and `Result`.
301+
#[derive(Debug, Copy, Clone, Eq, PartialEq)]
302+
pub struct NoneError;
303+
304+
/// Support for the `unwrap!` macro for `Option` and `Result`.
305+
pub trait Try {
306+
type Ok;
307+
type Error;
308+
#[allow(unused)]
309+
fn into_result(self) -> Result<Self::Ok, Self::Error>;
310+
}
311+
312+
impl<T> Try for Option<T> {
313+
type Ok = T;
314+
type Error = NoneError;
315+
316+
#[inline]
317+
fn into_result(self) -> Result<T, NoneError> {
318+
self.ok_or(NoneError)
319+
}
320+
}
321+
322+
impl<T, E> Try for Result<T, E> {
323+
type Ok = T;
324+
type Error = E;
325+
326+
#[inline]
327+
fn into_result(self) -> Self {
328+
self
329+
}
330+
}
331+
332+
#[cfg(feature = "defmt")]
333+
pub(crate) struct FmtError(pub(crate) core::fmt::Error);
334+
335+
#[cfg(feature = "defmt")]
336+
impl defmt::Format for FmtError {
337+
fn format(&self, f: defmt::Formatter<'_>) {
338+
defmt::write!(f, "{}", "FmtError")
339+
}
340+
}

0 commit comments

Comments
 (0)