Attribute Macro rquickjs::class

source ·
#[class]
Available on crate feature macro only.
Expand description

An attribute for implementing JsClass for a Rust type.

§Attribute options

The attribute has a number of options for configuring the generated trait implementation. These attributes can be passed to the class attribute as an argument: #[class(rename = "AnotherName")] or with a separate qjs attribute on the struct item: #[qjs(rename = "AnotherName")]. A option which is a Flag can be set just by adding the attribute: #[qjs(flag)] or by setting it to specific boolean value: #[qjs(flag = true)].

OptionValueDescription
crateStringChanges the name from which the attribute tries to use rquickjs types. Use when the name behind which the rquickjs crate is declared is not properly resolved by the macro.
renameStringChanges the name of the implemented class on the JavaScript side.
rename_allCasingConverts the case of all the fields of this struct which have implement accessors. Can be one of lowercase, UPPERCASE, camelCase, PascalCase,snake_case, or SCREAMING_SNAKE
frozenFlagChanges the class implementation to only allow borrowing immutably. Trying to borrow mutably will result in an error.

§Field options

The fields of a struct (doesn’t work on enums) can also tagged with an attribute to, for example make the fields accessible from JavaScript. These attributes are all in the form of #[qjs(option = value)].

OptionValueDescription
getFlagCreates a getter for this field, allowing read access to the field from JavaScript.
setFlagCreates a setter for this field, allowing write access to the field from JavaSccript.
enumerableFlagMakes the field, if it has a getter or setter, enumerable in JavaScript.
configurableFlagMakes the field, if it has a getter or setter, configurable in JavaScript.
renameStringChanges the name of the field getter and/or setter to the specified name in JavaScript.

§Example

use rquickjs::{class::Trace, CatchResultExt, Class, Context, Object, Runtime};

/// Implement JsClass for TestClass.
/// This allows passing any instance of TestClass straight to JavaScript.
/// It is command to also add #[derive(Trace)] as all types which implement JsClass need to
/// also implement trace.
#[derive(Trace)]
#[rquickjs::class(rename_all = "camelCase")]
pub struct TestClass<'js> {
    /// These attribute make the accessible from JavaScript with getters and setters.
    /// As we used `rename_all = "camelCase"` in the attribute it will be called `innerObject`
    /// on the JavaScript side.
    #[qjs(get, set)]
    inner_object: Object<'js>,

    /// This works for any value which implements `IntoJs` and `FromJs` and is clonable.
    #[qjs(get, set)]
    some_value: u32,
    /// Make a field enumerable.
    #[qjs(get, set, enumerable)]
    another_value: u32,
}

pub fn main() {
    let rt = Runtime::new().unwrap();
    let ctx = Context::full(&rt).unwrap();

    ctx.with(|ctx| {
        /// Create an insance of a JsClass
        let cls = Class::instance(
            ctx.clone(),
            TestClass {
                inner_object: Object::new(ctx.clone()).unwrap(),
                some_value: 1,
                another_value: 2,
            },
        )
        .unwrap();
        /// Pass it to JavaScript
        ctx.globals().set("t", cls.clone()).unwrap();
        ctx.eval::<(), _>(
            r#"
            // use the actual value.
            if(t.someValue !== 1){
                throw new Error(1)
            }"#
        ).unwrap();
    })
}