From 141b9eeac99a1d6f95ed54c49b4cb29ef47fbec1 Mon Sep 17 00:00:00 2001 From: joshua salzedo Date: Wed, 26 Aug 2020 14:18:07 -0700 Subject: [PATCH 1/6] [#171] First attempt at supporting defmt for heapless::Vec - defmt has native support for slices, so utilize that. --- Cargo.toml | 10 ++++++++-- src/vec.rs | 34 ++++++++++++++++++++++++++++++++++ 2 files changed, 42 insertions(+), 2 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index 0b2bbdb690..27e1436872 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,7 +1,7 @@ [package] authors = [ - "Jorge Aparicio ", - "Per Lindgren ", + "Jorge Aparicio ", + "Per Lindgren ", ] categories = [ "data-structures", @@ -27,6 +27,7 @@ ufmt-impl = ["ufmt-write"] x86-sync-pool = [] # only for tests __trybuild = [] +defmt_format = ["defmt"] [target.x86_64-unknown-linux-gnu.dev-dependencies] scoped_threadpool = "0.1.8" @@ -51,3 +52,8 @@ optional = true [dev-dependencies.ufmt] version = "0.1" + +[dependencies.defmt] +git = "https://github.com/knurling-rs/defmt" +branch = "main" +optional = true \ No newline at end of file diff --git a/src/vec.rs b/src/vec.rs index 65121224ef..d5fe4f3b73 100644 --- a/src/vec.rs +++ b/src/vec.rs @@ -2,6 +2,7 @@ use core::{fmt, hash, iter::FromIterator, mem::MaybeUninit, ops, ptr, slice}; use generic_array::{ArrayLength, GenericArray}; use hash32; +use defmt::Formatter; impl crate::i::Vec { /// `Vec` `const` constructor; wrap the returned value in [`Vec`](../struct.Vec.html) @@ -823,11 +824,19 @@ where } } +impl defmt::Format for Vec +where N: ArrayLength, T:defmt::Format{ + fn format(&self, fmt: &mut Formatter) { + fmt.fmt_slice(self) + } +} + #[cfg(test)] mod tests { use crate::{consts::*, Vec}; use as_slice::AsSlice; use core::fmt::Write; + use std::convert::TryInto; #[test] fn static_new() { @@ -1151,4 +1160,29 @@ mod tests { assert!(!v.ends_with(b"ba")); assert!(!v.ends_with(b"a")); } + + #[test] + /// Tests encoding Vec with defmt, + /// based loosely on https://github.com/knurling-rs/defmt/blob/main/tests/encode.rs#L483 + fn test_defmt_format(){ + let v: Vec<_, U8> = Vec::from_slice(b"abc").unwrap(); + let index = defmt::export::fetch_string_index(); + + // borrowed from https://github.com/knurling-rs/defmt/blob/main/tests/encode.rs#L49 + let fake_interned = index.wrapping_add(1) & 0x7F; + + let timestamp = defmt::export::fetch_timestamp(); + let mut formatter = defmt::Formatter::new(); + defmt::winfo!(formatter, "{:?}", v); + assert_eq!(formatter.bytes(), &[ + index, + timestamp, + v.len().try_into().unwrap(), + fake_interned, // Faked + // Data bytes. + 97u8, + 98u8, + 99u8, + ]); + } } From 80656bcb5649fa20383392f49154db42ab4a8bb8 Mon Sep 17 00:00:00 2001 From: joshua salzedo Date: Wed, 26 Aug 2020 14:26:43 -0700 Subject: [PATCH 2/6] [#171] extracted new impl to own optional module - to conform with other optional features --- Cargo.toml | 2 +- src/defmt.rs | 47 +++++++++++++++++++++++++++++++++++++++++++++++ src/lib.rs | 4 +++- src/vec.rs | 34 ++-------------------------------- 4 files changed, 53 insertions(+), 34 deletions(-) create mode 100644 src/defmt.rs diff --git a/Cargo.toml b/Cargo.toml index 27e1436872..0a3ec3590d 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -27,7 +27,7 @@ ufmt-impl = ["ufmt-write"] x86-sync-pool = [] # only for tests __trybuild = [] -defmt_format = ["defmt"] +defmt-impl = ["defmt"] [target.x86_64-unknown-linux-gnu.dev-dependencies] scoped_threadpool = "0.1.8" diff --git a/src/defmt.rs b/src/defmt.rs new file mode 100644 index 0000000000..a3486f2f35 --- /dev/null +++ b/src/defmt.rs @@ -0,0 +1,47 @@ +//! Defmt implementations for heapless types +//! + +use defmt::Formatter; +use generic_array::ArrayLength; + +use crate::Vec; + +impl defmt::Format for Vec + where N: ArrayLength, T: defmt::Format { + fn format(&self, fmt: &mut Formatter) { + fmt.fmt_slice(self) + } +} + + +#[cfg(test)] +mod tests { + use std::convert::TryInto; + + use crate::{consts::*, Vec}; + + #[test] + /// Tests encoding Vec with defmt, + /// based loosely on https://github.com/knurling-rs/defmt/blob/main/tests/encode.rs#L483 + fn test_defmt_format() { + let v: Vec<_, U8> = Vec::from_slice(b"abc").unwrap(); + let index = defmt::export::fetch_string_index(); + + // borrowed from https://github.com/knurling-rs/defmt/blob/main/tests/encode.rs#L49 + let fake_interned = index.wrapping_add(1) & 0x7F; + + let timestamp = defmt::export::fetch_timestamp(); + let mut formatter = defmt::Formatter::new(); + defmt::winfo!(formatter, "{:?}", v); + assert_eq!(formatter.bytes(), &[ + index, + timestamp, + v.len().try_into().unwrap(), + fake_interned, // Faked + // Data bytes. + 97u8, + 98u8, + 99u8, + ]); + } +} \ No newline at end of file diff --git a/src/lib.rs b/src/lib.rs index 4d95fe2427..69e679afa8 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -106,8 +106,10 @@ pub mod mpmc; pub mod pool; #[cfg(has_atomics)] pub mod spsc; +#[cfg(feature="defmt-impl")] +pub mod defmt; -#[cfg(feature = "ufmt-impl")] +#[cfg(feature="ufmt-impl")] mod ufmt; mod sealed; diff --git a/src/vec.rs b/src/vec.rs index d5fe4f3b73..4ecbd43de6 100644 --- a/src/vec.rs +++ b/src/vec.rs @@ -2,7 +2,6 @@ use core::{fmt, hash, iter::FromIterator, mem::MaybeUninit, ops, ptr, slice}; use generic_array::{ArrayLength, GenericArray}; use hash32; -use defmt::Formatter; impl crate::i::Vec { /// `Vec` `const` constructor; wrap the returned value in [`Vec`](../struct.Vec.html) @@ -824,19 +823,13 @@ where } } -impl defmt::Format for Vec -where N: ArrayLength, T:defmt::Format{ - fn format(&self, fmt: &mut Formatter) { - fmt.fmt_slice(self) - } -} + #[cfg(test)] mod tests { use crate::{consts::*, Vec}; use as_slice::AsSlice; use core::fmt::Write; - use std::convert::TryInto; #[test] fn static_new() { @@ -1161,28 +1154,5 @@ mod tests { assert!(!v.ends_with(b"a")); } - #[test] - /// Tests encoding Vec with defmt, - /// based loosely on https://github.com/knurling-rs/defmt/blob/main/tests/encode.rs#L483 - fn test_defmt_format(){ - let v: Vec<_, U8> = Vec::from_slice(b"abc").unwrap(); - let index = defmt::export::fetch_string_index(); - - // borrowed from https://github.com/knurling-rs/defmt/blob/main/tests/encode.rs#L49 - let fake_interned = index.wrapping_add(1) & 0x7F; - - let timestamp = defmt::export::fetch_timestamp(); - let mut formatter = defmt::Formatter::new(); - defmt::winfo!(formatter, "{:?}", v); - assert_eq!(formatter.bytes(), &[ - index, - timestamp, - v.len().try_into().unwrap(), - fake_interned, // Faked - // Data bytes. - 97u8, - 98u8, - 99u8, - ]); - } + } From 091bc6199d0c477ab2cc201c523a4eb7668e5a24 Mon Sep 17 00:00:00 2001 From: joshua salzedo Date: Wed, 26 Aug 2020 21:07:21 -0700 Subject: [PATCH 3/6] Undo unintended formatting changes to cargo.toml --- Cargo.toml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index 0a3ec3590d..a735e4782a 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,7 +1,7 @@ [package] authors = [ - "Jorge Aparicio ", - "Per Lindgren ", + "Jorge Aparicio ", + "Per Lindgren ", ] categories = [ "data-structures", @@ -56,4 +56,4 @@ version = "0.1" [dependencies.defmt] git = "https://github.com/knurling-rs/defmt" branch = "main" -optional = true \ No newline at end of file +optional = true From a792c49eca4d2a06442f7c582ff95581b946f9be Mon Sep 17 00:00:00 2001 From: joshua salzedo Date: Wed, 26 Aug 2020 21:13:43 -0700 Subject: [PATCH 4/6] Undo unintended out of scope formatting changes --- src/defmt.rs | 2 +- src/lib.rs | 4 ++-- src/vec.rs | 4 ---- 3 files changed, 3 insertions(+), 7 deletions(-) diff --git a/src/defmt.rs b/src/defmt.rs index a3486f2f35..f070b9fea9 100644 --- a/src/defmt.rs +++ b/src/defmt.rs @@ -44,4 +44,4 @@ mod tests { 99u8, ]); } -} \ No newline at end of file +} diff --git a/src/lib.rs b/src/lib.rs index 69e679afa8..6b9af2ead2 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -106,10 +106,10 @@ pub mod mpmc; pub mod pool; #[cfg(has_atomics)] pub mod spsc; -#[cfg(feature="defmt-impl")] +#[cfg(feature = "defmt-impl")] pub mod defmt; -#[cfg(feature="ufmt-impl")] +#[cfg(feature = "ufmt-impl")] mod ufmt; mod sealed; diff --git a/src/vec.rs b/src/vec.rs index 4ecbd43de6..65121224ef 100644 --- a/src/vec.rs +++ b/src/vec.rs @@ -823,8 +823,6 @@ where } } - - #[cfg(test)] mod tests { use crate::{consts::*, Vec}; @@ -1153,6 +1151,4 @@ mod tests { assert!(!v.ends_with(b"ba")); assert!(!v.ends_with(b"a")); } - - } From 4eabc248ef67cecfe16eaa51635e4b0dab82cc6e Mon Sep 17 00:00:00 2001 From: joshua salzedo Date: Fri, 28 Aug 2020 09:35:30 -0700 Subject: [PATCH 5/6] [#171] demote `defmt` impl to a private module --- src/lib.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/lib.rs b/src/lib.rs index 6b9af2ead2..dbe492acd2 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -107,7 +107,7 @@ pub mod pool; #[cfg(has_atomics)] pub mod spsc; #[cfg(feature = "defmt-impl")] -pub mod defmt; +mod defmt; #[cfg(feature = "ufmt-impl")] mod ufmt; From 883cd436bdb19b1e7e2cd0a156c5ed65f5b54b34 Mon Sep 17 00:00:00 2001 From: Joshua Salzedo Date: Wed, 23 Sep 2020 11:05:07 -0700 Subject: [PATCH 6/6] Defmt impl for String --- src/defmt.rs | 69 ++++++++++++++++++++++++++++++++++++++++------------ 1 file changed, 54 insertions(+), 15 deletions(-) diff --git a/src/defmt.rs b/src/defmt.rs index f070b9fea9..26a847de73 100644 --- a/src/defmt.rs +++ b/src/defmt.rs @@ -1,18 +1,29 @@ //! Defmt implementations for heapless types //! -use defmt::Formatter; -use generic_array::ArrayLength; - +use crate::ArrayLength; use crate::Vec; +use defmt::Formatter; impl defmt::Format for Vec - where N: ArrayLength, T: defmt::Format { +where + N: ArrayLength, + T: defmt::Format, +{ fn format(&self, fmt: &mut Formatter) { fmt.fmt_slice(self) } } +impl defmt::Format for crate::String +where + N: ArrayLength, + u8: defmt::Format, +{ + fn format(&self, fmt: &mut Formatter) { + fmt.str(self.as_str()); + } +} #[cfg(test)] mod tests { @@ -23,7 +34,7 @@ mod tests { #[test] /// Tests encoding Vec with defmt, /// based loosely on https://github.com/knurling-rs/defmt/blob/main/tests/encode.rs#L483 - fn test_defmt_format() { + fn test_defmt_format_vec() { let v: Vec<_, U8> = Vec::from_slice(b"abc").unwrap(); let index = defmt::export::fetch_string_index(); @@ -33,15 +44,43 @@ mod tests { let timestamp = defmt::export::fetch_timestamp(); let mut formatter = defmt::Formatter::new(); defmt::winfo!(formatter, "{:?}", v); - assert_eq!(formatter.bytes(), &[ - index, - timestamp, - v.len().try_into().unwrap(), - fake_interned, // Faked - // Data bytes. - 97u8, - 98u8, - 99u8, - ]); + assert_eq!( + formatter.bytes(), + &[ + index, + timestamp, + v.len().try_into().unwrap(), + fake_interned, // Faked + // Data bytes. + 97u8, + 98u8, + 99u8, + ] + ); + } + + /// Tests encoding String with defmt, + /// based loosely on https://github.com/knurling-rs/defmt/blob/main/tests/encode.rs#L483 + #[test] + fn test_defmt_format_str() { + let mut v: crate::String = crate::String::new(); + v.push_str("foo").unwrap(); + let index = defmt::export::fetch_string_index(); + + let timestamp = defmt::export::fetch_timestamp(); + let mut formatter = defmt::Formatter::new(); + defmt::winfo!(formatter, "{:?}", v); + assert_eq!( + formatter.bytes(), + &[ + index, + timestamp, + v.len().try_into().unwrap(), + // Data bytes. + 102u8, + 111u8, + 111u8, + ] + ); } }