quickjs_runtime/quickjs_utils/
atoms.rs

1//JS_AtomToCString(ctx: *mut JSContext, atom: JSAtom) -> *const ::std::os::raw::c_char
2use crate::jsutils::JsError;
3use crate::quickjs_utils::primitives;
4use crate::quickjsrealmadapter::QuickJsRealmAdapter;
5use crate::quickjsvalueadapter::QuickJsValueAdapter;
6use libquickjs_sys as q;
7use std::ffi::{CStr, CString};
8
9#[allow(clippy::upper_case_acronyms)]
10pub struct JSAtomRef {
11    context: *mut q::JSContext,
12    atom: q::JSAtom,
13}
14
15impl JSAtomRef {
16    pub fn new(context: *mut q::JSContext, atom: q::JSAtom) -> Self {
17        Self { context, atom }
18    }
19    pub(crate) fn get_atom(&self) -> q::JSAtom {
20        self.atom
21    }
22
23    pub(crate) fn increment_ref_ct(&self) {
24        unsafe { q::JS_DupAtom(self.context, self.atom) };
25    }
26    pub(crate) fn decrement_ref_ct(&self) {
27        unsafe { q::JS_FreeAtom(self.context, self.atom) };
28    }
29}
30
31impl Drop for JSAtomRef {
32    fn drop(&mut self) {
33        // free
34        self.decrement_ref_ct();
35    }
36}
37
38pub fn to_string_q(q_ctx: &QuickJsRealmAdapter, atom_ref: &JSAtomRef) -> Result<String, JsError> {
39    unsafe { to_string(q_ctx.context, atom_ref) }
40}
41
42/// # Safety
43/// When passing a context pointer please make sure the corresponding QuickJsContext is still valid
44pub unsafe fn to_string(
45    context: *mut q::JSContext,
46    atom_ref: &JSAtomRef,
47) -> Result<String, JsError> {
48    let val = q::JS_AtomToString(context, atom_ref.atom);
49    let val_ref = QuickJsValueAdapter::new(context, val, false, true, "atoms::to_string");
50    primitives::to_string(context, &val_ref)
51}
52
53pub fn to_string2_q(q_ctx: &QuickJsRealmAdapter, atom: &q::JSAtom) -> Result<String, JsError> {
54    unsafe { to_string2(q_ctx.context, atom) }
55}
56
57/// # Safety
58/// When passing a context pointer please make sure the corresponding QuickJsContext is still valid
59pub unsafe fn to_string2(context: *mut q::JSContext, atom: &q::JSAtom) -> Result<String, JsError> {
60    let val = q::JS_AtomToString(context, *atom);
61    let val_ref = QuickJsValueAdapter::new(context, val, false, true, "atoms::to_string");
62    primitives::to_string(context, &val_ref)
63}
64
65/// # Safety
66/// When passing a context pointer please make sure the corresponding QuickJsContext is still valid
67pub unsafe fn to_str(context: *mut q::JSContext, atom: &q::JSAtom) -> Result<&str, JsError> {
68    let c_string = q::JS_AtomToCString(context, *atom);
69    let c_str = CStr::from_ptr(c_string);
70    c_str
71        .to_str()
72        .map_err(|e| JsError::new_string(format!("{e}")))
73}
74
75pub fn from_string_q(q_ctx: &QuickJsRealmAdapter, string: &str) -> Result<JSAtomRef, JsError> {
76    unsafe { from_string(q_ctx.context, string) }
77}
78
79/// # Safety
80/// When passing a context pointer please make sure the corresponding QuickJsContext is still valid
81pub unsafe fn from_string(context: *mut q::JSContext, string: &str) -> Result<JSAtomRef, JsError> {
82    let s = CString::new(string).ok().unwrap();
83
84    let len = string.len();
85
86    let atom = q::JS_NewAtomLen(context, s.as_ptr(), len as _);
87    Ok(JSAtomRef::new(context, atom))
88}