snarkvm_ledger_store/block/confirmed_tx_type/
serialize.rs

1// Copyright (c) 2019-2025 Provable Inc.
2// This file is part of the snarkVM library.
3
4// Licensed under the Apache License, Version 2.0 (the "License");
5// you may not use this file except in compliance with the License.
6// You may obtain a copy of the License at:
7
8// http://www.apache.org/licenses/LICENSE-2.0
9
10// Unless required by applicable law or agreed to in writing, software
11// distributed under the License is distributed on an "AS IS" BASIS,
12// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13// See the License for the specific language governing permissions and
14// limitations under the License.
15
16use super::*;
17
18impl<N: Network> Serialize for ConfirmedTxType<N> {
19    #[inline]
20    fn serialize<S: Serializer>(&self, serializer: S) -> Result<S::Ok, S::Error> {
21        match serializer.is_human_readable() {
22            true => match self {
23                Self::AcceptedDeploy(index) => {
24                    let mut confirmed_tx_type = serializer.serialize_struct("ConfirmedTxType", 2)?;
25                    confirmed_tx_type.serialize_field("type", "AcceptedDeploy")?;
26                    confirmed_tx_type.serialize_field("index", index)?;
27                    confirmed_tx_type.end()
28                }
29                Self::AcceptedExecute(index) => {
30                    let mut confirmed_tx_type = serializer.serialize_struct("ConfirmedTxType", 2)?;
31                    confirmed_tx_type.serialize_field("type", "AcceptedExecute")?;
32                    confirmed_tx_type.serialize_field("index", index)?;
33                    confirmed_tx_type.end()
34                }
35                Self::RejectedDeploy(index, rejected) => {
36                    let mut confirmed_tx_type = serializer.serialize_struct("ConfirmedTxType", 3)?;
37                    confirmed_tx_type.serialize_field("type", "RejectedDeploy")?;
38                    confirmed_tx_type.serialize_field("index", index)?;
39                    confirmed_tx_type.serialize_field("rejected", rejected)?;
40                    confirmed_tx_type.end()
41                }
42                Self::RejectedExecute(index, rejected) => {
43                    let mut confirmed_tx_type = serializer.serialize_struct("ConfirmedTxType", 3)?;
44                    confirmed_tx_type.serialize_field("type", "RejectedExecute")?;
45                    confirmed_tx_type.serialize_field("index", index)?;
46                    confirmed_tx_type.serialize_field("rejected", rejected)?;
47                    confirmed_tx_type.end()
48                }
49            },
50            false => ToBytesSerializer::serialize_with_size_encoding(self, serializer),
51        }
52    }
53}
54
55impl<'de, N: Network> Deserialize<'de> for ConfirmedTxType<N> {
56    #[inline]
57    fn deserialize<D: Deserializer<'de>>(deserializer: D) -> Result<Self, D::Error> {
58        match deserializer.is_human_readable() {
59            true => {
60                let mut confirmed_tx_type = serde_json::Value::deserialize(deserializer)?;
61                let type_: String = DeserializeExt::take_from_value::<D>(&mut confirmed_tx_type, "type")?;
62
63                // Recover the confirmed transaction type.
64                match type_.as_str() {
65                    "AcceptedDeploy" => Ok(Self::AcceptedDeploy(
66                        DeserializeExt::take_from_value::<D>(&mut confirmed_tx_type, "index")
67                            .map_err(de::Error::custom)?,
68                    )),
69                    "AcceptedExecute" => Ok(Self::AcceptedExecute(
70                        DeserializeExt::take_from_value::<D>(&mut confirmed_tx_type, "index")
71                            .map_err(de::Error::custom)?,
72                    )),
73                    "RejectedDeploy" => {
74                        let index = DeserializeExt::take_from_value::<D>(&mut confirmed_tx_type, "index")
75                            .map_err(de::Error::custom)?;
76                        let rejected = DeserializeExt::take_from_value::<D>(&mut confirmed_tx_type, "rejected")
77                            .map_err(de::Error::custom)?;
78                        Ok(Self::RejectedDeploy(index, rejected))
79                    }
80                    "RejectedExecute" => {
81                        let index = DeserializeExt::take_from_value::<D>(&mut confirmed_tx_type, "index")
82                            .map_err(de::Error::custom)?;
83                        let rejected = DeserializeExt::take_from_value::<D>(&mut confirmed_tx_type, "rejected")
84                            .map_err(de::Error::custom)?;
85                        Ok(Self::RejectedExecute(index, rejected))
86                    }
87                    _ => Err(de::Error::custom(error("Invalid confirmed transaction type"))),
88                }
89            }
90            false => FromBytesDeserializer::<Self>::deserialize_with_size_encoding(
91                deserializer,
92                "confirmed transaction type",
93            ),
94        }
95    }
96}
97
98#[cfg(test)]
99mod tests {
100    use super::*;
101
102    fn check_serde_json<
103        T: Serialize + for<'a> Deserialize<'a> + Debug + Display + PartialEq + Eq + FromStr + ToBytes + FromBytes,
104    >(
105        expected: T,
106    ) {
107        // Serialize
108        let expected_string = expected.to_string();
109        let candidate_string = serde_json::to_string(&expected).unwrap();
110        let candidate = serde_json::from_str::<T>(&candidate_string).unwrap();
111        assert_eq!(expected, candidate);
112        assert_eq!(expected_string, candidate_string);
113        assert_eq!(expected_string, candidate.to_string());
114
115        // Deserialize
116        assert_eq!(expected, T::from_str(&expected_string).unwrap_or_else(|_| panic!("FromStr: {expected_string}")));
117        assert_eq!(expected, serde_json::from_str(&candidate_string).unwrap());
118    }
119
120    fn check_bincode<
121        T: Serialize + for<'a> Deserialize<'a> + Debug + Display + PartialEq + Eq + FromStr + ToBytes + FromBytes,
122    >(
123        expected: T,
124    ) {
125        // Serialize
126        let expected_bytes = expected.to_bytes_le().unwrap();
127        let expected_bytes_with_size_encoding = bincode::serialize(&expected).unwrap();
128        assert_eq!(&expected_bytes[..], &expected_bytes_with_size_encoding[8..]);
129
130        // Deserialize
131        assert_eq!(expected, T::read_le(&expected_bytes[..]).unwrap());
132        assert_eq!(expected, bincode::deserialize(&expected_bytes_with_size_encoding[..]).unwrap());
133    }
134
135    #[test]
136    fn test_serde_json() {
137        for rejected in crate::confirmed_tx_type::test_helpers::sample_confirmed_tx_types() {
138            check_serde_json(rejected);
139        }
140    }
141
142    #[test]
143    fn test_bincode() {
144        for rejected in crate::confirmed_tx_type::test_helpers::sample_confirmed_tx_types() {
145            check_bincode(rejected);
146        }
147    }
148}