Skip to main content

quickjs_rusty/value/
tag.rs

1use std::fmt::Debug;
2
3use libquickjs_ng_sys as q;
4
5#[repr(i32)]
6#[derive(PartialEq, Eq, Clone, Copy, Debug)]
7pub enum JsTag {
8    // Used by C code as a marker.
9    // Not relevant for bindings.
10    // First = q::JS_TAG_FIRST,
11    #[cfg(feature = "bigint")]
12    BigInt = q::JS_TAG_BIG_INT,
13    Symbol = q::JS_TAG_SYMBOL,
14    String = q::JS_TAG_STRING,
15    RopeString = q::JS_TAG_STRING_ROPE,
16    Module = q::JS_TAG_MODULE,
17    FunctionBytecode = q::JS_TAG_FUNCTION_BYTECODE,
18    Object = q::JS_TAG_OBJECT,
19
20    Int = q::JS_TAG_INT,
21    Bool = q::JS_TAG_BOOL,
22    Null = q::JS_TAG_NULL,
23    Undefined = q::JS_TAG_UNDEFINED,
24    Uninitialized = q::JS_TAG_UNINITIALIZED,
25    CatchOffset = q::JS_TAG_CATCH_OFFSET,
26    Exception = q::JS_TAG_EXCEPTION,
27    #[cfg(feature = "bigint")]
28    ShortBigInt = q::JS_TAG_SHORT_BIG_INT,
29    Float64 = q::JS_TAG_FLOAT64,
30}
31
32impl JsTag {
33    #[inline]
34    pub(super) fn from_c(value: &q::JSValue) -> JsTag {
35        let inner = unsafe { q::JS_Ext_ValueGetTag(*value) };
36        match inner {
37            q::JS_TAG_INT => JsTag::Int,
38            q::JS_TAG_BOOL => JsTag::Bool,
39            q::JS_TAG_NULL => JsTag::Null,
40            q::JS_TAG_MODULE => JsTag::Module,
41            q::JS_TAG_OBJECT => JsTag::Object,
42            q::JS_TAG_STRING => JsTag::String,
43            q::JS_TAG_STRING_ROPE => JsTag::RopeString,
44            q::JS_TAG_SYMBOL => JsTag::Symbol,
45            q::JS_TAG_FLOAT64 => JsTag::Float64,
46            q::JS_TAG_EXCEPTION => JsTag::Exception,
47            q::JS_TAG_UNDEFINED => JsTag::Undefined,
48            q::JS_TAG_CATCH_OFFSET => JsTag::CatchOffset,
49            q::JS_TAG_UNINITIALIZED => JsTag::Uninitialized,
50            q::JS_TAG_FUNCTION_BYTECODE => JsTag::FunctionBytecode,
51            #[cfg(feature = "bigint")]
52            q::JS_TAG_SHORT_BIG_INT => JsTag::ShortBigInt,
53            #[cfg(feature = "bigint")]
54            q::JS_TAG_BIG_INT => JsTag::BigInt,
55            _other => {
56                unreachable!("Unknown js_tag: {}", _other);
57            }
58        }
59    }
60
61    #[allow(dead_code)]
62    pub(super) fn to_c(self) -> i32 {
63        // TODO: figure out why this is needed
64        // Just casting with `as` does not work correctly
65        match self {
66            #[cfg(feature = "bigint")]
67            JsTag::BigInt => q::JS_TAG_FUNCTION_BYTECODE,
68            JsTag::Symbol => q::JS_TAG_SYMBOL,
69            JsTag::String => q::JS_TAG_STRING,
70            JsTag::RopeString => q::JS_TAG_STRING_ROPE,
71            JsTag::Module => q::JS_TAG_MODULE,
72            JsTag::FunctionBytecode => q::JS_TAG_FUNCTION_BYTECODE,
73            JsTag::Object => q::JS_TAG_OBJECT,
74
75            JsTag::Int => q::JS_TAG_INT,
76            JsTag::Bool => q::JS_TAG_BOOL,
77            JsTag::Null => q::JS_TAG_NULL,
78            JsTag::Undefined => q::JS_TAG_UNDEFINED,
79            JsTag::Uninitialized => q::JS_TAG_UNINITIALIZED,
80            JsTag::CatchOffset => q::JS_TAG_CATCH_OFFSET,
81            JsTag::Exception => q::JS_TAG_EXCEPTION,
82            #[cfg(feature = "bigint")]
83            JsTag::ShortBigInt => q::JS_TAG_SHORT_BIG_INT,
84            JsTag::Float64 => q::JS_TAG_FLOAT64,
85        }
86    }
87
88    /// Returns `true` if the js_tag is [`Undefined`].
89    #[inline]
90    pub fn is_undefined(&self) -> bool {
91        matches!(self, Self::Undefined)
92    }
93
94    /// Returns `true` if the js_tag is [`Object`].
95    #[inline]
96    pub fn is_object(&self) -> bool {
97        matches!(self, Self::Object)
98    }
99
100    /// Returns `true` if the js_tag is [`Exception`].
101    #[inline]
102    pub fn is_exception(&self) -> bool {
103        matches!(self, Self::Exception)
104    }
105
106    /// Returns `true` if the js_tag is [`Int`].
107    #[inline]
108    pub fn is_int(&self) -> bool {
109        matches!(self, Self::Int)
110    }
111
112    /// Returns `true` if the js_tag is [`Bool`].
113    #[inline]
114    pub fn is_bool(&self) -> bool {
115        matches!(self, Self::Bool)
116    }
117
118    /// Returns `true` if the js_tag is [`Null`].
119    #[inline]
120    pub fn is_null(&self) -> bool {
121        matches!(self, Self::Null)
122    }
123
124    /// Returns `true` if the js_tag is [`Module`].
125    #[inline]
126    pub fn is_module(&self) -> bool {
127        matches!(self, Self::Module)
128    }
129
130    /// Returns `true` if the js_tag is [`String`].
131    #[inline]
132    pub fn is_string(&self) -> bool {
133        matches!(self, Self::String)
134    }
135
136    /// Returns `true` if the js_tag is [`Symbol`].
137    #[inline]
138    pub fn is_symbol(&self) -> bool {
139        matches!(self, Self::Symbol)
140    }
141
142    /// Returns `true` if the js_tag is [`BigInt`].
143    #[cfg(feature = "bigint")]
144    #[inline]
145    pub fn is_big_int(&self) -> bool {
146        matches!(self, Self::BigInt)
147    }
148
149    /// Returns `true` if the js_tag is [`Float64`].
150    #[inline]
151    pub fn is_float64(&self) -> bool {
152        matches!(self, Self::Float64)
153    }
154}