quickjs_runtime/jsutils/
mod.rs

1//! This contains abstract traits and structs for use with different javascript runtimes
2//! the Adapter traits are use in the worker thread (EventLoop) of the Runtime and thus are not Send, they should never leave the thread
3//! The facade classes are for use outside the worker thread, they are Send
4//!
5
6use backtrace::Backtrace;
7use std::fmt::{Debug, Display, Error, Formatter};
8
9pub mod helper_tasks;
10pub mod jsproxies;
11pub mod modules;
12pub mod promises;
13
14pub trait ScriptPreProcessor {
15    fn process(&self, script: &mut Script) -> Result<(), JsError>;
16}
17
18/// the JsValueType represents the type of value for a JSValue
19#[derive(PartialEq, Copy, Clone, Eq)]
20pub enum JsValueType {
21    I32,
22    F64,
23    String,
24    Boolean,
25    Object,
26    Function,
27    BigInt,
28    Promise,
29    Date,
30    Null,
31    Undefined,
32    Array,
33    Error,
34}
35
36impl Display for JsValueType {
37    fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
38        match self {
39            JsValueType::I32 => f.write_str("I32"),
40            JsValueType::F64 => f.write_str("F64"),
41            JsValueType::String => f.write_str("String"),
42            JsValueType::Boolean => f.write_str("Boolean"),
43            JsValueType::Object => f.write_str("Object"),
44            JsValueType::Function => f.write_str("Function"),
45            JsValueType::BigInt => f.write_str("BigInt"),
46            JsValueType::Promise => f.write_str("Promise"),
47            JsValueType::Date => f.write_str("Date"),
48            JsValueType::Null => f.write_str("Null"),
49            JsValueType::Undefined => f.write_str("Undefined"),
50            JsValueType::Array => f.write_str("Array"),
51            JsValueType::Error => f.write_str("Error"),
52        }
53    }
54}
55
56#[derive(Debug)]
57pub struct JsError {
58    name: String,
59    message: String,
60    stack: String,
61}
62
63impl JsError {
64    pub fn new(name: String, message: String, stack: String) -> Self {
65        Self {
66            name,
67            message,
68            stack,
69        }
70    }
71    pub fn new_str(err: &str) -> Self {
72        Self::new_string(err.to_string())
73    }
74    pub fn new_string(err: String) -> Self {
75        let bt = Backtrace::new();
76        JsError {
77            name: "Error".to_string(),
78            message: err,
79            stack: format!("{bt:?}"),
80        }
81    }
82    pub fn get_message(&self) -> &str {
83        self.message.as_str()
84    }
85    pub fn get_stack(&self) -> &str {
86        self.stack.as_str()
87    }
88    pub fn get_name(&self) -> &str {
89        self.name.as_str()
90    }
91}
92
93impl std::error::Error for JsError {
94    fn description(&self) -> &str {
95        self.get_message()
96    }
97}
98
99impl From<anyhow::Error> for JsError {
100    fn from(err: anyhow::Error) -> Self {
101        JsError::new_string(err.to_string())
102    }
103}
104impl std::fmt::Display for JsError {
105    fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), Error> {
106        let e = format!("{}: {}\n{}", self.name, self.message, self.stack);
107        f.write_str(e.as_str())
108    }
109}
110
111impl From<Error> for JsError {
112    fn from(e: Error) -> Self {
113        JsError::new_string(format!("{e}"))
114    }
115}
116
117pub struct Script {
118    path: String,
119    code: String,
120    transpiled_code: Option<String>,
121    map: Option<String>,
122}
123
124impl Debug for Script {
125    fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
126        f.write_str(format!("Script:{}", self.path.as_str()).as_str())
127    }
128}
129
130impl Script {
131    pub fn new(absolute_path: &str, script_code: &str) -> Self {
132        Self {
133            path: absolute_path.to_string(),
134            code: script_code.to_string(),
135            transpiled_code: None,
136            map: None,
137        }
138    }
139    pub fn get_path(&self) -> &str {
140        self.path.as_str()
141    }
142    pub fn get_code(&self) -> &str {
143        self.code.as_str()
144    }
145    pub fn get_runnable_code(&self) -> &str {
146        if let Some(t_code) = self.transpiled_code.as_ref() {
147            t_code.as_str()
148        } else {
149            self.code.as_str()
150        }
151    }
152    pub fn set_code(&mut self, code: String) {
153        self.code = code;
154    }
155    pub fn set_transpiled_code(&mut self, transpiled_code: String, map: Option<String>) {
156        self.transpiled_code = Some(transpiled_code);
157        self.map = map;
158    }
159    pub fn get_map(&self) -> Option<&str> {
160        self.map.as_deref()
161    }
162}
163
164impl Clone for Script {
165    fn clone(&self) -> Self {
166        Self {
167            path: self.path.clone(),
168            code: self.code.clone(),
169            transpiled_code: self.transpiled_code.clone(),
170            map: self.map.clone(),
171        }
172    }
173}