Implement Vec<String>
diff --git a/src/cxx.cc b/src/cxx.cc
index b953904..e00fd6a 100644
--- a/src/cxx.cc
+++ b/src/cxx.cc
@@ -280,7 +280,8 @@
#define FOR_EACH_RUST_VEC(MACRO) \
FOR_EACH_NUMERIC(MACRO) \
- MACRO(bool, bool)
+ MACRO(bool, bool) \
+ MACRO(string, rust::String)
extern "C" {
FOR_EACH_STD_VECTOR(STD_VECTOR_OPS)
diff --git a/src/rust_vec.rs b/src/rust_vec.rs
index 9ff4bbf..5e7082a 100644
--- a/src/rust_vec.rs
+++ b/src/rust_vec.rs
@@ -1,3 +1,6 @@
+use crate::rust_string::RustString;
+use std::mem::ManuallyDrop;
+
#[repr(C)]
pub struct RustVec<T> {
repr: Vec<T>,
@@ -40,3 +43,37 @@
self.repr.as_ptr()
}
}
+
+impl RustVec<RustString> {
+ pub fn from_vec_string(v: Vec<String>) -> Self {
+ let mut v = ManuallyDrop::new(v);
+ let ptr = v.as_mut_ptr().cast::<RustString>();
+ let len = v.len();
+ let cap = v.capacity();
+ Self::from(unsafe { Vec::from_raw_parts(ptr, len, cap) })
+ }
+
+ pub fn from_ref_vec_string(v: &Vec<String>) -> &Self {
+ Self::from_ref(unsafe { &*(v as *const Vec<String> as *const Vec<RustString>) })
+ }
+
+ pub fn from_mut_vec_string(v: &mut Vec<String>) -> &mut Self {
+ Self::from_mut(unsafe { &mut *(v as *mut Vec<String> as *mut Vec<RustString>) })
+ }
+
+ pub fn into_vec_string(self) -> Vec<String> {
+ let mut v = ManuallyDrop::new(self.repr);
+ let ptr = v.as_mut_ptr().cast::<String>();
+ let len = v.len();
+ let cap = v.capacity();
+ unsafe { Vec::from_raw_parts(ptr, len, cap) }
+ }
+
+ pub fn as_vec_string(&self) -> &Vec<String> {
+ unsafe { &*(&self.repr as *const Vec<RustString> as *const Vec<String>) }
+ }
+
+ pub fn as_mut_vec_string(&mut self) -> &mut Vec<String> {
+ unsafe { &mut *(&mut self.repr as *mut Vec<RustString> as *mut Vec<String>) }
+ }
+}
diff --git a/src/symbols/rust_string.rs b/src/symbols/rust_string.rs
index 63d4ba7..d8e0f4a 100644
--- a/src/symbols/rust_string.rs
+++ b/src/symbols/rust_string.rs
@@ -3,6 +3,11 @@
use std::slice;
use std::str;
+#[repr(C)]
+pub(crate) struct RustString {
+ repr: String,
+}
+
#[export_name = "cxxbridge03$string$new"]
unsafe extern "C" fn string_new(this: &mut MaybeUninit<String>) {
ptr::write(this.as_mut_ptr(), String::new());
diff --git a/src/symbols/rust_vec.rs b/src/symbols/rust_vec.rs
index 9ce87ab..5465471 100644
--- a/src/symbols/rust_vec.rs
+++ b/src/symbols/rust_vec.rs
@@ -1,8 +1,9 @@
+use super::rust_string::RustString;
use std::mem;
use std::ptr;
#[repr(C)]
-pub struct RustVec<T> {
+pub(crate) struct RustVec<T> {
repr: Vec<T>,
}
@@ -13,38 +14,38 @@
};
}
-macro_rules! rust_vec_shims_for_primitive {
- ($ty:ident) => {
+macro_rules! rust_vec_shims {
+ ($segment:expr, $ty:ty) => {
const_assert_eq!(mem::size_of::<[usize; 3]>(), mem::size_of::<Vec<$ty>>());
const_assert_eq!(mem::align_of::<usize>(), mem::align_of::<Vec<$ty>>());
const _: () = {
attr! {
- #[export_name = concat!("cxxbridge03$rust_vec$", stringify!($ty), "$new")]
+ #[export_name = concat!("cxxbridge03$rust_vec$", $segment, "$new")]
unsafe extern "C" fn __new(this: *mut RustVec<$ty>) {
ptr::write(this, RustVec { repr: Vec::new() });
}
}
attr! {
- #[export_name = concat!("cxxbridge03$rust_vec$", stringify!($ty), "$drop")]
+ #[export_name = concat!("cxxbridge03$rust_vec$", $segment, "$drop")]
unsafe extern "C" fn __drop(this: *mut RustVec<$ty>) {
ptr::drop_in_place(this);
}
}
attr! {
- #[export_name = concat!("cxxbridge03$rust_vec$", stringify!($ty), "$len")]
+ #[export_name = concat!("cxxbridge03$rust_vec$", $segment, "$len")]
unsafe extern "C" fn __len(this: *const RustVec<$ty>) -> usize {
(*this).repr.len()
}
}
attr! {
- #[export_name = concat!("cxxbridge03$rust_vec$", stringify!($ty), "$data")]
+ #[export_name = concat!("cxxbridge03$rust_vec$", $segment, "$data")]
unsafe extern "C" fn __data(this: *const RustVec<$ty>) -> *const $ty {
(*this).repr.as_ptr()
}
}
attr! {
- #[export_name = concat!("cxxbridge03$rust_vec$", stringify!($ty), "$stride")]
+ #[export_name = concat!("cxxbridge03$rust_vec$", $segment, "$stride")]
unsafe extern "C" fn __stride() -> usize {
mem::size_of::<$ty>()
}
@@ -53,6 +54,12 @@
};
}
+macro_rules! rust_vec_shims_for_primitive {
+ ($ty:ident) => {
+ rust_vec_shims!(stringify!($ty), $ty);
+ };
+}
+
rust_vec_shims_for_primitive!(bool);
rust_vec_shims_for_primitive!(u8);
rust_vec_shims_for_primitive!(u16);
@@ -64,3 +71,5 @@
rust_vec_shims_for_primitive!(i64);
rust_vec_shims_for_primitive!(f32);
rust_vec_shims_for_primitive!(f64);
+
+rust_vec_shims!("string", RustString);