### Working with JavaScript Arrays in Rust Source: https://context7.com/delskayn/rquickjs/llms.txt Demonstrates creating, setting, getting, and iterating over JavaScript arrays from Rust. Includes converting between Rust iterators/Vecs and JS arrays. ```rust use rquickjs::{Runtime, Context, Result, Array, FromIteratorJs}; fn main() -> Result<()> { let rt = Runtime::new()?; let ctx = Context::full(&rt)?; ctx.with(|ctx| { // Create a new array let arr = Array::new(ctx.clone())?; // Set elements by index arr.set(0, "first")?; arr.set(1, "second")?; arr.set(2, 42)?; // Get array length assert_eq!(arr.len(), 3); // Get elements with type conversion let first: String = arr.get(0)?; let num: i32 = arr.get(2)?; assert_eq!(first, "first"); assert_eq!(num, 42); // Iterate over array elements for item in arr.iter::() { match item { Ok(s) => println!("Item: {}", s), Err(_) => println!("Item is not a string"), } } // Create array from Rust iterator let numbers = vec![1i32, 2, 3, 4, 5]; let js_array = numbers.iter().cloned().collect_js::(&ctx)?; assert_eq!(js_array.len(), 5); // Convert JS array to Rust Vec let js_arr: Array = ctx.eval("[10, 20, 30]")?; let rust_vec: Vec = js_arr.iter().collect::>()?; assert_eq!(rust_vec, vec![10, 20, 30]); Ok(()) }) } ``` -------------------------------- ### Configure Custom Module Loaders in rquickjs Source: https://context7.com/delskayn/rquickjs/llms.txt Set up custom resolvers and loaders to manage how JavaScript and native modules are located and loaded. This example demonstrates using built-in resolvers/loaders, file resolvers, and script loaders, along with defining a native module. ```rust use rquickjs::{ Runtime, Context, Result, Module, Function, loader::{BuiltinResolver, BuiltinLoader, FileResolver, ScriptLoader, ModuleLoader}, module::ModuleDef, }; // Define a native module struct MathModule; impl ModuleDef for MathModule { fn declare<'js>(decl: &rquickjs::module::Declarations<'js>) -> Result<()> { decl.declare("add")?; decl.declare("multiply")?; decl.declare("PI")?; Ok(()) } fn evaluate<'js>(_ctx: &rquickjs::Ctx<'js>, exports: &rquickjs::module::Exports<'js>) -> Result<()> { exports.export("add", rquickjs::prelude::Func::new(|a: f64, b: f64| a + b))?; exports.export("multiply", rquickjs::prelude::Func::new(|a: f64, b: f64| a * b))?; exports.export("PI", std::f64::consts::PI)?; Ok(()) } } // Embedded JavaScript module source const UTILS_MODULE: &str = r#" export function capitalize(str) { return str.charAt(0).toUpperCase() + str.slice(1); } export const VERSION = "1.0.0"; "#; fn main() -> Result<()> { let rt = Runtime::new()?; // Configure resolvers (determines how module names map to sources) let resolver = ( BuiltinResolver::default() .with_module("math") .with_module("utils"), FileResolver::default() .with_path("./modules") .with_path("./lib"), ); // Configure loaders (determines how modules are loaded) let loader = ( BuiltinLoader::default() .with_module("utils", UTILS_MODULE), ModuleLoader::default() .with_module("math", MathModule), ScriptLoader::default(), // Loads .js files ); // Set the loader on the runtime rt.set_loader(resolver, loader); let ctx = Context::full(&rt)?; ctx.with(|ctx| { // Import and use modules Module::evaluate(ctx.clone(), "main", r#" import { add, multiply, PI } from "math"; import { capitalize, VERSION } from "utils"; globalThis.result = { sum: add(1, 2), product: multiply(3, 4), pi: PI, name: capitalize("hello"), version: VERSION }; "#)?.finish::<()>()?; let result: rquickjs::Object = ctx.globals().get("result")?; println!("Sum: {}", result.get::<_, f64>("sum")?); println!("Product: {}", result.get::<_, f64>("product")?); Ok(()) }) } ``` -------------------------------- ### Define and Use JavaScript Class from Rust Source: https://context7.com/delskayn/rquickjs/llms.txt Register a Rust-defined class globally in the JavaScript context and use it to create instances and call methods. This example demonstrates creating instances from JavaScript and accessing/modifying data from Rust. ```rust use rquickjs::{ Runtime, Context, Result, Ctx, Object, Function, class::{Trace, Tracer, JsClass, Writable}, JsLifetime, Class, }; use rquickjs::prelude::This; // Define a Rust struct as a JavaScript class #[derive(Clone)] struct Vector2 { x: f64, y: f64, } // Implement Trace for garbage collection (required for JsClass) impl<'js> Trace<'js> for Vector2 { fn trace<'a>(&self, _tracer: Tracer<'a, 'js>) { // No JavaScript values to trace in this struct } } // Implement JsLifetime for lifetime management unsafe impl<'js> JsLifetime<'js> for Vector2 { type Changed<'to> = Vector2; } // Implement JsClass to define the JavaScript interface impl<'js> JsClass<'js> for Vector2 { const NAME: &'static str = "Vector2"; type Mutable = Writable; fn prototype(ctx: &Ctx<'js>) -> Result>> { let proto = Object::new(ctx.clone())?; // Add instance method proto.set("length", Function::new(ctx.clone(), |this: This>| { let v = this.borrow(); (v.x * v.x + v.y * v.y).sqrt() })?)?; // Add method that takes another Vector2 proto.set("add", Function::new(ctx.clone(), |this: This>, other: Class| -> Result { let a = this.borrow(); let b = other.borrow(); Ok(Vector2 { x: a.x + b.x, y: a.y + b.y }) } )?)?; Ok(Some(proto)) } fn constructor(ctx: &Ctx<'js>) -> Result>> { use rquickjs::value::Constructor; let constructor = Constructor::new_class::( ctx.clone(), |x: f64, y: f64| Vector2 { x, y } )?; Ok(Some(constructor)) } } fn main() -> Result<()> { let rt = Runtime::new()?; let ctx = Context::full(&rt)?; ctx.with(|ctx| { // Register the class constructor globally Class::::define(&ctx.globals())?; // Use the class from JavaScript let result: f64 = ctx.eval(r#" const v1 = new Vector2(3, 4); const v2 = new Vector2(1, 2); const v3 = v1.add(v2); v1.length() // Returns 5 (3-4-5 triangle) "#)?; assert!((result - 5.0).abs() < 0.001); // Create class instance from Rust let vec = Class::instance(ctx.clone(), Vector2 { x: 1.0, y: 1.0 })?; // Access the Rust data { let borrowed = vec.borrow(); println!("Vector: ({}, {})", borrowed.x, borrowed.y); } // Modify the data { let mut borrowed = vec.borrow_mut(); borrowed.x = 5.0; borrowed.y = 5.0; } Ok(()) }) } ``` -------------------------------- ### Parse and Stringify JSON in rquickjs Source: https://context7.com/delskayn/rquickjs/llms.txt Demonstrates parsing a JSON string into a JavaScript value and stringifying Rust objects into JSON. Includes examples of accessing parsed data and pretty-printing JSON. ```rust use rquickjs::{Runtime, Context, Result, Object, Array, Value}; fn main() -> Result<()> { let rt = Runtime::new()?; let ctx = Context::full(&rt)?; ctx.with(|ctx| { // Parse JSON string to JavaScript value let json_str = r#"{"name": "Alice", "age": 30, "hobbies": ["reading", "coding"]}"#; let value = ctx.json_parse(json_str)?; // Access parsed data let obj = value.into_object().unwrap(); let name: String = obj.get("name")?; let age: i32 = obj.get("age")?; let hobbies: Array = obj.get("hobbies")?; println!("Name: {}, Age: {}", name, age); println!("First hobby: {}", hobbies.get::(0)?); // Create object and stringify to JSON let new_obj = Object::new(ctx.clone())?; new_obj.set("message", "Hello")?; new_obj.set("count", 42)?; // Basic stringify let json = ctx.json_stringify(new_obj.clone())? .unwrap() .to_string()?; assert_eq!(json, r#"{"message":"Hello","count":42}"#); // Stringify with indentation (space parameter) let pretty_json = ctx.json_stringify_replacer_space( new_obj, Value::new_undefined(ctx.clone()), 2 // 2-space indentation )?.unwrap().to_string()?; println!("Pretty JSON:\n{}", pretty_json); Ok(()) }) } ``` -------------------------------- ### Work with JavaScript Objects in Rust Source: https://context7.com/delskayn/rquickjs/llms.txt Illustrates how to create, manipulate, and access JavaScript objects from Rust. This includes setting and getting properties of various types, checking for key existence, removing properties, iterating over keys and properties, and creating nested objects. ```rust use rquickjs::{Runtime, Context, Result, Object, Array, Value}; fn main() -> Result<()> { let rt = Runtime::new()?; let ctx = Context::full(&rt)?; ctx.with(|ctx| { // Create a new empty object let obj = Object::new(ctx.clone())?; // Set properties with various types obj.set("name", "Bob")?; obj.set("age", 25)?; obj.set("active", true)?; // Get properties with type conversion let name: String = obj.get("name")?; let age: i32 = obj.get("age")?; let active: bool = obj.get("active")?; // Check if key exists if obj.contains_key("name")? { println!("Object has 'name' property"); } // Remove a property obj.remove("active")?; // Iterate over object keys for key in obj.keys::() { let key = key?; println!("Key: {}", key); } // Iterate over key-value pairs for result in obj.props::() { let (key, value) = result?; println!( $"{}: {{:?}}", key, value); } // Create nested objects let inner = Object::new(ctx.clone())?; inner.set("x", 10)?; inner.set("y", 20)?; obj.set("position", inner)?; // Access nested properties let pos: Object = obj.get("position")?; let x: i32 = pos.get("x")?; assert_eq!(x, 10); Ok(()) }) } ``` -------------------------------- ### Create Runtime and Context in Rust Source: https://context7.com/delskayn/rquickjs/llms.txt Demonstrates creating a new JavaScript runtime, configuring its memory and stack limits, and setting a garbage collection threshold. It then creates a full context for script execution and evaluates a simple JavaScript expression. ```rust use rquickjs::{Runtime, Context, Result}; fn main() -> Result<()> { // Create a new runtime let runtime = Runtime::new()?; // Configure runtime settings runtime.set_memory_limit(1024 * 1024 * 10); // 10MB limit runtime.set_max_stack_size(1024 * 256); // 256KB stack runtime.set_gc_threshold(1024 * 1024); // 1MB GC threshold // Create a context with all standard intrinsics let ctx = Context::full(&runtime)?; // Execute JavaScript within the context ctx.with(|ctx| { let result: i32 = ctx.eval("1 + 2 + 3")?; println!("Result: {}", result); // Output: Result: 6 Ok(()) }) } ``` -------------------------------- ### Work with JavaScript Promises in Rust Source: https://context7.com/delskayn/rquickjs/llms.txt Shows how to create Promises in Rust and resolve/reject them, and how to evaluate JavaScript code that returns a Promise and retrieve its result. Handles both resolved and rejected promises. ```rust use rquickjs::{Runtime, Context, Result, Promise, Function}; use rquickjs::promise::PromiseState; fn main() -> Result<()> { let rt = Runtime::new()?; let ctx = Context::full(&rt)?; ctx.with(|ctx| { // Create a promise with resolve/reject functions let (promise, resolve, reject) = Promise::new(&ctx)?; // Check promise state assert_eq!(promise.state(), PromiseState::Pending); // Resolve the promise resolve.call::<_, ()>(("Success!",))?; assert_eq!(promise.state(), PromiseState::Resolved); // Get the result (blocks until resolved) let result: String = promise.finish()?; assert_eq!(result, "Success!"); // Work with promises from JavaScript let promise: Promise = ctx.eval(r#" new Promise((resolve, reject) => { resolve(42); }) "#)?; // Synchronously wait for promise to complete let value: i32 = promise.finish()?; assert_eq!(value, 42); // Handle rejected promises let rejected: Promise = ctx.eval(r#" new Promise((resolve, reject) => { reject(new Error("Something went wrong")); }) "#)?; match rejected.finish::<()>() { Ok(_) => println!("Promise resolved"), Err(e) => println!("Promise rejected: {:?}", e), } Ok(()) }) } ``` -------------------------------- ### Async Runtime and Promises as Futures in rquickjs Source: https://context7.com/delskayn/rquickjs/llms.txt Integrates JavaScript promises with Rust async/await using AsyncRuntime and AsyncContext. Demonstrates registering async Rust functions for JavaScript, evaluating async JavaScript code, and awaiting promises as Rust futures. ```rust use rquickjs::{AsyncRuntime, AsyncContext, Result, Promise, Function}; use rquickjs::prelude::{Func, Async}; use std::time::Duration; // Async function that can be called from JavaScript async fn delay(ms: u64) -> Result { tokio::time::sleep(Duration::from_millis(ms)).await; Ok(format!("Waited {} ms", ms)) } #[tokio::main] async fn main() -> Result<()> { // Create async runtime let rt = AsyncRuntime::new()?; let ctx = AsyncContext::full(&rt).await?; ctx.async_with(async |ctx| { let globals = ctx.globals(); // Register async Rust function globals.set("delay", Func::from(Async(delay)))?; // Evaluate async JavaScript code let promise: Promise = ctx.eval(r#" (async function() { const result = await delay(100); return "Got: " + result; })() "#)?; // Await the promise as a Rust future let result: String = promise.into_future().await?; println!("Result: {}", result); // Spawn background tasks ctx.spawn(async { tokio::time::sleep(Duration::from_millis(50)).await; println!("Background task completed"); }); Ok::<_, rquickjs::Error>(()) }).await?; // Drive all pending tasks to completion rt.idle().await; Ok(()) } ``` -------------------------------- ### Creating and Calling JavaScript Functions from Rust Source: https://context7.com/delskayn/rquickjs/llms.txt Shows how to define Rust closures that can be called from JavaScript and how to invoke JavaScript functions from Rust. Supports various argument types including optional, rest, and `this` context. ```rust use rquickjs::{Runtime, Context, Result, Function, Object}; use rquickjs::prelude::{Func, MutFn, Rest, This, Opt}; fn main() -> Result<()> { let rt = Runtime::new()?; let ctx = Context::full(&rt)?; ctx.with(|ctx| { let globals = ctx.globals(); // Simple function with no arguments globals.set("greet", Func::new(|| "Hello from Rust!"))?; let msg: String = ctx.eval("greet()")?; assert_eq!(msg, "Hello from Rust!"); // Function with typed arguments globals.set("add", Func::new(|a: i32, b: i32| a + b))?; let sum: i32 = ctx.eval("add(10, 20)")?; assert_eq!(sum, 30); // Function with variable arguments using Rest globals.set("sum_all", Func::new(|nums: Rest| { nums.iter().sum::() }))?; let total: i32 = ctx.eval("sum_all(1, 2, 3, 4, 5)")?; assert_eq!(total, 15); // Function with optional arguments globals.set("greet_name", Func::new(|name: Opt| { match name.0 { Some(n) => format!("Hello, {}!", n), None => "Hello, stranger!".to_string(), } }))?; // Function accessing `this` globals.set("get_value", Func::new(|this: This| -> Result { this.get("value") }))?; let result: i32 = ctx.eval(r###" let obj = { value: 42 }; get_value.call(obj) "###)?; assert_eq!(result, 42); // Mutable closure with state let mut counter = 0; globals.set("increment", Func::from(MutFn::new(move || { counter += 1; counter }))?); // Create function using Function::new for more control let multiply = Function::new(ctx.clone(), |a: f64, b: f64| a * b)? .with_name("multiply")?; globals.set("multiply", multiply)?; Ok(()) }) } ``` -------------------------------- ### Evaluate JavaScript Code in Rust Source: https://context7.com/delskayn/rquickjs/llms.txt Shows how to evaluate various JavaScript expressions, including simple arithmetic, string concatenation, function definitions, and object literals. It demonstrates retrieving results as different Rust types and calling JavaScript functions from Rust. ```rust use rquickjs::{Runtime, Context, Result, Object, Function}; fn main() -> Result<()> { let rt = Runtime::new()?; let ctx = Context::full(&rt)?; ctx.with(|ctx| { // Evaluate simple expressions let sum: i32 = ctx.eval("2 + 2")?; assert_eq!(sum, 4); // Evaluate with string results let greeting: String = ctx.eval(r#"Hello, " + "World!"#)?; assert_eq!(greeting, "Hello, World!"); // Evaluate functions and get Function objects let add_fn: Function = ctx.eval(r#" function add(a, b) { return a + b; } add "#)?; // Call the function with arguments let result: i32 = add_fn.call((5, 3))?; assert_eq!(result, 8); // Evaluate and return objects let obj: Object = ctx.eval(r#" ({ name: "Alice", age: 30, scores: [95, 87, 92] }) "#)?; let name: String = obj.get("name")?; let age: i32 = obj.get("age")?; println!("{} is {} years old", name, age); Ok(()) }) } ``` -------------------------------- ### Define Rust Class with Derive Macros Source: https://context7.com/delskayn/rquickjs/llms.txt Use `#[rquickjs::class]` and `#[rquickjs::methods]` to define Rust structs that can be exposed as JavaScript classes. This includes constructors, getters, setters, and methods, with options for renaming and implementing JavaScript-specific protocols like `toJSON` and `toString`. ```rust use rquickjs::{Runtime, Context, Result, Ctx, Object, Value, Null}; use rquickjs::class::Trace; use rquickjs::atom::PredefinedAtom; use rquickjs::JsLifetime; #[derive(Clone, Trace, JsLifetime)] #[rquickjs::class] pub struct Person { #[qjs(skip_trace)] name: String, #[qjs(skip_trace)] age: u32, } #[rquickjs::methods(rename_all = "camelCase")] impl Person { // Constructor #[qjs(constructor)] pub fn new(name: String, age: u32) -> Self { Self { name, age } } // Getter property #[qjs(get)] fn name(&self) -> String { self.name.clone() } // Setter property #[qjs(set, rename = "name")] fn set_name(&mut self, name: String) { self.name = name; } // Regular method fn greet(&self) -> String { format!("Hello, I'm {} and I'm {} years old", self.name, self.age) } // Method with custom JavaScript name #[qjs(rename = "haveBirthday")] fn birthday(&mut self) { self.age += 1; } // Implement toJSON for JSON.stringify #[qjs(rename = PredefinedAtom::ToJSON)] fn to_json<'js>(&self, ctx: Ctx<'js>) -> Result> { let obj = Object::new(ctx)?; obj.set("name", &self.name)?; obj.set("age", self.age)?; Ok(obj.into_value()) } // Implement toString #[qjs(rename = PredefinedAtom::ToString)] fn to_string(&self) -> String { format!("Person({}, {})", self.name, self.age) } } fn main() -> Result<()> { let rt = Runtime::new()?; let ctx = Context::full(&rt)?; ctx.with(|ctx| { // Register class (assuming Class::define is available) // Class::::define(&ctx.globals())?; // Would allow: // const p = new Person("Alice", 30); // p.name; // "Alice" // p.greet(); // "Hello, I'm Alice..." // p.haveBirthday(); // age becomes 31 // JSON.stringify(p); // {"name":"Alice","age":31} Ok(()) }) } ``` -------------------------------- ### Define Rust Struct as JavaScript Class Source: https://context7.com/delskayn/rquickjs/llms.txt Implement `Trace`, `JsLifetime`, and `JsClass` for a Rust struct to make it available as a JavaScript class. Ensure `Trace` is implemented for garbage collection and `JsLifetime` for lifetime management. ```rust use rquickjs::class::{Trace, Tracer, JsClass, Writable}; use rquickjs::JsLifetime; #[derive(Clone)] struct Vector2 { x: f64, y: f64, } impl<'js> Trace<'js> for Vector2 { fn trace<'a>(&self, _tracer: Tracer<'a, 'js>) { // No JavaScript values to trace in this struct } } unsafe impl<'js> JsLifetime<'js> for Vector2 { type Changed<'to> = Vector2; } impl<'js> JsClass<'js> for Vector2 { const NAME: &'static str = "Vector2"; type Mutable = Writable; fn prototype(ctx: &Ctx<'js>) -> Result>> { let proto = Object::new(ctx.clone())?; // Add instance method proto.set("length", Function::new(ctx.clone(), |this: This>| { let v = this.borrow(); (v.x * v.x + v.y * v.y).sqrt() })?)?; // Add method that takes another Vector2 proto.set("add", Function::new(ctx.clone(), |this: This>, other: Class| -> Result { let a = this.borrow(); let b = other.borrow(); Ok(Vector2 { x: a.x + b.x, y: a.y + b.y }) } )?)?; Ok(Some(proto)) } fn constructor(ctx: &Ctx<'js>) -> Result>> { use rquickjs::value::Constructor; let constructor = Constructor::new_class::( ctx.clone(), |x: f64, y: f64| Vector2 { x, y } )?; Ok(Some(constructor)) } } ``` -------------------------------- ### Store Custom Data with Userdata Source: https://context7.com/delskayn/rquickjs/llms.txt Use `store_userdata` and `userdata` to associate custom Rust data with a JavaScript context. Ensure your custom data type implements `JsLifetime` if it contains JavaScript values. ```rust use rquickjs::{Runtime, Context, Result, Function, JsLifetime}; // Custom data that can hold JavaScript references struct AppState<'js> { callback: Option>, counter: i32, } // Implement JsLifetime for types containing JS values unsafe impl<'js> JsLifetime<'js> for AppState<'js> { type Changed<'to> = AppState<'to>; } fn main() -> Result<()> { let rt = Runtime::new()?; let ctx = Context::full(&rt)?; ctx.with(|ctx| { // Store userdata let state = AppState { callback: None, counter: 0, }; ctx.store_userdata(state)?; // Access userdata later if let Some(guard) = ctx.userdata::() { println!("Counter: {}", guard.counter); } // Store a callback function let func: Function = ctx.eval("() => console.log('called!')")?; // Update userdata (requires re-storing or using interior mutability) ctx.remove_userdata::()?; ctx.store_userdata(AppState { callback: Some(func), counter: 1, })?; Ok(()) }) } ``` -------------------------------- ### Catch JavaScript Exceptions with CatchResultExt Source: https://context7.com/delskayn/rquickjs/llms.txt Use `CatchResultExt` to convert JavaScript exceptions into detailed Rust `CaughtError` variants. This allows for granular handling of different error types, including JS exceptions, thrown values, and internal runtime errors. ```rust use rquickjs::{Runtime, Context, Result, CatchResultExt, CaughtError, Exception}; fn main() -> Result<()> { let rt = Runtime::new()?; let ctx = Context::full(&rt)?; ctx.with(|ctx| { // Catch JavaScript exceptions let result = ctx.eval::( r#"throw new Error(\"Something went wrong!\");"# ).catch(&ctx); match result { Ok(value) => println!("Got value: {}", value), Err(CaughtError::Exception(exc)) => { println!("Exception: {}", exc.message().unwrap_or_default()); if let Some(stack) = exc.stack() { println!("Stack trace:\n{}", stack); } } Err(CaughtError::Value(val)) => { println!("Thrown value: {:?}", val); } Err(CaughtError::Error(err)) => { println!("Internal error: {:?}", err); } } // Throw custom exceptions from Rust let throw_error = |ctx: rquickjs::Ctx| -> Result<()> { Err(Exception::throw_message(&ctx, "Custom error from Rust")) }; // Manual exception handling match ctx.eval::<(), _>("undefinedFunction()") { Ok(_) => {} Err(rquickjs::Error::Exception) => { let exc = ctx.catch(); if let Some(exc) = exc.into_object().and_then(Exception::from_object) { println!("Caught: {}", exc.message().unwrap_or_default()); } } Err(e) => return Err(e), } Ok(()) }) } ``` === COMPLETE CONTENT === This response contains all available snippets from this library. No additional content exists. Do not make further requests.