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

to-spec json mapping via serde #558

Draft
wants to merge 34 commits into
base: master
Choose a base branch
from

Conversation

konradjniemiec
Copy link

@konradjniemiec konradjniemiec commented Nov 3, 2021

Addresses #75

First round for draft review.

Adds serde annotations with the json_mapping configuration option. There is also a json option which will config in all the code in serde.rs

Verified using the Google conformance test suite.

All things complete for theoretical initial merging:

  • enums
  • oneofs
  • maps with proper de/serialization for primitives
  • Timestamp fixes
  • Duration fixes

Not intending on addressing before merging:

  • google.protobuf.Any support
  • google.protobuf.Value support
  • google.protobuf.Struct support
  • google.protobuf.FieldMask support
  • failing serialization when multiple oneof options are specified
  • double/timestamp/duration min/max values being inexact when serializing
  • aliased enum name parsing
  • egregious timestamp values

There are a few recommended tests we are also ignoring

All currently failing tests from conformance/failing_tests.txt should fall into one of the above categories ^

@danburkert danburkert self-requested a review November 3, 2021 22:16
danburkert added a commit to danburkert/prost that referenced this pull request Apr 1, 2022
This PR implements to and from string methods for
`prost_types::Timestamp` following the RFC-3339 timestamp format, as
also specified by the [Protobuf JSON mapping spec][1]. The `Display`
impl always emits the Zulu (Z) timezone, whereas the parser is slightly
lenient in accepting fixed timezone offsets, as well as both the `T` and
space seperated date and time portions. This leniency in parsing makes
it much much more robust to parsing data of less-than-pristine
formatting, even though the protobuf spec allows no leniency.

Also, since it was easy with the new date time functionality, we've gone
ahead and added a trio of convenience construct functions to `Timestamp`
which makes it straightforward to create `Timestamp`s out of calendar
date time information.

This functionality will be used in follow-up PRs to add Serde
[de]serialization support to the types in `prost_types`, which is itself
a stepping stone towards full JSON support.

This PR was extracted from tokio-rs#558, and is based on code which myself and
@konradjniemiec have written, and which has been running in production
at @sisudata for a few years. The to-string portion of this code has
also been incorporated into [`tracing`][2], so it should be pretty well
battle hardened.

[1]: https://developers.google.com/protocol-buffers/docs/proto3#json
[2]: https://github.com/tokio-rs/tracing/blob/master/tracing-subscriber/src/fmt/time/datetime.rs
danburkert added a commit to danburkert/prost that referenced this pull request Apr 5, 2022
This PR implements to and from string methods for
`prost_types::Timestamp` following the RFC-3339 timestamp format, as
also specified by the [Protobuf JSON mapping spec][1]. The `Display`
impl always emits the Zulu (Z) timezone, whereas the parser is slightly
lenient in accepting fixed timezone offsets, as well as both the `T` and
space seperated date and time portions. This leniency in parsing makes
it much much more robust to parsing data of less-than-pristine
formatting, even though the protobuf spec allows no leniency.

Also, since it was easy with the new date time functionality, we've gone
ahead and added a trio of convenience construct functions to `Timestamp`
which makes it straightforward to create `Timestamp`s out of calendar
date time information.

This functionality will be used in follow-up PRs to add Serde
[de]serialization support to the types in `prost_types`, which is itself
a stepping stone towards full JSON support.

This PR was extracted from tokio-rs#558, and is based on code which myself and
@konradjniemiec have written, and which has been running in production
at @sisudata for a few years. The to-string portion of this code has
also been incorporated into [`tracing`][2], so it should be pretty well
battle hardened.

[1]: https://developers.google.com/protocol-buffers/docs/proto3#json
[2]: https://github.com/tokio-rs/tracing/blob/master/tracing-subscriber/src/fmt/time/datetime.rs
danburkert added a commit to sisudata/prost that referenced this pull request Apr 7, 2022
This PR implements to and from string methods for
`prost_types::Timestamp` following the RFC-3339 timestamp format, as
also specified by the [Protobuf JSON mapping spec][1]. The `Display`
impl always emits the Zulu (Z) timezone, whereas the parser is slightly
lenient in accepting fixed timezone offsets, as well as both the `T` and
space seperated date and time portions. This leniency in parsing makes
it much much more robust to parsing data of less-than-pristine
formatting, even though the protobuf spec allows no leniency.

