1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73
use { Class }; use sys::{self, c_string, c_func}; pub struct MethodSpecification { name: c_string, function: c_func, arity: isize, } pub enum MethodDefinition { Class(MethodSpecification), Instance(MethodSpecification) } impl MethodDefinition { pub fn class(name: c_string, function: c_func, arity: isize) -> MethodDefinition { MethodDefinition::Class(MethodSpecification { name: name, function: function, arity: arity }) } pub fn instance(name: c_string, function: c_func, arity: isize) -> MethodDefinition { MethodDefinition::Instance(MethodSpecification { name: name, function: function, arity: arity }) } } pub struct ClassDefinition { pub class: Class, } impl ClassDefinition { pub fn new(name: c_string) -> ClassDefinition { let raw_class = unsafe { sys::rb_define_class(name, sys::rb_cObject) }; ClassDefinition { class: Class(raw_class) } } pub fn wrapped(name: c_string, alloc_func: extern "C" fn(klass: sys::VALUE) -> sys::VALUE) -> ClassDefinition { let raw_class = unsafe { sys::rb_define_class(name, sys::rb_cObject) }; unsafe { sys::rb_define_alloc_func(raw_class, alloc_func) }; ClassDefinition { class: Class(raw_class) } } pub fn reopen(name: c_string) -> ClassDefinition { let raw_class = unsafe { let class_id = sys::rb_intern(name); sys::rb_const_get(sys::rb_cObject, class_id) }; ClassDefinition { class: Class(raw_class) } } pub fn define_method(&self, def: MethodDefinition) { match def { MethodDefinition::Instance(def) => { unsafe { sys::rb_define_method( self.class.0, def.name, def.function, def.arity ); }; }, MethodDefinition::Class(def) => { unsafe { sys::rb_define_singleton_method( self.class.0, def.name, def.function, def.arity ); }; } } } }