Crate magnus

source ·
Expand description

Magnus is a library for writing Ruby extentions in Rust, or running Ruby code from Rust.

§Overview

All Ruby objects are represented by Value. To make it easier to work with values that are instances of specific classes a number of wrapper types are available. These wrappers and Value all implement the ReprValue trait, so share many methods.

Ruby ClassMagnus Type
StringRString
IntegerInteger
FloatFloat
ArrayRArray
HashRHash
SymbolSymbol
ClassRClass
ModuleRModule

When writing Rust code to be called from Ruby the init attribute can be used to mark your init function that Ruby will call when your library is required.

When embedding Ruby in a Rust program, see embed::init for initialising the Ruby VM.

The method macro can be used to wrap a Rust function with automatic type conversion and error handing so it can be exposed to Ruby. The TryConvert trait handles conversions from Ruby to Rust, and anything implementing IntoValue can be returned to Ruby. See the Module and Object traits for defining methods.

Value::funcall can be used to call Ruby methods from Rust.

See the wrap attribute macro for wrapping Rust types as Ruby objects.

§Safety

When using Magnus, in Rust code, Ruby objects must be kept on the stack. If objects are moved to the heap the Ruby GC can not reach them, and they may be garbage collected. This could lead to memory safety issues.

It is not possible to enforce this rule in Rust’s type system or via the borrow checker, users of Magnus must maintain this rule manually.

An example of something that breaks this rule would be storing a Ruby object in a Rust heap allocated data structure, such as Vec, HashMap, or Box. This must be avoided at all costs.

While it would be possible to mark any functions that could expose this unsafty as unsafe, that would mean that almost every interaction with Ruby would be unsafe. This would leave no way to differentiate the really unsafe functions that need much more care to use.

§Examples

use magnus::{class, define_module, function, method, prelude::*, Error};

#[magnus::wrap(class = "Euclid::Point", free_immediately, size)]
struct Point {
    x: isize,
    y: isize,
}

impl Point {
    fn new(x: isize, y: isize) -> Self {
        Self { x, y }
    }

    fn x(&self) -> isize {
        self.x
    }

    fn y(&self) -> isize {
        self.y
    }
}

fn distance(a: &Point, b: &Point) -> f64 {
    (((b.x - a.x).pow(2) + (b.y - a.y).pow(2)) as f64).sqrt()
}

#[magnus::init]
fn init() -> Result<(), Error> {
    let module = define_module("Euclid")?;
    let class = module.define_class("Point", class::object())?;
    class.define_singleton_method("new", function!(Point::new, 2))?;
    class.define_method("x", method!(Point::x, 0))?;
    class.define_method("y", method!(Point::y, 0))?;
    module.define_module_function("distance", function!(distance, 2))?;
    Ok(())
}

§Crates that work with Magnus

  • rb-sys - low level bindings to Ruby.

§C Function Index

This lists all the Ruby C API functions currently implemented, and how they map to Rust functions and methods in Magnus.

Click to show

§A-N

§RARRAY

§RB

§rb_a-rb_arx

§rb_ary

§rb_as-rb_az

§rb_b

§rb_c

§rb_d

§rb_e-rb_enb

§rb_enc

§rb_en-rb_ez

§rb_f

§rb_g

§rb_h

§rb_i-rb_in

§rb_io

§rb_is-rb_iz

§rb_j-rb_k

  • rb_jump_tag: Return Error.

§rb_l

§rb_m

§rb_n

§rb_o

§rb_p

§rb_r

§rb_s-rb_strl

§rb_struct

§rb_str

§rb_st_

§rb_sy-rb_sz

§rb_t

§rb_u

§rb_v-rb_z

§rc-rt

§ruby_

§S-Z

Re-exports§

Modules§

  • Types and functions for working with Ruby blocks and Procs.
  • Types and functions for working with Ruby classes.
  • embedembed
    Helpers for use when embedding Ruby in a Rust project.
  • Types and functions for working with encodings.
  • Rust types for working with Ruby Exceptions and other interrupts.
  • Types and functions for working with Ruby exceptions.
  • Functions for working with Ruby’s Garbage Collector.
  • Traits for exposing Rust functions as Ruby methods.
  • Types and functions for working with Ruby modules.
  • Types and Traits for working with Ruby’s Numeric class.
  • Traits that commonly should be in scope.
  • Types and functions for working with Ruby’s Hash class.
  • Types for working with Ruby’s Regexp class.
  • Types for working with Ruby’s String class.
  • Types and functions for working with Ruby’s Struct class.
  • rb_sysrb-sys
    Functions for interoperability with rb-sys.
  • Types and functions for complex method arguments.
  • Types and traits for working with Ruby symbols.
  • Traits for converting from Ruby Values to Rust types.
  • Types and Traits for wrapping Rust types as Ruby objects.
  • Types for working with Ruby’s VALUE type, representing all objects, and ‘immediate’ values such as Fixnum.

Macros§

  • Create a new DataTypeBuilder.
  • Evaluate a literal string of Ruby code with the given local variables.
  • Wrap a Rust function item with Ruby type conversion and error handling, ignoring Ruby’s self argument.
  • Create a KwArgs from Rust key-value mappings. Keys must be string literals, while values can be anything that implements IntoValue.
  • Wrap a Rust function item with Ruby type conversion and error handling.
  • Create a RString from a Rust str literal.
  • Asserts a Ruby expression evaluates to a truthy value.

Structs§

  • BindingDeprecated
    A Value known to be an instance of Binding.
  • Wrapper type for a Value known to be an instance of Ruby’s Enumerator class.
  • A type wrapping either a Flonum or an RFloat value.
  • A type wrapping either a Fixnum or a RBignum.
  • Wrapper for RHash intended for use in the tuple implementations of ArgList to indicate that the last argument in the tuple is to be passed as keyword arguments.
  • A Value pointer to a RArray struct, Ruby’s internal representation of an Array.
  • A Value pointer to a RBignum struct, Ruby’s internal representation of large integers.
  • A Value pointer to a RComplex struct, Ruby’s internal representation of complex numbers.
  • A Value pointer to a RFile struct, Ruby’s internal representation of files.
  • A Value pointer to an RFloat struct, Ruby’s internal representation of high precision floating point numbers.
  • A Value pointer to a RMatch struct, Ruby’s internal representation of the MatchData returned from a regex match.
  • A Value pointer to a RObject struct, Ruby’s internal representation of generic objects, not covered by the other R* types.
  • A Value pointer to a RRational struct, Ruby’s internal representation of rational numbers.
  • A Value pointer to a RTypedData struct, Ruby’s internal representation of objects that wrap foreign types.
  • Wrapper type for a Value known to be an instance of Ruby’s Range class.
  • A handle to access Ruby’s API.

Traits§

  • Trait for types that can be used as an arguments list when calling Ruby methods.
  • Conversions from Rust types into Value.
  • Conversions from Rust types that do not contain Value into Value.
  • Functions available all non-immediate values.
  • Trait for types that can be used as an arguments list when calling Ruby Procs.

Functions§

Attribute Macros§

  • Mark a function as the ‘init’ function to be run for a library when it is required by Ruby code.
  • Allow a Rust type to be passed to Ruby, automatically wrapped as a Ruby object.

Derive Macros§

  • Derives DataTypeFunctions with default implementations, for simple uses of TypedData.
  • Derives TypedData, allowing the type to be passed to Ruby automatically wrapped as a Ruby object.