mruby safe bindings for Rust

Overview

mrusty. mruby safe bindings for Rust

Build Status Coverage Status Cargo Crate

mrusty lets you:

  • run Ruby 1.9 files with a very restricted API (without having to install Ruby)
  • reflect Rust structs and enums in mruby and run them

It does all this in a safely neat way, while also bringing spec testing and a REPL to the table.

Documentation

Example

A very simple example of a Container struct which will be passed to mruby and which is perfectly callable.

// mrusty_class!
#[macro_use]
extern crate mrusty;

use mrusty::{Mruby, MrubyImpl};

let mruby = Mruby::new();

struct Cont {
    value: i32
}

// Cont should not flood the current namespace. We will add it with require.
mrusty_class!(Cont, "Container", {
    // Converts mruby types automatically & safely.
    def!("initialize", |v: i32| {
        Cont { value: v }
    });

    // Converts slf to Cont.
    def!("value", |mruby, slf: (&Cont)| {
        mruby.fixnum(slf.value)
    });
});

// Add file to the context, making it requirable.
mruby.def_file::<Cont>("cont");

// Add spec testing.
describe!(Cont, "
  context 'when containing 1' do
    it 'returns 1 when calling #value' do
      expect(Container.new(1).value).to eql 1
    end
  end
");

let result = mruby.run("
  require 'cont'

  Container.new(3).value
").unwrap(); // Returns Value.

println!("{}", result.to_i32().unwrap()); // Prints "3".
Comments
  • Nested mruby Rust calls cause memory leaks in the case of uncaught exceptions.

    Nested mruby Rust calls cause memory leaks in the case of uncaught exceptions.

    Currently, to raise errors within Ruby from Rust, I'm using the following:

    mruby
        .run("self")
        .unwrap()
        .call("raise",
               vec!(mruby.string(my_error_message)))
        .unwrap()
    
    

    I noticed that there's a method on Mruby named raise, but it's a private method. What are the reasons behind this decision? Would it be easy to make it public, or should I continue using my current workaround?

    bug 
    opened by silversquirl 17
  • Call Rust functions with Ruby blocks

    Call Rust functions with Ruby blocks

    Currently, to allow a Rust function to accept a block, I have to write the Rust function, have it accept a Value and write a wrapper for that function in Ruby, that accepts a block and passes it to the underlying Rust function as a Proc, which can then be called using my_proc.call("call", Vec::new()).unwrap().

    This seems a little hacky, so either I'm missing something or this could do with being implemented.

    enhancement 
    opened by silversquirl 10
  • Don't require glob import to use mrfn! et al

    Don't require glob import to use mrfn! et al

    The $crate variable automatically expands to your module global path (i.e. ::mrusty), so that can be used to make mrusty's macros hygienic. This is a major issue, because requiring glob imports for macros to work is considered very bad practice in Rust-land.

    I may attempt a PR for this, if I have the time.

    enhancement 
    opened by andybarron 9
  • Support Ruby file loading, class extraction and method call

    Support Ruby file loading, class extraction and method call

    First of all, thanks for this library! I was stunned by the elegancy of your crate :)

    I'm in a great need of an embedded language in a Rust project. I wanted to use Python, then I read your post in reddit and I got here.

    I need to load a pure Ruby module with a class, create an instance from the class (with parameters), then call a method on the instance several times. I found an interesting wiki page which shows the steps what I want to accomplish (just in C). I didn't find Rust bindings for some methods (e.g. mrb_class_get_under). Do you want to support this use-case?

    Thanks!

    enhancement 
    opened by ihrwein 9
  • Is there a way to put class macro definitions in separate modules?

    Is there a way to put class macro definitions in separate modules?

    I tried moving some mrusty_class!(...) macros to separate files, but nothing gets the pub keyword applied to it, so it's all inaccessible from other modules.

    opened by Qard 7
  • Catch up current mruby (3.0.0) and Rust (1.54.0-nightly)

    Catch up current mruby (3.0.0) and Rust (1.54.0-nightly)

    • Use 3.0.0 mruby and re-created mruby-out.tar
    • Use Rust 1.54.0 (current nightly), with all of warnings erased (including std::mem::uninitialized usage, fixing try!s and gcc -> cc change)

    p.s. I'm afraid I don't know what status this project is, but I have a will to inherit the maintainer role of this project.

    Thanks!

    opened by udzura 5
  • "error: no rules expected the token ..." when using mrfn! with Value parameters.

    I may well be missing something, but the following code raises an error for me:

    #[macro_use]
    extern crate mrusty;
    use mrusty::*;
    
    struct Foo(value);
    
    fn main() {
        let mrb = Mruby::new();
        mrb.def_class_for::<Foo>("Foo");
        mrb.def_method_for::<Foo, _>(
            "initialize",
            mrfn!(|_mrb, slf: Value, x: Value| {
                slf.init(Foo(x))
            }));
    }
    

    Here's the error

    error: no rules expected the token `x`
       --> <mrusty macros>:136:19
        |
    136 | @ init $ ( $ name : $ t ) , * ) ; let mrb = $ mruby . borrow (  ) . mrb ; let
        |                   ^
    

    Any insights on either what I'm doing wrong or what this issue could be?

    opened by silversquirl 3
  • Avoid glob imports from top-level of crate

    Avoid glob imports from top-level of crate

    It's generally considered best practice to put "recommended" glob imports into a prelude module (std::io::prelude, iron::prelude, etc.) so that the user would write

    extern crate mrusty;
    use mrusty::prelude::*;
    

    rather than

    extern crate mrusty;
    use mrusty::*;
    
    enhancement 
    opened by eternaleye 2
  • Consider using travis-cargo for travis ci.

    Consider using travis-cargo for travis ci.

    With travis-cargo, you can upload the docs without needing to install anything, so you could use sudo: false in your .travis.yml. This makes use of Travis' container-based build, which is faster.

    • it can build, run tests, bench all in one.
    enhancement 
    opened by krodyrobi 2
  • Expand macro functionality.

    Expand macro functionality.

    mrmodule!("MyMod", {
      mrclass!("Outer", {
        let class = mrclass!(Inner, "Inner", {
          def!...
        });
    
        class.def_const("one", mruby.fixnum(1));
      });
    });
    
    • [ ] recursive mrclass
    • [ ] mrclass should return Class
    • [ ] mrmodule
    • [ ] mrclass & mrmodule should execute everything that's not a def*! or mr*!
    enhancement 
    opened by dragostis 1
  • Support mruby 2.1.0

    Support mruby 2.1.0

    • Fixed warning for rustc 1.42.0.
    • Fixed some bug.
    • Fixed FAILED test with cargo test
    • Support mruby 2.1.0.
      • two stages from 1.2.0 to 1.4.1 and 2.1.0.
        • mrb_int changed int32_t to int64_t since mruby 1.4.1.
    opened by wordijp 0
  • [WIP] Support mruby 1.4.1

    [WIP] Support mruby 1.4.1

    In relation to issue: #98 I've also wanted to upgrade to mruby 1.4.1. Applying few hacks (I just wanted to make it run first, then think about doing things properly).

    I managed to make mrusty compile but cargo test fails

    running 113 tests
    error: process didn't exit successfully: `target/debug/deps/mrusty-a7b41d5ff22307c3` (signal: 11, SIGSEGV: invalid memory reference)
    

    @dragostis I know you don't want to spent much time maintaining mrusty anymore but perhaps you can help me with some advice? I don't have much experience with Rust and even less with Ruby.

    opened by mlga 1
  • update mruby to 1.4.1

    update mruby to 1.4.1

    I couldn't get this to compile for the included mruby of 1.2 . Tried to update it to 1.4.1 but the build.rs file is broken for mrbgems because the include files aren't located where its searching.

    The directory mruby-io has an error when trying to include this -> #include "mruby/ext/io.h"

    the include is located under mrubygems/mruby-io/include/mruby/ext/io.h

    CFLAGS = None DEBUG = Some("true") running: "gcc.exe" "-O0" "-ffunction-sections" "-fdata-sections" "-g" "-m64" "-I" "target/mruby-out/include" "-Wall" "-Wextra" "-o" "C:\Dominic\programming\repos\git\mrusty\target\debug\build\mrusty-509596ed8d3c3d96\out\target/mruby-out/src\mrbgems\mruby-io\gem_init.o" "-c" "target/mruby-out/src\mrbgems\mruby-io\gem_init.c" exit code: 0 TARGET = Some("x86_64-pc-windows-gnu") OPT_LEVEL = Some("0") TARGET = Some("x86_64-pc-windows-gnu") HOST = Some("x86_64-pc-windows-gnu") TARGET = Some("x86_64-pc-windows-gnu") TARGET = Some("x86_64-pc-windows-gnu") HOST = Some("x86_64-pc-windows-gnu") CC_x86_64-pc-windows-gnu = None CC_x86_64_pc_windows_gnu = None HOST_CC = None CC = None TARGET = Some("x86_64-pc-windows-gnu") HOST = Some("x86_64-pc-windows-gnu") CFLAGS_x86_64-pc-windows-gnu = None CFLAGS_x86_64_pc_windows_gnu = None HOST_CFLAGS = None CFLAGS = None DEBUG = Some("true") running: "gcc.exe" "-O0" "-ffunction-sections" "-fdata-sections" "-g" "-m64" "-I" "target/mruby-out/include" "-Wall" "-Wextra" "-o" "C:\Dominic\programming\repos\git\mrusty\target\debug\build\mrusty-509596ed8d3c3d96\out\target/mruby-out/src\mrbgems\mruby-io\src\file.o" "-c" "target/mruby-out/src\mrbgems\mruby-io\src\file.c" cargo:warning=target/mruby-out/src\mrbgems\mruby-io\src\file.c:9:10: fatal error: mruby/ext/io.h: No such file or directory cargo:warning= #include "mruby/ext/io.h" cargo:warning= ^~~~~~~~~~~~~~~~ cargo:warning=compilation terminated. exit code: 1

    --- stderr thread 'main' panicked at '

    Internal error occurred: Command "gcc.exe" "-O0" "-ffunction-sections" "-fdata-sections" "-g" "-m64" "-I" "target/mruby-out/include" "-Wall" "-Wextra" "-o" "C:\Dominic\programming\repos\git\mrusty\target\debug\build\mrusty-509596ed8d3c3d96\out\target/mruby-out/src\mrbgems\mruby-io\src\file.o" "-c" "target/mruby-out/src\mrbgems\mruby-io\src\file.c" with args "gcc.exe" did not execute successfully (status code exit code: 1).

    ', C:\Users\Dominic E Sisneros.cargo\registry\src\github.com-1ecc6299db9ec823\gcc-0.3.55\src\lib.rs:1672:5 note: Run with RUST_BACKTRACE=1 for a backtrace.

    opened by dsisnero 1
  • Don't match macros on exact type names

    Don't match macros on exact type names

    opened by andybarron 2
