alloy_primitives/log/
serde.rs1use crate::{Address, Log};
14use serde::{Deserialize, Deserializer, Serialize, Serializer};
15
16#[derive(Serialize)]
17#[serde(rename = "Log")]
18struct LogFlattenSerializer<'a, T> {
19 address: &'a Address,
20 #[serde(flatten)]
21 data: &'a T,
22}
23
24#[derive(Deserialize)]
25#[serde(rename = "Log")]
26struct LogFlattenDeserializer<T> {
27 address: Address,
28 #[serde(flatten)]
29 data: T,
30}
31
32#[derive(Serialize)]
33#[serde(rename = "Log")]
34struct LogUnflattenSerializer<'a, T> {
35 address: &'a Address,
36 data: &'a T,
37}
38
39#[derive(Deserialize)]
40#[serde(rename = "Log")]
41struct LogUnflattenDeserializer<T> {
42 address: Address,
43 data: T,
44}
45
46impl<T: Serialize> Serialize for Log<T> {
47 fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
48 where
49 S: Serializer,
50 {
51 let Self { address, data } = self;
52 if serializer.is_human_readable() {
53 let replace = LogFlattenSerializer { address, data };
54 replace.serialize(serializer)
55 } else {
56 let replace = LogUnflattenSerializer { address, data };
57 replace.serialize(serializer)
58 }
59 }
60}
61
62impl<'de, T: Deserialize<'de>> Deserialize<'de> for Log<T> {
63 fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
64 where
65 D: Deserializer<'de>,
66 {
67 if deserializer.is_human_readable() {
68 let LogFlattenDeserializer { address, data } = <_>::deserialize(deserializer)?;
69 Ok(Self { address, data })
70 } else {
71 let LogUnflattenDeserializer { address, data } = <_>::deserialize(deserializer)?;
72 Ok(Self { address, data })
73 }
74 }
75}
76
77#[cfg(test)]
78mod tests {
79 use crate::{
80 log::{Log, LogData},
81 Bytes,
82 };
83 use alloc::vec::Vec;
84
85 #[derive(Debug, PartialEq, serde::Serialize, serde::Deserialize)]
86 struct TestStruct {
87 logs: Vec<Log>,
88 }
89
90 fn gen_test_struct() -> TestStruct {
91 TestStruct {
93 logs: vec![Log {
94 address: address!("0x3100000000000000000000000000000000000001"),
95 data: LogData::new(
96 vec![b256!("0x32eff959e2e8d1609edc4b39ccf75900aa6c1da5719f8432752963fdf008234f")],
97 Bytes::from_static(b"00000000000000000000000000000000000000000000000000000000000000021e9dbc1a11f8e046a72d1296cc2d8bb0d1544d56fd0b9bb8890a0f89b88036541e9dbc1a11f8e046a72d1296cc2d8bb0d1544d56fd0b9bb8890a0f89b8803654"),
98 ).unwrap(),
99 }],
100 }
101 }
102
103 #[test]
104 fn test_log_bincode_roundtrip() {
105 let generated = gen_test_struct();
106
107 let bytes = bincode::serialize(&generated).unwrap();
108 let parsed: TestStruct = bincode::deserialize(&bytes).unwrap();
109 assert_eq!(generated, parsed);
110 }
111
112 #[test]
113 fn test_log_bcs_roundtrip() {
114 let generated = gen_test_struct();
115
116 let bytes = bcs::to_bytes(&generated).unwrap();
117 let parsed: TestStruct = bcs::from_bytes(&bytes).unwrap();
118 assert_eq!(generated, parsed);
119 }
120
121 #[test]
122 fn test_log_json_roundtrip() {
123 let expected = "{\"logs\":[{\"address\":\"0x3100000000000000000000000000000000000001\",\"topics\":[\"0x32eff959e2e8d1609edc4b39ccf75900aa6c1da5719f8432752963fdf008234f\"],\"data\":\"0x303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030323165396462633161313166386530343661373264313239366363326438626230643135343464353666643062396262383839306130663839623838303336353431653964626331613131663865303436613732643132393663633264386262306431353434643536666430623962623838393061306638396238383033363534\"}]}";
124
125 let parsed: TestStruct = serde_json::from_str(expected).unwrap();
126 let dumped = serde_json::to_string(&parsed).unwrap();
127
128 assert_eq!(expected, dumped);
129 }
130}