-
Notifications
You must be signed in to change notification settings - Fork 226
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
Correct and optimize custom serializers for stringized values, hashes, nullable and optional fields #1351
Merged
Merged
Correct and optimize custom serializers for stringized values, hashes, nullable and optional fields #1351
Changes from all commits
Commits
Show all changes
11 commits
Select commit
Hold shift + click to select a range
5295fef
proto: optimize from_str serializers
mzabaluev 6d8458d
proto: fix round-trip for serializer::nullable
mzabaluev efdb515
tendermint: improve hash serializers
mzabaluev bda754e
tendermint: fix serializers::option_hash
mzabaluev 13d9f74
Changelog entry for #1351
mzabaluev 23102fe
Handle owned values in string deserializers
mzabaluev e20e1db
proto: fix round-trip for serializers::optional
mzabaluev a3e7b5a
Fix build for tests
mzabaluev cb1b603
Changelog entry on breaking changes in #1351
mzabaluev 954aefa
Correct Cow type in serializers::optional_from_str
mzabaluev 185315e
Test owned case in serializers::optional_from_str
mzabaluev File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
16 changes: 16 additions & 0 deletions
16
.changelog/unreleased/breaking-changes/1351-serializer-fixes.md
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,16 @@ | ||
- Changed the serde schema produced by `serialize` functions in these | ||
helper modules ([\#1351](https://github.com/informalsystems/tendermint- | ||
rs/pull/1351)): | ||
|
||
* In `tendermint-proto`: | ||
- `serializers::nullable` | ||
- `serializers::optional` | ||
* In `tendermint`: | ||
- `serializers::apphash` | ||
- `serializers::hash` | ||
- `serializers::option_hash` | ||
|
||
If `serde_json` is used for serialization, the output schema does not change. | ||
But since serde is a generic framework, the changes may be breaking for | ||
other users. Overall, these changes should make the serialized data | ||
acceptable by the corresponding deserializer agnostically of the format. |
3 changes: 3 additions & 0 deletions
3
.changelog/unreleased/improvements/1351-serializer-improvements.md
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
- Corrected custom serializer helpers to consistently produce the format | ||
accepted by the deserializer. Improved performance of deserializers. | ||
([\#1351](https://github.com/informalsystems/tendermint-rs/pull/1351)) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,26 +1,49 @@ | ||
//! `Option<Hash>` serialization with validation | ||
|
||
use serde::{Deserializer, Serializer}; | ||
use alloc::borrow::Cow; | ||
|
||
use serde::{de, Deserialize, Deserializer, Serializer}; | ||
|
||
use super::hash; | ||
use crate::Hash; | ||
use crate::{hash::Algorithm, Hash}; | ||
|
||
/// Deserialize hexstring into `Option<Hash>` | ||
/// Deserialize a nullable hexstring into `Option<Hash>`. | ||
/// A null value is deserialized as `None`. | ||
pub fn deserialize<'de, D>(deserializer: D) -> Result<Option<Hash>, D::Error> | ||
where | ||
D: Deserializer<'de>, | ||
{ | ||
hash::deserialize(deserializer).map(Some) | ||
match Option::<Cow<'_, str>>::deserialize(deserializer)? { | ||
Some(s) => Hash::from_hex_upper(Algorithm::Sha256, &s) | ||
.map(Some) | ||
.map_err(de::Error::custom), | ||
None => Ok(None), | ||
} | ||
} | ||
|
||
/// Serialize from `Option<Hash>` into hexstring | ||
/// Serialize from `Option<Hash>` into a nullable hexstring. None is serialized as null. | ||
pub fn serialize<S>(value: &Option<Hash>, serializer: S) -> Result<S::Ok, S::Error> | ||
where | ||
S: Serializer, | ||
{ | ||
if value.is_none() { | ||
serializer.serialize_none() | ||
} else { | ||
hash::serialize(&value.unwrap(), serializer) | ||
// hash::serialize serializes as Option<String>, so this is consistent | ||
// with the other branch. | ||
hash::serialize(value.as_ref().unwrap(), serializer) | ||
} | ||
} | ||
|
||
#[cfg(test)] | ||
mod tests { | ||
use super::*; | ||
|
||
#[test] | ||
fn none_round_trip() { | ||
let v: Option<Hash> = None; | ||
let json = serde_json::to_string(&v).unwrap(); | ||
let parsed: Option<Hash> = serde_json::from_str(&json).unwrap(); | ||
assert!(parsed.is_none()); | ||
} | ||
} |
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The behaviour of this helper is questionable, before or after this change. If the type has a reasonable default value, why make the domain type field an
Option
? And in the other direction, why uselessly serialize a default value when aNone
would do as well?There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes, It's kind of a head-scratcher!
I see this is derived on fields of certain proto types with
Option<…>
types (e.g. here). Perhaps, those types do not inherently need to be Option. Consequently, they required serde to handle Option this way.