Owner
Anima
The quirky game engine
Anima
Rust bindings for writing safe and fast native Node.js modules.

Rust bindings for writing safe and fast native Node.js modules. Getting started Once you have the platform dependencies installed, getting started is

The Neon Project 7k Jan 4, 2023
Safe Rust <---> GraalVM Polyglot bindings using procedural macros

The class macro is the primary way to generate bindings to Java types; it will generate a struct (with generics if specified) that implements Pass and Receive and has all the methods you give stubs for. The methods generated can be used like normal rust methods, however mutability is not enforced. The fully-qualified type name should precede a block containing method and constructor stubs. Java primitives like char, int, and byte are aliased to corresponding Rust types.

Alec Petridis 33 Dec 28, 2022
Safe interop between Rust and C++

CXX — safe FFI between Rust and C++ This library provides a safe mechanism for calling C++ code from Rust and Rust code from C++, not subject to the m

David Tolnay 4.4k Jan 7, 2023
Safe Rust bridge for creating Erlang NIF functions

Rustler Documentation | Getting Started | Example Rustler is a library for writing Erlang NIFs in safe Rust code. That means there should be no ways t

Rusterlium 3.5k Jan 7, 2023
WebAssembly implementation from scratch in Safe Rust with zero dependencies

wain wain is a WebAssembly INterpreter written in Rust from scratch with zero dependencies. An implementation of WebAssembly. Features: No unsafe code

