diff options
Diffstat (limited to 'test/rubygems/test_gem_ext_cargo_builder/rust_ruby_example/src/lib.rs')
-rw-r--r-- | test/rubygems/test_gem_ext_cargo_builder/rust_ruby_example/src/lib.rs | 51 |
1 files changed, 51 insertions, 0 deletions
diff --git a/test/rubygems/test_gem_ext_cargo_builder/rust_ruby_example/src/lib.rs b/test/rubygems/test_gem_ext_cargo_builder/rust_ruby_example/src/lib.rs new file mode 100644 index 0000000000..0626f04e0f --- /dev/null +++ b/test/rubygems/test_gem_ext_cargo_builder/rust_ruby_example/src/lib.rs @@ -0,0 +1,51 @@ +extern crate rb_sys; + +use rb_sys::{ + rb_define_module, rb_define_module_function, rb_string_value_cstr, rb_utf8_str_new, VALUE, +}; +use std::ffi::{CStr, CString}; +use std::os::raw::{c_char, c_long}; + +#[inline] +unsafe fn cstr_to_string(str: *const c_char) -> String { + CStr::from_ptr(str).to_string_lossy().into_owned() +} + +#[no_mangle] +unsafe extern "C" fn pub_reverse(_klass: VALUE, mut input: VALUE) -> VALUE { + let ruby_string = cstr_to_string(rb_string_value_cstr(&mut input)); + let reversed = ruby_string.to_string().chars().rev().collect::<String>(); + let reversed_cstring = CString::new(reversed).unwrap(); + let size = ruby_string.len() as c_long; + + rb_utf8_str_new(reversed_cstring.as_ptr(), size) +} + +#[cfg(rubygems)] +#[no_mangle] +pub extern "C" fn hello_from_rubygems() {} + +#[cfg(rubygems_0_0_0)] +#[no_mangle] +pub extern "C" fn should_never_exist() {} + +#[cfg(rubygems_x_x_x)] +#[no_mangle] +pub extern "C" fn hello_from_rubygems_version() {} + +#[allow(non_snake_case)] +#[no_mangle] +pub extern "C" fn Init_rust_ruby_example() { + let name = CString::new("RustRubyExample").unwrap(); + let function_name = CString::new("reverse").unwrap(); + // bindgen does not properly detect the arity of the ruby callback function, so we have to transmute + let callback = unsafe { + std::mem::transmute::< + unsafe extern "C" fn(VALUE, VALUE) -> VALUE, + unsafe extern "C" fn() -> VALUE, + >(pub_reverse) + }; + let klass = unsafe { rb_define_module(name.as_ptr()) }; + + unsafe { rb_define_module_function(klass, function_name.as_ptr(), Some(callback), 1) } +} |