impls.rs
1 // Copyright (c) 2025 ADnet Contributors 2 // This file is part of the AlphaVM 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 16 use std::io::{Read, Write}; 17 18 use crate::{FromBytes, SerializationError, ToBytes, serialize::traits::*}; 19 20 use bincode::Options; 21 22 use std::{borrow::Cow, collections::BTreeMap, marker::PhantomData, rc::Rc, sync::Arc}; 23 24 impl Valid for bool { 25 fn check(&self) -> Result<(), SerializationError> { 26 Ok(()) 27 } 28 } 29 30 impl CanonicalSerialize for bool { 31 #[inline] 32 fn serialize_with_mode<W: Write>(&self, mut writer: W, _compress: Compress) -> Result<(), SerializationError> { 33 Ok(self.write_le(&mut writer)?) 34 } 35 36 #[inline] 37 fn serialized_size(&self, _compress: Compress) -> usize { 38 1 39 } 40 } 41 42 impl CanonicalDeserialize for bool { 43 #[inline] 44 fn deserialize_with_mode<R: Read>( 45 reader: R, 46 _compress: Compress, 47 _validate: Validate, 48 ) -> Result<Self, SerializationError> { 49 Ok(bool::read_le(reader)?) 50 } 51 } 52 53 impl CanonicalSerialize for String { 54 #[inline] 55 fn serialize_with_mode<W: Write>(&self, mut writer: W, _compress: Compress) -> Result<(), SerializationError> { 56 Ok(bincode::serialize_into(&mut writer, self)?) 57 } 58 59 #[inline] 60 fn serialized_size(&self, _compress: Compress) -> usize { 61 self.len() + 8 62 } 63 } 64 65 impl Valid for String { 66 #[inline] 67 fn check(&self) -> Result<(), SerializationError> { 68 Ok(()) 69 } 70 71 #[inline] 72 fn batch_check<'a>(_batch: impl Iterator<Item = &'a Self>) -> Result<(), SerializationError> 73 where 74 Self: 'a, 75 { 76 Ok(()) 77 } 78 } 79 80 impl CanonicalDeserialize for String { 81 #[inline] 82 fn deserialize_with_mode<R: Read>( 83 reader: R, 84 _compress: Compress, 85 _validate: Validate, 86 ) -> Result<Self, SerializationError> { 87 Ok(bincode::DefaultOptions::new() 88 .with_fixint_encoding() // this option is for compatibility with the defaults 89 .allow_trailing_bytes() // so is this 90 .with_limit(10 * 1024) // a limit to guard against OOMs 91 .deserialize_from(reader)?) 92 } 93 } 94 95 macro_rules! impl_canonical_serialization_uint { 96 ($type:ty) => { 97 impl CanonicalSerialize for $type { 98 #[inline] 99 fn serialize_with_mode<W: Write>( 100 &self, 101 mut writer: W, 102 _compress: Compress, 103 ) -> Result<(), SerializationError> { 104 Ok(writer.write_all(&self.to_le_bytes())?) 105 } 106 107 #[inline] 108 fn serialized_size(&self, _compress: Compress) -> usize { 109 std::mem::size_of::<$type>() 110 } 111 } 112 impl Valid for $type { 113 #[inline] 114 fn check(&self) -> Result<(), SerializationError> { 115 Ok(()) 116 } 117 118 #[inline] 119 fn batch_check<'a>(_batch: impl Iterator<Item = &'a Self>) -> Result<(), SerializationError> 120 where 121 Self: 'a, 122 { 123 Ok(()) 124 } 125 } 126 127 impl CanonicalDeserialize for $type { 128 #[inline] 129 fn deserialize_with_mode<R: Read>( 130 mut reader: R, 131 _compress: Compress, 132 _validate: Validate, 133 ) -> Result<Self, SerializationError> { 134 let mut bytes = [0u8; std::mem::size_of::<$type>()]; 135 reader.read_exact(&mut bytes)?; 136 Ok(<$type>::from_le_bytes(bytes)) 137 } 138 } 139 }; 140 } 141 142 impl_canonical_serialization_uint!(u8); 143 impl_canonical_serialization_uint!(u16); 144 impl_canonical_serialization_uint!(u32); 145 impl_canonical_serialization_uint!(u64); 146 147 impl CanonicalSerialize for usize { 148 #[inline] 149 fn serialize_with_mode<W: Write>(&self, mut writer: W, _compress: Compress) -> Result<(), SerializationError> { 150 let u64_value = u64::try_from(*self).map_err(|_| SerializationError::IncompatibleTarget)?; 151 Ok(writer.write_all(&u64_value.to_le_bytes())?) 152 } 153 154 #[inline] 155 fn serialized_size(&self, _compress: Compress) -> usize { 156 8 157 } 158 } 159 160 impl Valid for usize { 161 #[inline] 162 fn check(&self) -> Result<(), SerializationError> { 163 Ok(()) 164 } 165 166 #[inline] 167 fn batch_check<'a>(_batch: impl Iterator<Item = &'a Self>) -> Result<(), SerializationError> 168 where 169 Self: 'a, 170 { 171 Ok(()) 172 } 173 } 174 175 impl CanonicalDeserialize for usize { 176 #[inline] 177 fn deserialize_with_mode<R: Read>( 178 mut reader: R, 179 _compress: Compress, 180 _validate: Validate, 181 ) -> Result<Self, SerializationError> { 182 let u64_value = u64::deserialize_compressed(&mut reader)?; 183 usize::try_from(u64_value).map_err(|_| SerializationError::IncompatibleTarget) 184 } 185 } 186 187 impl<T: CanonicalSerialize> CanonicalSerialize for Option<T> { 188 #[inline] 189 fn serialize_with_mode<W: Write>(&self, mut writer: W, compress: Compress) -> Result<(), SerializationError> { 190 self.is_some().serialize_with_mode(&mut writer, compress)?; 191 if let Some(item) = self { 192 item.serialize_with_mode(&mut writer, compress)?; 193 } 194 195 Ok(()) 196 } 197 198 #[inline] 199 fn serialized_size(&self, compress: Compress) -> usize { 200 bool::serialized_size(&self.is_some(), compress) 201 + self.as_ref().map(|s| s.serialized_size(compress)).unwrap_or(0) 202 } 203 } 204 205 impl<T: Valid> Valid for Option<T> { 206 #[inline] 207 fn check(&self) -> Result<(), SerializationError> { 208 match self { 209 Some(v) => v.check(), 210 None => Ok(()), 211 } 212 } 213 214 #[inline] 215 fn batch_check<'a>(batch: impl Iterator<Item = &'a Self> + Send) -> Result<(), SerializationError> 216 where 217 Self: 'a, 218 { 219 T::batch_check(batch.map(Option::as_ref).filter(Option::is_some).flatten()) 220 } 221 } 222 223 impl<T: CanonicalDeserialize> CanonicalDeserialize for Option<T> { 224 #[inline] 225 fn deserialize_with_mode<R: Read>( 226 mut reader: R, 227 compress: Compress, 228 validate: Validate, 229 ) -> Result<Self, SerializationError> { 230 let is_some = bool::deserialize_with_mode(&mut reader, compress, validate)?; 231 let data = if is_some { Some(T::deserialize_with_mode(&mut reader, compress, validate)?) } else { None }; 232 233 Ok(data) 234 } 235 } 236 237 // No-op 238 impl<T> CanonicalSerialize for std::marker::PhantomData<T> { 239 #[inline] 240 fn serialize_with_mode<W: Write>(&self, _writer: W, _compress: Compress) -> Result<(), SerializationError> { 241 Ok(()) 242 } 243 244 #[inline] 245 fn serialized_size(&self, _compress: Compress) -> usize { 246 0 247 } 248 } 249 250 impl<T: Sync> Valid for PhantomData<T> { 251 #[inline] 252 fn check(&self) -> Result<(), SerializationError> { 253 Ok(()) 254 } 255 } 256 257 impl<T: Send + Sync> CanonicalDeserialize for std::marker::PhantomData<T> { 258 #[inline] 259 fn deserialize_with_mode<R: Read>( 260 _reader: R, 261 _compress: Compress, 262 _validate: Validate, 263 ) -> Result<Self, SerializationError> { 264 Ok(std::marker::PhantomData) 265 } 266 } 267 268 impl<T: CanonicalSerialize + ToOwned> CanonicalSerialize for Rc<T> { 269 #[inline] 270 fn serialize_with_mode<W: Write>(&self, mut writer: W, compress: Compress) -> Result<(), SerializationError> { 271 self.as_ref().serialize_with_mode(&mut writer, compress) 272 } 273 274 #[inline] 275 fn serialized_size(&self, compress: Compress) -> usize { 276 self.as_ref().serialized_size(compress) 277 } 278 } 279 280 // impl<T: Valid> Valid for Rc<T> { 281 // #[inline] 282 // fn check(&self) -> Result<(), SerializationError> { 283 // self.as_ref().check() 284 // } 285 286 // #[inline] 287 288 // fn batch_check<'a>(batch: impl Iterator<Item = &'a Self>) -> Result<(), SerializationError> 289 // where 290 // Self: 'a, 291 // { 292 // T::batch_check(batch.map(|v| v.as_ref())) 293 // } 294 // } 295 296 // impl<T: CanonicalDeserialize + ToOwned> CanonicalDeserialize for Rc<T> { 297 // #[inline] 298 // fn deserialize_with_mode<R: Read>( 299 // reader: R, 300 // compress: Compress, 301 // validate: Validate, 302 // ) -> Result<Self, SerializationError> { 303 // Ok(Rc::new(T::deserialize_with_mode(reader, compress, validate)?)) 304 // } 305 // } 306 307 impl<T: CanonicalSerialize> CanonicalSerialize for Arc<T> { 308 #[inline] 309 fn serialize_with_mode<W: Write>(&self, mut writer: W, compress: Compress) -> Result<(), SerializationError> { 310 self.as_ref().serialize_with_mode(&mut writer, compress) 311 } 312 313 #[inline] 314 fn serialized_size(&self, compress: Compress) -> usize { 315 self.as_ref().serialized_size(compress) 316 } 317 } 318 319 impl<T: Valid + Sync + Send> Valid for Arc<T> { 320 #[inline] 321 fn check(&self) -> Result<(), SerializationError> { 322 self.as_ref().check() 323 } 324 325 #[inline] 326 fn batch_check<'a>(batch: impl Iterator<Item = &'a Self> + Send) -> Result<(), SerializationError> 327 where 328 Self: 'a, 329 { 330 T::batch_check(batch.map(|v| v.as_ref())) 331 } 332 } 333 334 impl<T: CanonicalDeserialize + Sync + Send> CanonicalDeserialize for Arc<T> { 335 #[inline] 336 fn deserialize_with_mode<R: Read>( 337 reader: R, 338 compress: Compress, 339 validate: Validate, 340 ) -> Result<Self, SerializationError> { 341 Ok(Arc::new(T::deserialize_with_mode(reader, compress, validate)?)) 342 } 343 } 344 345 impl<T: CanonicalSerialize + ToOwned> CanonicalSerialize for Cow<'_, T> { 346 #[inline] 347 fn serialize_with_mode<W: Write>(&self, mut writer: W, compress: Compress) -> Result<(), SerializationError> { 348 self.as_ref().serialize_with_mode(&mut writer, compress) 349 } 350 351 #[inline] 352 fn serialized_size(&self, compress: Compress) -> usize { 353 self.as_ref().serialized_size(compress) 354 } 355 } 356 357 // impl<'b, T> Valid for Cow<'b, T> 358 // where 359 // T: ToOwned + Sync + Valid + Send, 360 // <T as ToOwned>::Owned: CanonicalDeserialize + Send + Valid, 361 // { 362 // #[inline] 363 // fn check(&self) -> Result<(), SerializationError> { 364 // <<T as ToOwned>::Owned>::check(self.as_ref().borrow()) 365 // } 366 367 // #[inline] 368 369 // fn batch_check<'a>(batch: impl Iterator<Item = &'a Self>) -> Result<(), SerializationError> 370 // where 371 // Self: 'a 372 // { 373 // <<T as ToOwned>::Owned>::batch_check(batch.map(|v| v.as_ref())) 374 // } 375 // } 376 377 // impl<'a, T> CanonicalDeserialize for Cow<'a, T> 378 // where 379 // T: ToOwned + Valid + Valid + Sync + Send, 380 // <T as ToOwned>::Owned: CanonicalDeserialize + Valid + Send, 381 // { 382 // #[inline] 383 // fn deserialize_with_mode<R: Read>(reader: R, compress: Compress, validate: Validate) -> Result<Self, SerializationError> { 384 // Ok(Cow::Owned(<T as ToOwned>::Owned::deserialize_with_mode(reader, compress, validate)?)) 385 // } 386 // } 387 388 impl<T: CanonicalSerialize> CanonicalSerialize for Vec<T> { 389 #[inline] 390 fn serialize_with_mode<W: Write>(&self, mut writer: W, compress: Compress) -> Result<(), SerializationError> { 391 self.as_slice().serialize_with_mode(&mut writer, compress) 392 } 393 394 #[inline] 395 fn serialized_size(&self, compress: Compress) -> usize { 396 self.as_slice().serialized_size(compress) 397 } 398 } 399 400 impl<T: Valid> Valid for Vec<T> { 401 #[inline] 402 fn check(&self) -> Result<(), SerializationError> { 403 T::batch_check(self.iter()) 404 } 405 406 #[inline] 407 fn batch_check<'a>(batch: impl Iterator<Item = &'a Self> + Send) -> Result<(), SerializationError> 408 where 409 Self: 'a, 410 { 411 T::batch_check(batch.flatten()) 412 } 413 } 414 415 impl<T: CanonicalDeserialize> CanonicalDeserialize for Vec<T> { 416 #[inline] 417 fn deserialize_with_mode<R: Read>( 418 mut reader: R, 419 compress: Compress, 420 validate: Validate, 421 ) -> Result<Self, SerializationError> { 422 let len = u64::deserialize_with_mode(&mut reader, compress, validate)?; 423 let mut values = Vec::new(); 424 let _ = values.try_reserve(len as usize); 425 for _ in 0..len { 426 values.push(T::deserialize_with_mode(&mut reader, compress, Validate::No)?); 427 } 428 429 if let Validate::Yes = validate { 430 T::batch_check(values.iter())? 431 } 432 Ok(values) 433 } 434 } 435 436 impl<T: CanonicalDeserialize + std::fmt::Debug> CanonicalDeserialize for [T; 32] { 437 #[inline] 438 fn deserialize_with_mode<R: Read>( 439 mut reader: R, 440 compress: Compress, 441 validate: Validate, 442 ) -> Result<Self, SerializationError> { 443 let values = [(); 32].map(|_| T::deserialize_with_mode(&mut reader, compress, Validate::No)); 444 445 // check that each value is error free 446 if values.iter().any(|value| value.is_err()) { 447 return Err(SerializationError::InvalidData); 448 } 449 450 let values = values.map(|r| r.unwrap()); 451 452 if let Validate::Yes = validate { 453 T::batch_check(values.iter())? 454 } 455 456 Ok(values) 457 } 458 } 459 460 impl<T: Valid> Valid for [T; 32] { 461 #[inline] 462 fn check(&self) -> Result<(), SerializationError> { 463 T::batch_check(self.iter()) 464 } 465 466 #[inline] 467 fn batch_check<'a>(batch: impl Iterator<Item = &'a Self> + Send) -> Result<(), SerializationError> 468 where 469 Self: 'a, 470 { 471 T::batch_check(batch.flatten()) 472 } 473 } 474 475 impl<T: CanonicalSerialize> CanonicalSerialize for [T] { 476 #[inline] 477 fn serialize_with_mode<W: Write>(&self, mut writer: W, compress: Compress) -> Result<(), SerializationError> { 478 let len = self.len() as u64; 479 len.serialize_with_mode(&mut writer, compress)?; 480 for item in self.iter() { 481 item.serialize_with_mode(&mut writer, compress)?; 482 } 483 Ok(()) 484 } 485 486 #[inline] 487 fn serialized_size(&self, compress: Compress) -> usize { 488 8 + self.iter().map(|item| item.serialized_size(compress)).sum::<usize>() 489 } 490 } 491 492 impl<T: CanonicalSerialize> CanonicalSerialize for [T; 32] { 493 #[inline] 494 fn serialize_with_mode<W: Write>(&self, mut writer: W, compress: Compress) -> Result<(), SerializationError> { 495 for item in self.iter() { 496 item.serialize_with_mode(&mut writer, compress)?; 497 } 498 Ok(()) 499 } 500 501 #[inline] 502 fn serialized_size(&self, compress: Compress) -> usize { 503 8 + self.iter().map(|item| item.serialized_size(compress)).sum::<usize>() 504 } 505 } 506 507 impl<T: CanonicalSerialize> CanonicalSerialize for &'_ [T] { 508 #[inline] 509 fn serialize_with_mode<W: Write>(&self, mut writer: W, compress: Compress) -> Result<(), SerializationError> { 510 (*self).serialize_with_mode(&mut writer, compress) 511 } 512 513 #[inline] 514 fn serialized_size(&self, compress: Compress) -> usize { 515 (*self).serialized_size(compress) 516 } 517 } 518 519 // Implement Serialization for tuples 520 macro_rules! impl_tuple { 521 ($( $ty: ident : $no: tt, )+) => { 522 impl<$($ty, )+> Valid for ($($ty,)+) where 523 $($ty: Valid,)+ 524 { 525 #[inline] 526 fn check(&self) -> Result<(), SerializationError> { 527 $(self.$no.check()?;)* 528 Ok(()) 529 } 530 } 531 532 impl<$($ty, )+> CanonicalSerialize for ($($ty,)+) where 533 $($ty: CanonicalSerialize,)+ 534 { 535 #[inline] 536 fn serialize_with_mode<W: Write>(&self, mut writer: W, compress: Compress) -> Result<(), SerializationError> { 537 $(self.$no.serialize_with_mode(&mut writer, compress)?;)* 538 Ok(()) 539 } 540 541 #[inline] 542 fn serialized_size(&self, compress: Compress) -> usize { 543 [$( 544 self.$no.serialized_size(compress), 545 )*].iter().sum() 546 } 547 } 548 549 impl<$($ty, )+> CanonicalDeserialize for ($($ty,)+) where 550 $($ty: CanonicalDeserialize,)+ 551 { 552 #[inline] 553 fn deserialize_with_mode<R: Read>(mut reader: R, compress: Compress, validate: Validate) -> Result<Self, SerializationError> { 554 Ok(($( 555 $ty::deserialize_with_mode(&mut reader, compress, validate)?, 556 )+)) 557 } 558 } 559 } 560 } 561 562 impl_tuple!(A:0, B:1,); 563 impl_tuple!(A:0, B:1, C:2,); 564 impl_tuple!(A:0, B:1, C:2, D:3,); 565 566 impl<K, V> CanonicalSerialize for BTreeMap<K, V> 567 where 568 K: CanonicalSerialize, 569 V: CanonicalSerialize, 570 { 571 /// Serializes a `BTreeMap` as `len(map) || key 1 || value 1 || ... || key n || value n`. 572 fn serialize_with_mode<W: Write>(&self, mut writer: W, compress: Compress) -> Result<(), SerializationError> { 573 let len = self.len() as u64; 574 len.serialize_with_mode(&mut writer, compress)?; 575 for (k, v) in self.iter() { 576 k.serialize_with_mode(&mut writer, compress)?; 577 v.serialize_with_mode(&mut writer, compress)?; 578 } 579 Ok(()) 580 } 581 582 fn serialized_size(&self, compress: Compress) -> usize { 583 8 + self.iter().map(|(k, v)| k.serialized_size(compress) + v.serialized_size(compress)).sum::<usize>() 584 } 585 } 586 587 impl<K: Valid, V: Valid> Valid for BTreeMap<K, V> { 588 #[inline] 589 fn check(&self) -> Result<(), SerializationError> { 590 K::batch_check(self.keys())?; 591 V::batch_check(self.values()) 592 } 593 594 #[inline] 595 fn batch_check<'a>(batch: impl Iterator<Item = &'a Self>) -> Result<(), SerializationError> 596 where 597 Self: 'a, 598 { 599 let (keys, values): (Vec<_>, Vec<_>) = batch.map(|b| (b.keys(), b.values())).unzip(); 600 K::batch_check(keys.into_iter().flatten())?; 601 V::batch_check(values.into_iter().flatten()) 602 } 603 } 604 605 impl<K, V> CanonicalDeserialize for BTreeMap<K, V> 606 where 607 K: Ord + CanonicalDeserialize, 608 V: CanonicalDeserialize, 609 { 610 /// Deserializes a `BTreeMap` from `len(map) || key 1 || value 1 || ... || key n || value n`. 611 fn deserialize_with_mode<R: Read>( 612 mut reader: R, 613 compress: Compress, 614 validate: Validate, 615 ) -> Result<Self, SerializationError> { 616 let len = u64::deserialize_with_mode(&mut reader, compress, validate)?; 617 let mut map = BTreeMap::new(); 618 for _ in 0..len { 619 map.insert( 620 K::deserialize_with_mode(&mut reader, compress, validate)?, 621 V::deserialize_with_mode(&mut reader, compress, validate)?, 622 ); 623 } 624 Ok(map) 625 } 626 } 627 628 #[cfg(test)] 629 mod test { 630 use super::*; 631 use crate::{deserialize_vec_without_len, serialize_vec_without_len, serialized_vec_size_without_len}; 632 633 fn test_serialize<T: PartialEq + std::fmt::Debug + CanonicalSerialize + CanonicalDeserialize>(data: T) { 634 let combinations = [ 635 (Compress::No, Validate::No), 636 (Compress::Yes, Validate::No), 637 (Compress::No, Validate::Yes), 638 (Compress::Yes, Validate::Yes), 639 ]; 640 for (compress, validate) in combinations { 641 let mut serialized = vec![]; 642 data.serialize_with_mode(&mut serialized, compress).unwrap(); 643 let de = T::deserialize_with_mode(&serialized[..], compress, validate).unwrap(); 644 assert_eq!(data, de); 645 646 assert_eq!(data.serialized_size(compress), serialized.len()); 647 } 648 } 649 650 fn test_serialize_without_len<T: PartialEq + std::fmt::Debug + CanonicalSerialize + CanonicalDeserialize>( 651 data: Vec<T>, 652 ) { 653 let combinations = [ 654 (Compress::No, Validate::No), 655 (Compress::Yes, Validate::No), 656 (Compress::No, Validate::Yes), 657 (Compress::Yes, Validate::Yes), 658 ]; 659 for (compress, validate) in combinations { 660 let len = serialized_vec_size_without_len(&data, compress); 661 let mut serialized = vec![0; len]; 662 serialize_vec_without_len(data.iter(), serialized.as_mut_slice(), compress).unwrap(); 663 let elements = if len > 0 { len / CanonicalSerialize::serialized_size(&data[0], compress) } else { 0 }; 664 let de = deserialize_vec_without_len(serialized.as_slice(), compress, validate, elements).unwrap(); 665 assert_eq!(data, de); 666 } 667 } 668 669 #[test] 670 fn test_bool() { 671 test_serialize(true); 672 test_serialize(false); 673 } 674 675 #[test] 676 fn test_uint() { 677 test_serialize(192830918usize); 678 test_serialize(192830918u64); 679 test_serialize(192830918u32); 680 test_serialize(22313u16); 681 test_serialize(123u8); 682 } 683 684 #[test] 685 fn test_string() { 686 test_serialize("asdf".to_owned()); 687 } 688 689 #[test] 690 fn test_vec() { 691 test_serialize(vec![1u64, 2, 3, 4, 5]); 692 test_serialize(Vec::<u64>::new()); 693 } 694 695 #[test] 696 fn test_vec_without_len() { 697 test_serialize_without_len(vec![1u64, 2, 3, 4, 5]); 698 test_serialize_without_len(Vec::<u64>::new()); 699 } 700 701 #[test] 702 fn test_tuple() { 703 test_serialize((123u64, 234u32, 999u16)); 704 } 705 706 #[test] 707 fn test_tuple_vec() { 708 test_serialize(vec![(123u64, 234u32, 999u16), (123u64, 234u32, 999u16), (123u64, 234u32, 999u16)]); 709 } 710 711 #[test] 712 fn test_option() { 713 test_serialize(Some(3u32)); 714 test_serialize(None::<u32>); 715 } 716 717 #[test] 718 fn test_phantomdata() { 719 test_serialize(std::marker::PhantomData::<u64>); 720 } 721 }