Linda_pp 328 Jan 2, 2023
A minimalist and safe ECS library for rust!

The full ECS (Entity-Component-System) library. Support an Open Source Developer! ♥️ Composed of two smaller libraries: world_dispatcher: the System p

Joël Lupien 124 Dec 19, 2022
A safe Rust FFI binding for the NVIDIA® Tools Extension SDK (NVTX).

NVIDIA® Tools Extension SDK (NVTX) is a C-based Application Programming Interface (API) for annotating events, code ranges, and resources in your applications. Official documentation for NVIDIA®'s NVTX can be found here.

Spencer Imbleau 78 Jan 2, 2023
High-level memory-safe binding generator for Flutter/Dart <-> Rust

flutter_rust_bridge: High-level memory-safe binding generator for Flutter/Dart <-> Rust Want to combine the best between Flutter, a cross-platform hot

fzyzcjy 2.1k Dec 31, 2022
A collection of unsound rust functions using entirly *safe* code

A collection of unsound rust functions using entirly *safe* code

null 2 Sep 6, 2022
A memory safe Lua interpreter

Hematita Da Lua Hematita Da Lua is an interpreter for the scripting language Lua, written entirely in 100% safe Rust. Hematita is the portugese word f

Daniel 149 Dec 29, 2022
Rust based WASM/JS bindings for ur-rust

