rquickjs/lib.rs
1//! # High-level bindings to QuickJS
2//!
3//! The `rquickjs` crate provides safe high-level bindings to the
4//! [QuickJS](https://bellard.org/quickjs/) JavaScript engine. This crate is heavily inspired by
5//! the [rlua](https://crates.io/crates/rlua) crate.
6//!
7//! # The `Runtime` and `Context` objects
8//!
9//! The main entry point of this library is the [`Runtime`] struct. It represents the interpreter
10//! state and is used to create [`Context`] objects. As the QuickJS library does not support
11//! threading the runtime is locked behind a mutex. Multiple threads cannot run a script or create
12//! objects from the same runtime at the same time. The [`Context`] object represents a global
13//! environment. Contexts of the same runtime can share JavaScript objects like in the browser between
14//! frames of the same origin.
15//!
16//! As both [`Runtime`] and [`Context`] use a lock it is discouraged to use them in a async
17//! environment. Instead, when the `futures` feature is enabled this library also exposes
18//! [`AsyncRuntime`] and [`AsyncContext`] which use a future aware lock.
19//!
20//! # Converting Values
21//!
22//! This library has multiple traits for converting to and from JavaScript. The [`IntoJs`] trait is
23//! used for taking Rust values and turning them into JavaScript values. The [`FromJs`] is for
24//! converting JavaScript values to Rust. Note that this trait does not perform automatic
25//! coercion but [`Coerced`] can be used to convert the values with coercion.
26//!
27//! For values which represent the name of variables or indices, the trait [`IntoAtom`] is
28//! available to convert values to the representation QuickJS requires.
29//!
30//! # Optional features
31//!
32//! ## Default
33//!
34//! This crate can be customized via features. The following features are enabled by default but can
35//! be disabled when not needed:
36//!
37//! - `classes` enables support for ES6 classes. Any user-defined Rust
38//! type can be exported to JS as an ES6 class which can be derived and extended by JS.
39//! - `properties` enables support for object properties (`Object.defineProperty`).
40//!
41//! ## Advanced
42//!
43//! The following features may be enabled to get an extra functionality:
44//!
45//! - `allocator` adds support for custom allocators for [`Runtime`]. The allocators should
46//! implements [`std::alloc::Allocator`] trait and can be plugged on [`Runtime`] creation via
47//! [`Runtime::new_with_alloc`].
48//!
49//! - `rust-alloc` forces using Rust's global allocator by default instead of libc's one.
50//!
51//! - `loader` adds support for custom ES6 modules resolvers and loaders. The resolvers and loaders
52//! should implements [`Resolver`](loader::Resolver) and [Loader](loader::Loader) traits
53//! respectively and can be plugged in already existing [`Runtime`] before loading modules via
54//! [`Runtime::set_loader`]. The resolvers and loaders can be easily combined via tuples. When the
55//! previous resolver or loader failed the next one will be applied.
56//!
57//! - `dyn-load` adds support for loadable native modules (so/dll/dylib).
58//!
59//! - `array-buffer` adds support for [`ArrayBuffer`] and [`TypedArray`].
60//!
61//! - `futures` adds support for async Rust. When enabled the library exports [`AsyncRuntime`] and
62//! [`AsyncContext`]. These are the asynchronous variants of the normal runtime and context. In
63//! order to ensure that QuickJS is used properly the runtime is placed behind a lock. For the
64//! normal runtime this is a normal mutex. You should avoid blocking threads in asynchronous Rust
65//! so the async runtime uses a future aware mutex. In the async runtime Rust futures can be passed
66//! to JS as [ES6
67//! Promises](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise)
68//! and ES6 Promises can be given back as Rust futures.
69//!
70//! - `macro` enables some useful procedural macros which gets Rust/JS interop much easy. An
71//! [attribute](#attributes) macros can be applied to functions, constants and modules. An
72//! [derive](#derives) macros can be used with structs and enums.
73//!
74//! - `phf` enables using Perfect Hash Function for builtin modules lookup
75//!
76//! ## Extra types
77//!
78//! This crate has support for conversion of many Rust types like [`Option`],
79//! [`Result`](std::result::Result), [`Vec`] and other collections. In addition an extra types
80//! support can be enabled via features:
81//!
82//! - `either` adds [`FromJs`]/[`IntoJs`] implementations for [`Either`](`either::Either`)
83//!
84//! - `indexmap` adds [`FromJs`]/[`IntoJs`] implementations for [`IndexSet`](`indexmap::IndexSet`)
85//! and [`IndexMap`](`indexmap_rs::IndexMap`)
86//!
87//! ## Bindings
88//!
89//! The bindings are pre-generated for the following platforms:
90//!
91//! - Linux:
92//! - `aarch64-unknown-linux-musl`
93//! - `i686-unknown-linux-gnu`
94//! - `x86_64-unknown-linux-gnu`
95//! - `x86_64-unknown-linux-musl`
96//! - `loongarch64-unknown-linux-gnu`
97//! - `loongarch64-unknown-linux-musl`
98//! - macOS:
99//! - `aarch64-apple-darwin`
100//! - `x86_64-apple-darwin`
101//! - Windows:
102//! - `i686-pc-windows-gnu`
103//! - `x86_64-pc-windows-gnu`
104//! - `i686-pc-windows-msvc`
105//! - `x86_64-pc-windows-msvc`
106//!
107//! To build the crate for any other target you must enable the `bindgen` feature.
108//!
109//! ## Experimental
110//!
111//! - `parallel` enables multithreading support.
112//!
113//! Note that the experimental features which may not works as expected. Use it for your own risk.
114//!
115//! ## Debugging
116//!
117//! QuickJS can be configured to output some info which can help debug. The following features
118//! enable that:
119//!
120//! - `dump-bytecode`
121//! - `dump-gc`
122//! - `dump-gc-free`
123//! - `dump-free`
124//! - `dump-leaks`
125//! - `dump-mem`
126//! - `dump-objects`
127//! - `dump-atoms`
128//! - `dump-shapes`
129//! - `dump-module-resolve`
130//! - `dump-promise`
131//! - `dump-read-object`
132
133#![cfg_attr(feature = "doc-cfg", feature(doc_cfg))]
134
135pub use rquickjs_core::*;
136
137#[cfg_attr(feature = "doc-cfg", doc(cfg(feature = "macro")))]
138#[cfg(feature = "macro")]
139pub use rquickjs_macro::{class, embed, function, methods, module, JsLifetime};
140
141pub mod class {
142 //! JavaScript classes defined from Rust.
143
144 pub use rquickjs_core::class::*;
145 #[cfg_attr(feature = "doc-cfg", doc(cfg(feature = "macro")))]
146 #[cfg(feature = "macro")]
147 pub use rquickjs_macro::Trace;
148}
149
150// The following imports needed to linking docs
151
152#[cfg(feature = "either")]
153#[cfg_attr(feature = "doc-cfg", doc(cfg(feature = "either")))]
154extern crate either_rs as either;
155
156#[cfg(feature = "indexmap")]
157#[cfg_attr(feature = "doc-cfg", doc(cfg(feature = "indexmap")))]
158extern crate indexmap_rs as indexmap;