cardano_serialization_lib/serialization/numeric/
big_int.rs1use crate::*;
2use crate::serialization::utils::read_nint;
3
4impl Serialize for BigInt {
5 fn serialize<'se, W: Write>(
6 &self,
7 serializer: &'se mut Serializer<W>,
8 ) -> cbor_event::Result<&'se mut Serializer<W>> {
9 let (sign, u64_digits) = self.0.to_u64_digits();
10 match u64_digits.len() {
11 0 => serializer.write_unsigned_integer(0),
12 1 => match sign {
14 num_bigint::Sign::Plus | num_bigint::Sign::NoSign => {
16 serializer.write_unsigned_integer(*u64_digits.first().unwrap())
17 }
18 num_bigint::Sign::Minus => serializer
20 .write_negative_integer(-(*u64_digits.first().unwrap() as i128) as i64),
21 },
22 _ => {
23 if sign == num_bigint::Sign::Minus && u64_digits == vec![0, 1] {
26 serializer.write_negative_integer(-18446744073709551616i128 as i64)
27 } else {
28 let (sign, bytes) = self.0.to_bytes_be();
29 match sign {
30 num_bigint::Sign::Plus | num_bigint::Sign::NoSign => {
32 serializer.write_tag(2u64)?;
33 write_bounded_bytes(serializer, &bytes)
34 }
35 num_bigint::Sign::Minus => {
37 serializer.write_tag(3u64)?;
38 use std::ops::Neg;
39 let adjusted = self
41 .0
42 .clone()
43 .neg()
44 .checked_sub(&num_bigint::BigInt::from(1u32))
45 .unwrap()
46 .to_biguint()
47 .unwrap();
48 write_bounded_bytes(serializer, &adjusted.to_bytes_be())
49 }
50 }
51 }
52 }
53 }
54 }
55}
56
57impl Deserialize for BigInt {
58 fn deserialize<R: BufRead + Seek>(raw: &mut Deserializer<R>) -> Result<Self, DeserializeError> {
59 (|| -> Result<_, DeserializeError> {
60 match raw.cbor_type()? {
61 CBORType::Tag => {
63 let tag = raw.tag()?;
64 let bytes = read_bounded_bytes(raw)?;
65 match tag {
66 2 => Ok(Self(num_bigint::BigInt::from_bytes_be(
68 num_bigint::Sign::Plus,
69 &bytes,
70 ))),
71 3 => {
73 let initial =
75 num_bigint::BigInt::from_bytes_be(num_bigint::Sign::Plus, &bytes);
76 use std::ops::Neg;
77 let adjusted = initial
78 .checked_add(&num_bigint::BigInt::from(1u32))
79 .unwrap()
80 .neg();
81 Ok(Self(adjusted))
82 }
83 _ => {
84 return Err(DeserializeFailure::TagMismatch {
85 found: tag,
86 expected: 2,
87 }
88 .into());
89 }
90 }
91 }
92 CBORType::UnsignedInteger => {
94 Ok(Self(num_bigint::BigInt::from(raw.unsigned_integer()?)))
95 }
96 CBORType::NegativeInteger => Ok(Self(num_bigint::BigInt::from(read_nint(raw)?))),
98 _ => return Err(DeserializeFailure::NoVariantMatched.into()),
99 }
100 })()
101 .map_err(|e| e.annotate("BigInt"))
102 }
103}