serde.rs 4.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118
  1. use crate::arch::word::Word;
  2. use crate::buffer::Buffer;
  3. use crate::ibig::IBig;
  4. use crate::primitive::WORD_BITS_USIZE;
  5. use crate::ubig::UBig;
  6. use alloc::vec::Vec;
  7. use core::fmt::{self, Formatter};
  8. use serde::de::{Deserialize, Deserializer, SeqAccess, Visitor};
  9. use serde::ser::{Serialize, SerializeSeq, Serializer};
  10. use static_assertions::const_assert;
  11. const_assert!(64 % WORD_BITS_USIZE == 0);
  12. const WORDS_PER_U64: usize = 64 / WORD_BITS_USIZE;
  13. impl Serialize for UBig {
  14. #[allow(clippy::useless_conversion)]
  15. fn serialize<S: Serializer>(&self, serializer: S) -> Result<S::Ok, S::Error> {
  16. let chunks = self.as_words().chunks(WORDS_PER_U64);
  17. let mut seq = serializer.serialize_seq(Some(chunks.len()))?;
  18. for chunk in chunks {
  19. let mut word_u64: u64 = 0;
  20. for (i, word) in chunk.iter().enumerate() {
  21. word_u64 |= u64::from(*word) << (i * WORD_BITS_USIZE);
  22. }
  23. seq.serialize_element(&word_u64)?;
  24. }
  25. seq.end()
  26. }
  27. }
  28. impl<'de> Deserialize<'de> for UBig {
  29. fn deserialize<D: Deserializer<'de>>(deserializer: D) -> Result<Self, D::Error> {
  30. deserializer.deserialize_seq(UBigVisitor)
  31. }
  32. }
  33. struct UBigVisitor;
  34. impl<'de> Visitor<'de> for UBigVisitor {
  35. type Value = UBig;
  36. fn expecting(&self, f: &mut Formatter) -> fmt::Result {
  37. write!(f, "a sequence of 64-bit words")
  38. }
  39. fn visit_seq<A: SeqAccess<'de>>(self, mut seq: A) -> Result<UBig, A::Error> {
  40. match seq.size_hint() {
  41. Some(0) => {
  42. assert!(seq.next_element::<u64>()?.is_none());
  43. Ok(UBig::from_word(0))
  44. }
  45. Some(1) => {
  46. let word_64: u64 = seq.next_element()?.expect(&format!(
  47. "Called `expect()` at {}:{} (git sha: {})",
  48. file!(),
  49. line!(),
  50. env!("GIT_SHA")
  51. ));
  52. assert!(seq.next_element::<u64>()?.is_none());
  53. Ok(UBig::from(word_64))
  54. }
  55. Some(num_words_64) => {
  56. let mut buffer = Buffer::allocate(len_64_to_max_len(num_words_64));
  57. for _ in 0..num_words_64 {
  58. let word_64: u64 = seq.next_element()?.expect(&format!(
  59. "Called `expect()` at {}:{} (git sha: {})",
  60. file!(),
  61. line!(),
  62. env!("GIT_SHA")
  63. ));
  64. push_word_64(&mut buffer, word_64);
  65. }
  66. assert!(seq.next_element::<u64>()?.is_none());
  67. Ok(buffer.into())
  68. }
  69. None => {
  70. let mut words_64 = Vec::new();
  71. while let Some(word_64) = seq.next_element()? {
  72. words_64.push(word_64);
  73. }
  74. let mut buffer = Buffer::allocate(len_64_to_max_len(words_64.len()));
  75. for word_64 in words_64 {
  76. push_word_64(&mut buffer, word_64);
  77. }
  78. Ok(buffer.into())
  79. }
  80. }
  81. }
  82. }
  83. fn push_word_64(buffer: &mut Buffer, word_64: u64) {
  84. for i in 0..WORDS_PER_U64 {
  85. buffer.push((word_64 >> (i * WORD_BITS_USIZE)) as Word);
  86. }
  87. }
  88. #[allow(clippy::absurd_extreme_comparisons)]
  89. fn len_64_to_max_len(len_64: usize) -> usize {
  90. // Make sure we always have enough space for leading zero Words.
  91. const_assert!(Buffer::MAX_CAPACITY - UBig::MAX_LEN >= WORDS_PER_U64 - 1);
  92. #[allow(clippy::redundant_closure)]
  93. len_64
  94. .checked_mul(WORDS_PER_U64)
  95. .unwrap_or_else(|| UBig::panic_number_too_large())
  96. }
  97. impl Serialize for IBig {
  98. fn serialize<S: Serializer>(&self, serializer: S) -> Result<S::Ok, S::Error> {
  99. (self.sign(), self.magnitude()).serialize(serializer)
  100. }
  101. }
  102. impl<'de> Deserialize<'de> for IBig {
  103. fn deserialize<D: Deserializer<'de>>(deserializer: D) -> Result<Self, D::Error> {
  104. let (sign, magnitude) = Deserialize::deserialize(deserializer)?;
  105. Ok(IBig::from_sign_magnitude(sign, magnitude))
  106. }
  107. }