deno_core icon indicating copy to clipboard operation
deno_core copied to clipboard

op2 object wraps

Open littledivy opened this issue 7 months ago • 4 comments

Object wrap for Cppgc-backed objects

#[op2] will generate the glue code declarations for impl blocks to create JS objects in Rust using the op2 infra.

deno_core::extension!(
   // ...
  objects = [MyObject],
)

Currently supported bindings:

  • constructor
  • methods
  • static methods

Planned support:

  • getters
  • setters

Future:

  • webidl validation

Example:

// dompoint.rs
pub struct DOMPoint {
  x: f64,
  y: f64,
  z: f64,
  w: f64,
}

impl GarbageCollected for DOMPoint {}

#[op2]
impl DOMPoint {
  #[constructor]
  #[cppgc]
  fn new(
    x: Option<f64>,
    y: Option<f64>,
    z: Option<f64>,
    w: Option<f64>,
  ) -> DOMPoint {
    DOMPoint {
      x: x.unwrap_or(0.0),
      y: y.unwrap_or(0.0),
      z: z.unwrap_or(0.0),
      w: w.unwrap_or(0.0),
    }
  }

  #[static_method]
  #[cppgc]
  fn from_point(
    scope: &mut v8::HandleScope,
    other: v8::Local<v8::Object>,
  ) -> Result<DOMPoint, AnyError> {
    fn get(
      scope: &mut v8::HandleScope,
      other: v8::Local<v8::Object>,
      key: &str,
    ) -> Option<f64> {
      let key = v8::String::new(scope, key).unwrap();
      other
        .get(scope, key.into())
        .map(|x| x.to_number(scope).unwrap().value())
    }

    Ok(DOMPoint {
      x: get(scope, other, "x").unwrap_or(0.0),
      y: get(scope, other, "y").unwrap_or(0.0),
      z: get(scope, other, "z").unwrap_or(0.0),
      w: get(scope, other, "w").unwrap_or(0.0),
    })
  }

  #[fast]
  fn x(&self) -> f64 {
    self.x
  }
}
import { DOMPoint } from "ext:core/ops";

const p = new DOMPoint(200, 300);
p.x(); // 200.0

littledivy avatar Jul 04 '24 08:07 littledivy