pub unsafe trait TypedData
where Self: Send + Sized,
{ // Required methods fn class(ruby: &Ruby) -> RClass; fn data_type() -> &'static DataType; // Provided method fn class_for(ruby: &Ruby, value: &Self) -> RClass { ... } }
Expand description

A trait for Rust types that can be used with the rb_data_typed_object_wrap API.

§Safety

This trait is unsafe to implement as the fields of DataType returned by TypedData::data_type control low level behaviour that can go very wrong if set incorrectly. Implementing this trait is the only way a DataType can be passed to Ruby and result in safety violations, DataType is otherwise safe (but useless) to create.

The TypedData or wrap macros can help implementing this trait more safely.

Required Methods§

source

fn class(ruby: &Ruby) -> RClass

Should return the class for the Ruby object wrapping the Rust type.

This can be overridden on a case by case basis by implementing TypedData::class_for, but the result of this function will always be used in error messages if a value fails to convert to Self.

If using class_for it is advised to have this function return the superclass of those returned by class_for.

§Examples
use magnus::{prelude::*, value::Lazy, RClass, Ruby, TypedData};

struct Example();

unsafe impl TypedData for Example {
    fn class(ruby: &Ruby) -> RClass {
        static CLASS: Lazy<RClass> = Lazy::new(|ruby| {
            let class = ruby.define_class("Example", ruby.class_object()).unwrap();
            class.undef_default_alloc_func();
            class
        });
        ruby.get_inner(&CLASS)
    }

    // ...
}
source

fn data_type() -> &'static DataType

Should return a static reference to a DataType with metadata about the wrapped type.

§Examples
use magnus::{data_type_builder, DataType, DataTypeFunctions, TypedData};

#[derive(DataTypeFunctions)]
struct Example();

unsafe impl TypedData for Example {
    // ...

    fn data_type() -> &'static DataType {
        static DATA_TYPE: DataType = data_type_builder!(Example, "example").build();
        &DATA_TYPE
    }
}

Provided Methods§

source

fn class_for(ruby: &Ruby, value: &Self) -> RClass

Used to customise the class wrapping a specific value of Self.

The provided implementation simply returns the value of TypedData::class.

The classes returned by this function must be subclasses of TypedData::class. TypedData::class will always be used in error messages if a value fails to convert to Self.

See also Obj::wrap_as/RTypedData::wrap_as.

§Examples
use magnus::{prelude::*, value::Lazy, RClass, Ruby, TypedData};

enum Example {
    A,
    B,
}

unsafe impl TypedData for Example {
    // ...

    fn class_for(ruby: &Ruby, value: &Self) -> RClass {
        static A: Lazy<RClass> = Lazy::new(|ruby| {
            let class = ruby.define_class("A", Example::class(ruby)).unwrap();
            class.undef_default_alloc_func();
            class
        });
        static B: Lazy<RClass> = Lazy::new(|ruby| {
            let class = ruby.define_class("B", Example::class(ruby)).unwrap();
            class.undef_default_alloc_func();
            class
        });
        match value {
            Self::A => ruby.get_inner(&A),
            Self::B => ruby.get_inner(&B),
        }
    }
}

Object Safety§

This trait is not object safe.

Implementors§