dylanmckay/rurust

More ergonomic class definition

Opened this issue · 8 comments

Possibly worth looking into for inspiration:

  • Helix, which has a very nice class definition syntax (though it's directed more towards extension than embedding).
  • mrusty, which separates "defining a class" from "injecting it in the namespace" by having the user bind their classes to files, which can then be loaded from the embedded Ruby interpreter with require.

The two could work very well together - it may be possible to use Helix outright, if mrusty's injection strategy is followed.

The thing that I think sets rurust out from the rest is that the exact same code should be able to be used from Rust and Ruby.

From the looks of it, Helix and mrusty both allow defining Ruby objects in Rust, but not using them from Rust as well.

My goal is to be able to take any Rust struct, put an attribute on it, and be able to plug it directly into Ruby. Ultimately you should be able to do something like this:

#[pluggable]
struct Vector3(pub f64, pub f64, pub f64);

#[pluggable]
struct Player
{
    pub name: String,
    pub position: Vector3,
    pub rotation: Vector3,
}

#[pluggable]
impl Player
{
    pub fn center(&mut self) { self.position = Vector3(0, 0, 0) }

    pub fn draw(&self) { ... }
}

fn main() {
    let mut vm = VM::new();
    let main_player = Player::new("bob");
    vm.plug("main_player", main_player);

    vm.eval("main_player.center");
    vm.eval("main_player.position = Vector3.new(10.0, 5.0, 1.0)");

    main_player.draw();
}

BTW this project is only aimed at being an idiomatic Rust wrapper over the C API. It is plugger which will/has this functionality. Aside from that, the aim is to allow plugger to support other languages (such as python) with no extra effort.

Plugger is also currently waiting on Rust PR 33738. I cannot have the API I want without it.

Am happy to see Rust <=> Ruby integration becoming mainstream :)

Calling Ruby methods on Ruby objects is third in Helix's list of short-term TODOs at the top of its README - just after autocoercion of Rust return types and defining coercions of all the core Ruby types. Similarly, mrusty has the same ability to eval Ruby (and extract its results) as rurust - see the end of its README.

You may also find the overarching Rust Bridge project - of which Helix is a part - interesting. Its goal is much the same as yours for Plugger, and already has a Node.js bridge (Neon) in addition to Helix's Ruby bridge.

Anyway, I do think mrusty's separation of "define" and "inject" is worth noting - especially as it has parallels in nearly any other ecosystem, such as importing in python, the new ES modules in JavaScript, and so forth.

Helix looks good, it also has something plugger is missing - coercion of Ruby VALUEs into Rust objects. That is what I'm planning on working on next, however.

The Rust bridge is an interesting idea.

One thing worth noting is that all of Helix's macros are macro_rules - no syntax extensions/procedural macros/compiler plugins to be seen.

I'm really surprised by that, that's pretty impressive actually.

Have put actual information for the plugger README and put a note in the README for this repo about plugger.