Skip to content

Commit

Permalink
Minor improvements
Browse files Browse the repository at this point in the history
  • Loading branch information
dylni committed Nov 16, 2023
1 parent 3abbfad commit 8fc2a14
Show file tree
Hide file tree
Showing 4 changed files with 38 additions and 95 deletions.
41 changes: 19 additions & 22 deletions src/ext.rs
Original file line number Diff line number Diff line change
Expand Up @@ -56,36 +56,34 @@ pub(super) fn check_bound(string: &OsStr, index: usize) {
);
}

#[cfg(feature = "memchr")]
use memchr::memmem::find;
#[cfg(feature = "memchr")]
use memchr::memmem::rfind;

#[cfg(not(feature = "memchr"))]
fn find(string: &[u8], pat: &[u8]) -> Option<usize> {
(0..=string.len().checked_sub(pat.len())?)
.find(|&x| string[x..].starts_with(pat))
}

#[cfg(not(feature = "memchr"))]
fn rfind(string: &[u8], pat: &[u8]) -> Option<usize> {
(pat.len()..=string.len())
.rfind(|&x| string[..x].ends_with(pat))
.map(|x| x - pat.len())
macro_rules! r#impl {
( $($name:ident),+ ) => {
$(
#[cfg(feature = "memchr")]
use memchr::memmem::$name;

#[cfg(not(feature = "memchr"))]
fn $name(string: &[u8], pat: &[u8]) -> Option<usize> {
(pat.len()..=string.len())
.$name(|&x| string[..x].ends_with(pat))
.map(|x| x - pat.len())
}
)+
};
}
r#impl!(find, rfind);

pub(super) unsafe fn os_str(string: &[u8]) -> &OsStr {
// SAFETY: This function has equivalent safety requirements.
unsafe { OsStr::from_encoded_bytes_unchecked(string) }
}

