napi-rs/napi/src/js_values/bigint.rs

86 lines
2 KiB
Rust
Raw Normal View History

2020-07-10 20:14:32 +09:00
use std::convert::TryFrom;
use std::ptr;
use super::{Error, Value};
use crate::error::check_status;
use crate::{sys, Result};
#[derive(Debug)]
pub struct JsBigint(pub(crate) Value);
/// The BigInt will be converted losslessly when the value is over what an int64 could hold.
impl TryFrom<JsBigint> for i64 {
type Error = Error;
fn try_from(value: JsBigint) -> Result<i64> {
value.get_i64().map(|(v, _)| v)
}
}
/// The BigInt will be converted losslessly when the value is over what an uint64 could hold.
impl TryFrom<JsBigint> for u64 {
type Error = Error;
fn try_from(value: JsBigint) -> Result<u64> {
value.get_u64().map(|(v, _)| v)
}
}
impl JsBigint {
/// https://nodejs.org/api/n-api.html#n_api_napi_get_value_bigint_words
pub fn get_words(&self, sign_bit: bool) -> Result<Vec<u64>> {
let mut word_count: u64 = 0;
check_status(unsafe {
sys::napi_get_value_bigint_words(
self.0.env,
self.0.value,
ptr::null_mut(),
&mut word_count,
ptr::null_mut(),
)
})?;
let mut words: Vec<u64> = Vec::with_capacity(word_count as usize);
let mut sign_bit = match sign_bit {
true => 1,
false => 0,
};
check_status(unsafe {
sys::napi_get_value_bigint_words(
self.0.env,
self.0.value,
&mut sign_bit,
&mut word_count,
words.as_mut_ptr(),
)
})?;
unsafe {
words.set_len(word_count as usize);
};
Ok(words)
}
#[inline]
pub fn get_u64(&self) -> Result<(u64, bool)> {
let mut val: u64 = 0;
let mut loss = false;
check_status(unsafe {
sys::napi_get_value_bigint_uint64(self.0.env, self.0.value, &mut val, &mut loss)
})?;
Ok((val, loss))
}
#[inline]
pub fn get_i64(&self) -> Result<(i64, bool)> {
let mut val: i64 = 0;
let mut loss: bool = false;
check_status(unsafe {
sys::napi_get_value_bigint_int64(self.0.env, self.0.value, &mut val, &mut loss)
})?;
Ok((val, loss))
}
}