-
-
Notifications
You must be signed in to change notification settings - Fork 85
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
359: Implement precedence of inner display hint r=japaric a=justahero This PR implements precedence of display hints inner types, e.g. `u8`, `u16` etc. It implements the display hint precedence rules given in #319. When formating variables using the `defmt::Format` trait, either by implementing it or using the `derive` macro, the outer display hint is ignored depending on the inner type & its display hint. For example, a struct that uses the `derive` marco ```rust #[derive(Format)] struct S { x: u8 } // derive would expand to impl defmt::Format for S { fn format(&self, f: defmt::Formatter) { write!(f, "S {{ x: {=u8:?} }}", self.x); } } ``` This uses the `Debug` display hint (`:?`) for the inner type `x` of struct `S`. When displaying the above struct `S` with ```rust info!("{:x}", S { x: 42 }); // -> INFO S { x: 0x2a } ``` the outer display hint `:x` is applied to the inner type `x`. In this case the outer display hint hexadecimal is used. On the other hand if the inner type is one of `:x` (hex), `:b` (binary), the outer display hint will be ignored and the inner hint has precedence. This time the implementation uses the `:b` (binary) display hint to format inner type `x`. ```rust impl defmt::Format for S { fn format(&self, f: defmt::Formatter) { write!(f, "S {{ x: {=u8:b} }}", self.x); } } ``` When logging the struct this time ```rust info!("{:x}", S { x: 42 }); // -> INFO S { x: 0b101010 } ``` the outer display hint `:x` is ignored, the inner display hint `:b` is used, therefore the value `42` is formatted as a binary string `0b101010`. Another precedence rule is related to `str` fields of structs. As given in the RFC #319, the following struct with an inner `str` field is deriving the `defmt::Format` trait as follows. ```rust #[derive(Format)] struct S { x: &'static str } // derive now expands to impl defmt::Format for S { fn format(&self, f: defmt::Formatter) { write!(f, "S {{ x: {=str:?} }}", self.x); } } ``` The difference is `x: &'static str` is expanded to `{=str:?}` instead of a plain `{=str}`. This way string in `x` is enclosed by double quotes. ```rust defmt::info!("{} world", S { x: "hello" }); // -> "hello" world defmt::info("hello {:?}", S { x: "world" }); // -> hello "world" ``` Both display hints `{}` and `{:?}` now produce the same desired output. Co-authored-by: Sebastian Ziebell <sebastian.ziebell@asquera.de>
- Loading branch information
Showing
6 changed files
with
329 additions
and
3 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,10 @@ | ||
0.000000 INFO S1 { x: "hi", y: 0x2a } | ||
0.000001 INFO S2 { x: 0x2a } | ||
0.000002 WARN Debug hint: S { x: "hello", y: 512 } | ||
0.000003 WARN no hint: S { x: "hello", y: 1024 } | ||
0.000004 INFO S2 { s: S1 { x: 0b100, y: 12 }, z: 20 } | ||
0.000005 INFO S2 { s: S1 { x: 0b100, y: 12 }, z: 20 } | ||
0.000006 INFO S2 { s: S1 { x: 0b100, y: 12 }, z: 0x14 } | ||
0.000007 INFO S2 { s: S1 { x: 0b100, y: 12 }, z: 0b10100 } | ||
0.000008 INFO S1 { x: "hi", y: 42 } | ||
0.000009 INFO S1 { x: "hi", y: 0x2a } |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,10 @@ | ||
0.000000 INFO S1 { x: "hi", y: 0x2a } | ||
0.000001 INFO S2 { x: 0x2a } | ||
0.000002 WARN Debug hint: S { x: "hello", y: 512 } | ||
0.000003 WARN no hint: S { x: "hello", y: 1024 } | ||
0.000004 INFO S2 { s: S1 { x: 0b100, y: 12 }, z: 20 } | ||
0.000005 INFO S2 { s: S1 { x: 0b100, y: 12 }, z: 20 } | ||
0.000006 INFO S2 { s: S1 { x: 0b100, y: 12 }, z: 0x14 } | ||
0.000007 INFO S2 { s: S1 { x: 0b100, y: 12 }, z: 0b10100 } | ||
0.000008 INFO S1 { x: "hi", y: 42 } | ||
0.000009 INFO S1 { x: "hi", y: 0x2a } |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,142 @@ | ||
#![no_std] | ||
#![no_main] | ||
|
||
use core::sync::atomic::{AtomicU32, Ordering}; | ||
|
||
use cortex_m_rt::entry; | ||
use cortex_m_semihosting::debug; | ||
|
||
use defmt::write; | ||
use defmt_semihosting as _; // global logger | ||
|
||
#[entry] | ||
fn main() -> ! { | ||
{ | ||
struct S1 { | ||
x: &'static str, | ||
y: u8, | ||
} | ||
impl defmt::Format for S1 { | ||
fn format(&self, f: defmt::Formatter) { | ||
write!(f, "S1 {{ x: {=str:?}, y: {=u8:?} }}", self.x, self.y) | ||
} | ||
} | ||
|
||
// outputs: "S { x: "hi", y: 0x2a }" | ||
defmt::info!("{:x}", S1 { x: "hi", y: 42 }); | ||
} | ||
|
||
{ | ||
struct S2 { | ||
x: u8, | ||
} | ||
impl defmt::Format for S2 { | ||
fn format(&self, f: defmt::Formatter) { | ||
write!(f, "S2 {{ x: {=u8:x} }}", self.x) | ||
} | ||
} | ||
|
||
// ignores outer :b hint, should output: "S { x: 0x2a }" | ||
defmt::info!("{:b}", S2 { x: 42 }); | ||
} | ||
|
||
{ | ||
#[derive(defmt::Format)] | ||
struct S { | ||
x: &'static str, | ||
y: u32, | ||
} | ||
|
||
// 0.1.x version | ||
defmt::warn!("Debug hint: {:?}", S { x: "hello", y: 512 }); | ||
// 0.2.x version, results in same output | ||
defmt::warn!( | ||
" no hint: {}", | ||
S { | ||
x: "hello", | ||
y: 1024 | ||
} | ||
); | ||
} | ||
|
||
{ | ||
// nested struct | ||
struct S1 { | ||
x: u16, | ||
y: u32, | ||
} | ||
impl defmt::Format for S1 { | ||
fn format(&self, f: defmt::Formatter) { | ||
write!(f, "S1 {{ x: {=u16:b}, y: {} }}", self.x, self.y); | ||
} | ||
} | ||
|
||
struct S2 { | ||
s: S1, | ||
z: u8, | ||
} | ||
impl defmt::Format for S2 { | ||
fn format(&self, f: defmt::Formatter) { | ||
write!(f, "S2 {{ s: {:?}, z: {} }}", self.s, self.z); | ||
} | ||
} | ||
|
||
defmt::info!( | ||
"{}", | ||
S2 { | ||
s: S1 { x: 4, y: 12 }, | ||
z: 20 | ||
} | ||
); | ||
defmt::info!( | ||
"{:?}", | ||
S2 { | ||
s: S1 { x: 4, y: 12 }, | ||
z: 20 | ||
} | ||
); | ||
defmt::info!( | ||
"{:x}", | ||
S2 { | ||
s: S1 { x: 4, y: 12 }, | ||
z: 20 | ||
} | ||
); | ||
defmt::info!( | ||
"{:b}", | ||
S2 { | ||
s: S1 { x: 4, y: 12 }, | ||
z: 20 | ||
} | ||
); | ||
} | ||
|
||
{ | ||
#[derive(defmt::Format)] | ||
struct S1<T> { | ||
x: T, | ||
y: u8, | ||
} | ||
|
||
// outputs: "S { x: "hi", y: 42 }" | ||
defmt::info!("{}", S1 { x: "hi", y: 42 }); | ||
// outputs: "S { x: "hi", y: 0x2a }" | ||
defmt::info!("{:x}", S1 { x: "hi", y: 42 }); | ||
} | ||
|
||
loop { | ||
debug::exit(debug::EXIT_SUCCESS) | ||
} | ||
} | ||
|
||
static COUNT: AtomicU32 = AtomicU32::new(0); | ||
defmt::timestamp!("{=u32:µs}", COUNT.fetch_add(1, Ordering::Relaxed)); | ||
|
||
// like `panic-semihosting` but doesn't print to stdout (that would corrupt the defmt stream) | ||
#[cfg(target_os = "none")] | ||
#[panic_handler] | ||
fn panic(_: &core::panic::PanicInfo) -> ! { | ||
loop { | ||
debug::exit(debug::EXIT_FAILURE) | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters