#[macro_export]
macro_rules! codegen_coercions {
({
type: class,
rust_name: $rust_name:tt,
ruby_name: $ruby_name:tt,
meta: { pub: $pub:tt, reopen: $reopen:tt },
struct: (),
methods: $methods:tt
}) => (
impl $crate::FromRuby for $rust_name {
type Checked = $crate::CheckedValue<$rust_name>;
fn from_ruby(value: $crate::sys::VALUE) -> $crate::CheckResult<$crate::CheckedValue<$rust_name>> {
use $crate::{CheckedValue, sys};
use ::std::ffi::{CStr};
if unsafe { $rust_name == $crate::as_usize(sys::rb_obj_class(value)) } {
Ok(unsafe { CheckedValue::new(value) })
} else {
let val = unsafe { CStr::from_ptr(sys::rb_obj_classname(value)).to_string_lossy() };
type_error!(format!("No implicit conversion of {} into {}", val, stringify!($rust_name)))
}
}
fn from_checked(checked: $crate::CheckedValue<$rust_name>) -> $rust_name {
$rust_name { helix: checked.to_value() }
}
}
impl_to_ruby!(&'a $rust_name);
impl_to_ruby!(&'a mut $rust_name);
);
({
type: class,
rust_name: $rust_name:tt,
ruby_name: $ruby_name:tt,
meta: { pub: $pub:tt, reopen: false },
struct: $struct:tt,
methods: $methods:tt
}) => (
impl $crate::FromRuby for $rust_name {
type Checked = Box<$rust_name>;
fn from_ruby(value: $crate::sys::VALUE) -> $crate::CheckResult<Box<$rust_name>> {
use $crate::{ToError, sys};
if unsafe { $rust_name != $crate::as_usize(sys::rb_obj_class(value)) } {
type_error!(value, stringify!($rust_name));
}
let ptr = unsafe { sys::Data_Get_Struct_Value(value) };
if ptr != ::std::ptr::null_mut() {
Ok(unsafe { ::std::mem::transmute(ptr) })
} else {
Err(format!("Uninitialized {}", stringify!($rust_name)).to_error())
}
}
fn from_checked(mut checked: Box<$rust_name>) -> $rust_name {
unsafe { $crate::sys::Data_Set_Struct_Value(checked.helix, ::std::ptr::null_mut()) };
checked.helix = unsafe { $crate::sys::Qnil };
*checked
}
}
impl_struct_to_rust!(&'a $rust_name, $rust_name);
impl_struct_to_rust!(&'a mut $rust_name, $rust_name);
impl $crate::ToRuby for $rust_name {
fn to_ruby(self) -> $crate::ToRubyResult {
Ok($rust_name::__alloc_with__(Some(Box::new(self))))
}
}
impl_to_ruby!(&'a $rust_name);
impl_to_ruby!(&'a mut $rust_name);
);
}
#[macro_export]
macro_rules! impl_struct_to_rust {
($rust_name:ty, $helix_id:tt) => {
impl<'a> $crate::FromRuby for $rust_name {
type Checked = $rust_name;
fn from_ruby(value: $crate::sys::VALUE) -> $crate::CheckResult<$rust_name> {
use $crate::{ToError, sys};
if unsafe { $helix_id != $crate::as_usize(sys::rb_obj_class(value)) } {
type_error!(value, stringify!($helix_id));
}
let ptr = unsafe { sys::Data_Get_Struct_Value(value) };
if ptr != ::std::ptr::null_mut() {
Ok(unsafe { ::std::mem::transmute(ptr) })
} else {
Err(format!("Uninitialized {}", stringify!($helix_id)).to_error())
}
}
fn from_checked(checked: $rust_name) -> $rust_name {
checked
}
}
}
}
#[doc(hidden)]
#[macro_export]
macro_rules! impl_to_ruby {
($rust_name:ty) => {
item! {
impl<'a> $crate::ToRuby for $rust_name {
fn to_ruby(self) -> $crate::ToRubyResult {
Ok(self.helix)
}
}
}
}
}