use oden_js_sys as sys; use std::ffi::{CString, NulError}; use thiserror::Error; mod atom; mod callback; mod class; mod context; mod conversion; pub mod module; mod promise; mod runtime; mod value; pub use atom::{Atom, AtomRef}; pub use class::{Class, ClassID}; pub use context::{Context, ContextRef, EvalFlags}; pub use conversion::*; pub use promise::Promise; pub use runtime::Runtime; pub use value::{Value, ValueRef, ValueType}; #[derive(Debug, Error)] pub enum Error { #[error("too many classes have been registered")] TooManyClasses, #[error("the specified value is not an instance of the class {0}")] WrongClass(String), #[error("input script contained an embedded NUL byte")] UnexpectedNul, #[error("the target context is from a different runtime")] DifferentRuntime, #[error("the specified value had the wrong type (expected {expected:?}, found {found:?})")] InvalidType { expected: ValueType, found: ValueType, }, #[error("argument count mismatch, expected {expected} but received {received}")] ArgumentCountMismatch { expected: usize, received: usize }, #[error("a conversion error occurred: {0}")] ConversionError(String), #[error("an error occurred calling a rust function: {0}")] RustFunctionError(String), #[error("an exception was thrown during evaluation: {1}\nStack: {2}")] Exception(Value, String, String), #[error("out of memory")] OutOfMemory, #[error("an io error occurred: {0}")] IOError(std::io::Error), #[error("one or more errors occurred parsing {0}: {1}")] ParseError(String, String), } impl Error { // Convert the error into an exception-type object which can be // thrown. This is *different* from try_into_value which just propagates // the error. pub fn to_js_error(&self, context: &ContextRef) -> Value { if let Error::Exception(e, _, _) = self { e.clone() } else { let message = self.to_string(); context.new_error(&message) } } } impl From for Error { fn from(_: NulError) -> Self { Error::UnexpectedNul } } impl From for Error { fn from(e: std::io::Error) -> Self { Error::IOError(e) } } pub type Result = core::result::Result; pub type ValueResult = core::result::Result; pub(crate) fn throw_error(context: &ContextRef, error: Error) -> sys::JSValue { match error { Error::Exception(v, _, _) => unsafe { sys::JS_DupValue(context.ctx, v.val); sys::JS_Throw(context.ctx, v.val) }, other => throw_string(context, other.to_string()), } } pub(crate) fn throw_string(context: &ContextRef, message: String) -> sys::JSValue { let err = context.new_error(&message); unsafe { sys::JS_DupValue(context.ctx, err.val); sys::JS_Throw(context.ctx, err.val) } }