ur-wasm-js WASM/JS bindings for the ur-rust rust library Getting started Installation Either build the library yourself with wasm-pack or install for

Lightning Digital Entertainment 5 Feb 28, 2024
A project for generating C bindings from Rust code

cbindgen   Read the full user docs here! cbindgen creates C/C++11 headers for Rust libraries which expose a public C API. While you could do this by h

Ryan Hunt 1.7k Jan 3, 2023
Automatically generates Rust FFI bindings to C (and some C++) libraries.

bindgen bindgen automatically generates Rust FFI bindings to C (and some C++) libraries. For example, given the C header doggo.h: typedef struct Doggo

The Rust Programming Language 3.2k Jan 4, 2023
Rust-JDBC bindings

jdbc A Rust library that allows you to use JDBC and JDBC drivers. Usage First, add the following to your Cargo.toml: [dependencies] jdbc = "0.1" Next,

Aurora 18 Feb 9, 2022
Lua 5.3 bindings for Rust

rust-lua53 Aims to be complete Rust bindings for Lua 5.3 and beyond. Currently, master is tracking Lua 5.3.3. Requires a Unix-like environment. On Win

J.C. Moyer 150 Dec 14, 2022
Objective-C Runtime bindings and wrapper for Rust.

Objective-C Runtime bindings and wrapper for Rust. Documentation: http://ssheldon.github.io/rust-objc/objc/ Crate: https://crates.io/crates/objc Messa

Steven Sheldon 336 Jan 2, 2023
High-level Rust bindings to Perl XS API

Perl XS for Rust High-level Rust bindings to Perl XS API. Example xs! { package Array::Sum; sub sum_array(ctx, array: AV) { array.iter().map(|

Vickenty Fesunov 59 Oct 6, 2022
Rust <-> Python bindings

rust-cpython Rust bindings for the python interpreter. Documentation Cargo package: cpython Copyright (c) 2015-2020 Daniel Grunwald. Rust-cpython is l

Daniel Grunwald 1.7k Dec 29, 2022
Rust bindings for the Python interpreter

PyO3 Rust bindings for Python. This includes running and interacting with Python code from a Rust binary, as well as writing native Python modules. Us

PyO3 7.2k Jan 4, 2023