extendr / helloextendr

Minimal Example of the Rust extendr Crate
Other
19 stars 10 forks source link

Add example with multiple files #10

Closed mfakaehler closed 2 years ago

mfakaehler commented 2 years ago

Hi @yutannihilation, I have read your blog and found this example-project really helpful. Now I was trying to add some more complicated rust-functions that I don't want to define in the lib.rs file. However, I did not manage to get an example working that pulls a function from a submodule. I tried the following and a variety of variants of where to place invocation of extendr_module, but none really worked.

use extendr_api::prelude::*;

mod submodule;

#[extendr]
pub use submodule::some_function;

/// Return string `"Hello world!"` to R.
/// @export
#[extendr]
fn hello_world() -> &'static str {
    "Hello world!"
}

// Macro to generate exports.
// This ensures exported functions are registered with R.
// See corresponding C code in `entrypoint.c`.
extendr_module! {
    mod mypackage;
    fn hello_world;
    fn submodule::some_function;
}

If I use extendr_module in every submodule, I seem to break the automatically generated C-wrappers in entypoint.c.

This is probably just my lack of rust-experience. Apologies if this overly simple. Maybe we can make an additional example for this package, that illustrates how it works across multiple files, if other users are struggeling with this, too.

yutannihilation commented 2 years ago

Ah, thanks for catching. This is possible by https://github.com/extendr/extendr/pull/160, but it definitely needs some example to understand how to use it (I actually didn't know what to do...).

You need to use #[extendr] and extend_module! in the submodule like this:

use extendr_api::prelude::*;

#[extendr]
pub fn hello_world2() -> &'static str {
    "Hello world!"
}

extendr_module! {
    mod submodule;
    fn hello_world2;
}

so that you can export it in the main lib.rs:

mod submodule;
use submodule::*;

// ...snip...

extendr_module! {
    // ...snip...

    use submodule;
}

c.f. https://github.com/extendr/extendr/blob/1264ad5ae3c491247878470aceed584ba9a87844/tests/extendrtests/src/rust/src/submodule.rs

yutannihilation commented 2 years ago

Regarding your suggestion,

Maybe we can make an additional example for this package, that illustrates how it works across multiple files

I agree with you but I have no idea if this is the right place. I think this repository is mainly for showing the bare package generated by rextendr::use_extendr(). extendr definitely needs more examples, but the template needs to be simple.

mfakaehler commented 2 years ago

Thank you so much @yutannihilation! It works like charm. Let me know, if I can help integrating this as an example somewhere. I agree, that modifying the bare package is probably not the best place for documentation.

yutannihilation commented 2 years ago

Thanks, I filed a new issue on the main repo extendr/extendr#342. I'm afraid we don't have a bandwidth to focus on the documents at the moment, but we'll definitely improve the documents in future. Feel free to comment suggestions there :)

mfakaehler commented 2 years ago

Thank you! I will know where to look, if I find anything useful to add!