22use anyhow:: Result ;
33use bao_tree:: blake3;
44use postcard:: experimental:: max_size:: MaxSize ;
5- use serde:: { de, Deserialize , Deserializer , Serialize , Serializer } ;
5+ use serde:: {
6+ de:: { self , SeqAccess } ,
7+ ser:: SerializeTuple ,
8+ Deserialize , Deserializer , Serialize , Serializer ,
9+ } ;
610use std:: { fmt, result, str:: FromStr } ;
711use thiserror:: Error ;
812pub mod io;
@@ -156,7 +160,13 @@ impl Serialize for Hash {
156160 where
157161 S : Serializer ,
158162 {
159- serializer. serialize_bytes ( self . 0 . as_bytes ( ) )
163+ // Fixed-length structures, including arrays, are supported in Serde as tuples
164+ // See: https://serde.rs/impl-serialize.html#serializing-a-tuple
165+ let mut s = serializer. serialize_tuple ( 32 ) ?;
166+ for item in self . 0 . as_bytes ( ) {
167+ s. serialize_element ( item) ?;
168+ }
169+ s. end ( )
160170 }
161171}
162172
@@ -165,7 +175,7 @@ impl<'de> Deserialize<'de> for Hash {
165175 where
166176 D : Deserializer < ' de > ,
167177 {
168- deserializer. deserialize_bytes ( HashVisitor )
178+ deserializer. deserialize_tuple ( 32 , HashVisitor )
169179 }
170180}
171181
@@ -178,12 +188,22 @@ impl<'de> de::Visitor<'de> for HashVisitor {
178188 write ! ( f, "an array of 32 bytes containing hash data" )
179189 }
180190
181- fn visit_bytes < E > ( self , v : & [ u8 ] ) -> Result < Self :: Value , E >
191+ /// Process a sequence into an array
192+ fn visit_seq < A > ( self , mut seq : A ) -> Result < Self :: Value , A :: Error >
182193 where
183- E : de :: Error ,
194+ A : SeqAccess < ' de > ,
184195 {
185- let bytes: [ u8 ; 32 ] = v. try_into ( ) . map_err ( E :: custom) ?;
186- Ok ( Hash :: from ( bytes) )
196+ let mut arr = [ 0u8 ; 32 ] ;
197+ let mut i = 0 ;
198+ while let Some ( val) = seq. next_element ( ) ? {
199+ arr[ i] = val;
200+ i += 1 ;
201+ if i > 32 {
202+ return Err ( de:: Error :: invalid_length ( i, & self ) ) ;
203+ }
204+ }
205+
206+ Ok ( Hash :: from ( arr) )
187207 }
188208}
189209
@@ -244,6 +264,8 @@ impl NonSend {
244264mod tests {
245265 use super :: * ;
246266
267+ use serde_test:: { assert_tokens, Token } ;
268+
247269 #[ test]
248270 fn test_hash ( ) {
249271 let data = b"hello world" ;
@@ -252,4 +274,30 @@ mod tests {
252274 let encoded = hash. to_string ( ) ;
253275 assert_eq ! ( encoded. parse:: <Hash >( ) . unwrap( ) , hash) ;
254276 }
277+
278+ #[ test]
279+ fn test_hash_serde ( ) {
280+ let hash = Hash :: new ( "hello" ) ;
281+
282+ // Hashes are serialized as 32 tuples
283+ let mut tokens = Vec :: new ( ) ;
284+ tokens. push ( Token :: Tuple { len : 32 } ) ;
285+ for byte in hash. as_bytes ( ) {
286+ tokens. push ( Token :: U8 ( * byte) ) ;
287+ }
288+ tokens. push ( Token :: TupleEnd ) ;
289+ assert_eq ! ( tokens. len( ) , 34 ) ;
290+
291+ assert_tokens ( & hash, & tokens) ;
292+ }
293+
294+ #[ test]
295+ fn test_hash_postcard ( ) {
296+ let hash = Hash :: new ( "hello" ) ;
297+ let ser = postcard:: to_stdvec ( & hash) . unwrap ( ) ;
298+ let de = postcard:: from_bytes ( & ser) . unwrap ( ) ;
299+ assert_eq ! ( hash, de) ;
300+
301+ assert_eq ! ( ser. len( ) , 32 ) ;
302+ }
255303}
0 commit comments