diff --git a/examples/rutie_ruby_example/src/lib.rs b/examples/rutie_ruby_example/src/lib.rs index ebefa104..fe97d993 100644 --- a/examples/rutie_ruby_example/src/lib.rs +++ b/examples/rutie_ruby_example/src/lib.rs @@ -1,7 +1,7 @@ #[macro_use] extern crate rutie; -use rutie::{Class, Object, RString, VM}; +use rutie::{Class, Object, RString, VM, Marshal, AnyObject, NilClass}; class!(RutieExample); @@ -13,6 +13,14 @@ methods!( RString::new_utf8(&ruby_string.to_string().chars().rev().collect::()) } + + fn pub_dump(input: AnyObject) -> RString { + Marshal::dump(input.unwrap(), NilClass::new().into()) + } + + fn pub_load(input: RString) -> AnyObject { + Marshal::load(input.unwrap()) + } ); #[allow(non_snake_case)] @@ -20,5 +28,7 @@ methods!( pub extern "C" fn Init_rutie_ruby_example() { Class::new("RutieExample", None).define(|klass| { klass.def_self("reverse", pub_reverse); + klass.def_self("dump", pub_dump); + klass.def_self("load", pub_load); }); } diff --git a/src/binding/marshal.rs b/src/binding/marshal.rs new file mode 100644 index 00000000..552bc6ba --- /dev/null +++ b/src/binding/marshal.rs @@ -0,0 +1,9 @@ +use crate::{rubysys::marshal, types::Value, RString}; + +pub fn marshal_dump(val: Value, port: Value) -> Value { + unsafe { marshal::rb_marshal_dump(val, port) } +} + +pub fn marshal_load(port: RString) -> Value { + unsafe { marshal::rb_marshal_load(port) } +} diff --git a/src/binding/mod.rs b/src/binding/mod.rs index 89a02332..325ba567 100644 --- a/src/binding/mod.rs +++ b/src/binding/mod.rs @@ -6,6 +6,7 @@ pub mod float; pub mod gc; pub mod global; pub mod hash; +pub mod marshal; pub mod module; pub mod rproc; pub mod string; diff --git a/src/class/marshal.rs b/src/class/marshal.rs new file mode 100644 index 00000000..b0e8e529 --- /dev/null +++ b/src/class/marshal.rs @@ -0,0 +1,38 @@ +use crate::{binding::marshal, types::Value, AnyObject, NilClass, RString}; + +/// `Marshal` +#[derive(Debug)] +#[repr(C)] +pub struct Marshal { + value: Value, +} + +impl Marshal { + /// Dump a Ruby object and load back + /// + /// # Examples + /// + /// ``` + /// use rutie::{Boolean, VM, NilClass, Marshal}; + /// # VM::init(); + /// + /// let dumped = Marshal::dump(Boolean::new(true).into(), NilClass::new().into()); + /// + /// assert_eq!(Marshal::load(dumped), Boolean::new(true).into()); + /// ``` + /// + /// Ruby: + /// + /// ```ruby + /// dumped = Marshal::dump(true) + /// + /// Marshal::load(dumped) == true + /// ``` + pub fn load(port: RString) -> AnyObject { + marshal::marshal_load(port).into() + } + + pub fn dump(val: AnyObject, port: AnyObject) -> RString { + marshal::marshal_dump(val.into(), port.into()).into() + } +} diff --git a/src/class/mod.rs b/src/class/mod.rs index d0c91555..73c65836 100644 --- a/src/class/mod.rs +++ b/src/class/mod.rs @@ -11,6 +11,7 @@ pub mod float; pub mod gc; pub mod hash; pub mod integer; +pub mod marshal; pub mod module; pub mod nil_class; pub mod rproc; diff --git a/src/lib.rs b/src/lib.rs index e42fe4ff..518083bd 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -17,8 +17,8 @@ pub mod util; pub use crate::class::{ any_exception::AnyException, any_object::AnyObject, array::Array, binding::Binding, boolean::Boolean, class::Class, encoding::Encoding, enumerator::Enumerator, fixnum::Fixnum, - float::Float, gc::GC, hash::Hash, integer::Integer, module::Module, nil_class::NilClass, - rproc::Proc, string::RString, symbol::Symbol, thread::Thread, vm::VM, + float::Float, gc::GC, hash::Hash, integer::Integer, marshal::Marshal, module::Module, + nil_class::NilClass, rproc::Proc, string::RString, symbol::Symbol, thread::Thread, vm::VM, }; pub use crate::class::traits::{ diff --git a/src/rubysys/marshal.rs b/src/rubysys/marshal.rs new file mode 100644 index 00000000..87fa00ca --- /dev/null +++ b/src/rubysys/marshal.rs @@ -0,0 +1,10 @@ +use crate::{rubysys::types::Value, RString}; + +extern "C" { + // VALUE + // rb_marshal_dump(VALUE obj, VALUE port) + pub fn rb_marshal_dump(val: Value, port: Value) -> Value; + // VALUE + // rb_marshal_load(VALUE port) + pub fn rb_marshal_load(port: RString) -> Value; +} diff --git a/src/rubysys/mod.rs b/src/rubysys/mod.rs index ad2ebf67..4f0fd6f3 100644 --- a/src/rubysys/mod.rs +++ b/src/rubysys/mod.rs @@ -8,6 +8,7 @@ pub mod fixnum; pub mod float; pub mod gc; pub mod hash; +pub mod marshal; pub mod rproc; pub mod string; pub mod symbol;