mirror of
https://github.com/fish-shell/fish-shell.git
synced 2026-06-03 06:41:14 -03:00
Make C++ env_var_t wrap Rust EnvVar
This reimplements C++'s env_var_t to reference a Rust EnvVar. The C++ env_var_t is now just a thin wrapper.
This commit is contained in:
committed by
Peter Ammon
parent
10ee87eb28
commit
0681b6b53a
@@ -25,6 +25,7 @@ fn main() -> miette::Result<()> {
|
||||
let source_files = vec![
|
||||
"src/abbrs.rs",
|
||||
"src/ast.rs",
|
||||
"src/env/env_ffi.rs",
|
||||
"src/event.rs",
|
||||
"src/common.rs",
|
||||
"src/fd_monitor.rs",
|
||||
|
||||
119
fish-rust/src/env/env_ffi.rs
vendored
Normal file
119
fish-rust/src/env/env_ffi.rs
vendored
Normal file
@@ -0,0 +1,119 @@
|
||||
use super::var::{EnvVar, EnvVarFlags};
|
||||
use crate::ffi::{wchar_t, wcharz_t, wcstring_list_ffi_t};
|
||||
use crate::wchar_ffi::WCharToFFI;
|
||||
use crate::wchar_ffi::{AsWstr, WCharFromFFI};
|
||||
use cxx::{CxxWString, UniquePtr};
|
||||
use std::pin::Pin;
|
||||
|
||||
#[allow(clippy::module_inception)]
|
||||
#[cxx::bridge]
|
||||
mod env_ffi {
|
||||
/// Return values for `EnvStack::set()`.
|
||||
#[repr(u8)]
|
||||
#[cxx_name = "env_stack_set_result_t"]
|
||||
enum EnvStackSetResult {
|
||||
ENV_OK,
|
||||
ENV_PERM,
|
||||
ENV_SCOPE,
|
||||
ENV_INVALID,
|
||||
ENV_NOT_FOUND,
|
||||
}
|
||||
|
||||
extern "C++" {
|
||||
include!("wutil.h");
|
||||
type wcstring_list_ffi_t = super::wcstring_list_ffi_t;
|
||||
type wcharz_t = super::wcharz_t;
|
||||
}
|
||||
|
||||
extern "Rust" {
|
||||
type EnvVar;
|
||||
|
||||
fn is_empty(&self) -> bool;
|
||||
|
||||
fn exports(&self) -> bool;
|
||||
fn is_read_only(&self) -> bool;
|
||||
fn is_pathvar(&self) -> bool;
|
||||
|
||||
#[cxx_name = "equals"]
|
||||
fn equals_ffi(&self, rhs: &EnvVar) -> bool;
|
||||
|
||||
#[cxx_name = "as_string"]
|
||||
fn as_string_ffi(&self) -> UniquePtr<CxxWString>;
|
||||
|
||||
#[cxx_name = "as_list"]
|
||||
fn as_list_ffi(&self) -> UniquePtr<wcstring_list_ffi_t>;
|
||||
|
||||
#[cxx_name = "to_list"]
|
||||
fn to_list_ffi(&self, out: Pin<&mut wcstring_list_ffi_t>);
|
||||
|
||||
#[cxx_name = "get_delimiter"]
|
||||
fn get_delimiter_ffi(&self) -> wchar_t;
|
||||
|
||||
#[cxx_name = "get_flags"]
|
||||
fn get_flags_ffi(&self) -> u8;
|
||||
|
||||
#[cxx_name = "clone_box"]
|
||||
fn clone_box_ffi(&self) -> Box<EnvVar>;
|
||||
|
||||
#[cxx_name = "env_var_create"]
|
||||
fn env_var_create_ffi(vals: &wcstring_list_ffi_t, flags: u8) -> Box<EnvVar>;
|
||||
|
||||
#[cxx_name = "env_var_create_from_name"]
|
||||
fn env_var_create_from_name_ffi(
|
||||
name: wcharz_t,
|
||||
values: &wcstring_list_ffi_t,
|
||||
) -> Box<EnvVar>;
|
||||
}
|
||||
}
|
||||
pub use env_ffi::EnvStackSetResult;
|
||||
|
||||
impl Default for EnvStackSetResult {
|
||||
fn default() -> Self {
|
||||
EnvStackSetResult::ENV_OK
|
||||
}
|
||||
}
|
||||
|
||||
/// FFI bits.
|
||||
impl EnvVar {
|
||||
pub fn equals_ffi(&self, rhs: &EnvVar) -> bool {
|
||||
self == rhs
|
||||
}
|
||||
|
||||
pub fn as_string_ffi(&self) -> UniquePtr<CxxWString> {
|
||||
self.as_string().to_ffi()
|
||||
}
|
||||
|
||||
pub fn as_list_ffi(&self) -> UniquePtr<wcstring_list_ffi_t> {
|
||||
self.as_list().to_ffi()
|
||||
}
|
||||
|
||||
pub fn to_list_ffi(&self, mut out: Pin<&mut wcstring_list_ffi_t>) {
|
||||
out.as_mut().clear();
|
||||
for val in self.as_list() {
|
||||
out.as_mut().push(val);
|
||||
}
|
||||
}
|
||||
|
||||
pub fn clone_box_ffi(&self) -> Box<Self> {
|
||||
Box::new(self.clone())
|
||||
}
|
||||
|
||||
pub fn get_flags_ffi(&self) -> u8 {
|
||||
self.get_flags().bits()
|
||||
}
|
||||
|
||||
pub fn get_delimiter_ffi(self: &EnvVar) -> wchar_t {
|
||||
self.get_delimiter().into()
|
||||
}
|
||||
}
|
||||
|
||||
fn env_var_create_ffi(vals: &wcstring_list_ffi_t, flags: u8) -> Box<EnvVar> {
|
||||
Box::new(EnvVar::new_vec(
|
||||
vals.from_ffi(),
|
||||
EnvVarFlags::from_bits(flags).expect("invalid flags"),
|
||||
))
|
||||
}
|
||||
|
||||
pub fn env_var_create_from_name_ffi(name: wcharz_t, values: &wcstring_list_ffi_t) -> Box<EnvVar> {
|
||||
Box::new(EnvVar::new_from_name_vec(name.as_wstr(), values.from_ffi()))
|
||||
}
|
||||
1
fish-rust/src/env/mod.rs
vendored
1
fish-rust/src/env/mod.rs
vendored
@@ -1,3 +1,4 @@
|
||||
mod env_ffi;
|
||||
pub mod environment;
|
||||
pub mod var;
|
||||
|
||||
|
||||
11
fish-rust/src/env/var.rs
vendored
11
fish-rust/src/env/var.rs
vendored
@@ -11,7 +11,6 @@
|
||||
pub const PATH_ARRAY_SEP: char = ':';
|
||||
pub const NONPATH_ARRAY_SEP: char = ' ';
|
||||
|
||||
// Flags that may be passed as the 'mode' in env_stack_t::set() / environment_t::get().
|
||||
bitflags! {
|
||||
/// Flags that may be passed as the 'mode' in env_stack_t::set() / environment_t::get().
|
||||
#[repr(C)]
|
||||
@@ -71,6 +70,12 @@ pub enum EnvStackSetResult {
|
||||
ENV_NOT_FOUND,
|
||||
}
|
||||
|
||||
impl Default for EnvStackSetResult {
|
||||
fn default() -> Self {
|
||||
EnvStackSetResult::ENV_OK
|
||||
}
|
||||
}
|
||||
|
||||
/// A struct of configuration directories, determined in main() that fish will optionally pass to
|
||||
/// env_init.
|
||||
pub struct ConfigPaths {
|
||||
@@ -213,7 +218,7 @@ pub fn as_list(&self) -> &[WString] {
|
||||
}
|
||||
|
||||
/// Returns the delimiter character used when converting from a list to a string.
|
||||
fn get_delimiter(&self) -> char {
|
||||
pub fn get_delimiter(&self) -> char {
|
||||
if self.is_pathvar() {
|
||||
PATH_ARRAY_SEP
|
||||
} else {
|
||||
@@ -250,7 +255,7 @@ pub fn setting_pathvar(&mut self, pathvar: bool) -> Self {
|
||||
}
|
||||
|
||||
/// Returns flags for a variable with the given name.
|
||||
fn flags_for(name: &wstr) -> EnvVarFlags {
|
||||
pub fn flags_for(name: &wstr) -> EnvVarFlags {
|
||||
let mut result = EnvVarFlags::empty();
|
||||
if is_read_only(name) {
|
||||
result.insert(EnvVarFlags::READ_ONLY);
|
||||
|
||||
@@ -104,6 +104,18 @@ fn into_cpp(self) -> cxx::UniquePtr<cxx::CxxWString> {
|
||||
}
|
||||
}
|
||||
|
||||
impl ToCppWString for WString {
|
||||
fn into_cpp(self) -> cxx::UniquePtr<cxx::CxxWString> {
|
||||
self.to_ffi()
|
||||
}
|
||||
}
|
||||
|
||||
impl ToCppWString for &WString {
|
||||
fn into_cpp(self) -> cxx::UniquePtr<cxx::CxxWString> {
|
||||
self.to_ffi()
|
||||
}
|
||||
}
|
||||
|
||||
/// WString may be converted to CxxWString.
|
||||
impl WCharToFFI for WString {
|
||||
type Target = cxx::UniquePtr<cxx::CxxWString>;
|
||||
@@ -213,6 +225,12 @@ fn as_wstr(&'a self) -> &'a wstr {
|
||||
}
|
||||
}
|
||||
|
||||
impl AsWstr<'_> for wcharz_t {
|
||||
fn as_wstr(&self) -> &wstr {
|
||||
wstr::from_char_slice(self.chars())
|
||||
}
|
||||
}
|
||||
|
||||
use crate::ffi_tests::add_test;
|
||||
add_test!("test_wcstring_list_ffi_t", || {
|
||||
let data: Vec<WString> = wcstring_list_ffi_t::get_test_data().from_ffi();
|
||||
|
||||
Reference in New Issue
Block a user