1use std::ops::{Deref, DerefMut};
8
9use mozjs::jsapi::{JS_ValueToSource, NullHandleValue, SameValue, UndefinedHandleValue};
10use mozjs::jsval::{
11 BigIntValue, BooleanValue, DoubleValue, Int32Value, JSVal, NullValue, ObjectValue, SymbolValue, UInt32Value,
12 UndefinedValue,
13};
14
15use crate::bigint::BigInt;
16use crate::conversions::ToValue as _;
17use crate::{Array, Context, Local, Object, Symbol};
18
19#[derive(Debug)]
22pub struct Value<'v> {
23 val: Local<'v, JSVal>,
24}
25
26impl<'v> Value<'v> {
27 pub fn bool(cx: &Context, b: bool) -> Value<'_> {
29 Value::from(cx.root(BooleanValue(b)))
30 }
31
32 pub fn i32(cx: &Context, i: i32) -> Value<'_> {
34 Value::from(cx.root(Int32Value(i)))
35 }
36
37 pub fn u32(cx: &Context, u: u32) -> Value<'_> {
39 Value::from(cx.root(UInt32Value(u)))
40 }
41
42 pub fn f64(cx: &Context, f: f64) -> Value<'_> {
44 Value::from(cx.root(DoubleValue(f)))
45 }
46
47 pub fn string(cx: &'v Context, str: &str) -> Value<'v> {
49 str.as_value(cx)
50 }
51
52 pub fn bigint<'cx>(cx: &'cx Context, bi: &BigInt) -> Value<'cx> {
54 Value::from(cx.root(BigIntValue(unsafe { &*bi.get() })))
55 }
56
57 pub fn symbol<'cx>(cx: &'cx Context, sym: &Symbol) -> Value<'cx> {
59 Value::from(cx.root(SymbolValue(unsafe { &*sym.get() })))
60 }
61
62 pub fn object<'cx>(cx: &'cx Context, object: &Object) -> Value<'cx> {
64 Value::from(cx.root(ObjectValue(object.handle().get())))
65 }
66
67 pub fn array<'cx>(cx: &'cx Context, array: &Array) -> Value<'cx> {
69 Value::from(cx.root(ObjectValue(array.handle().get())))
70 }
71
72 pub fn undefined(cx: &Context) -> Value<'_> {
74 Value::from(cx.root(UndefinedValue()))
75 }
76
77 pub fn null(cx: &Context) -> Value<'_> {
79 Value::from(cx.root(NullValue()))
80 }
81
82 pub fn undefined_handle() -> Value<'v> {
83 Value::from(unsafe { Local::from_raw_handle(UndefinedHandleValue) })
84 }
85
86 pub fn null_handle() -> Value<'v> {
87 Value::from(unsafe { Local::from_raw_handle(NullHandleValue) })
88 }
89
90 pub fn to_object<'cx>(&self, cx: &'cx Context) -> Object<'cx> {
95 cx.root(self.handle().to_object()).into()
96 }
97
98 pub fn is_same(&self, cx: &Context, other: &Value) -> bool {
101 let mut same = false;
102 unsafe { SameValue(cx.as_ptr(), self.handle().into(), other.handle().into(), &raw mut same) && same }
103 }
104
105 pub fn to_source<'cx>(&self, cx: &'cx Context) -> crate::String<'cx> {
106 crate::String::from(cx.root(unsafe { JS_ValueToSource(cx.as_ptr(), self.handle().into()) }))
107 }
108}
109
110impl<'v> From<Local<'v, JSVal>> for Value<'v> {
111 fn from(val: Local<'v, JSVal>) -> Value<'v> {
112 Value { val }
113 }
114}
115
116impl<'v> Deref for Value<'v> {
117 type Target = Local<'v, JSVal>;
118
119 fn deref(&self) -> &Self::Target {
120 &self.val
121 }
122}
123
124impl DerefMut for Value<'_> {
125 fn deref_mut(&mut self) -> &mut Self::Target {
126 &mut self.val
127 }
128}