Derive Macro magnus::TypedData

source ·
#[derive(TypedData)]
{
    // Attributes available to this derive:
    #[magnus]
}
Expand description

Derives TypedData, allowing the type to be passed to Ruby automatically wrapped as a Ruby object.

For simple cases, see wrap.

Attributes

The #[magnus(...)] attribute can be set with the following values.

  • class = "..." - required, sets the Ruby class to wrap the Rust type. Supports module paths, e.g. Foo::Bar::Baz.
  • name = "..." - debug name for the type, must be unique. Defaults to the class name.
  • free_immediately - Drop the Rust type as soon as the Ruby object has been garbage collected. This is only safe to set if the type’s Drop and DataTypeFunctions::free implementations do not call Ruby.
  • mark - Enable Ruby calling the DataTypeFunctions::mark function.
  • size - Enable Ruby calling the DataTypeFunctions::size function.
  • compact - Enable Ruby calling the DataTypeFunctions::compact function.
  • wb_protected - Enable the wb_protected flag.
  • frozen_shareable - Enable the frozen_shareable flag.

Examples

use magnus::{DataTypeFunctions, TypedData};

#[derive(DataTypeFunctions, TypedData)]
#[magnus(class = "RbPoint", size, free_immediately)]
struct Point {
    x: isize,
    y: isize,
}

// the `Point` struct is automatically wrapped in a Ruby `RbPoint` object
// when returned to Ruby.
fn point(x: isize, y: isize) -> Point {
    Point { x, y }
}

// Ruby `RbPoint` objects are automatically unwrapped to references to the
// `Point` structs they are wrapping when this function is called from Ruby.
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() {
    magnus::define_global_function("point", magnus::function!(point, 2));
    magnus::define_global_function("distance", magnus::function!(distance, 2));
}

Defining a custom DataType function.

use std::mem::size_of_val;
use magnus::{DataTypeFunctions, TypedData};

#[derive(TypedData)]
#[magnus(class = "Name", size, free_immediately)]
struct Name {
    first: String,
    last: String,
}

impl DataTypeFunctions for Name {
    fn size(&self) -> usize {
        size_of_val(&self.first) + size_of_val(&self.last)
    }
}