diff --git a/crates/wcstringutil/src/lib.rs b/crates/wcstringutil/src/lib.rs index b8b7d94fd..424552e34 100644 --- a/crates/wcstringutil/src/lib.rs +++ b/crates/wcstringutil/src/lib.rs @@ -1,12 +1,7 @@ //! Helper functions for working with wcstring. -use std::{ - ffi::{CStr, CString, OsString}, - os::unix::ffi::OsStringExt as _, -}; - use fish_fallback::{fish_wcwidth, lowercase, lowercase_rev, wcscasecmp, wcscasecmp_fuzzy}; -use fish_widestring::{ELLIPSIS_CHAR, decode_byte_from_char, prelude::*}; +use fish_widestring::{ELLIPSIS_CHAR, prelude::*}; /// Return the number of newlines in a string. pub fn count_newlines(s: &wstr) -> usize { @@ -340,145 +335,6 @@ pub fn string_fuzzy_match_string( StringFuzzyMatch::try_create(string, match_against, anchor_start) } -/// Implementation of wcs2bytes that accepts a callback. -/// The first argument can be either a `&str` or `&wstr`. -/// This invokes `func` with byte slices containing the UTF-8 encoding of the characters in the -/// input, doing one invocation per character. -/// If `func` returns false, it stops; otherwise it continues. -/// Return false if the callback returned false, otherwise true. -pub fn str2bytes_callback(input: impl IntoCharIter, mut func: impl FnMut(&[u8]) -> bool) -> bool { - // A `char` represents an Unicode scalar value, which takes up at most 4 bytes when encoded in UTF-8. - let mut converted = [0_u8; 4]; - - for c in input.chars() { - let bytes = if let Some(byte) = decode_byte_from_char(c) { - converted[0] = byte; - &converted[..=0] - } else { - c.encode_utf8(&mut converted).as_bytes() - }; - if !func(bytes) { - return false; - } - } - true -} - -/// Returns a newly allocated multibyte character string equivalent of the specified wide character -/// string. -/// -/// This function decodes illegal character sequences in a reversible way using the private use -/// area. -pub fn wcs2bytes(input: impl IntoCharIter) -> Vec { - let mut result = vec![]; - wcs2bytes_appending(&mut result, input); - result -} - -pub fn wcs2osstring(input: &wstr) -> OsString { - if input.is_empty() { - return OsString::new(); - } - - let mut result = vec![]; - wcs2bytes_appending(&mut result, input); - OsString::from_vec(result) -} - -/// Same as [`wcs2bytes`]. Meant to be used when we need a zero-terminated string to feed legacy APIs. -/// Note: if `input` contains any interior NUL bytes, the result will be truncated at the first! -pub fn wcs2zstring(input: &wstr) -> CString { - if input.is_empty() { - return CString::default(); - } - - let mut vec = Vec::with_capacity(input.len() + 1); - str2bytes_callback(input, |buff| { - vec.extend_from_slice(buff); - true - }); - vec.push(b'\0'); - - match CString::from_vec_with_nul(vec) { - Ok(cstr) => cstr, - Err(err) => { - // `input` contained a NUL in the middle; we can retrieve `vec`, though - let mut vec = err.into_bytes(); - let pos = vec.iter().position(|c| *c == b'\0').unwrap(); - vec.truncate(pos + 1); - // Safety: We truncated after the first NUL - unsafe { CString::from_vec_with_nul_unchecked(vec) } - } - } -} - -/// Like [`wcs2bytes`], but appends to `output` instead of returning a new string. -pub fn wcs2bytes_appending(output: &mut Vec, input: impl IntoCharIter) { - str2bytes_callback(input, |buff| { - output.extend_from_slice(buff); - true - }); -} - -/// A trait to make it more convenient to pass ascii/Unicode strings to functions that can take -/// non-Unicode values. The result is nul-terminated and can be passed to OS functions. -/// -/// This is only implemented for owned types where an owned instance will skip allocations (e.g. -/// `CString` can return `self`) but not implemented for owned instances where a new allocation is -/// always required (e.g. implemented for `&wstr` but not `WideString`) because you might as well be -/// left with the original item if we're going to allocate from scratch in all cases. -pub trait ToCString { - /// Correctly convert to a nul-terminated [`CString`] that can be passed to OS functions. - fn to_cstring(self) -> CString; -} - -impl ToCString for CString { - fn to_cstring(self) -> CString { - self - } -} - -impl ToCString for &CStr { - fn to_cstring(self) -> CString { - self.to_owned() - } -} - -/// Safely converts from `&wstr` to a `CString` to a nul-terminated `CString` that can be passed to -/// OS functions, taking into account non-Unicode values that have been shifted into the private-use -/// range by using [`wcs2zstring()`]. -impl ToCString for &wstr { - /// The wide string may contain non-Unicode bytes mapped to the private-use Unicode range, so we - /// have to use [`wcs2zstring()`](self::wcs2zstring) to convert it correctly. - fn to_cstring(self) -> CString { - self::wcs2zstring(self) - } -} - -/// Safely converts from `&WString` to a nul-terminated `CString` that can be passed to OS -/// functions, taking into account non-Unicode values that have been shifted into the private-use -/// range by using [`wcs2zstring()`]. -impl ToCString for &WString { - fn to_cstring(self) -> CString { - self.as_utfstr().to_cstring() - } -} - -/// Convert a (probably ascii) string to CString that can be passed to OS functions. -impl ToCString for Vec { - fn to_cstring(mut self) -> CString { - self.push(b'\0'); - CString::from_vec_with_nul(self).unwrap() - } -} - -/// Convert a (probably ascii) string to nul-terminated CString that can be passed to OS functions. -impl ToCString for &[u8] { - fn to_cstring(self) -> CString { - CString::new(self).unwrap() - } -} - /// Split a string by runs of any of the separator characters provided in `seps`. /// Note the delimiters are the characters in `seps`, not `seps` itself. /// `seps` may contain the NUL character. diff --git a/crates/widestring/src/lib.rs b/crates/widestring/src/lib.rs index 86ad45e3f..4eb3bbb4a 100644 --- a/crates/widestring/src/lib.rs +++ b/crates/widestring/src/lib.rs @@ -6,7 +6,12 @@ pub mod word_char; -use std::{iter, slice}; +use std::{ + ffi::{CStr, CString, OsString}, + iter, + os::unix::ffi::OsStringExt as _, + slice, +}; pub use widestring::{Utf32Str as wstr, Utf32String as WString, utf32str as L, utfstr::CharsUtf32}; pub mod prelude { @@ -44,6 +49,86 @@ pub fn encode_byte_to_char(byte: u8) -> char { .expect("private-use codepoint should be valid char") } +/// Returns a newly allocated multibyte character string equivalent of the specified wide character +/// string. +/// +/// This function decodes illegal character sequences in a reversible way using the private use +/// area. +pub fn wcs2bytes(input: impl IntoCharIter) -> Vec { + let mut result = vec![]; + wcs2bytes_appending(&mut result, input); + result +} + +pub fn wcs2osstring(input: &wstr) -> OsString { + if input.is_empty() { + return OsString::new(); + } + + let mut result = vec![]; + wcs2bytes_appending(&mut result, input); + OsString::from_vec(result) +} + +/// Same as [`wcs2bytes`]. Meant to be used when we need a zero-terminated string to feed legacy APIs. +/// Note: if `input` contains any interior NUL bytes, the result will be truncated at the first! +pub fn wcs2zstring(input: &wstr) -> CString { + if input.is_empty() { + return CString::default(); + } + + let mut vec = Vec::with_capacity(input.len() + 1); + str2bytes_callback(input, |buff| { + vec.extend_from_slice(buff); + true + }); + vec.push(b'\0'); + + match CString::from_vec_with_nul(vec) { + Ok(cstr) => cstr, + Err(err) => { + // `input` contained a NUL in the middle; we can retrieve `vec`, though + let mut vec = err.into_bytes(); + let pos = vec.iter().position(|c| *c == b'\0').unwrap(); + vec.truncate(pos + 1); + // Safety: We truncated after the first NUL + unsafe { CString::from_vec_with_nul_unchecked(vec) } + } + } +} + +/// Like [`wcs2bytes`], but appends to `output` instead of returning a new string. +pub fn wcs2bytes_appending(output: &mut Vec, input: impl IntoCharIter) { + str2bytes_callback(input, |buff| { + output.extend_from_slice(buff); + true + }); +} + +/// Implementation of wcs2bytes that accepts a callback. +/// The first argument can be either a `&str` or `&wstr`. +/// This invokes `func` with byte slices containing the UTF-8 encoding of the characters in the +/// input, doing one invocation per character. +/// If `func` returns false, it stops; otherwise it continues. +/// Return false if the callback returned false, otherwise true. +pub fn str2bytes_callback(input: impl IntoCharIter, mut func: impl FnMut(&[u8]) -> bool) -> bool { + // A `char` represents an Unicode scalar value, which takes up at most 4 bytes when encoded in UTF-8. + let mut converted = [0_u8; 4]; + + for c in input.chars() { + let bytes = if let Some(byte) = decode_byte_from_char(c) { + converted[0] = byte; + &converted[..=0] + } else { + c.encode_utf8(&mut converted).as_bytes() + }; + if !func(bytes) { + return false; + } + } + true +} + /// Decode a literal byte from a UTF-32 character. pub fn decode_byte_from_char(c: char) -> Option { if c >= ENCODE_DIRECT_BASE && c < ENCODE_DIRECT_END { @@ -57,6 +142,65 @@ pub fn decode_byte_from_char(c: char) -> Option { } } +/// A trait to make it more convenient to pass ascii/Unicode strings to functions that can take +/// non-Unicode values. The result is nul-terminated and can be passed to OS functions. +/// +/// This is only implemented for owned types where an owned instance will skip allocations (e.g. +/// `CString` can return `self`) but not implemented for owned instances where a new allocation is +/// always required (e.g. implemented for `&wstr` but not `WideString`) because you might as well be +/// left with the original item if we're going to allocate from scratch in all cases. +pub trait ToCString { + /// Correctly convert to a nul-terminated [`CString`] that can be passed to OS functions. + fn to_cstring(self) -> CString; +} + +impl ToCString for CString { + fn to_cstring(self) -> CString { + self + } +} + +impl ToCString for &CStr { + fn to_cstring(self) -> CString { + self.to_owned() + } +} + +/// Safely converts from `&wstr` to a `CString` to a nul-terminated `CString` that can be passed to +/// OS functions, taking into account non-Unicode values that have been shifted into the private-use +/// range by using [`wcs2zstring()`]. +impl ToCString for &wstr { + /// The wide string may contain non-Unicode bytes mapped to the private-use Unicode range, so we + /// have to use [`wcs2zstring()`](self::wcs2zstring) to convert it correctly. + fn to_cstring(self) -> CString { + self::wcs2zstring(self) + } +} + +/// Safely converts from `&WString` to a nul-terminated `CString` that can be passed to OS +/// functions, taking into account non-Unicode values that have been shifted into the private-use +/// range by using [`wcs2zstring()`]. +impl ToCString for &WString { + fn to_cstring(self) -> CString { + self.as_utfstr().to_cstring() + } +} + +/// Convert a (probably ascii) string to CString that can be passed to OS functions. +impl ToCString for Vec { + fn to_cstring(mut self) -> CString { + self.push(b'\0'); + CString::from_vec_with_nul(self).unwrap() + } +} + +/// Convert a (probably ascii) string to nul-terminated CString that can be passed to OS functions. +impl ToCString for &[u8] { + fn to_cstring(self) -> CString { + CString::new(self).unwrap() + } +} + mod decoder { use crate::{ENCODE_DIRECT_BASE, ENCODE_DIRECT_END, char_offset, wstr}; use buffer::Buffer; diff --git a/src/autoload.rs b/src/autoload.rs index 68b9fc859..ea0123676 100644 --- a/src/autoload.rs +++ b/src/autoload.rs @@ -9,8 +9,7 @@ wutil::{FileId, INVALID_FILE_ID, file_id_for_path}, }; use fish_common::ScopeGuard; -use fish_wcstringutil::wcs2bytes; -use fish_widestring::{L, WExt as _, WString, wstr}; +use fish_widestring::{L, WExt as _, WString, wcs2bytes, wstr}; use lru::LruCache; use rust_embed::RustEmbed; use std::collections::{HashMap, HashSet}; @@ -467,7 +466,7 @@ mod tests { fn test_autoload() { let _cleanup = test_init(); use crate::fds::wopen_cloexec; - use fish_wcstringutil::wcs2zstring; + use fish_widestring::wcs2zstring; use nix::fcntl::OFlag; macro_rules! run { diff --git a/src/bin/fish.rs b/src/bin/fish.rs index 690dd862d..c26e18577 100644 --- a/src/bin/fish.rs +++ b/src/bin/fish.rs @@ -59,7 +59,7 @@ wutil::waccess, }; use fish_common::save_term_foreground_process_group; -use fish_wcstringutil::wcs2bytes; +use fish_widestring::wcs2bytes; use libc::{STDERR_FILENO, STDIN_FILENO}; use nix::{ sys::resource::{UsageWho, getrusage}, diff --git a/src/builtins/fish_indent.rs b/src/builtins/fish_indent.rs index 30206ba1f..7c343e347 100644 --- a/src/builtins/fish_indent.rs +++ b/src/builtins/fish_indent.rs @@ -24,8 +24,9 @@ }; use assert_matches::assert_matches; use fish_common::{ReadExt as _, UnescapeFlags, UnescapeStringStyle}; -use fish_wcstringutil::{count_preceding_backslashes, wcs2bytes}; +use fish_wcstringutil::count_preceding_backslashes; use fish_wgetopt::{ArgType, WGetopter, WOption, wopt}; +use fish_widestring::wcs2bytes; use std::{ ffi::OsStr, fmt::Write as _, diff --git a/src/builtins/status.rs b/src/builtins/status.rs index 9905fa4c9..2c5c40deb 100644 --- a/src/builtins/status.rs +++ b/src/builtins/status.rs @@ -14,7 +14,7 @@ use cfg_if::cfg_if; use fish_feature_flags::{self as features, feature_test}; use fish_util::wcsfilecmp_glob; -use fish_wcstringutil::wcs2bytes; +use fish_widestring::wcs2bytes; use nix::unistd::AccessFlags; use rust_embed::RustEmbed; diff --git a/src/common.rs b/src/common.rs index 39cafef49..c517ae525 100644 --- a/src/common.rs +++ b/src/common.rs @@ -4,23 +4,24 @@ BRACE_BEGIN, BRACE_END, BRACE_SEP, BRACE_SPACE, HOME_DIRECTORY, INTERNAL_SEPARATOR, PROCESS_EXPAND_SELF, PROCESS_EXPAND_SELF_STR, VARIABLE_EXPAND, VARIABLE_EXPAND_SINGLE, }; -use crate::global_safety::AtomicRef; -use crate::global_safety::RelaxedAtomicBool; -use crate::prelude::*; -use crate::terminal::Outputter; -use crate::termsize::Termsize; -use crate::wildcard::{ANY_CHAR, ANY_STRING, ANY_STRING_RECURSIVE}; -use crate::wutil::fish_iswalnum; +use crate::{ + global_safety::{AtomicRef, RelaxedAtomicBool}, + prelude::*, + terminal::Outputter, + termsize::Termsize, + wildcard::{ANY_CHAR, ANY_STRING, ANY_STRING_RECURSIVE}, + wutil::fish_iswalnum, +}; use fish_fallback::fish_wcwidth; use fish_feature_flags::{FeatureFlag, feature_test}; -use fish_wcstringutil::wcs2bytes; -use fish_widestring::{decode_byte_from_char, encode_byte_to_char, subslice_position}; +use fish_widestring::{decode_byte_from_char, encode_byte_to_char, subslice_position, wcs2bytes}; use nix::sys::termios::Termios; -use std::env; -use std::ffi::{CStr, OsStr}; -use std::os::unix::prelude::*; -use std::sync::atomic::Ordering; -use std::sync::{MutexGuard, OnceLock}; +use std::{ + env, + ffi::{CStr, OsStr}, + os::unix::prelude::*, + sync::{MutexGuard, OnceLock, atomic::Ordering}, +}; use fish_common::*; diff --git a/src/env/environment_impl.rs b/src/env/environment_impl.rs index 609c3f190..6e040e79a 100644 --- a/src/env/environment_impl.rs +++ b/src/env/environment_impl.rs @@ -13,7 +13,7 @@ use crate::reader::{commandline_get_state, reader_status_count}; use crate::threads::{is_forked_child, is_main_thread}; use crate::wutil::fish_wcstol_radix; -use fish_wcstringutil::wcs2zstring; +use fish_widestring::wcs2zstring; use nix::sys::stat::{Mode, umask}; use std::cell::{RefCell, UnsafeCell}; use std::collections::HashSet; diff --git a/src/env/mod.rs b/src/env/mod.rs index a8eeb5fc1..06c665cff 100644 --- a/src/env/mod.rs +++ b/src/env/mod.rs @@ -4,7 +4,7 @@ pub mod var; pub use environment::*; -use fish_wcstringutil::ToCString; +use fish_widestring::ToCString; use std::sync::{Mutex, atomic::AtomicUsize}; pub use var::*; @@ -22,7 +22,7 @@ /// environment variables. /// /// As values could contain non-unicode characters, they must first be converted from &wstr to a -/// `CString` with [`fish_wcstringutil::wcs2zstring()`]. +/// `CString` with [`fish_widestring::wcs2zstring()`]. pub fn setenv_lock(name: S1, value: S2, overwrite: bool) { let name = name.to_cstring(); let value = value.to_cstring(); diff --git a/src/env_universal_common.rs b/src/env_universal_common.rs index 399a63d2f..05a9e0dfe 100644 --- a/src/env_universal_common.rs +++ b/src/env_universal_common.rs @@ -6,8 +6,8 @@ use crate::prelude::*; use crate::wutil::{FileId, INVALID_FILE_ID, file_id_for_file, file_id_for_path_narrow, wrealpath}; use fish_common::{UnescapeFlags, UnescapeStringStyle}; -use fish_wcstringutil::{LineIterator, join_strings, wcs2zstring}; -use fish_widestring::decode_byte_from_char; +use fish_wcstringutil::{LineIterator, join_strings}; +use fish_widestring::{decode_byte_from_char, wcs2zstring}; use itertools::Itertools as _; use std::collections::HashSet; use std::collections::hash_map::Entry; @@ -814,8 +814,7 @@ mod tests { use crate::tests::prelude::*; use crate::wutil::{INVALID_FILE_ID, file_id_for_path}; use fish_tempfile::TempDir; - use fish_wcstringutil::wcs2osstring; - use fish_widestring::{ENCODE_DIRECT_BASE, char_offset}; + use fish_widestring::{ENCODE_DIRECT_BASE, char_offset, wcs2osstring}; const UVARS_PER_THREAD: usize = 8; diff --git a/src/exec.rs b/src/exec.rs index 9770a6dd2..34bb23084 100644 --- a/src/exec.rs +++ b/src/exec.rs @@ -45,8 +45,7 @@ use crate::wutil::{fish_wcstol, perror_io}; use errno::{errno, set_errno}; use fish_common::{ScopeGuard, exit_without_destructors, truncate_at_nul, write_loop}; -use fish_wcstringutil::{wcs2bytes, wcs2zstring}; -use fish_widestring::ToWString as _; +use fish_widestring::{ToWString as _, wcs2bytes, wcs2zstring}; use libc::{ EACCES, ENOENT, ENOEXEC, ENOTDIR, EPIPE, EXIT_FAILURE, EXIT_SUCCESS, STDERR_FILENO, STDIN_FILENO, STDOUT_FILENO, diff --git a/src/fds.rs b/src/fds.rs index e7d26ea3d..abbb9ca56 100644 --- a/src/fds.rs +++ b/src/fds.rs @@ -1,20 +1,20 @@ -use crate::flog::flog; -use crate::prelude::*; -use crate::signal::signal_check_cancel; -use crate::wutil::perror_nix; +use crate::{flog::flog, prelude::*, signal::signal_check_cancel, wutil::perror_nix}; use cfg_if::cfg_if; use fish_util::perror; -use fish_wcstringutil::wcs2zstring; +use fish_widestring::wcs2zstring; use libc::{EINTR, F_GETFD, F_GETFL, F_SETFD, F_SETFL, FD_CLOEXEC, O_NONBLOCK, c_int}; -use nix::fcntl::FcntlArg; -use nix::fcntl::OFlag; -use std::ffi::CStr; -use std::fs::File; -use std::io; -use std::mem::ManuallyDrop; -use std::ops::{Deref, DerefMut}; -use std::os::fd::{AsRawFd, FromRawFd, IntoRawFd, OwnedFd}; -use std::os::unix::prelude::*; +use nix::fcntl::{FcntlArg, OFlag}; +use std::{ + ffi::CStr, + fs::File, + io, + mem::ManuallyDrop, + ops::{Deref, DerefMut}, + os::{ + fd::{AsRawFd, FromRawFd, IntoRawFd, OwnedFd}, + unix::prelude::*, + }, +}; localizable_consts!( pub PIPE_ERROR diff --git a/src/flog.rs b/src/flog.rs index 9c269bdc9..217d818f2 100644 --- a/src/flog.rs +++ b/src/flog.rs @@ -2,7 +2,7 @@ use crate::wildcard::wildcard_match; use crate::{parse_util::unescape_wildcards, wutil::unescape_bytes_and_write_to_fd}; use fish_util::write_to_fd; -use fish_wcstringutil::wcs2bytes; +use fish_widestring::wcs2bytes; use libc::c_int; use std::sync::atomic::{AtomicI32, Ordering}; diff --git a/src/fs.rs b/src/fs.rs index 40393ba9e..4ce6eb127 100644 --- a/src/fs.rs +++ b/src/fs.rs @@ -7,7 +7,7 @@ wutil::{FileId, INVALID_FILE_ID, file_id_for_file, file_id_for_path, wdirname, wunlink}, }; use fish_tempfile::random_filename; -use fish_wcstringutil::{wcs2bytes, wcs2osstring}; +use fish_widestring::{wcs2bytes, wcs2osstring}; use libc::{LOCK_EX, LOCK_SH, c_int}; use nix::{fcntl::OFlag, sys::stat::Mode}; use std::{ diff --git a/src/function.rs b/src/function.rs index 7f96df871..d2965ba9e 100644 --- a/src/function.rs +++ b/src/function.rs @@ -2,24 +2,28 @@ // autoloading functions in the $fish_function_path. Actual function evaluation is taken care of by // the parser and to some degree the builtin handling library. -use crate::ast::{self, Node as _}; -use crate::autoload::{Autoload, AutoloadResult}; -use crate::common::{escape, valid_func_name}; -use crate::complete::complete_wrap_map; -use crate::env::{EnvStack, Environment}; -use crate::event::{self, EventDescription}; -use crate::global_safety::RelaxedAtomicBool; -use crate::parse_tree::NodeRef; -use crate::parser::Parser; -use crate::parser_keywords::parser_keywords_is_reserved; -use crate::prelude::*; -use crate::proc::Pid; -use crate::wutil::dir_iter::DirIter; +use crate::{ + ast::{self, Node as _}, + autoload::{Autoload, AutoloadResult}, + common::{escape, valid_func_name}, + complete::complete_wrap_map, + env::{EnvStack, Environment}, + event::{self, EventDescription}, + global_safety::RelaxedAtomicBool, + parse_tree::NodeRef, + parser::Parser, + parser_keywords::parser_keywords_is_reserved, + prelude::*, + proc::Pid, + wutil::dir_iter::DirIter, +}; use fish_common::{FilenameRef, assert_sync}; -use fish_wcstringutil::wcs2bytes; -use std::collections::{HashMap, HashSet}; -use std::num::NonZeroU32; -use std::sync::{Arc, LazyLock, Mutex}; +use fish_widestring::wcs2bytes; +use std::{ + collections::{HashMap, HashSet}, + num::NonZeroU32, + sync::{Arc, LazyLock, Mutex}, +}; #[derive(Clone)] pub struct FunctionProperties { diff --git a/src/history/file.rs b/src/history/file.rs index ae51cd81c..f9759e400 100644 --- a/src/history/file.rs +++ b/src/history/file.rs @@ -9,7 +9,7 @@ path::{DirRemoteness, path_get_data_remoteness}, wutil::FileId, }; -use fish_wcstringutil::wcs2bytes; +use fish_widestring::wcs2bytes; use libc::{ENODEV, MAP_ANONYMOUS, MAP_FAILED, MAP_PRIVATE, PROT_READ, PROT_WRITE}; use std::{ fs::File, diff --git a/src/history/history.rs b/src/history/history.rs index b48e2b483..a85d3d85e 100644 --- a/src/history/history.rs +++ b/src/history/history.rs @@ -1805,9 +1805,8 @@ mod tests { use crate::prelude::*; use crate::tests::prelude::test_init; use fish_build_helper::workspace_root; - use fish_wcstringutil::{ - string_prefixes_string, string_prefixes_string_case_insensitive, wcs2bytes, - }; + use fish_wcstringutil::{string_prefixes_string, string_prefixes_string_case_insensitive}; + use fish_widestring::wcs2bytes; use rand::Rng as _; use rand::rngs::ThreadRng; use std::collections::VecDeque; diff --git a/src/io.rs b/src/io.rs index aaac310f5..58bcf8b22 100644 --- a/src/io.rs +++ b/src/io.rs @@ -1,26 +1,27 @@ -use crate::builtins::shared::{STATUS_CMD_ERROR, STATUS_CMD_OK, STATUS_READ_TOO_MUCH}; -use crate::common::bytes2wcstring; -use crate::fd_monitor::{Callback, FdMonitor, FdMonitorItemId}; -use crate::fds::{ - BorrowedFdFile, PIPE_ERROR, make_autoclose_pipes, make_fd_nonblocking, wopen_cloexec, +use crate::{ + builtins::shared::{STATUS_CMD_ERROR, STATUS_CMD_OK, STATUS_READ_TOO_MUCH}, + common::bytes2wcstring, + fd_monitor::{Callback, FdMonitor, FdMonitorItemId}, + fds::{BorrowedFdFile, PIPE_ERROR, make_autoclose_pipes, make_fd_nonblocking, wopen_cloexec}, + flog::{flog, flogf, should_flog}, + nix::isatty, + path::path_apply_working_directory, + prelude::*, + proc::JobGroupRef, + redirection::{RedirectionMode, RedirectionSpecList}, + wutil::{perror_io, unescape_bytes_and_write_to_fd, wdirname, wstat}, }; -use crate::flog::{flog, flogf, should_flog}; -use crate::nix::isatty; -use crate::path::path_apply_working_directory; -use crate::prelude::*; -use crate::proc::JobGroupRef; -use crate::redirection::{RedirectionMode, RedirectionSpecList}; -use crate::wutil::{perror_io, unescape_bytes_and_write_to_fd, wdirname, wstat}; use errno::Errno; use fish_util::perror; -use fish_wcstringutil::wcs2bytes; +use fish_widestring::wcs2bytes; use libc::{EAGAIN, EINTR, ENOENT, ENOTDIR, EWOULDBLOCK, STDOUT_FILENO}; -use nix::fcntl::OFlag; -use nix::sys::stat::Mode; -use std::fs::File; -use std::io; -use std::os::fd::{AsFd as _, AsRawFd as _, BorrowedFd, OwnedFd, RawFd}; -use std::sync::{Arc, LazyLock, Mutex, MutexGuard}; +use nix::{fcntl::OFlag, sys::stat::Mode}; +use std::{ + fs::File, + io, + os::fd::{AsFd as _, AsRawFd as _, BorrowedFd, OwnedFd, RawFd}, + sync::{Arc, LazyLock, Mutex, MutexGuard}, +}; /// separated_buffer_t represents a buffer of output from commands, prepared to be turned into a /// variable. For example, command substitutions output into one of these. Most commands just diff --git a/src/parser.rs b/src/parser.rs index 92cfe44fd..f37736a6e 100644 --- a/src/parser.rs +++ b/src/parser.rs @@ -36,8 +36,7 @@ EscapeFlags, EscapeStringStyle, FilenameRef, ScopeGuarding, ScopedCell, ScopedRefCell, }; use fish_util::get_time; -use fish_wcstringutil::wcs2bytes; -use fish_widestring::WExt as _; +use fish_widestring::{WExt as _, wcs2bytes}; use libc::c_int; use std::cell::{Ref, RefCell, RefMut}; use std::ffi::OsStr; diff --git a/src/path.rs b/src/path.rs index fd8a23803..ed646a889 100644 --- a/src/path.rs +++ b/src/path.rs @@ -9,7 +9,7 @@ use crate::wutil::{normalize_path, path_normalize_for_cd, waccess, wdirname, wstat}; use cfg_if::cfg_if; use errno::{Errno, errno, set_errno}; -use fish_wcstringutil::{wcs2osstring, wcs2zstring}; +use fish_widestring::{wcs2osstring, wcs2zstring}; use libc::{EACCES, ENOENT, ENOTDIR, X_OK}; use nix::unistd::AccessFlags; use std::ffi::OsStr; diff --git a/src/screen.rs b/src/screen.rs index 57ae7aae6..604d90ad6 100644 --- a/src/screen.rs +++ b/src/screen.rs @@ -26,8 +26,8 @@ use crate::wutil::fstat; use fish_common::write_loop; use fish_fallback::{fish_wcswidth_canonicalizing, fish_wcwidth}; -use fish_wcstringutil::{fish_wcwidth_visible, string_prefixes_string, wcs2bytes}; -use fish_widestring::ELLIPSIS_CHAR; +use fish_wcstringutil::{fish_wcwidth_visible, string_prefixes_string}; +use fish_widestring::{ELLIPSIS_CHAR, wcs2bytes}; use libc::{STDERR_FILENO, STDOUT_FILENO}; use nix::sys::termios; use std::cell::RefCell; diff --git a/src/terminal.rs b/src/terminal.rs index b2d8be900..d830e55ee 100644 --- a/src/terminal.rs +++ b/src/terminal.rs @@ -8,7 +8,7 @@ use fish_color::{Color, Color24}; use fish_common::{EscapeStringStyle, write_loop}; use fish_feature_flags::FeatureFlag; -use fish_wcstringutil::{wcs2bytes, wcs2bytes_appending}; +use fish_widestring::{wcs2bytes, wcs2bytes_appending}; use std::cell::{RefCell, RefMut}; use std::ops::{Deref, DerefMut}; use std::os::fd::RawFd; diff --git a/src/universal_notifier/inotify.rs b/src/universal_notifier/inotify.rs index 9ad971f38..d28f6bd30 100644 --- a/src/universal_notifier/inotify.rs +++ b/src/universal_notifier/inotify.rs @@ -2,7 +2,7 @@ use crate::prelude::*; use crate::universal_notifier::UniversalNotifier; use crate::wutil::{wbasename, wdirname}; -use fish_wcstringutil::wcs2osstring; +use fish_widestring::wcs2osstring; use nix::sys::inotify::{AddWatchFlags, InitFlags, Inotify}; use std::ffi::OsString; use std::os::fd::{AsFd as _, AsRawFd as _, RawFd}; diff --git a/src/universal_notifier/kqueue.rs b/src/universal_notifier/kqueue.rs index 82eadcb73..511119293 100644 --- a/src/universal_notifier/kqueue.rs +++ b/src/universal_notifier/kqueue.rs @@ -3,7 +3,7 @@ use crate::prelude::*; use crate::universal_notifier::UniversalNotifier; use crate::wutil::wdirname; -use fish_wcstringutil::wcs2osstring; +use fish_widestring::wcs2osstring; use nix::sys::event::{EvFlags, EventFilter, FilterFlag, KEvent, Kqueue}; use std::fs::File; use std::os::fd::AsFd; diff --git a/src/universal_notifier/test_helpers.rs b/src/universal_notifier/test_helpers.rs index 5a4daf734..574086c3e 100644 --- a/src/universal_notifier/test_helpers.rs +++ b/src/universal_notifier/test_helpers.rs @@ -17,7 +17,7 @@ pub fn test_notifiers(notifiers: &[&dyn UniversalNotifier], fish_variables_path: // Helper to simulate modifying a file, using the atomic rename() approach. let modify_path = |path: &wstr| -> Result<(), std::io::Error> { - use fish_wcstringutil::wcs2osstring; + use fish_widestring::wcs2osstring; use std::fs; use std::io::Write as _; let path = wcs2osstring(path); diff --git a/src/wutil/dir_iter.rs b/src/wutil/dir_iter.rs index 363d051ef..0f9a4b258 100644 --- a/src/wutil/dir_iter.rs +++ b/src/wutil/dir_iter.rs @@ -2,8 +2,7 @@ use crate::common::bytes2wcstring; use crate::wutil::DevInode; use cfg_if::cfg_if; -use fish_wcstringutil::wcs2zstring; -use fish_widestring::{WString, wstr}; +use fish_widestring::{WString, wcs2zstring, wstr}; use libc::{ EACCES, EIO, ELOOP, ENAMETOOLONG, ENODEV, ENOENT, ENOTDIR, S_IFBLK, S_IFCHR, S_IFDIR, S_IFIFO, S_IFLNK, S_IFMT, S_IFREG, S_IFSOCK, diff --git a/src/wutil/fileid.rs b/src/wutil/fileid.rs index 49a4b3305..f29dd7518 100644 --- a/src/wutil/fileid.rs +++ b/src/wutil/fileid.rs @@ -1,8 +1,10 @@ use crate::wutil::wstr; -use fish_wcstringutil::wcs2zstring; -use std::ffi::{CStr, OsStr}; -use std::fs::{self, File, Metadata}; -use std::os::unix::prelude::*; +use fish_widestring::wcs2zstring; +use std::{ + ffi::{CStr, OsStr}, + fs::{self, File, Metadata}, + os::unix::prelude::*, +}; /// Struct for representing a file's inode. We use this to detect and avoid symlink loops, among /// other things. diff --git a/src/wutil/mod.rs b/src/wutil/mod.rs index c7ac5a580..b83407796 100644 --- a/src/wutil/mod.rs +++ b/src/wutil/mod.rs @@ -17,13 +17,17 @@ use errno::{Errno, set_errno}; use fish_common::fish_reserved_codepoint; use fish_util::{perror, write_to_fd}; -use fish_wcstringutil::{join_strings, str2bytes_callback, wcs2osstring, wcs2zstring}; -use fish_widestring::{IntoCharIter, L, WExt as _, WString, wstr}; +use fish_wcstringutil::join_strings; +use fish_widestring::{ + IntoCharIter, L, WExt as _, WString, str2bytes_callback, wcs2osstring, wcs2zstring, wstr, +}; use nix::unistd::AccessFlags; -use std::ffi::OsStr; -use std::fs::{self, canonicalize}; -use std::io; -use std::os::unix::prelude::*; +use std::{ + ffi::OsStr, + fs::{self, canonicalize}, + io, + os::unix::prelude::*, +}; pub use crate::wutil::printf::{eprintf, fprintf, printf, sprintf};