mirror of
https://github.com/fish-shell/fish-shell.git
synced 2024-11-24 18:40:42 +08:00
Support constructing a wcstring_list_ffi_t from Rust
This allows passing a vector of strings from Rust to C++
This commit is contained in:
parent
f0360efbfa
commit
1bf29a5e13
|
@ -302,6 +302,7 @@ impl Repin for output_stream_t {}
|
||||||
impl Repin for parser_t {}
|
impl Repin for parser_t {}
|
||||||
impl Repin for process_t {}
|
impl Repin for process_t {}
|
||||||
impl Repin for function_properties_ref_t {}
|
impl Repin for function_properties_ref_t {}
|
||||||
|
impl Repin for wcstring_list_ffi_t {}
|
||||||
|
|
||||||
pub use autocxx::c_int;
|
pub use autocxx::c_int;
|
||||||
pub use ffi::*;
|
pub use ffi::*;
|
||||||
|
|
|
@ -6,7 +6,7 @@
|
||||||
//! - wcharz_t: a "newtyped" pointer to a nul-terminated string, implemented in C++.
|
//! - wcharz_t: a "newtyped" pointer to a nul-terminated string, implemented in C++.
|
||||||
//! This is useful for FFI boundaries, to work around autocxx limitations on pointers.
|
//! This is useful for FFI boundaries, to work around autocxx limitations on pointers.
|
||||||
|
|
||||||
pub use crate::ffi::{wchar_t, wcharz_t, wcstring_list_ffi_t};
|
pub use crate::ffi::{wchar_t, wcharz_t, wcstring_list_ffi_t, ToCppWString};
|
||||||
use crate::wchar::{wstr, WString};
|
use crate::wchar::{wstr, WString};
|
||||||
use autocxx::WithinUniquePtr;
|
use autocxx::WithinUniquePtr;
|
||||||
use once_cell::sync::Lazy;
|
use once_cell::sync::Lazy;
|
||||||
|
@ -98,6 +98,12 @@ pub trait WCharToFFI {
|
||||||
fn to_ffi(&self) -> Self::Target;
|
fn to_ffi(&self) -> Self::Target;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl ToCppWString for &wstr {
|
||||||
|
fn into_cpp(self) -> cxx::UniquePtr<cxx::CxxWString> {
|
||||||
|
self.to_ffi()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// WString may be converted to CxxWString.
|
/// WString may be converted to CxxWString.
|
||||||
impl WCharToFFI for WString {
|
impl WCharToFFI for WString {
|
||||||
type Target = cxx::UniquePtr<cxx::CxxWString>;
|
type Target = cxx::UniquePtr<cxx::CxxWString>;
|
||||||
|
@ -122,6 +128,19 @@ impl WCharToFFI for wcharz_t {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Convert from a slice of something that can be referenced as a wstr,
|
||||||
|
/// to unique_ptr<wcstring_list_ffi_t>.
|
||||||
|
impl<T: AsRef<wstr>> WCharToFFI for [T] {
|
||||||
|
type Target = cxx::UniquePtr<wcstring_list_ffi_t>;
|
||||||
|
fn to_ffi(&self) -> cxx::UniquePtr<wcstring_list_ffi_t> {
|
||||||
|
let mut list_ptr = wcstring_list_ffi_t::create();
|
||||||
|
for s in self {
|
||||||
|
list_ptr.as_mut().unwrap().push(s.as_ref());
|
||||||
|
}
|
||||||
|
list_ptr
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// Convert from a CxxWString, in preparation for using over FFI.
|
/// Convert from a CxxWString, in preparation for using over FFI.
|
||||||
pub trait WCharFromFFI<Target> {
|
pub trait WCharFromFFI<Target> {
|
||||||
/// Convert from a CxxWString for FFI purposes.
|
/// Convert from a CxxWString for FFI purposes.
|
||||||
|
@ -196,7 +215,7 @@ impl<'a> AsWstr<'a> for cxx::CxxWString {
|
||||||
|
|
||||||
use crate::ffi_tests::add_test;
|
use crate::ffi_tests::add_test;
|
||||||
add_test!("test_wcstring_list_ffi_t", || {
|
add_test!("test_wcstring_list_ffi_t", || {
|
||||||
use crate::ffi::wcstring_list_ffi_t;
|
|
||||||
let data: Vec<WString> = wcstring_list_ffi_t::get_test_data().from_ffi();
|
let data: Vec<WString> = wcstring_list_ffi_t::get_test_data().from_ffi();
|
||||||
assert_eq!(data, vec!["foo", "bar", "baz"]);
|
assert_eq!(data, vec!["foo", "bar", "baz"]);
|
||||||
|
wcstring_list_ffi_t::check_test_data(data.to_ffi());
|
||||||
});
|
});
|
||||||
|
|
|
@ -905,3 +905,11 @@ bool file_id_t::operator<(const file_id_t &rhs) const { return this->compare_fil
|
||||||
wcstring_list_ffi_t wcstring_list_ffi_t::get_test_data() {
|
wcstring_list_ffi_t wcstring_list_ffi_t::get_test_data() {
|
||||||
return wcstring_list_t{L"foo", L"bar", L"baz"};
|
return wcstring_list_t{L"foo", L"bar", L"baz"};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// static
|
||||||
|
void wcstring_list_ffi_t::check_test_data(wcstring_list_ffi_t data) {
|
||||||
|
assert(data.size() == 3);
|
||||||
|
assert(data.at(0) == L"foo");
|
||||||
|
assert(data.at(1) == L"bar");
|
||||||
|
assert(data.at(2) == L"baz");
|
||||||
|
}
|
||||||
|
|
14
src/wutil.h
14
src/wutil.h
|
@ -40,15 +40,25 @@ struct wcharz_t {
|
||||||
// A helper type for passing vectors of strings back to Rust.
|
// A helper type for passing vectors of strings back to Rust.
|
||||||
// This hides the vector so that autocxx doesn't complain about templates.
|
// This hides the vector so that autocxx doesn't complain about templates.
|
||||||
struct wcstring_list_ffi_t {
|
struct wcstring_list_ffi_t {
|
||||||
wcstring_list_t vals;
|
wcstring_list_t vals{};
|
||||||
|
|
||||||
|
wcstring_list_ffi_t() = default;
|
||||||
/* implicit */ wcstring_list_ffi_t(wcstring_list_t vals) : vals(std::move(vals)) {}
|
/* implicit */ wcstring_list_ffi_t(wcstring_list_t vals) : vals(std::move(vals)) {}
|
||||||
|
|
||||||
size_t size() const { return vals.size(); }
|
size_t size() const { return vals.size(); }
|
||||||
const wcstring &at(size_t idx) const { return vals.at(idx); }
|
const wcstring &at(size_t idx) const { return vals.at(idx); }
|
||||||
|
|
||||||
/// Helper function used in tests only.
|
/// Helper to construct one.
|
||||||
|
static std::unique_ptr<wcstring_list_ffi_t> create() {
|
||||||
|
return std::unique_ptr<wcstring_list_ffi_t>(new wcstring_list_ffi_t());
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Append a string.
|
||||||
|
void push(wcstring s) { vals.push_back(std::move(s)); }
|
||||||
|
|
||||||
|
/// Helper functions used in tests only.
|
||||||
static wcstring_list_ffi_t get_test_data();
|
static wcstring_list_ffi_t get_test_data();
|
||||||
|
static void check_test_data(wcstring_list_ffi_t data);
|
||||||
};
|
};
|
||||||
|
|
||||||
class autoclose_fd_t;
|
class autoclose_fd_t;
|
||||||
|
|
Loading…
Reference in New Issue
Block a user