forest_bigint/
bigint_ser.rs1use num_bigint::{BigInt, Sign};
5use serde::{Deserialize, Serialize};
6use std::borrow::Cow;
7
8#[derive(Serialize)]
10#[serde(transparent)]
11pub struct BigIntSer<'a>(#[serde(with = "self")] pub &'a BigInt);
12
13#[derive(Deserialize, Serialize, Clone, Default, PartialEq)]
15#[serde(transparent)]
16pub struct BigIntDe(#[serde(with = "self")] pub BigInt);
17
18pub fn serialize<S>(int: &BigInt, serializer: S) -> Result<S::Ok, S::Error>
20where
21 S: serde::Serializer,
22{
23 let (sign, mut bz) = int.to_bytes_be();
24
25 match sign {
27 Sign::Minus => bz.insert(0, 1),
28 Sign::Plus => bz.insert(0, 0),
29 Sign::NoSign => bz = Vec::new(),
30 }
31
32 serde_bytes::Serialize::serialize(&bz, serializer)
34}
35
36pub fn deserialize<'de, D>(deserializer: D) -> Result<BigInt, D::Error>
38where
39 D: serde::Deserializer<'de>,
40{
41 let bz: Cow<'de, [u8]> = serde_bytes::Deserialize::deserialize(deserializer)?;
42 if bz.is_empty() {
43 return Ok(BigInt::default());
44 }
45 let sign_byte = bz[0];
46 let sign: Sign = match sign_byte {
47 1 => Sign::Minus,
48 0 => Sign::Plus,
49 _ => {
50 return Err(serde::de::Error::custom(
51 "First byte must be valid sign (0, 1)",
52 ));
53 }
54 };
55 Ok(BigInt::from_bytes_be(sign, &bz[1..]))
56}
57
58#[cfg(feature = "json")]
59pub mod json {
60 use super::*;
61 use std::str::FromStr;
62
63 pub fn serialize<S>(int: &BigInt, serializer: S) -> Result<S::Ok, S::Error>
65 where
66 S: serde::Serializer,
67 {
68 String::serialize(&int.to_string(), serializer)
69 }
70
71 pub fn deserialize<'de, D>(deserializer: D) -> Result<BigInt, D::Error>
73 where
74 D: serde::Deserializer<'de>,
75 {
76 let s = String::deserialize(deserializer)?;
77 BigInt::from_str(&s).map_err(serde::de::Error::custom)
78 }
79
80 pub mod opt {
81 use super::*;
82 use serde::{self, Deserialize, Deserializer, Serialize, Serializer};
83
84 pub fn serialize<S>(v: &Option<BigInt>, serializer: S) -> Result<S::Ok, S::Error>
85 where
86 S: Serializer,
87 {
88 v.as_ref().map(|s| s.to_string()).serialize(serializer)
89 }
90
91 pub fn deserialize<'de, D>(deserializer: D) -> Result<Option<BigInt>, D::Error>
92 where
93 D: Deserializer<'de>,
94 {
95 let s: Option<String> = Deserialize::deserialize(deserializer)?;
96 if let Some(v) = s {
97 return Ok(Some(
98 BigInt::from_str(&v).map_err(serde::de::Error::custom)?,
99 ));
100 }
101 Ok(None)
102 }
103 }
104}