Implement passing ownership of string to Rust
diff --git a/macro/src/expand.rs b/macro/src/expand.rs
index 1896a13..16dab26 100644
--- a/macro/src/expand.rs
+++ b/macro/src/expand.rs
@@ -233,21 +233,17 @@
let args = efn.args.iter().map(|arg| expand_extern_arg(arg, types));
let vars = efn.args.iter().map(|arg| {
let ident = &arg.ident;
- let var = if types.needs_indirect_abi(&arg.ty) {
- quote!(::std::ptr::read(#ident))
- } else {
- quote!(#ident)
- };
match &arg.ty {
- Type::Ident(ident) if ident == "String" => quote!(#var.into_string()),
- Type::RustBox(_) => quote!(::std::boxed::Box::from_raw(#var)),
- Type::UniquePtr(_) => quote!(::cxx::UniquePtr::from_raw(#var)),
+ Type::Ident(i) if i == "String" => quote!(::std::mem::take((*#ident).as_mut_string())),
+ Type::RustBox(_) => quote!(::std::boxed::Box::from_raw(#ident)),
+ Type::UniquePtr(_) => quote!(::cxx::UniquePtr::from_raw(#ident)),
Type::Ref(ty) => match &ty.inner {
- Type::Ident(ident) if ident == "String" => quote!(#var.as_string()),
- _ => var,
+ Type::Ident(i) if i == "String" => quote!(#ident.as_string()),
+ _ => quote!(#ident),
},
- Type::Str(_) => quote!(#var.as_str()),
- _ => var,
+ Type::Str(_) => quote!(#ident.as_str()),
+ ty if types.needs_indirect_abi(ty) => quote!(::std::ptr::read(#ident)),
+ _ => quote!(#ident),
}
});
let mut outparam = None;
diff --git a/src/rust_string.rs b/src/rust_string.rs
index 43cd5a6..345d969 100644
--- a/src/rust_string.rs
+++ b/src/rust_string.rs
@@ -24,6 +24,10 @@
pub fn as_string(&self) -> &String {
&self.repr
}
+
+ pub fn as_mut_string(&mut self) -> &mut String {
+ &mut self.repr
+ }
}
#[export_name = "cxxbridge01$string$new"]
diff --git a/tests/ffi/tests.cc b/tests/ffi/tests.cc
index 65640df..c94e34d 100644
--- a/tests/ffi/tests.cc
+++ b/tests/ffi/tests.cc
@@ -100,7 +100,7 @@
r_take_unique_ptr(std::unique_ptr<C>(new C{2020}));
r_take_ref_c(C{2020});
r_take_str(rust::Str("2020"));
- // TODO r_take_rust_string(rust::String("2020"));
+ r_take_rust_string(rust::String("2020"));
r_take_unique_ptr_string(
std::unique_ptr<std::string>(new std::string("2020")));