Closed har7an closed 7 months ago
Foreign types that implement Clone
can be unboxed, so if you derive Clone
for FooTypeInner
and FooType
, the following should work:
self.foo = new_foo
.as_value()
.unbox::<FooType>()
.expect("Not a FooType");
Alright, it works. Thanks for the tip!
Hello,
thanks again for helping me out with #119! I've since poked around in the code I'm trying to wrapup/expose and found another thing I don't know how to work around. This time I want to create instances of Rust types in Julia (which I'm capable of now) and then mutate them. I'm treating all of the involved types as opaque, but my problem is I can't seem to find a way that allows passing in instances of other Rust types into the function and make them usable.
I have yet another example:
Rust Code Example
```rust use jlrs::{ data::{ managed::value::typed::{TypedValue, TypedValueRef, TypedValueRet}, types::foreign_type::OpaqueType, }, prelude::*, }; #[derive(Debug, Default)] pub enum FooTypeInner { Apples = 0, Bananas, Oranges, #[default] Raspberries, } #[derive(Debug, Default)] pub struct FooType { _inner: FooTypeInner, } unsafe impl OpaqueType for FooType {} #[derive(Debug, Default)] pub struct BarType { foo: FooType, } unsafe impl OpaqueType for BarType {} impl FooType { pub fn new_apples() -> TypedValueRet {
unsafe {
CCall::stackless_invoke(|unrooted| {
TypedValue::new(
unrooted,
Self {
_inner: FooTypeInner::Apples,
},
)
.leak()
})
}
}
pub fn is_apples(&self) -> u8 {
matches!(self._inner, FooTypeInner::Apples).into()
}
}
impl BarType {
pub fn new() -> TypedValueRet {
unsafe {
CCall::stackless_invoke(|unrooted| TypedValue::new(unrooted, Default::default()).leak())
}
}
pub fn set_foo(&mut self, new_foo: TypedValue) {
todo!("and this is where I'm stuck");
// self.foo = new_foo ... ?
}
}
fn main() {
println!("Hello, world!");
}
jlrs::prelude::julia_module! {
become example_bootstrap;
struct FooType;
in FooType fn new_apples() -> TypedValueRet as make_apples;
in FooType fn is_apples(&self) -> u8 as is_apples;
struct BarType;
in BarType fn new() -> TypedValueRet as new_bar;
in BarType fn set_foo(&mut self, new_foo: TypedValue) as set_foo!;
fn main() -> () as say_hello;
}
```
What I've figured out so far is that anything that is to be taken as argument in exposed functions must
impl CCallArg
. Given the list of rust types implementing that trait,TypedValue
seems to be what I want to go with, especially since my "constructors" return aTypedValueRet
. And this is where I'm stuck, shown in thetodo!
in the code above: Once I have thatValueRef
I don't know what to do with it.I have tried something like
track_shared()
and other functions that sounded plausible to me, but at some point I fail due to trait constraints on my custom types. For example, instaces ofTracked
can only bederef
ed when their wrappedT
implementsValidLayout
, which, according to the docs, shouldn't be derived by hand is meant primarily forJlrsReflect
. So how exactly do I go on here?Thank you in advance!