Skip to content
This repository has been archived by the owner on Mar 25, 2024. It is now read-only.

Support emitting comments, blocks and alternate integer encodings in serialized output #234

Closed
wants to merge 4 commits into from

Conversation

cfrantz
Copy link

@cfrantz cfrantz commented Feb 8, 2022

This PR represents a first attempt at allowing serde-yaml to emit comments, multi-line string blocks and alternate integer encodings in serialized output.

Why might you want this

I have a number of tools in which I want to emit human & machine readable outputs. Some of the outputs represent data from hardware devices (e.g. SPI eeproms) or low-level information about hardware (CPU addresses, register values). For human readability, it is often more convenient represent these integers as hex or binary.

Furthermore, since some of my tools are diagnostic in nature, it is convenient to have comments which would either show the breakdown of register bitfields or to tell the user what a particular value should be: ie: the signature field of a SPI eeprom's SFDP header should be the value 0x50444653 (aka 'SFDP'). See the samples in tests/test_format.rs.

The implementation

In order to accomplish this, I have some as-yet uncommitted changes to the rust-yaml library which permit emitting comments and multi-line string blocks.

Within the serde-yaml library, I've added a procedural macro which allows the user to derive YamlFormat on a struct and specify attributes which inform the serializer about the preferred output forms (e.g. #[yaml(format=hex, comment="CPU Address")]).

The generated code uses the inventory crate to remember the type-ids of every struct for which YamlFormat is derived. During serialization, the type-id of each struct is looked up and if the struct has YamlFormat, it is queried for preferred output forms and comments and the serializer formats the output accordingly.

Concerns

This is my first go at this sort of thing.

  • A lot of the proc macro is cribbed from looking at thiserror and some of your other work.
  • I don't really understand the relationship between 'static and std::any::TypeId (ie: why should TypeId care about 'static?) and have written my own type-id function based on this example.
  • I'm not sure I've taken the best approach within the serializer.
  • I think I should re-work my extensions to yaml-rust a bit: relocate all of my extensions under a single variant within the Yaml enum.

Chris Frantz added 4 commits December 30, 2021 17:05
Yaml formatting includes:
- Emitting numbers in the various bases supported by Yaml.
- Emitting strings as block scalars.
- Emitting comments along with struct fields to improve human readability.

These emitter enhancments are facilitated by a derivable YamlFormat
trait which allow the schema (struct) author to declare the desired
formatting and comments on a field-by-field basis.

Signed-off-by: Chris Frantz <frantzcj@gmail.com>
Signed-off-by: Chris Frantz <frantzcj@gmail.com>
Signed-off-by: Chris Frantz <frantzcj@gmail.com>
Signed-off-by: Chris Frantz <frantzcj@gmail.com>
Copy link
Owner

@dtolnay dtolnay left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for the PR. I am not interested in this for this library, but somebody could perhaps maintain a different yaml crate for this use case.

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants