Move class intialization to method

This allows generating the init function from class names alone
This commit is contained in:
konstin 2018-03-28 17:23:29 +02:00
parent 0baf995e04
commit f148ac0d62
3 changed files with 55 additions and 3 deletions

View File

@ -49,3 +49,7 @@ pub type ToRubyResult = Result<VALUE, Error>;
pub trait ToRuby {
fn to_ruby(self) -> ToRubyResult;
}
pub trait InitRuby {
fn init_ruby();
}

View File

@ -212,10 +212,44 @@ macro_rules! codegen_method {
};
}
#[macro_export]
macro_rules! codegen_ruby_init {
({
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::InitRuby for $rust_name {
fn init_ruby() {
codegen_class_binding!({
type: class,
rust_name: $rust_name,
ruby_name: $ruby_name,
meta: { pub: $pub, reopen: $reopen },
struct: (),
methods: $methods
}, {
type: class,
rust_name: $rust_name,
ruby_name: $ruby_name,
meta: { pub: $pub, reopen: $reopen },
struct: (),
methods: $methods
});
}
}
);
}
#[macro_export]
macro_rules! codegen_extra_impls {
($class:tt) => (
codegen_allocator!($class);
codegen_coercions!($class);
codegen_ruby_init!($class);
)
}

View File

@ -1,18 +1,32 @@
#[macro_export]
macro_rules! codegen_init {
{ [ $($class:tt)* ] } => {
// Extracts the list of rust class names and calls the actual codegen_init with that
{ [ $({
type: class,
rust_name: $ rust_name: tt,
ruby_name: { $ ( $ ruby_name: tt) * },
meta: { pub: $ pub: tt, reopen: false },
struct: (),
methods: [ $ ( $ method: tt) * ]
})* ] } => (
codegen_init!{ [ $($rust_name)* ] }
);
{ [ $($rust_name:tt)* ] } => {
#[allow(non_snake_case)]
#[no_mangle]
pub extern "C" fn Init_native() {
use $crate::InitRuby;
$crate::sys::check_version();
$(
codegen_class_binding!($class, $class);
$rust_name::init_ruby();
)*
}
}
};
}
#[macro_export]
macro_rules! codegen_class_binding {
{ $class:tt, {