Closed hughjonesd closed 1 month ago
Hi, thanks for the content suggestion of savvy's documentation! Could you elaborate? I can't imagine in what situation you need "a lot of boilerplate code".
Suppose just that you want to return a (reference to a) struct from an external crate, and/or pass that back into the crate's functions from R.
How is it different from this simple example? I think you can just define a newtype and pass it around.
That works for a struct defined in my own crate. Can I do the same for a struct defined in an external crate?
Ah, do you mean something like
type Foo = External::Bar
No, I meant this. Do you know the newtype pattern? It's a common practice to deal with the restriction of the orphan rule.
#[savvy]
struct Foo(External::Bar)
Thank you for this. I get the impression that
#[savvy]
struct Foo<'a>(External::Bar<'a>);
does not currently work, or is that just me?
Ah, you are right. Savvy currently doesn't support a struct with lifetime and I don't think it will because crossing the boundary of FFI means losing the track of the lifetimes. I think an obvious workaround is to use 'static
lifetime if you can.
Added a short description about lifetime. Thanks for the suggestion.
https://yutannihilation.github.io/savvy/guide/struct.html#lifetime
Honestly, I'm yet to figure out what's the supposed way to deal with lifetimes, but if you provide more details, I might able to help.
I don't think I understand lifetimes (or rust in general) enough myself to be very helpful... I'm trying to wrap a bunch of the objects in ratatui, and some of them have lifetimes.
Hmm, sorry, your description is too vague and I'm not sure if I can help you. I wish you can eventually find some good example to illustrate what your problem is!
Here is a specific example: ratatui::widgets::Paragraph
has a lifetime <'a>
, and an associated method pub fn block(self, block: Block<'a>) -> Self
. I'd like to wrap this type and method. But if I wrap it in e.g. a struct, that will require a lifetime too. I tried extendr
and wasn't able to get past the borrow checker - they are also thinking of supporting lifetimes, but don't yet. I guess savvy
would be the same.
Would something like Box
help here?
See https://docs.rs/ratatui/latest/ratatui/widgets/struct.Paragraph.html
In that case, Paragraph
's lifetime comes from this 'a
.
where
T: Into<Text<'a>>,
Text
implements From<&'a str>
.
https://docs.rs/ratatui/latest/ratatui/text/struct.Text.html#impl-From%3C%26str%3E-for-Text%3C'a%3E
So, you can pass &str
with 'static
lifetime. You might find String::leak()
useful for this.
https://doc.rust-lang.org/std/string/struct.String.html#method.leak
This is maybe more of a documentation request. I'd like to provide an R interface to an external crate, which has its own structs and functions. At the moment my approach is to create wrapper structs and functions, then invoke the
#[savvy]
macro. But is there a better way to do this which doesn't require a lot of boilerplate code?