use rquickjs::{class::Trace, Atom, Context, JsLifetime, Result, Runtime, Value};
#[derive(Trace, JsLifetime)]
#[rquickjs::class(exotic)]
pub struct TestClass {
value: i32,
}
impl TestClass {
pub fn new(value: i32) -> Self {
Self { value }
}
}
#[rquickjs::exotic]
impl TestClass {
#[qjs(get)]
pub fn value(&self, atom: Atom<'_>) -> Option<i32> {
if atom.to_string().unwrap() == "value" {
Some(self.value)
} else {
None
}
}
#[qjs(set)]
pub fn set_value(&mut self, atom: Atom<'_>, value: Value<'_>) -> bool {
if atom.to_string().unwrap() == "value" {
self.value = value.as_int().unwrap();
true
} else {
false
}
}
#[qjs(has)]
pub fn has_value(&self, atom: Atom<'_>) -> bool {
atom.to_string().unwrap() == "value"
}
#[qjs(delete)]
pub fn delete_value(&mut self, atom: Atom<'_>) -> bool {
if atom.to_string().unwrap() == "value" {
self.value = 0;
true
} else {
false
}
}
}
fn main() -> Result<()> {
let rt = Runtime::new()?;
let ctx = Context::full(&rt)?;
ctx.with(|ctx| -> Result<()> {
let global = ctx.globals();
let my_class = TestClass::new(42);
global.set("my_class", my_class)?;
let value = ctx.eval::<u32, _>(r#"my_class.value"#)?;
assert_eq!(value, 42);
let value = ctx.eval::<Option<i32>, _>(r#"my_class.other"#)?;
assert!(value.is_none());
let value = ctx.eval::<i32, _>(r#"my_class.value = 43; my_class.value"#)?;
assert_eq!(value, 43);
let value = ctx.eval::<i32, _>(r#"delete my_class.value; my_class.value"#)?;
assert_eq!(value, 0);
let value = ctx.eval::<bool, _>(r#""value" in my_class"#)?;
assert!(value);
let value = ctx.eval::<bool, _>(r#""other" in my_class"#)?;
assert!(!value);
Ok(())
})?;
Ok(())
}