Class: Rust::RubyWrapperGenerator
- Inherits:
-
Object
- Object
- Rust::RubyWrapperGenerator
- Defined in:
- lib/rust_require/ruby_wrapper_generator.rb
Overview
This class generates Ruby wrappers for a dylib with information from an info.json file and a ruby Module (or Class) Object
Instance Attribute Summary collapse
-
#rust_lib ⇒ Object
writeonly
@rust_lib: path to the rust lib to be included (String).
Instance Method Summary collapse
-
#attach_fns(fn_headers, mod, mod_string) ⇒ Object
attaches fns via FFI to mod.
-
#attach_items(rust_module, mod, mod_string) ⇒ Object
attaches items to mod, mod_string is the mod’s prefix eg ‘mod_submod_’.
-
#attach_structs(struct_defs, mod) ⇒ Object
attaches structs via FFI to mod.
-
#include_lib(mod) ⇒ Object
makes items from lib available in mod mod: Module/Class into which the wrappers should get included (Module || Class).
-
#info_file=(info_file) ⇒ Object
@info_file: info.json file, parsed with JSON.
Instance Attribute Details
#rust_lib=(value) ⇒ Object (writeonly)
@rust_lib: path to the rust lib to be included (String)
12 13 14 |
# File 'lib/rust_require/ruby_wrapper_generator.rb', line 12 def rust_lib=(value) @rust_lib = value end |
Instance Method Details
#attach_fns(fn_headers, mod, mod_string) ⇒ Object
attaches fns via FFI to mod
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 |
# File 'lib/rust_require/ruby_wrapper_generator.rb', line 35 def attach_fns(fn_headers, mod, mod_string) # add ffi and the rust lib to mod mod.extend FFI::Library mod.ffi_lib @rust_lib fn_headers.each do |fn| rust_fn_name = fn['name'] # fn mod::fn() => fn _mod_fn_wrapper wrapper_name = "_#{mod_string+fn['name']}_wrapper".to_sym input_types = fn['inputs'].map { |t| Rust::Types.find_type(t) } ffi_input_types = input_types.map { |t| t.ffi_input_type } output_type = Rust::Types.find_type(fn['output']) ffi_output_type = output_type.ffi_output_type # attach fn and define ruby wrapper mod.attach_function wrapper_name, ffi_input_types, ffi_output_type mod.instance_eval do define_method(rust_fn_name) do |*args| # check input parameter count raise ArgumentError, "wrong number of arguments (#{args.count} for #{input_types.count})" unless args.count == input_types.count # check & convert ruby objects before handling them to FFI args.map!.with_index do |arg,i| input_types[i].ruby_input_conversion(arg) end # call FFI function and convert output raw_output = send wrapper_name, *args output_type.ruby_output_conversion raw_output end end end end |
#attach_items(rust_module, mod, mod_string) ⇒ Object
attaches items to mod, mod_string is the mod’s prefix eg ‘mod_submod_’
23 24 25 26 27 28 29 30 31 32 |
# File 'lib/rust_require/ruby_wrapper_generator.rb', line 23 def attach_items(rust_module, mod, mod_string) rust_module['submodules'].each do |x| rust_mod = Module.new attach_items(x, rust_mod, mod_string+x['name']+'_') mod.const_set(x['name'].camelize, rust_mod) end attach_fns(rust_module['fn_headers'], mod, mod_string) attach_structs(rust_module['structs'], mod) end |
#attach_structs(struct_defs, mod) ⇒ Object
attaches structs via FFI to mod
74 75 76 77 78 79 80 81 82 83 84 85 86 |
# File 'lib/rust_require/ruby_wrapper_generator.rb', line 74 def attach_structs(struct_defs, mod) struct_defs.each do |s| fields = s['fields'].map do |name, type| type = Rust::Types.find_type(type) [name.to_sym, type.ffi_output_type] end.flatten struct = Class.new(FFI::Struct) struct.layout *fields mod.const_set(s['name'], struct) end end |
#include_lib(mod) ⇒ Object
makes items from lib available in mod mod: Module/Class into which the wrappers should get included (Module || Class)
16 17 18 19 |
# File 'lib/rust_require/ruby_wrapper_generator.rb', line 16 def include_lib(mod) # attach items according to @info_file attach_items(@info_file, mod, '') end |
#info_file=(info_file) ⇒ Object
@info_file: info.json file, parsed with JSON
7 8 9 |
# File 'lib/rust_require/ruby_wrapper_generator.rb', line 7 def info_file=(info_file) @info_file = info_file end |