From c8724aae1f726ae28fa8bc75a5c967add3603243 Mon Sep 17 00:00:00 2001 From: Divyansh Patel Date: Sun, 1 Nov 2026 15:22:07 +0530 Subject: [PATCH 1/3] implement defmt::Format for all types that implement Debug --- src/error.rs | 22 ++++++++++++++++++++++ src/iterators/drain.rs | 15 +++++++++++++++ src/iterators/extractif.rs | 18 ++++++++++++++++++ src/iterators/intoiter.rs | 15 +++++++++++++++ src/iterators/splice.rs | 17 +++++++++++++++++ 5 files changed, 87 insertions(+) diff --git a/src/error.rs b/src/error.rs index 5bc4c59a..9b46fd8c 100644 --- a/src/error.rs +++ b/src/error.rs @@ -1,3 +1,9 @@ +#[cfg(feature = "defmt")] +use defmt::{ + Format as DeFormat, + Formatter as DeFormatter, + write as dewrite +}; use { alloc::alloc::handle_alloc_error, core::{ @@ -26,6 +32,22 @@ impl Display for SmallVecError { impl Error for SmallVecError {} +// `Layout` doesn't implement `defmt::Format`, so this can't be derived. +#[cfg(feature = "defmt")] +impl DeFormat for SmallVecError { + fn format(&self, fmt: DeFormatter) { + match self { + SmallVecError::CapacityOverflow => dewrite!(fmt, "CapacityOverflow"), + SmallVecError::AllocationError(layout) => dewrite!( + fmt, + "AllocationError(Layout {{ size: {=usize}, align: {=usize} }})", + layout.size(), + layout.align() + ) + } + } +} + impl SmallVecError { #[cold] #[inline(never)] diff --git a/src/iterators/drain.rs b/src/iterators/drain.rs index 07f5e546..7fef4aaa 100644 --- a/src/iterators/drain.rs +++ b/src/iterators/drain.rs @@ -1,3 +1,9 @@ +#[cfg(feature = "defmt")] +use defmt::{ + Format as DeFormat, + Formatter as DeFormatter, + write as dewrite +}; use { super::super::{ SmallVec, @@ -246,3 +252,12 @@ impl Debug for Drain<'_, Item f.debug_tuple("Drain").field(&self.iter.as_slice()).finish() } } + +#[cfg(feature = "defmt")] +impl DeFormat + for Drain<'_, Item, INLINE, Heap> +{ + fn format(&self, fmt: DeFormatter) { + dewrite!(fmt, "Drain({=[?]})", self.iter.as_slice()); + } +} diff --git a/src/iterators/extractif.rs b/src/iterators/extractif.rs index e0ee1b5f..38066b51 100644 --- a/src/iterators/extractif.rs +++ b/src/iterators/extractif.rs @@ -1,3 +1,9 @@ +#[cfg(feature = "defmt")] +use defmt::{ + Format as DeFormat, + Formatter as DeFormatter, + write as dewrite +}; use { super::super::{ SmallVec, @@ -51,6 +57,18 @@ where } } +#[cfg(feature = "defmt")] +impl DeFormat + for ExtractIf<'_, Item, INLINE, F, Heap> +where + F: FnMut(&mut Item) -> bool, + Item: DeFormat +{ + fn format(&self, fmt: DeFormatter) { + dewrite!(fmt, "ExtractIf({=[?]})", self.vec.as_ref()); + } +} + impl Iterator for ExtractIf<'_, Item, INLINE, F, Heap> where F: FnMut(&mut Item) -> bool diff --git a/src/iterators/intoiter.rs b/src/iterators/intoiter.rs index ec08ec90..b02baa91 100644 --- a/src/iterators/intoiter.rs +++ b/src/iterators/intoiter.rs @@ -1,3 +1,9 @@ +#[cfg(feature = "defmt")] +use defmt::{ + Format as DeFormat, + Formatter as DeFormatter, + write as dewrite +}; use { super::super::{ DropDealloc, @@ -223,3 +229,12 @@ impl Debug for IntoIter DeFormat + for IntoIter +{ + fn format(&self, fmt: DeFormatter) { + dewrite!(fmt, "IntoIter({=[?]})", self.as_ref()); + } +} diff --git a/src/iterators/splice.rs b/src/iterators/splice.rs index a08086dd..5d0605e6 100644 --- a/src/iterators/splice.rs +++ b/src/iterators/splice.rs @@ -1,3 +1,9 @@ +#[cfg(feature = "defmt")] +use defmt::{ + Format as DeFormat, + Formatter as DeFormatter, + write as dewrite +}; use { super::{ super::{ @@ -43,6 +49,17 @@ where } } +#[cfg(feature = "defmt")] +impl<'valid, I, const INLINE: usize, Heap: Allocator> DeFormat for Splice<'valid, I, INLINE, Heap> +where + I: Iterator + 'valid, + ::Item: DeFormat +{ + fn format(&self, fmt: DeFormatter) { + dewrite!(fmt, "Splice({})", self.drain); + } +} + impl Iterator for Splice<'_, I, INLINE, Heap> { type Item = I::Item; From a838084f13cdd734ee4d149b0a95ad3970ac8fc5 Mon Sep 17 00:00:00 2001 From: Divyansh Patel Date: Sun, 1 Nov 2026 15:22:29 +0530 Subject: [PATCH 2/3] add defmt Format test --- Cargo.toml | 4 ++++ tests/defmt.rs | 24 ++++++++++++++++++++++++ 2 files changed, 28 insertions(+) create mode 100644 tests/defmt.rs diff --git a/Cargo.toml b/Cargo.toml index 606c2a22..7cf30cc0 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -88,6 +88,10 @@ required-features = ["bytemuck"] name = "bytes" required-features = ["bytes"] +[[test]] +name = "defmt" +required-features = ["defmt"] + [[test]] name = "encase" required-features = ["encase"] diff --git a/tests/defmt.rs b/tests/defmt.rs new file mode 100644 index 00000000..06f4503e --- /dev/null +++ b/tests/defmt.rs @@ -0,0 +1,24 @@ +use { + core::iter::Empty, + defmt::Format, + smallvec::{ + Drain, + ExtractIf, + IntoIter, + SmallVec, + SmallVecError, + Splice + } +}; + +fn assert_format() {} + +#[test] +fn format() { + assert_format::>(); + assert_format::>(); + assert_format::>(); + assert_format:: bool>>(); + assert_format::, 4>>(); + assert_format::(); +} From f2a903c4edd971d6416ae72f9a7993d48fc88626 Mon Sep 17 00:00:00 2001 From: Divyansh Patel Date: Sun, 1 Nov 2026 16:13:00 +0530 Subject: [PATCH 3/3] added debug and defmt for RawSmallVec & LocatedLength --- Cargo.toml | 4 ---- src/error.rs | 22 ---------------------- src/locatedlength.rs | 38 +++++++++++++++++++++++++++++++++++++- src/rawsmallvec.rs | 26 ++++++++++++++++++++++++++ tests/defmt.rs | 24 ------------------------ 5 files changed, 63 insertions(+), 51 deletions(-) delete mode 100644 tests/defmt.rs diff --git a/Cargo.toml b/Cargo.toml index 7cf30cc0..606c2a22 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -88,10 +88,6 @@ required-features = ["bytemuck"] name = "bytes" required-features = ["bytes"] -[[test]] -name = "defmt" -required-features = ["defmt"] - [[test]] name = "encase" required-features = ["encase"] diff --git a/src/error.rs b/src/error.rs index 9b46fd8c..5bc4c59a 100644 --- a/src/error.rs +++ b/src/error.rs @@ -1,9 +1,3 @@ -#[cfg(feature = "defmt")] -use defmt::{ - Format as DeFormat, - Formatter as DeFormatter, - write as dewrite -}; use { alloc::alloc::handle_alloc_error, core::{ @@ -32,22 +26,6 @@ impl Display for SmallVecError { impl Error for SmallVecError {} -// `Layout` doesn't implement `defmt::Format`, so this can't be derived. -#[cfg(feature = "defmt")] -impl DeFormat for SmallVecError { - fn format(&self, fmt: DeFormatter) { - match self { - SmallVecError::CapacityOverflow => dewrite!(fmt, "CapacityOverflow"), - SmallVecError::AllocationError(layout) => dewrite!( - fmt, - "AllocationError(Layout {{ size: {=usize}, align: {=usize} }})", - layout.size(), - layout.align() - ) - } - } -} - impl SmallVecError { #[cold] #[inline(never)] diff --git a/src/locatedlength.rs b/src/locatedlength.rs index fc833347..29022294 100644 --- a/src/locatedlength.rs +++ b/src/locatedlength.rs @@ -1,4 +1,17 @@ -use core::marker::PhantomData; +use core::{ + fmt::{ + Debug, + Formatter, + Result as Format + }, + marker::PhantomData +}; +#[cfg(feature = "defmt")] +use defmt::{ + Format as DeFormat, + Formatter as DeFormatter, + write as dewrite +}; /// Vec guarantees that its length is always less than [`isize::MAX`] in /// *bytes*. @@ -23,6 +36,29 @@ impl Clone for LocatedLength { impl Copy for LocatedLength {} +impl Debug for LocatedLength { + fn fmt(&self, f: &mut Formatter<'_>) -> Format { + let (length, on_heap) = self.parts(); + f.debug_struct("LocatedLength") + .field("length", &length) + .field("on_heap", &on_heap) + .finish() + } +} + +#[cfg(feature = "defmt")] +impl DeFormat for LocatedLength { + fn format(&self, fmt: DeFormatter) { + let (length, on_heap) = self.parts(); + dewrite!( + fmt, + "LocatedLength {{ length: {=usize}, on_heap: {=bool} }}", + length, + on_heap + ); + } +} + #[allow(clippy::len_without_is_empty)] impl LocatedLength { const MAX_LEN: usize = usize::MAX >> Self::SHIFT; diff --git a/src/rawsmallvec.rs b/src/rawsmallvec.rs index 7c8d8f8e..9b0d39b6 100644 --- a/src/rawsmallvec.rs +++ b/src/rawsmallvec.rs @@ -1,3 +1,9 @@ +#[cfg(feature = "defmt")] +use defmt::{ + Format as DeFormat, + Formatter as DeFormatter, + write as dewrite +}; use { super::{ allocator::Allocator, @@ -6,6 +12,11 @@ use { }, core::{ alloc::Layout, + fmt::{ + Debug, + Formatter, + Result as Format + }, mem::{ ManuallyDrop, MaybeUninit @@ -23,6 +34,21 @@ pub union RawSmallVec { pub heap: (NonNull, usize) } +// The active member is tracked by `LocatedLength`, not by the union itself, so +// neither member can be read safely here. +impl Debug for RawSmallVec { + fn fmt(&self, f: &mut Formatter<'_>) -> Format { + f.debug_struct("RawSmallVec").finish_non_exhaustive() + } +} + +#[cfg(feature = "defmt")] +impl DeFormat for RawSmallVec { + fn format(&self, fmt: DeFormatter) { + dewrite!(fmt, "RawSmallVec {{ .. }}"); + } +} + impl RawSmallVec { pub const INLINE_CAP: usize = if Self::IS_ZST { usize::MAX } else { INLINE }; const IS_ZST: bool = size_of::() == 0; diff --git a/tests/defmt.rs b/tests/defmt.rs deleted file mode 100644 index 06f4503e..00000000 --- a/tests/defmt.rs +++ /dev/null @@ -1,24 +0,0 @@ -use { - core::iter::Empty, - defmt::Format, - smallvec::{ - Drain, - ExtractIf, - IntoIter, - SmallVec, - SmallVecError, - Splice - } -}; - -fn assert_format() {} - -#[test] -fn format() { - assert_format::>(); - assert_format::>(); - assert_format::>(); - assert_format:: bool>>(); - assert_format::, 4>>(); - assert_format::(); -}