Trait magnus::typed_data::TypedData
source · pub unsafe trait TypedData{
// 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§
sourcefn class(ruby: &Ruby) -> RClass
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)
}
// ...
}
sourcefn data_type() -> &'static DataType
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§
sourcefn class_for(ruby: &Ruby, value: &Self) -> RClass
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),
}
}
}