Also, since it was easy with the new date time functionality, we've gone
ahead and added a trio of convenience construct functions to `Timestamp`
which makes it straightforward to create `Timestamp`s out of calendar
date time information.

This functionality will be used in follow-up PRs to add Serde
[de]serialization support to the types in `prost_types`, which is itself
a stepping stone towards full JSON support.

This PR was extracted from tokio-rs#558, and is based on code which myself and
@konradjniemiec have written, and which has been running in production
at @sisudata for a few years. The to-string portion of this code has
also been incorporated into [`tracing`][2], so it should be pretty well
battle hardened.

[1]: https://developers.google.com/protocol-buffers/docs/proto3#json
[2]: https://github.com/tokio-rs/tracing/blob/master/tracing-subscriber/src/fmt/time/datetime.rs
danburkert added a commit to danburkert/prost that referenced this pull request Apr 14, 2022
This PR implements to and from string methods for
`prost_types::Timestamp` following the RFC-3339 timestamp format, as
also specified by the [Protobuf JSON mapping spec][1]. The `Display`
impl always emits the Zulu (Z) timezone, whereas the parser is slightly
lenient in accepting fixed timezone offsets, as well as both the `T` and
space seperated date and time portions. This leniency in parsing makes
it much much more robust to parsing data of less-than-pristine
formatting, even though the protobuf spec allows no leniency.

Also, since it was easy with the new date time functionality, we've gone
ahead and added a trio of convenience construct functions to `Timestamp`
which makes it straightforward to create `Timestamp`s out of calendar
date time information.

This functionality will be used in follow-up PRs to add Serde
[de]serialization support to the types in `prost_types`, which is itself
a stepping stone towards full JSON support.

This PR was extracted from tokio-rs#558, and is based on code which myself and
@konradjniemiec have written, and which has been running in production
at @sisudata for a few years. The to-string portion of this code has
also been incorporated into [`tracing`][2], so it should be pretty well
battle hardened.

[1]: https://developers.google.com/protocol-buffers/docs/proto3#json
[2]: https://github.com/tokio-rs/tracing/blob/master/tracing-subscriber/src/fmt/time/datetime.rs
danburkert added a commit that referenced this pull request Apr 14, 2022
This PR implements to and from string methods for
`prost_types::Timestamp` following the RFC-3339 timestamp format, as
also specified by the [Protobuf JSON mapping spec][1]. The `Display`
impl always emits the Zulu (Z) timezone, whereas the parser is slightly
lenient in accepting fixed timezone offsets, as well as both the `T` and
space seperated date and time portions. This leniency in parsing makes
it much much more robust to parsing data of less-than-pristine
formatting, even though the protobuf spec allows no leniency.

Also, since it was easy with the new date time functionality, we've gone
ahead and added a trio of convenience construct functions to `Timestamp`
which makes it straightforward to create `Timestamp`s out of calendar
date time information.

This functionality will be used in follow-up PRs to add Serde
[de]serialization support to the types in `prost_types`, which is itself
a stepping stone towards full JSON support.

This PR was extracted from #558, and is based on code which myself and
@konradjniemiec have written, and which has been running in production
at @sisudata for a few years. The to-string portion of this code has
also been incorporated into [`tracing`][2], so it should be pretty well
battle hardened.

[1]: https://developers.google.com/protocol-buffers/docs/proto3#json
[2]: https://github.com/tokio-rs/tracing/blob/master/tracing-subscriber/src/fmt/time/datetime.rs
@oldgalileo
Copy link

@konradjniemiec @danburkert I saw a mention that this was being used at @sisudata and I'm curious if that extends to the JSON parsing as well, and/or if this is the latest given more recent (April 2022) activity around some of this. Generally, this seems like it's a good start to moving JSON support along. Would be interested in hopping on this to keep the ball rolling if this has stalled!

@konradjniemiec
Copy link
Author

Hey @oldgalileo I'd love some help on this if you have some time. In the last working state, this is fully functional for most use cases (you can check the failing_tests.txt for things that don't work)

I think to get these to merge ready:

  1. Merge back with upstream changes since @danburkert merged some of the timestamp functionality separately.
  2. Make sure CI runs, especially since I broke the no-std testing suite.
  3. Add any additional support you think is important from the conformance/failing_tests.txt

I think cargo test -p conformance runs the test suite if I remember correctly

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.

3 participants