Skip to main content

rug/integer/
borsh.rs

1// Copyright © 2016–2026 Trevor Spiteri
2
3// This program is free software: you can redistribute it and/or modify it under
4// the terms of the GNU Lesser General Public License as published by the Free
5// Software Foundation, either version 3 of the License, or (at your option) any
6// later version.
7//
8// This program is distributed in the hope that it will be useful, but WITHOUT
9// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
10// FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
11// details.
12//
13// You should have received a copy of the GNU Lesser General Public License and
14// a copy of the GNU General Public License along with this program. If not, see
15// <https://www.gnu.org/licenses/>.
16
17use crate::Integer;
18use crate::serdeize::Data;
19use borsh::io::{Error, ErrorKind, Read, Result, Write};
20use borsh::{BorshDeserialize, BorshSerialize};
21
22impl BorshSerialize for Integer {
23    fn serialize<W: Write>(&self, writer: &mut W) -> Result<()> {
24        let data: Data = self.into();
25        data.serialize(writer)
26    }
27}
28
29impl BorshDeserialize for Integer {
30    fn deserialize_reader<R: Read>(reader: &mut R) -> Result<Self> {
31        let data = Data::deserialize_reader(reader)?;
32        let p: super::big::ParseIncomplete = data
33            .try_into()
34            .map_err(|error| Error::new(ErrorKind::InvalidInput, error))?;
35        Ok(Integer::from(p))
36    }
37}
38
39#[cfg(test)]
40mod tests {
41    use crate::{Assign, Integer};
42    use az::StrictCast;
43
44    fn assert(a: &Integer, b: &Integer) {
45        assert_eq!(a, b);
46    }
47
48    enum Check<'a> {
49        SerDe(&'a Integer),
50        De(&'a Integer),
51        DeError(&'a str),
52    }
53
54    impl Check<'_> {
55        fn check(self, radix: i32, value: &'static str) {
56            use crate::serdeize::test::*;
57            use byteorder::{LittleEndian, WriteBytesExt};
58            use std::io::Write;
59
60            let mut bytes = Vec::<u8>::new();
61            bytes.write_u8(0).unwrap();
62            bytes.write_i32::<LittleEndian>(radix).unwrap();
63            bytes
64                .write_u32::<LittleEndian>(value.len().strict_cast())
65                .unwrap();
66            bytes.write_all(value.as_bytes()).unwrap();
67            match self {
68                Check::SerDe(i) => {
69                    borsh_assert_value(i, &bytes, assert);
70                }
71                Check::De(i) => {
72                    borsh_assert_de_value(i, &bytes, assert);
73                }
74                Check::DeError(msg) => {
75                    borsh_assert_de_error::<Integer>(&bytes, msg);
76                }
77            }
78        }
79    }
80
81    #[test]
82    fn check() {
83        Check::DeError("radix 1 less than minimum 2").check(1, "0");
84        Check::DeError("radix 37 greater than maximum 36").check(37, "0");
85
86        let mut i = Integer::new();
87        Check::SerDe(&i).check(10, "0");
88        Check::De(&i).check(10, "+0");
89        Check::De(&i).check(10, "-00");
90
91        i.assign(-0xffff_ffff_i64);
92        Check::SerDe(&i).check(10, "-4294967295");
93        Check::De(&i).check(16, "-ffffffff");
94
95        i = i.abs() + 1;
96        Check::SerDe(&i).check(16, "100000000");
97        Check::De(&i).check(10, "4294967296");
98    }
99}