Skip to content
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

feat(serde)!: use internal serialization to roundtrip crate types #135

Merged
merged 1 commit into from Nov 25, 2022

Conversation

martinohmann
Copy link
Owner

@martinohmann martinohmann commented Nov 25, 2022

BREAKING CHANGE: hcl::ser::Serializer does not implement serde::Serializer anymore. Use serializer.serialize(&value) in places where value.serialize(&mut serializer) was used before.

This essentially uses the approach that the author of minijinja describes in this blog post: https://lucumr.pocoo.org/2021/11/14/abusing-serde/

I originally read this before I even added serialization support to hcl-rs and decided back then to go without internal serialization.

However, the number of types involved to represent the HCL structural, expression and template languages now makes it necessary to switch to internal serialization since each type needs a custom serializer implementation just for the sake of roundtripping it through serde. The amount of code that I wrote to make this work is already quite massive and would even get bigger once serialization of template via serde is fully supported. Also it was quite messy.

Thus, I switched to internal serialization to roundtrip all expression and structure types. This meant that I could remove a lot of custom serializers.

This also had some positive side effects:

  • The #[serde(rename = "$hcl::...")] markers could be removed almost everywhere since they were only needed to make the roundtripping through serde work. The only type that still has this marker is Body since we need to special-case it during deserialization.
  • The serializer code is much cleaner now.
  • Serialization of types that are subject to roundtripping is quite a bit faster.
  • It is now possible (and this change already implements most of it) to properly support serialization of HCL blocks (with or without labels) from custom types. The public API and documentation for this will be added as a followup. The custom_blocks test in src/structure/ser/tests.rs should give a first hint how this will work.

BREAKING CHANGE: `hcl::ser::Serializer` does not implement
`serde::Serializer` anymore. Use `serializer.serialize(&value)` in
places where `value.serialize(&mut serializer)` was used before.

This essentially uses the approach that the author of `minijinja`
describes in this blog post: https://lucumr.pocoo.org/2021/11/14/abusing-serde/

I originally read this before I even added serialization support to
`hcl-rs` and decided back then to go without internal serialization.

However, the number of types involved to represent the HCL structural,
expression and template languages now makes it necessary to switch to
internal serialization since each type needs a custom serializer
implementation just for the sake of roundtripping it through `serde`.
The amount of code that I wrote to make this work is already quite
massive and would even get bigger once serialization of template via
`serde` is fully supported. Also it was quite messy.

Thus, I switched to internal serialization to roundtrip all expression
and structure types. This meant that I could remove a lot of custom
serializers.

This also had some positive side effects:

- The `#[serde(rename = "$hcl::...")]` markers could be removed almost
  everywhere since they were only needed to make the roundtripping
  through serde work. The only type that still has this marker is `Body`
  since we need to special-case it during deserialization.
- The serializer code is much cleaner now.
- It is now possible (and this change already implements most of it) to
  properly support serialization of HCL blocks (with or without labels)
  from custom types. The public API and documentation for this will be
  added as a followup. The `custom_blocks` test in
  `src/structure/ser/tests.rs` should give a first hint how this will
  work.
@martinohmann martinohmann merged commit fbd555b into main Nov 25, 2022
@martinohmann martinohmann deleted the internal-serialization branch November 25, 2022 19:44
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

1 participant