-
-
Notifications
You must be signed in to change notification settings - Fork 85
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Add ':cbor' hint for CBOR Diagnostic Notation (EDN) #916
base: main
Are you sure you want to change the base?
Conversation
Seeing CI items fail one by one:
|
Apologies for the delay, we were out for Christmas vacation. The MSRV is set to support Ferrocene and isn't something we can change on this crate at this time. If you can adjust the dependencies to work with what we have, that would be great. Adding a new variant in DisplayHint is a breaking change to anyone exhaustively matching on it. That enum should probably be |
Thanks for your feedback! There's now a commit in that does mark DisplayHint as cbor-edn is now updated and tested to match defmt's MSRV. I expect a less experimental version of that crate soon (we're having a discussion on the last working group changes of the output format today; not that any of that would affect the API used here). I'm already testing this with probe-rs-tools, which needs nothing but an update to defmt-decoder once that is released with the change. |
We do the version bump in a release PR, and we mark breaking changes with a breaking-change tag, which stops the semver-check CI job from complaining. I'm not against changing that policy though. Maybe having |
I have applied some small fixes, enhancing documentation and bringing cbor-edn to its latest version. It's still an early version as the WG specifying the diagnostic format is not done with its document, but they are converging far enough that I'm confident progressing. (Note that that crate is only responsible for producing a human readable version of CBOR, and not affecting the format, so even if the WG did a 180 on everything in there, what is produced is still a human readable version of the binary data, and will stay a human readable version when updated to an RFC of EDN where it looks different).
So, can I rebase this onto latest main, and remove the commt that does --- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -544,2 +544,3 @@ Initial release
* [#902] Minor change to `impl StreamDecoder` for `Raw` and `Rzcobs`, eliding a lifetime specifier to satisfy Clippy 1.83. No observable change.
+* [#916] Support the ":cbor" display hint, adding new dependency `cbor-edn`.
@@ -609,2 +610,5 @@ Initial release
+* [#916] Mark `DisplayHint` as `non_exhaustive`. This is a breaking change.
+* [#916] Add display hint ":cbor", indicating RFC8949 encoded data to be displayed in diagnostic notation.
+
### [defmt-parser-v0.4.1] (2024-11-27) from the PR? (I think rebasing will help with some of the failing CI steps). |
To clarify - I think adding notable changes to the CHANGELOG is good, but we want to hold off on version number bumps in these feature PRs. |
cc842a0
to
b403c6d
Compare
Thanks for the clarification. I've rebased things to sort out the CI issues, but no success ("E: Package 'qemu' has no installation candidate"). On the open issues I had originally:
|
I think ubuntu-latest moved to ubuntu-24.04 and packages have changed. I'll fix it. |
This is currently labelled as "waits on author"; I think the more accurate description is that this is blocked by #922; I think it is done from my side. [edit: unblocked now, awaiting CI verdict…] |
Fantastic. Now I just need to decide whether adding |
OK, it seems fine. With probe-rs 0.25:
With probe-rs 0.26 patched to use this PR's version of defmt-decoder:
This is because So no Defmt Version bump required. |
At least for CBOR, the rendering a la |
So as far as I know, if you say
i.e. any If you do So, #[derive(defmt::Format)]
struct Config<'a> {
name: &'a str,
payload: &'a [u8],
}
let c = Config { name: "test", payload: &[130, 1, 130, 2, 3] };
info!("Config is {:cbor}", c); In this PR it currently prints:
but probably should print:
|
Although #925 might be a problem. |
How will this interact here? In the pattern of core::fmt, AIU the :x top-level is stored in the formatter. That is probably unavailable in the formatter (it is information that the embedded system should not need to care about), but then the host side formatter would store the information, and apply it where something "looks for it" (as number formatting would do). For :cbor, there's not much to store, because it only acts on arrays, so there are no nested formattings. At most, something could do let item: Item = todo();
info!("My item is {:x}", item);
impl defmt::Format for Item {
fn … {
write!("I am an item with scalar {} and details {=[u8]:cbor}", self.scalar(), self.details());
}
} Without doing anything, the fix for #925 would affect the |
Just to clarify, In your example, I expect But I still think it's a bug that |
I often find myself sending CBOR (a format for standardized data interchange with embedded devices; binary, using a superset of JSON's data model) through defmt. CBOR comes with a human-readable format (that is a superset of JSON's serialization), which is designed with human usability and not embedded devices in mind. The diagnostic notation is exactly capable of round-tripping binary data to a human readable form and back to binary.
Currently, the best way to send CBOR over defmt is in
{=[u8]:02x}
, so that output such asa1, 04, 41, 2b
can be copy-pasted into the right side of https://cbor.me/, so that after pressing the right-to-left green button, it shows what that means:{4: h'2B'}
. DerivingFormat
on parsed items is an alternative, but it has severe downsides of decreasing severity:more reasons
Format
shows the structure of the parsed item, and manually implementing it to look like CBOR EDN again is manual work (and moreover, there may be situations in which one would want to see the struct's view rather than the original data view)This PR proposes a new hint,
:cbor
, to defmt. If the same data[a1, 04, 41, 2b]
is passed into{=[u8]:cbor}
, the output is then{4: h'2B'}
on display right away, which a developer can make better use of.Note that this is not trying to hard-code an exception to the design choice that we don't take types that then need host knowledge of the type: This is not a concrete type, but a format of data serialization. It can be used with serialized data from a large set of CBOR serializing crates, and a large set of protocols and their implementations in types, using a single mechanism.
Example code
Output:
PR status
This is a working draft, but a bit minimal in that
{=[u8]:cbor}
and not with{:cbor}
-- maybe that's OK, maybe I'd just need to find the right spot in the code to put the code in (which will then need refactoring into a dedicated function)I still ask for review now already because while I've seen some slight positive reaction on the Rust Embedded channel, I don't want to sink too much time in here if the project does not want to go this way at all.