1 use super::{biguint_from_vec, BigUint};
2
3 use crate::std_alloc::Vec;
4
5 use core::{cmp, fmt, mem};
6 use serde::de::{SeqAccess, Visitor};
7 use serde::{Deserialize, Deserializer, Serialize, Serializer};
8
9 // `cautious` is based on the function of the same name in `serde`, but specialized to `u32`:
10 // https://github.com/dtolnay/serde/blob/399ef081ecc36d2f165ff1f6debdcbf6a1dc7efb/serde/src/private/size_hint.rs#L11-L22
cautious(hint: Option<usize>) -> usize11 fn cautious(hint: Option<usize>) -> usize {
12 const MAX_PREALLOC_BYTES: usize = 1024 * 1024;
13
14 cmp::min(
15 hint.unwrap_or(0),
16 MAX_PREALLOC_BYTES / mem::size_of::<u32>(),
17 )
18 }
19
20 impl Serialize for BigUint {
21 #[cfg(not(u64_digit))]
serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error> where S: Serializer,22 fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
23 where
24 S: Serializer,
25 {
26 // Note: do not change the serialization format, or it may break forward
27 // and backward compatibility of serialized data! If we ever change the
28 // internal representation, we should still serialize in base-`u32`.
29 let data: &[u32] = &self.data;
30 data.serialize(serializer)
31 }
32
33 #[cfg(u64_digit)]
serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error> where S: Serializer,34 fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
35 where
36 S: Serializer,
37 {
38 use serde::ser::SerializeSeq;
39
40 if let Some((&last, data)) = self.data.split_last() {
41 let last_lo = last as u32;
42 let last_hi = (last >> 32) as u32;
43 let u32_len = data.len() * 2 + 1 + (last_hi != 0) as usize;
44 let mut seq = serializer.serialize_seq(Some(u32_len))?;
45 for &x in data {
46 seq.serialize_element(&(x as u32))?;
47 seq.serialize_element(&((x >> 32) as u32))?;
48 }
49 seq.serialize_element(&last_lo)?;
50 if last_hi != 0 {
51 seq.serialize_element(&last_hi)?;
52 }
53 seq.end()
54 } else {
55 let data: &[u32] = &[];
56 data.serialize(serializer)
57 }
58 }
59 }
60
61 impl<'de> Deserialize<'de> for BigUint {
deserialize<D>(deserializer: D) -> Result<Self, D::Error> where D: Deserializer<'de>,62 fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
63 where
64 D: Deserializer<'de>,
65 {
66 deserializer.deserialize_seq(U32Visitor)
67 }
68 }
69
70 struct U32Visitor;
71
72 impl<'de> Visitor<'de> for U32Visitor {
73 type Value = BigUint;
74
expecting(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result75 fn expecting(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result {
76 formatter.write_str("a sequence of unsigned 32-bit numbers")
77 }
78
79 #[cfg(not(u64_digit))]
visit_seq<S>(self, mut seq: S) -> Result<Self::Value, S::Error> where S: SeqAccess<'de>,80 fn visit_seq<S>(self, mut seq: S) -> Result<Self::Value, S::Error>
81 where
82 S: SeqAccess<'de>,
83 {
84 let len = cautious(seq.size_hint());
85 let mut data = Vec::with_capacity(len);
86
87 while let Some(value) = seq.next_element::<u32>()? {
88 data.push(value);
89 }
90
91 Ok(biguint_from_vec(data))
92 }
93
94 #[cfg(u64_digit)]
visit_seq<S>(self, mut seq: S) -> Result<Self::Value, S::Error> where S: SeqAccess<'de>,95 fn visit_seq<S>(self, mut seq: S) -> Result<Self::Value, S::Error>
96 where
97 S: SeqAccess<'de>,
98 {
99 use crate::big_digit::BigDigit;
100 use num_integer::Integer;
101
102 let u32_len = cautious(seq.size_hint());
103 let len = Integer::div_ceil(&u32_len, &2);
104 let mut data = Vec::with_capacity(len);
105
106 while let Some(lo) = seq.next_element::<u32>()? {
107 let mut value = BigDigit::from(lo);
108 if let Some(hi) = seq.next_element::<u32>()? {
109 value |= BigDigit::from(hi) << 32;
110 data.push(value);
111 } else {
112 data.push(value);
113 break;
114 }
115 }
116
117 Ok(biguint_from_vec(data))
118 }
119 }
120