rquickjs_core/value/
symbol.rs1use crate::{qjs, Atom, Ctx, Result, Value};
2
3#[derive(Debug, Clone, PartialEq, Hash)]
5#[repr(transparent)]
6pub struct Symbol<'js>(pub(crate) Value<'js>);
7
8impl<'js> Symbol<'js> {
9 pub fn description(&self) -> Result<Value<'js>> {
11 let atom = Atom::from_str(self.0.ctx.clone(), "description")?;
12 unsafe {
13 let val = qjs::JS_GetProperty(self.0.ctx.as_ptr(), self.0.as_js_value(), atom.atom);
14 let val = self.0.ctx.handle_exception(val)?;
15 Ok(Value::from_js_value(self.0.ctx.clone(), val))
16 }
17 }
18
19 pub fn as_atom(&self) -> Atom<'js> {
21 Atom::from_value(self.0.ctx().clone(), &self.0)
22 .expect("symbols should always convert to atoms")
23 }
24}
25
26macro_rules! impl_symbols {
27 ($($(#[$m:meta])? $fn_name:ident => $const_name:ident)*) => {
28 impl<'js> Symbol<'js> {
29 $(
30 $(#[$m])*
31 pub fn $fn_name(ctx: Ctx<'js>) -> Self {
32 let v = unsafe {
34 let v = qjs::JS_AtomToValue(ctx.as_ptr(),qjs::$const_name as qjs::JSAtom);
35 Value::from_js_value(ctx, v)
36 };
37
38 v.into_symbol().unwrap()
39 }
40 )*
41 }
42 };
43}
44
45impl_symbols! {
46 to_primitive => JS_ATOM_Symbol_toPrimitive
48 iterator => JS_ATOM_Symbol_iterator
50 r#match => JS_ATOM_Symbol_match
52 match_all => JS_ATOM_Symbol_matchAll
54 replace => JS_ATOM_Symbol_replace
56 search => JS_ATOM_Symbol_search
58 split => JS_ATOM_Symbol_split
60 has_instance => JS_ATOM_Symbol_hasInstance
62 species => JS_ATOM_Symbol_species
64 unscopables => JS_ATOM_Symbol_unscopables
66 async_iterator => JS_ATOM_Symbol_asyncIterator
68}
69
70#[cfg(test)]
71mod test {
72 use crate::*;
73
74 #[test]
75 fn description() {
76 test_with(|ctx| {
77 let s: Symbol<'_> = ctx.eval("Symbol('foo bar baz')").unwrap();
78 assert_eq!(
79 s.description()
80 .unwrap()
81 .into_string()
82 .unwrap()
83 .to_string()
84 .unwrap(),
85 "foo bar baz"
86 );
87
88 let s: Symbol<'_> = ctx.eval("Symbol()").unwrap();
89 assert!(s.description().unwrap().is_undefined());
90 });
91 }
92}