rquickjs_core/value/
bigint.rs

1use crate::{qjs, Ctx, Error, Result, Value};
2
3/// Rust representation of a JavaScript big int.
4#[derive(Debug, Clone, PartialEq, Eq, Hash)]
5#[repr(transparent)]
6pub struct BigInt<'js>(pub(crate) Value<'js>);
7
8impl<'js> BigInt<'js> {
9    pub fn from_i64(ctx: Ctx<'js>, v: i64) -> Result<Self> {
10        unsafe {
11            let v = ctx.handle_exception(qjs::JS_NewBigInt64(ctx.as_ptr(), v))?;
12            Ok(BigInt(Value::from_js_value(ctx, v)))
13        }
14    }
15
16    pub fn from_u64(ctx: Ctx<'js>, v: u64) -> Result<Self> {
17        unsafe {
18            let v = ctx.handle_exception(qjs::JS_NewBigUint64(ctx.as_ptr(), v))?;
19            Ok(BigInt(Value::from_js_value(ctx, v)))
20        }
21    }
22
23    pub fn to_i64(self) -> Result<i64> {
24        unsafe {
25            let mut res: i64 = 0;
26            if qjs::JS_ToInt64Ext(self.0.ctx.as_ptr(), &mut res, self.0.value) == -1 {
27                return Err(Error::Unknown);
28            }
29            Ok(res)
30        }
31    }
32}
33
34#[cfg(test)]
35mod test {
36    use crate::*;
37    #[test]
38    fn from_javascript() {
39        test_with(|ctx| {
40            let s: BigInt = ctx.eval(format!("{}n", i64::MAX)).unwrap();
41            assert_eq!(s.to_i64().unwrap(), i64::MAX);
42        })
43    }
44
45    #[test]
46    fn to_javascript() {
47        test_with(|ctx| {
48            let bigint = BigInt::from_i64(ctx.clone(), i64::MAX).unwrap();
49            let func: Function = ctx
50                .eval(format!(
51                    "x => {{
52                if( x != {}n){{
53                    throw 'error'
54                }}
55            }}",
56                    i64::MAX
57                ))
58                .unwrap();
59            func.call::<_, ()>((bigint,)).unwrap();
60        })
61    }
62}