numbat_wasm_debug/
big_int_mock.rs

1use crate::big_uint_mock::*;
2
3use core::ops::{Add, Div, Mul, Neg, Rem, Sub};
4use core::ops::{AddAssign, DivAssign, MulAssign, RemAssign, SubAssign};
5use num_traits::sign::Signed;
6
7use alloc::vec::Vec;
8use numbat_wasm::BigIntApi;
9
10use core::cmp::Ordering;
11use num_bigint::{BigInt, Sign};
12
13#[derive(Debug)]
14pub struct RustBigInt(pub num_bigint::BigInt);
15
16impl RustBigInt {
17	pub fn value(&self) -> &BigInt {
18		&self.0
19	}
20}
21
22impl From<RustBigUint> for RustBigInt {
23	fn from(item: RustBigUint) -> Self {
24		RustBigInt(item.0)
25	}
26}
27
28impl From<i64> for RustBigInt {
29	fn from(item: i64) -> Self {
30		RustBigInt(item.into())
31	}
32}
33
34impl From<i32> for RustBigInt {
35	fn from(item: i32) -> Self {
36		RustBigInt(item.into())
37	}
38}
39
40impl From<BigInt> for RustBigInt {
41	fn from(item: BigInt) -> Self {
42		RustBigInt(item)
43	}
44}
45
46impl Clone for RustBigInt {
47	fn clone(&self) -> Self {
48		RustBigInt(self.0.clone())
49	}
50}
51
52macro_rules! binary_operator {
53	($trait:ident, $method:ident) => {
54		impl $trait for RustBigInt {
55			type Output = RustBigInt;
56
57			fn $method(self, other: RustBigInt) -> RustBigInt {
58				RustBigInt((self.0).$method(other.0))
59			}
60		}
61
62		impl<'a, 'b> $trait<&'b RustBigInt> for &'a RustBigInt {
63			type Output = RustBigInt;
64
65			fn $method(self, other: &RustBigInt) -> RustBigInt {
66				RustBigInt(self.0.clone().$method(other.0.clone()))
67			}
68		}
69	};
70}
71
72binary_operator! {Add, add}
73binary_operator! {Sub, sub}
74binary_operator! {Mul, mul}
75binary_operator! {Div, div}
76binary_operator! {Rem, rem}
77
78macro_rules! binary_assign_operator {
79	($trait:ident, $method:ident) => {
80		impl $trait<RustBigInt> for RustBigInt {
81			fn $method(&mut self, other: Self) {
82				BigInt::$method(&mut self.0, other.0)
83			}
84		}
85
86		impl $trait<&RustBigInt> for RustBigInt {
87			fn $method(&mut self, other: &RustBigInt) {
88				BigInt::$method(&mut self.0, &other.0)
89			}
90		}
91	};
92}
93
94binary_assign_operator! {AddAssign, add_assign}
95binary_assign_operator! {SubAssign, sub_assign}
96binary_assign_operator! {MulAssign, mul_assign}
97binary_assign_operator! {DivAssign, div_assign}
98binary_assign_operator! {RemAssign, rem_assign}
99
100impl Neg for RustBigInt {
101	type Output = RustBigInt;
102
103	fn neg(self) -> Self::Output {
104		RustBigInt(-self.0)
105	}
106}
107
108impl PartialEq<Self> for RustBigInt {
109	#[inline]
110	fn eq(&self, other: &Self) -> bool {
111		PartialEq::eq(&self.0, &other.0)
112	}
113}
114
115impl Eq for RustBigInt {}
116
117impl PartialOrd<Self> for RustBigInt {
118	#[inline]
119	fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
120		PartialOrd::partial_cmp(&self.0, &other.0)
121	}
122}
123
124impl Ord for RustBigInt {
125	#[inline]
126	fn cmp(&self, other: &Self) -> Ordering {
127		Ord::cmp(&self.0, &other.0)
128	}
129}
130
131impl PartialEq<i64> for RustBigInt {
132	#[inline]
133	fn eq(&self, other: &i64) -> bool {
134		PartialEq::eq(&self.0, &BigInt::from(*other))
135	}
136}
137
138impl PartialOrd<i64> for RustBigInt {
139	#[inline]
140	fn partial_cmp(&self, other: &i64) -> Option<Ordering> {
141		PartialOrd::partial_cmp(&self.0, &BigInt::from(*other))
142	}
143}
144
145use numbat_wasm::numbat_codec::*;
146
147impl NestedEncode for RustBigInt {
148	const TYPE_INFO: TypeInfo = TypeInfo::BigInt;
149
150	fn dep_encode<O: NestedEncodeOutput>(&self, dest: &mut O) -> Result<(), EncodeError> {
151		self.to_signed_bytes_be().as_slice().dep_encode(dest)
152	}
153
154	fn dep_encode_or_exit<O: NestedEncodeOutput, ExitCtx: Clone>(
155		&self,
156		dest: &mut O,
157		c: ExitCtx,
158		exit: fn(ExitCtx, EncodeError) -> !,
159	) {
160		self.to_signed_bytes_be()
161			.as_slice()
162			.dep_encode_or_exit(dest, c, exit);
163	}
164}
165
166impl TopEncode for RustBigInt {
167	const TYPE_INFO: TypeInfo = TypeInfo::BigInt;
168
169	fn top_encode<O: TopEncodeOutput>(&self, output: O) -> Result<(), EncodeError> {
170		self.to_signed_bytes_be().top_encode(output)
171	}
172
173	fn top_encode_or_exit<O: TopEncodeOutput, ExitCtx: Clone>(
174		&self,
175		output: O,
176		c: ExitCtx,
177		exit: fn(ExitCtx, EncodeError) -> !,
178	) {
179		self.to_signed_bytes_be()
180			.top_encode_or_exit(output, c, exit)
181	}
182}
183
184impl NestedDecode for RustBigInt {
185	const TYPE_INFO: TypeInfo = TypeInfo::BigInt;
186
187	fn dep_decode<I: NestedDecodeInput>(input: &mut I) -> Result<Self, DecodeError> {
188		let size = usize::dep_decode(input)?;
189		let bytes = input.read_slice(size)?;
190		Ok(RustBigInt::from_signed_bytes_be(bytes))
191	}
192
193	fn dep_decode_or_exit<I: NestedDecodeInput, ExitCtx: Clone>(
194		input: &mut I,
195		c: ExitCtx,
196		exit: fn(ExitCtx, DecodeError) -> !,
197	) -> Self {
198		let size = usize::dep_decode_or_exit(input, c.clone(), exit);
199		let bytes = input.read_slice_or_exit(size, c, exit);
200		RustBigInt::from_signed_bytes_be(bytes)
201	}
202}
203
204impl TopDecode for RustBigInt {
205	const TYPE_INFO: TypeInfo = TypeInfo::BigInt;
206
207	fn top_decode<I: TopDecodeInput>(input: I) -> Result<Self, DecodeError> {
208		Ok(RustBigInt::from_signed_bytes_be(
209			&*input.into_boxed_slice_u8(),
210		))
211	}
212
213	fn top_decode_or_exit<I: TopDecodeInput, ExitCtx: Clone>(
214		input: I,
215		_: ExitCtx,
216		_: fn(ExitCtx, DecodeError) -> !,
217	) -> Self {
218		RustBigInt::from_signed_bytes_be(&*input.into_boxed_slice_u8())
219	}
220}
221
222impl numbat_wasm::abi::TypeAbi for RustBigInt {
223	fn type_name() -> String {
224		String::from("BigInt")
225	}
226}
227
228impl numbat_wasm::BigIntApi<RustBigUint> for RustBigInt {
229	fn abs_uint(&self) -> RustBigUint {
230		RustBigUint(self.0.abs())
231	}
232
233	fn sign(&self) -> numbat_wasm::Sign {
234		match self.0.sign() {
235			num_bigint::Sign::Minus => numbat_wasm::Sign::NoSign,
236			num_bigint::Sign::NoSign => numbat_wasm::Sign::NoSign,
237			num_bigint::Sign::Plus => numbat_wasm::Sign::Plus,
238		}
239	}
240
241	fn to_signed_bytes_be(&self) -> Vec<u8> {
242		if self.0.sign() == Sign::NoSign {
243			Vec::new()
244		} else {
245			self.0.to_signed_bytes_be()
246		}
247	}
248
249	fn from_signed_bytes_be(bytes: &[u8]) -> Self {
250		let bi = BigInt::from_signed_bytes_be(bytes);
251		bi.into()
252	}
253}