Skip to content

Commit 01f865c

Browse files
committed
Implement serde for BoxedUint
Adapted from #587
1 parent 2734f18 commit 01f865c

File tree

4 files changed

+79
-2
lines changed

4 files changed

+79
-2
lines changed

Cargo.lock

Lines changed: 3 additions & 2 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Cargo.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,7 @@ num-modular = { version = "0.6", features = ["num-bigint", "num-integer", "num-t
3838
proptest = "1.5"
3939
rand_core = { version = "0.9", features = ["std", "os_rng"] }
4040
rand_chacha = "0.9"
41+
serde_json = { version = "1.0.140", features = ["alloc"] }
4142

4243

4344
[features]

src/uint/boxed/encoding.rs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,9 @@ use crate::{DecodeError, Limb, Word, uint::encoding};
55
use alloc::{boxed::Box, string::String, vec::Vec};
66
use subtle::{Choice, CtOption};
77

8+
#[cfg(feature = "serde")]
9+
mod serde;
10+
811
impl BoxedUint {
912
/// Create a new [`BoxedUint`] from the provided big endian bytes.
1013
///

src/uint/boxed/encoding/serde.rs

Lines changed: 72 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,72 @@
1+
use serdect::serde::{Deserialize, Deserializer, Serialize, Serializer, de::Error};
2+
3+
use crate::BoxedUint;
4+
5+
impl<'de> Deserialize<'de> for BoxedUint {
6+
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
7+
where
8+
D: Deserializer<'de>,
9+
{
10+
let slice = serdect::slice::deserialize_hex_or_bin_vec(deserializer)?;
11+
Self::from_le_slice(&slice, slice.len() as u32 * 8).map_err(Error::custom)
12+
}
13+
}
14+
15+
impl Serialize for BoxedUint {
16+
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
17+
where
18+
S: Serializer,
19+
{
20+
serdect::slice::serialize_hex_lower_or_bin(&self.to_le_bytes(), serializer)
21+
}
22+
}
23+
24+
#[cfg(test)]
25+
mod tests {
26+
use super::BoxedUint;
27+
28+
#[test]
29+
fn serde_roundabout() {
30+
let n = BoxedUint::from(11223344u64);
31+
let ser = serde_json::to_string(&n).unwrap();
32+
let de: BoxedUint = serde_json::from_str(&ser).unwrap();
33+
assert_eq!(n, de);
34+
}
35+
36+
#[test]
37+
#[cfg(target_pointer_width = "64")]
38+
fn serde() {
39+
let test: BoxedUint = BoxedUint::from_be_hex("7711223344556600", 64).unwrap();
40+
41+
let serialized = bincode::serialize(&test).unwrap();
42+
let deserialized: BoxedUint = bincode::deserialize(&serialized).unwrap();
43+
44+
assert_eq!(test, deserialized);
45+
}
46+
47+
#[test]
48+
#[cfg(target_pointer_width = "64")]
49+
fn serde_owned() {
50+
let test: BoxedUint = BoxedUint::from_be_hex("7711223344556600", 64).unwrap();
51+
52+
let serialized = bincode::serialize(&test).unwrap();
53+
let deserialized: BoxedUint = bincode::deserialize_from(serialized.as_slice()).unwrap();
54+
55+
assert_eq!(test, deserialized);
56+
}
57+
58+
#[test]
59+
#[cfg(target_pointer_width = "32")]
60+
fn from_le_slice_eq_test() {
61+
let bytes = hex!("7766554433221100");
62+
let box_uint = BoxedUint::from_le_slice(&bytes, 64).unwrap();
63+
64+
let serialized = bincode::serialize(&box_uint).unwrap();
65+
let deserialized: BoxedUint = bincode::deserialize_from(serialized.as_slice()).unwrap();
66+
67+
assert_eq!(
68+
deserialized.as_limbs(),
69+
&[Limb(0x44556677), Limb(0x00112233)]
70+
);
71+
}
72+
}

0 commit comments

Comments
 (0)