From 406b8b4eb239cf42a8fde50cce0891e263b93e58 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Robert=20J=C3=B6rdens?= Date: Wed, 29 Jan 2025 18:35:55 +0100 Subject: [PATCH 1/5] make Format trait dyn compatible * `Format::_format_tag()` -> `Format::_format_tag(&self)` * change the wire format for empty slices and arrays to be just a `usize(0)` --- defmt/src/export/mod.rs | 20 +++++++++++--------- defmt/src/export/traits.rs | 2 +- defmt/src/impls/adapter.rs | 4 ++-- defmt/src/impls/arrays.rs | 2 +- defmt/src/impls/core_/cell.rs | 4 ++-- defmt/src/impls/core_/mod.rs | 14 +++++++------- defmt/src/impls/mod.rs | 6 +++--- defmt/src/impls/primitives.rs | 4 ++-- defmt/src/impls/tuples.rs | 6 +++--- defmt/src/traits.rs | 2 +- defmt/tests/encode.rs | 2 +- macros/src/derives/format.rs | 2 +- macros/src/items/bitflags.rs | 2 +- 13 files changed, 36 insertions(+), 34 deletions(-) diff --git a/defmt/src/export/mod.rs b/defmt/src/export/mod.rs index c0cd7be3..e4604b58 100644 --- a/defmt/src/export/mod.rs +++ b/defmt/src/export/mod.rs @@ -135,16 +135,21 @@ pub fn panic() -> ! { /// Implementation detail pub fn fmt(f: &T) { - istr(&T::_format_tag()); + istr(&f._format_tag()); f._format_data(); } /// Implementation detail pub fn fmt_slice(values: &[T]) { - usize(&values.len()); - istr(&T::_format_tag()); - for value in values { - value._format_data(); + if let Some((first, remainder)) = values.split_first() { + usize(&values.len()); + istr(&first._format_tag()); + first._format_data(); + for value in remainder { + value._format_data(); + } + } else { + usize(&0); } } @@ -180,10 +185,7 @@ pub fn u8_array(a: &[u8]) { // NOTE: This is passed `&[u8; N]` – it's just coerced to a slice. pub fn fmt_array(a: &[T]) { - istr(&T::_format_tag()); - for value in a { - value._format_data(); - } + fmt_slice(a) } /// Implementation detail diff --git a/defmt/src/export/traits.rs b/defmt/src/export/traits.rs index 45b012e7..ca3b3424 100644 --- a/defmt/src/export/traits.rs +++ b/defmt/src/export/traits.rs @@ -44,7 +44,7 @@ impl Format for NoneError { unreachable!(); } - fn _format_tag() -> Str { + fn _format_tag(&self) -> Str { defmt_macros::internp!("Unwrap of a None option value") } diff --git a/defmt/src/impls/adapter.rs b/defmt/src/impls/adapter.rs index 75d2f98e..2b9a288b 100644 --- a/defmt/src/impls/adapter.rs +++ b/defmt/src/impls/adapter.rs @@ -33,7 +33,7 @@ impl fmt::Debug for Debug2Format<'_, T> { impl Format for Debug2Format<'_, T> { default_format!(); - fn _format_tag() -> Str { + fn _format_tag(&self) -> Str { defmt_macros::internp!("{=__internal_Debug}") } @@ -77,7 +77,7 @@ impl fmt::Display for Display2Format<'_, T> { impl Format for Display2Format<'_, T> { default_format!(); - fn _format_tag() -> Str { + fn _format_tag(&self) -> Str { defmt_macros::internp!("{=__internal_Display}") } diff --git a/defmt/src/impls/arrays.rs b/defmt/src/impls/arrays.rs index 7d512aae..2e79d2e4 100644 --- a/defmt/src/impls/arrays.rs +++ b/defmt/src/impls/arrays.rs @@ -10,7 +10,7 @@ macro_rules! arrays { default_format!(); #[inline] - fn _format_tag() -> Str { + fn _format_tag(&self) -> Str { match N { $( $len => internp!($fmt), diff --git a/defmt/src/impls/core_/cell.rs b/defmt/src/impls/core_/cell.rs index 3d3d9e22..ebe2a569 100644 --- a/defmt/src/impls/core_/cell.rs +++ b/defmt/src/impls/core_/cell.rs @@ -16,7 +16,7 @@ where default_format!(); #[inline] - fn _format_tag() -> Str { + fn _format_tag(&self) -> Str { internp!("RefCell {{ value: }}|RefCell {{ value: {=?} }}") } @@ -26,7 +26,7 @@ where Err(_) => export::u8(&0), Ok(x) => { export::u8(&1); - export::istr(&T::_format_tag()); + export::istr(&self._format_tag()); x._format_data() } } diff --git a/defmt/src/impls/core_/mod.rs b/defmt/src/impls/core_/mod.rs index b005ca57..f2fb71e4 100644 --- a/defmt/src/impls/core_/mod.rs +++ b/defmt/src/impls/core_/mod.rs @@ -26,7 +26,7 @@ where default_format!(); #[inline] - fn _format_tag() -> Str { + fn _format_tag(&self) -> Str { internp!("None|Some({=?})") } @@ -36,7 +36,7 @@ where None => export::u8(&0), Some(x) => { export::u8(&1); - export::istr(&T::_format_tag()); + export::istr(&self._format_tag()); x._format_data() } } @@ -51,7 +51,7 @@ where default_format!(); #[inline] - fn _format_tag() -> Str { + fn _format_tag(&self) -> Str { internp!("Err({=?})|Ok({=?})") } @@ -60,12 +60,12 @@ where match self { Err(e) => { export::u8(&0); - export::istr(&E::_format_tag()); + export::istr(&e._format_tag()); e._format_data() } Ok(x) => { export::u8(&1); - export::istr(&T::_format_tag()); + export::istr(&x._format_tag()); x._format_data() } } @@ -76,7 +76,7 @@ impl Format for core::marker::PhantomData { default_format!(); #[inline] - fn _format_tag() -> Str { + fn _format_tag(&self) -> Str { internp!("PhantomData") } @@ -88,7 +88,7 @@ impl Format for core::convert::Infallible { default_format!(); #[inline] - fn _format_tag() -> Str { + fn _format_tag(&self) -> Str { unreachable!(); } diff --git a/defmt/src/impls/mod.rs b/defmt/src/impls/mod.rs index f0e4a205..62eaf652 100644 --- a/defmt/src/impls/mod.rs +++ b/defmt/src/impls/mod.rs @@ -2,7 +2,7 @@ macro_rules! default_format { () => { #[inline] fn format(&self, _fmt: Formatter) { - crate::export::istr(&Self::_format_tag()); + crate::export::istr(&self._format_tag()); self._format_data(); } }; @@ -16,8 +16,8 @@ macro_rules! delegate_format { } #[inline] - fn _format_tag() -> Str { - <$ty as Format>::_format_tag() + fn _format_tag(&$self_) -> Str { + <$ty as Format>::_format_tag($val) } #[inline] diff --git a/defmt/src/impls/primitives.rs b/defmt/src/impls/primitives.rs index 4c62a9e9..8e1b5bfa 100644 --- a/defmt/src/impls/primitives.rs +++ b/defmt/src/impls/primitives.rs @@ -8,7 +8,7 @@ macro_rules! prim { default_format!(); #[inline] - fn _format_tag() -> Str { + fn _format_tag(&self) -> Str { internp!($fmt) } @@ -46,7 +46,7 @@ where default_format!(); #[inline] - fn _format_tag() -> Str { + fn _format_tag(&self) -> Str { internp!("{=[?]}") } diff --git a/defmt/src/impls/tuples.rs b/defmt/src/impls/tuples.rs index a979fc42..717301ce 100644 --- a/defmt/src/impls/tuples.rs +++ b/defmt/src/impls/tuples.rs @@ -5,7 +5,7 @@ impl Format for () { default_format!(); #[inline] - fn _format_tag() -> Str { + fn _format_tag(&self) -> Str { internp!("()") } @@ -19,7 +19,7 @@ macro_rules! tuple { default_format!(); #[inline] - fn _format_tag() -> Str { + fn _format_tag(&self) -> Str { internp!($format) } @@ -28,7 +28,7 @@ macro_rules! tuple { fn _format_data(&self) { let ($(ref $name,)+) = *self; $( - export::istr(&$name::_format_tag()); + export::istr(&self._format_tag()); $name._format_data(); )+ } diff --git a/defmt/src/traits.rs b/defmt/src/traits.rs index a9acdb54..abc94994 100644 --- a/defmt/src/traits.rs +++ b/defmt/src/traits.rs @@ -48,7 +48,7 @@ pub trait Format { fn format(&self, fmt: Formatter); #[doc(hidden)] - fn _format_tag() -> Str { + fn _format_tag(&self) -> Str { internp!("{=__internal_FormatSequence}") } diff --git a/defmt/tests/encode.rs b/defmt/tests/encode.rs index 67f0677e..77593089 100644 --- a/defmt/tests/encode.rs +++ b/defmt/tests/encode.rs @@ -44,7 +44,7 @@ fn inc(index: u16, n: u16) -> u16 { } fn write_format(val: &T) { - defmt::export::istr(&T::_format_tag()); + defmt::export::istr(&val._format_tag()); val._format_data(); } diff --git a/macros/src/derives/format.rs b/macros/src/derives/format.rs index 4b122c0f..441ed61c 100644 --- a/macros/src/derives/format.rs +++ b/macros/src/derives/format.rs @@ -36,7 +36,7 @@ pub(crate) fn expand(input: TokenStream) -> TokenStream { defmt::unreachable!() } - fn _format_tag() -> defmt::Str { + fn _format_tag(&self) -> defmt::Str { #format_tag } diff --git a/macros/src/items/bitflags.rs b/macros/src/items/bitflags.rs index d3d71e23..4b01584b 100644 --- a/macros/src/items/bitflags.rs +++ b/macros/src/items/bitflags.rs @@ -45,7 +45,7 @@ pub(crate) fn expand(input: TokenStream) -> TokenStream { defmt::unreachable!() } - fn _format_tag() -> defmt::Str { + fn _format_tag(&self) -> defmt::Str { #format_tag } From 713c7b47bb71dbfc19bb3f982ebf6bf2b51fdee8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Robert=20J=C3=B6rdens?= Date: Wed, 29 Jan 2025 18:54:42 +0100 Subject: [PATCH 2/5] Format: format empty arrays as nothing --- defmt/src/export/mod.rs | 8 +++++++- defmt/tests/encode.rs | 10 +++++++++- 2 files changed, 16 insertions(+), 2 deletions(-) diff --git a/defmt/src/export/mod.rs b/defmt/src/export/mod.rs index e4604b58..fb451b52 100644 --- a/defmt/src/export/mod.rs +++ b/defmt/src/export/mod.rs @@ -185,7 +185,13 @@ pub fn u8_array(a: &[u8]) { // NOTE: This is passed `&[u8; N]` – it's just coerced to a slice. pub fn fmt_array(a: &[T]) { - fmt_slice(a) + if let Some((first, remainder)) = a.split_first() { + istr(&first._format_tag()); + first._format_data(); + for value in remainder { + value._format_data(); + } + } } /// Implementation detail diff --git a/defmt/tests/encode.rs b/defmt/tests/encode.rs index 77593089..7a953fcf 100644 --- a/defmt/tests/encode.rs +++ b/defmt/tests/encode.rs @@ -557,6 +557,15 @@ fn slice() { 23u8, // val[0] 42u8, // val[1] ], + ); + + let val: &[u8] = &[]; + check_format!( + val, + [ + inc(index, 2), // "{=[?]}" + val.len() as u32, // length + ], ) } @@ -737,7 +746,6 @@ fn format_arrays() { &array, [ index, // "{=[?;0]}" - inc(index, 1), // "{=u16}" ] ); From 57e3acdb5932c5ddfc430618767fdda9631512f4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Robert=20J=C3=B6rdens?= Date: Wed, 29 Jan 2025 18:58:07 +0100 Subject: [PATCH 3/5] [fixup] Option format_data() --- defmt/src/impls/core_/mod.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/defmt/src/impls/core_/mod.rs b/defmt/src/impls/core_/mod.rs index f2fb71e4..718e6cea 100644 --- a/defmt/src/impls/core_/mod.rs +++ b/defmt/src/impls/core_/mod.rs @@ -36,7 +36,7 @@ where None => export::u8(&0), Some(x) => { export::u8(&1); - export::istr(&self._format_tag()); + export::istr(&x._format_tag()); x._format_data() } } From 34f603933eae1749efc265096cc5b96cf3265c71 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Robert=20J=C3=B6rdens?= Date: Wed, 29 Jan 2025 18:59:08 +0100 Subject: [PATCH 4/5] [fixup] Cell format_data() --- defmt/src/impls/core_/cell.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/defmt/src/impls/core_/cell.rs b/defmt/src/impls/core_/cell.rs index ebe2a569..31f39d8f 100644 --- a/defmt/src/impls/core_/cell.rs +++ b/defmt/src/impls/core_/cell.rs @@ -26,7 +26,7 @@ where Err(_) => export::u8(&0), Ok(x) => { export::u8(&1); - export::istr(&self._format_tag()); + export::istr(&x._format_tag()); x._format_data() } } From 877cf146c484c485ccfec34c0a3e61554cdebaec Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Robert=20J=C3=B6rdens?= Date: Wed, 29 Jan 2025 19:01:08 +0100 Subject: [PATCH 5/5] [fixup] tuple format_data() --- defmt/src/impls/tuples.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/defmt/src/impls/tuples.rs b/defmt/src/impls/tuples.rs index 717301ce..27dd3ac6 100644 --- a/defmt/src/impls/tuples.rs +++ b/defmt/src/impls/tuples.rs @@ -28,7 +28,7 @@ macro_rules! tuple { fn _format_data(&self) { let ($(ref $name,)+) = *self; $( - export::istr(&self._format_tag()); + export::istr(&$name._format_tag()); $name._format_data(); )+ }