fn split_once<'a, 'b, F, P>(
fn split_once<'a, 'b, P>(
string: &'a OsStr,
pat: &'b P,
find_fn: F,
find_fn: fn(&OsStr, &'b str) -> Option<usize>,
) -> Option<(&'a OsStr, &'a OsStr)>
where
F: FnOnce(&OsStr, &'b str) -> Option<usize>,
P: EncodedPattern,
{
let pat = pat.__as_str();
Expand All @@ -98,13 +96,12 @@ where
Some(unsafe { (os_str(prefix), os_str(suffix)) })
}

fn trim_matches<'a, 'b, P, F>(
fn trim_matches<'a, 'b, P>(
mut string: &'a OsStr,
pat: &'b P,
strip_fn: F,
strip_fn: for<'c> fn(&'c OsStr, &'b str) -> Option<&'c OsStr>,
) -> &'a OsStr
where
F: for<'c> Fn(&'c OsStr, &'b str) -> Option<&'c OsStr>,
P: EncodedPattern,
{
let pat = pat.__as_str();
Expand Down
84 changes: 15 additions & 69 deletions src/raw_str.rs
Original file line number Diff line number Diff line change
Expand Up @@ -20,12 +20,12 @@ use super::OsStrBytesExt;
use super::Pattern;

if_checked_conversions! {
use super::EncodingError;
use super::Result;
}

if_conversions! {
use super::convert;
use super::OsStrBytes;
use super::OsStringBytes;
}

#[allow(clippy::missing_safety_doc)]
Expand Down Expand Up @@ -162,20 +162,7 @@ impl RawOsStr {
}

if_conversions! {
fn cow_from_raw_bytes_checked(
string: &[u8],
) -> convert::Result<Cow<'_, Self>> {
convert::os_str_from_bytes(string).map(RawOsStrCow::from_os_str)
}
}

if_conversions! {
/// Converts and wraps a byte string.
///
/// # Panics
///
/// Panics if the string is not valid for the [unspecified encoding]
/// used by this crate.
/// Equivalent to [`OsStrBytes::assert_from_raw_bytes`].
///
/// # Examples
///
Expand All @@ -192,26 +179,17 @@ impl RawOsStr {
/// #
/// # Ok::<_, io::Error>(())
/// ```
///
/// [unspecified encoding]: super#encoding-conversions
#[cfg_attr(os_str_bytes_docs_rs, doc(cfg(feature = "conversions")))]
#[inline]
#[must_use = "method should not be used for validation"]
#[track_caller]
pub fn assert_cow_from_raw_bytes(string: &[u8]) -> Cow<'_, Self> {
expect_encoded!(Self::cow_from_raw_bytes_checked(string))
Cow::from_os_str(OsStr::assert_from_raw_bytes(string))
}
}

if_checked_conversions! {
/// Converts and wraps a byte string.
///
/// [`assert_cow_from_raw_bytes`] should almost always be used instead.
/// For more information, see [`EncodingError`].
///
/// # Errors
///
/// See documentation for [`EncodingError`].
/// Equivalent to [`OsStrBytes::from_raw_bytes`].
///
/// # Examples
///
Expand All @@ -231,15 +209,13 @@ impl RawOsStr {
/// #
/// # Ok::<_, io::Error>(())
/// ```
///
/// [`assert_cow_from_raw_bytes`]: Self::assert_cow_from_raw_bytes
#[cfg_attr(
os_str_bytes_docs_rs,
doc(cfg(feature = "checked_conversions"))
)]
#[inline]
pub fn cow_from_raw_bytes(string: &[u8]) -> Result<Cow<'_, Self>> {
Self::cow_from_raw_bytes_checked(string).map_err(EncodingError)
OsStr::from_raw_bytes(string).map(Cow::from_os_str)
}
}

Expand Down Expand Up @@ -643,9 +619,7 @@ impl RawOsStr {
}

if_conversions! {
/// Converts and returns the byte string stored by this container.
///
/// The returned string will use an [unspecified encoding].
/// Equivalent to [`OsStrBytes::to_raw_bytes`].
///
/// # Examples
///
Expand All @@ -656,13 +630,11 @@ impl RawOsStr {
/// let raw = RawOsStr::new(string);
/// assert_eq!(string.as_bytes(), &*raw.to_raw_bytes());
/// ```
///
/// [unspecified encoding]: super#encoding-conversions
#[cfg_attr(os_str_bytes_docs_rs, doc(cfg(feature = "conversions")))]
#[inline]
#[must_use]
pub fn to_raw_bytes(&self) -> Cow<'_, [u8]> {
convert::os_str_to_bytes(self.as_os_str())
self.as_os_str().to_raw_bytes()
}
}

Expand Down Expand Up @@ -1019,18 +991,7 @@ impl RawOsString {
}

if_conversions! {
fn from_raw_vec_checked(string: Vec<u8>) -> convert::Result<Self> {
convert::os_string_from_vec(string).map(Self::new)
}
}

if_conversions! {
/// Wraps a byte string, without copying or encoding conversion.
///
/// # Panics
///
/// Panics if the string is not valid for the [unspecified encoding]
/// used by this crate.
/// Equivalent to [`OsStringBytes::assert_from_raw_vec`].
///
/// # Examples
///
Expand All @@ -1047,26 +1008,17 @@ impl RawOsString {
/// #
/// # Ok::<_, io::Error>(())
/// ```
///
/// [unspecified encoding]: super#encoding-conversions
#[cfg_attr(os_str_bytes_docs_rs, doc(cfg(feature = "conversions")))]
#[inline]
#[must_use = "method should not be used for validation"]
#[track_caller]
pub fn assert_from_raw_vec(string: Vec<u8>) -> Self {
expect_encoded!(Self::from_raw_vec_checked(string))
Self::new(OsString::assert_from_raw_vec(string))
}
}

if_checked_conversions! {
/// Wraps a byte string, without copying or encoding conversion.
///
/// [`assert_from_raw_vec`] should almost always be used instead. For
/// more information, see [`EncodingError`].
///
/// # Errors
///
/// See documentation for [`EncodingError`].
/// Equivalent to [`OsStringBytes::from_raw_vec`].
///
/// # Examples
///
Expand All @@ -1083,20 +1035,18 @@ impl RawOsString {
/// #
/// # Ok::<_, io::Error>(())
/// ```
///
/// [`assert_from_raw_vec`]: Self::assert_from_raw_vec
#[cfg_attr(
os_str_bytes_docs_rs,
doc(cfg(feature = "checked_conversions"))
)]
#[inline]
pub fn from_raw_vec(string: Vec<u8>) -> Result<Self> {
Self::from_raw_vec_checked(string).map_err(EncodingError)
OsString::from_raw_vec(string).map(Self::new)
}
}

if_conversions! {
/// Wraps a byte string, without copying or encoding conversion.
/// Converts and wraps a byte string.
///
/// # Safety
///
Expand Down Expand Up @@ -1225,9 +1175,7 @@ impl RawOsString {
}

if_conversions! {
/// Returns the byte string stored by this container.
///
/// The returned string will use an [unspecified encoding].
/// Equivalent to [`OsStringBytes::into_raw_vec`].
///
/// # Examples
///
Expand All @@ -1238,13 +1186,11 @@ impl RawOsString {
/// let raw = RawOsString::new(string.clone());
/// assert_eq!(string.into_bytes(), raw.into_raw_vec());
/// ```
///
/// [unspecified encoding]: super#encoding-conversions
#[cfg_attr(os_str_bytes_docs_rs, doc(cfg(feature = "conversions")))]
#[inline]
#[must_use]
pub fn into_raw_vec(self) -> Vec<u8> {
convert::os_string_into_vec(self.into_os_string())
self.into_os_string().into_raw_vec()
}
}

Expand Down
4 changes: 2 additions & 2 deletions src/windows/convert/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,8 +13,8 @@ use std::ops::Not;
use std::result;
use std::str;

use super::sys::ffi::OsStrExt;
use super::sys::ffi::OsStringExt;
use super::os::ffi::OsStrExt;
use super::os::ffi::OsStringExt;

mod wtf8;
use wtf8::DecodeWide;
Expand Down
4 changes: 2 additions & 2 deletions src/windows/mod.rs
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
if_conversions! {
#[cfg(target_os = "uefi")]
use std::os::uefi as sys;
use std::os::uefi as os;
#[cfg(windows)]
use std::os::windows as sys;
use std::os::windows as os;
}

pub(super) mod convert_io;
Expand Down

0 comments on commit 8fc2a14

Please sign in to comment.