1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
use std::ptr;
use log::trace;
use crate::TryIntoJs;
use crate::JSValue;
use crate::sys::napi_value;
use crate::val::JsEnv;
use crate::NjError;
pub use num_bigint::*;
impl<'a> JSValue<'a> for BigInt {
fn convert_to_rust(env: &'a JsEnv, js_value: napi_value) -> Result<Self, NjError> {
trace!("Converting JS BigInt to Rust!");
env.assert_type(js_value, crate::sys::napi_valuetype_napi_bigint)?;
let mut word_count: usize = 0;
crate::napi_call_result!(crate::sys::napi_get_value_bigint_words(
env.inner(),
js_value,
ptr::null_mut(),
&mut word_count,
ptr::null_mut(),
))?;
let mut napi_buffer: Vec<u64> = vec![0; word_count];
let mut sign = 0;
crate::napi_call_result!(crate::sys::napi_get_value_bigint_words(
env.inner(),
js_value,
&mut sign,
&mut word_count,
napi_buffer.as_mut_ptr(),
))?;
let mut bytes: Vec<u8> = Vec::new();
for i in &napi_buffer {
bytes.extend_from_slice(&i.to_le_bytes());
}
let sign = match sign {
0 => Sign::Plus,
1 => Sign::Minus,
_ => unreachable!(),
};
let res = BigInt::from_bytes_le(sign, &bytes);
trace!(
"Converted JS BigInt to Rust! words: {:#X?}, bytes: {:#?}, len: {:?}, bigint: {:#?}",
napi_buffer,
bytes,
bytes.len(),
res
);
Ok(res)
}
}
impl TryIntoJs for BigInt {
fn try_to_js(self, env: &JsEnv) -> Result<napi_value, NjError> {
let (sign, bytes) = self.to_bytes_le();
let mut words: Vec<u64> = Vec::new();
use std::cmp::min;
for i in 0..(bytes.len() / 8 + 1) {
let mut slice: [u8; 8] = [0; 8];
for (place, element) in slice
.iter_mut()
.zip(bytes[i * 8..min((i + 1) * 8, bytes.len())].iter())
{
*place = *element;
}
words.push(u64::from_le_bytes(slice));
}
let sign = match sign {
Sign::Minus => 1,
Sign::Plus | Sign::NoSign => 0,
};
let word_count = words.len();
trace!(
"Converted Rust BigInt to JS Bigint: {:#?}!, bytes: {:#?}, len: {:?}, words: {:#?}, word_count {:#?}, sign: {:#?}",
self,
bytes,
bytes.len(),
words,
word_count,
sign,
);
let mut napi_buffer = ptr::null_mut();
crate::napi_call_result!(crate::sys::napi_create_bigint_words(
env.inner(),
sign,
word_count,
words.as_ptr(),
&mut napi_buffer
))?;
Ok(napi_buffer)
}
}