tendermint_proto/serializers/
part_set_header_total.rs

1//! Serialize and deserialize part_set_header.total (from string or u32), (into u32 in
2//! part_set_header.total).
3//!
4//! The deserializer is created for backwards compatibility: `total` was changed from a
5//! string-quoted integer value into an integer value without quotes in Tendermint Core v0.34.0.
6//! This deserializer allows backwards-compatibility by deserializing both ways.
7//! See also: <https://github.com/informalsystems/tendermint-rs/issues/679>
8
9use core::fmt::Formatter;
10
11use serde::{
12    de::{Error, Visitor},
13    Deserializer, Serialize, Serializer,
14};
15
16use crate::prelude::*;
17
18struct PartSetHeaderTotalStringOrU32;
19
20/// Deserialize (string or u32) into u32(part_set_header.total)
21pub fn deserialize<'de, D>(deserializer: D) -> Result<u32, D::Error>
22where
23    D: Deserializer<'de>,
24{
25    deserializer.deserialize_any(PartSetHeaderTotalStringOrU32)
26}
27
28/// Serialize from u32(part_set_header.total) into u32
29pub fn serialize<S>(value: &u32, serializer: S) -> Result<S::Ok, S::Error>
30where
31    S: Serializer,
32{
33    value.serialize(serializer)
34}
35
36impl Visitor<'_> for PartSetHeaderTotalStringOrU32 {
37    type Value = u32;
38
39    fn expecting(&self, formatter: &mut Formatter<'_>) -> core::fmt::Result {
40        formatter.write_str("an integer or string between 0 and 2^32")
41    }
42
43    fn visit_u64<E>(self, v: u64) -> Result<Self::Value, E>
44    where
45        E: Error,
46    {
47        u32::try_from(v).map_err(|e| E::custom(format!("part_set_header.total {e}")))
48    }
49
50    fn visit_i64<E>(self, v: i64) -> Result<Self::Value, E>
51    where
52        E: Error,
53    {
54        u32::try_from(v).map_err(|e| E::custom(format!("part_set_header.total {e}")))
55    }
56
57    fn visit_str<E>(self, v: &str) -> Result<Self::Value, E>
58    where
59        E: Error,
60    {
61        v.parse::<u32>()
62            .map_err(|e| E::custom(format!("part_set_header.total {e}")))
63    }
64}