use crate::ffi::{ZStr, ZString};
use crate::io;
#[cfg(feature = "itoa")]
use crate::path::DecInt;
use crate::path::SMALL_PATH_BUFFER_SIZE;
use alloc::borrow::Cow;
use alloc::string::String;
use alloc::vec::Vec;
use core::str;
#[cfg(feature = "std")]
use std::ffi::{OsStr, OsString};
#[cfg(feature = "std")]
#[cfg(target_os = "hermit")]
use std::os::hermit::ext::ffi::{OsStrExt, OsStringExt};
#[cfg(feature = "std")]
#[cfg(unix)]
use std::os::unix::ffi::{OsStrExt, OsStringExt};
#[cfg(feature = "std")]
#[cfg(target_os = "vxworks")]
use std::os::vxworks::ext::ffi::{OsStrExt, OsStringExt};
#[cfg(feature = "std")]
#[cfg(target_os = "wasi")]
use std::os::wasi::ffi::{OsStrExt, OsStringExt};
#[cfg(feature = "std")]
use std::path::{Component, Components, Iter, Path, PathBuf};
pub trait Arg {
fn as_str(&self) -> io::Result<&str>;
fn to_string_lossy(&self) -> Cow<'_, str>;
fn as_cow_z_str(&self) -> io::Result<Cow<'_, ZStr>>;
fn into_z_str<'b>(self) -> io::Result<Cow<'b, ZStr>>
where
Self: 'b;
fn into_with_z_str<T, F>(self, f: F) -> io::Result<T>
where
Self: Sized,
F: FnOnce(&ZStr) -> io::Result<T>;
#[cfg(not(feature = "rustc-dep-of-std"))]
#[inline]
fn as_cow_c_str(&self) -> io::Result<Cow<'_, ZStr>> {
self.as_cow_z_str()
}
#[cfg(not(feature = "rustc-dep-of-std"))]
#[inline]
fn into_c_str<'b>(self) -> io::Result<Cow<'b, ZStr>>
where
Self: 'b + Sized,
{
self.into_z_str()
}
#[cfg(not(feature = "rustc-dep-of-std"))]
#[inline]
fn into_with_c_str<T, F>(self, f: F) -> io::Result<T>
where
Self: Sized,
F: FnOnce(&ZStr) -> io::Result<T>,
{
self.into_with_z_str(f)
}
}
impl Arg for &str {
#[inline]
fn as_str(&self) -> io::Result<&str> {
Ok(self)
}
#[inline]
fn to_string_lossy(&self) -> Cow<'_, str> {
Cow::Borrowed(self)
}
#[inline]
fn as_cow_z_str(&self) -> io::Result<Cow<'_, ZStr>> {
Ok(Cow::Owned(
ZString::new(self.as_bytes()).map_err(|_cstr_err| io::Error::INVAL)?,
))
}
#[inline]
fn into_z_str<'b>(self) -> io::Result<Cow<'b, ZStr>>
where
Self: 'b,
{
Ok(Cow::Owned(
ZString::new(self).map_err(|_cstr_err| io::Error::INVAL)?,
))
}
#[inline]
fn into_with_z_str<T, F>(self, f: F) -> io::Result<T>
where
Self: Sized,
F: FnOnce(&ZStr) -> io::Result<T>,
{
with_z_str(self.as_bytes(), f)
}
}
impl Arg for &String {
#[inline]
fn as_str(&self) -> io::Result<&str> {
Ok(self)
}
#[inline]
fn to_string_lossy(&self) -> Cow<'_, str> {
Cow::Borrowed(self)
}
#[inline]
fn as_cow_z_str(&self) -> io::Result<Cow<'_, ZStr>> {
Ok(Cow::Owned(
ZString::new(String::as_str(self).as_bytes()).map_err(|_cstr_err| io::Error::INVAL)?,
))
}
#[inline]
fn into_z_str<'b>(self) -> io::Result<Cow<'b, ZStr>>
where
Self: 'b,
{
self.as_str().into_z_str()
}
#[inline]
fn into_with_z_str<T, F>(self, f: F) -> io::Result<T>
where
Self: Sized,
F: FnOnce(&ZStr) -> io::Result<T>,
{
with_z_str(self.as_bytes(), f)
}
}
impl Arg for String {
#[inline]
fn as_str(&self) -> io::Result<&str> {
Ok(self)
}
#[inline]
fn to_string_lossy(&self) -> Cow<'_, str> {
Cow::Borrowed(self)
}
#[inline]
fn as_cow_z_str(&self) -> io::Result<Cow<'_, ZStr>> {
Ok(Cow::Owned(
ZString::new(self.as_bytes()).map_err(|_cstr_err| io::Error::INVAL)?,
))
}
#[inline]
fn into_z_str<'b>(self) -> io::Result<Cow<'b, ZStr>>
where
Self: 'b,
{
Ok(Cow::Owned(
ZString::new(self).map_err(|_cstr_err| io::Error::INVAL)?,
))
}
#[inline]
fn into_with_z_str<T, F>(self, f: F) -> io::Result<T>
where
Self: Sized,
F: FnOnce(&ZStr) -> io::Result<T>,
{
f(&ZString::new(self).map_err(|_cstr_err| io::Error::INVAL)?)
}
}
#[cfg(feature = "std")]
impl Arg for &OsStr {
#[inline]
fn as_str(&self) -> io::Result<&str> {
self.to_str().ok_or(io::Error::INVAL)
}
#[inline]
fn to_string_lossy(&self) -> Cow<'_, str> {
OsStr::to_string_lossy(self)
}
#[inline]
fn as_cow_z_str(&self) -> io::Result<Cow<'_, ZStr>> {
Ok(Cow::Owned(
ZString::new(self.as_bytes()).map_err(|_cstr_err| io::Error::INVAL)?,
))
}
#[inline]
fn into_z_str<'b>(self) -> io::Result<Cow<'b, ZStr>>
where
Self: 'b,
{
Ok(Cow::Owned(
ZString::new(self.as_bytes()).map_err(|_cstr_err| io::Error::INVAL)?,
))
}
#[inline]
fn into_with_z_str<T, F>(self, f: F) -> io::Result<T>
where
Self: Sized,
F: FnOnce(&ZStr) -> io::Result<T>,
{
with_z_str(self.as_bytes(), f)
}
}
#[cfg(feature = "std")]
impl Arg for &OsString {
#[inline]
fn as_str(&self) -> io::Result<&str> {
OsString::as_os_str(self).to_str().ok_or(io::Error::INVAL)
}
#[inline]
fn to_string_lossy(&self) -> Cow<'_, str> {
self.as_os_str().to_string_lossy()
}
#[inline]
fn as_cow_z_str(&self) -> io::Result<Cow<'_, ZStr>> {
Ok(Cow::Owned(
ZString::new(OsString::as_os_str(self).as_bytes())
.map_err(|_cstr_err| io::Error::INVAL)?,
))
}
#[inline]
fn into_z_str<'b>(self) -> io::Result<Cow<'b, ZStr>>
where
Self: 'b,
{
self.as_os_str().into_z_str()
}
#[inline]
fn into_with_z_str<T, F>(self, f: F) -> io::Result<T>
where
Self: Sized,
F: FnOnce(&ZStr) -> io::Result<T>,
{
with_z_str(self.as_bytes(), f)
}
}
#[cfg(feature = "std")]
impl Arg for OsString {
#[inline]
fn as_str(&self) -> io::Result<&str> {
self.as_os_str().to_str().ok_or(io::Error::INVAL)
}
#[inline]
fn to_string_lossy(&self) -> Cow<'_, str> {
self.as_os_str().to_string_lossy()
}
#[inline]
fn as_cow_z_str(&self) -> io::Result<Cow<'_, ZStr>> {
Ok(Cow::Owned(
ZString::new(self.as_bytes()).map_err(|_cstr_err| io::Error::INVAL)?,
))
}
#[inline]
fn into_z_str<'b>(self) -> io::Result<Cow<'b, ZStr>>
where
Self: 'b,
{
Ok(Cow::Owned(
ZString::new(self.into_vec()).map_err(|_cstr_err| io::Error::INVAL)?,
))
}
#[inline]
fn into_with_z_str<T, F>(self, f: F) -> io::Result<T>
where
Self: Sized,
F: FnOnce(&ZStr) -> io::Result<T>,
{
f(&ZString::new(self.into_vec()).map_err(|_cstr_err| io::Error::INVAL)?)
}
}
#[cfg(feature = "std")]
impl Arg for &Path {
#[inline]
fn as_str(&self) -> io::Result<&str> {
self.as_os_str().to_str().ok_or(io::Error::INVAL)
}
#[inline]
fn to_string_lossy(&self) -> Cow<'_, str> {
Path::to_string_lossy(self)
}
#[inline]
fn as_cow_z_str(&self) -> io::Result<Cow<'_, ZStr>> {
Ok(Cow::Owned(
ZString::new(self.as_os_str().as_bytes()).map_err(|_cstr_err| io::Error::INVAL)?,
))
}
#[inline]
fn into_z_str<'b>(self) -> io::Result<Cow<'b, ZStr>>
where
Self: 'b,
{
Ok(Cow::Owned(
ZString::new(self.as_os_str().as_bytes()).map_err(|_cstr_err| io::Error::INVAL)?,
))
}
#[inline]
fn into_with_z_str<T, F>(self, f: F) -> io::Result<T>
where
Self: Sized,
F: FnOnce(&ZStr) -> io::Result<T>,
{
with_z_str(self.as_os_str().as_bytes(), f)
}
}
#[cfg(feature = "std")]
impl Arg for &PathBuf {
#[inline]
fn as_str(&self) -> io::Result<&str> {
PathBuf::as_path(self)
.as_os_str()
.to_str()
.ok_or(io::Error::INVAL)
}
#[inline]
fn to_string_lossy(&self) -> Cow<'_, str> {
self.as_path().to_string_lossy()
}
#[inline]
fn as_cow_z_str(&self) -> io::Result<Cow<'_, ZStr>> {
Ok(Cow::Owned(
ZString::new(PathBuf::as_path(self).as_os_str().as_bytes())
.map_err(|_cstr_err| io::Error::INVAL)?,
))
}
#[inline]
fn into_z_str<'b>(self) -> io::Result<Cow<'b, ZStr>>
where
Self: 'b,
{
self.as_path().into_z_str()
}
#[inline]
fn into_with_z_str<T, F>(self, f: F) -> io::Result<T>
where
Self: Sized,
F: FnOnce(&ZStr) -> io::Result<T>,
{
with_z_str(self.as_os_str().as_bytes(), f)
}
}
#[cfg(feature = "std")]
impl Arg for PathBuf {
#[inline]
fn as_str(&self) -> io::Result<&str> {
self.as_os_str().to_str().ok_or(io::Error::INVAL)
}
#[inline]
fn to_string_lossy(&self) -> Cow<'_, str> {
self.as_os_str().to_string_lossy()
}
#[inline]
fn as_cow_z_str(&self) -> io::Result<Cow<'_, ZStr>> {
Ok(Cow::Owned(
ZString::new(self.as_os_str().as_bytes()).map_err(|_cstr_err| io::Error::INVAL)?,
))
}
#[inline]
fn into_z_str<'b>(self) -> io::Result<Cow<'b, ZStr>>
where
Self: 'b,
{
Ok(Cow::Owned(
ZString::new(self.into_os_string().into_vec()).map_err(|_cstr_err| io::Error::INVAL)?,
))
}
#[inline]
fn into_with_z_str<T, F>(self, f: F) -> io::Result<T>
where
Self: Sized,
F: FnOnce(&ZStr) -> io::Result<T>,
{
f(
&ZString::new(self.into_os_string().into_vec())
.map_err(|_cstr_err| io::Error::INVAL)?,
)
}
}
impl Arg for &ZStr {
#[inline]
fn as_str(&self) -> io::Result<&str> {
self.to_str().map_err(|_utf8_err| io::Error::INVAL)
}
#[inline]
fn to_string_lossy(&self) -> Cow<'_, str> {
ZStr::to_string_lossy(self)
}
#[inline]
fn as_cow_z_str(&self) -> io::Result<Cow<'_, ZStr>> {
Ok(Cow::Borrowed(self))
}
#[inline]
fn into_z_str<'b>(self) -> io::Result<Cow<'b, ZStr>>
where
Self: 'b,
{
Ok(Cow::Borrowed(self))
}
#[inline]
fn into_with_z_str<T, F>(self, f: F) -> io::Result<T>
where
Self: Sized,
F: FnOnce(&ZStr) -> io::Result<T>,
{
f(self)
}
}
impl Arg for &ZString {
#[inline]
fn as_str(&self) -> io::Result<&str> {
unimplemented!()
}
#[inline]
fn to_string_lossy(&self) -> Cow<'_, str> {
unimplemented!()
}
#[inline]
fn as_cow_z_str(&self) -> io::Result<Cow<'_, ZStr>> {
Ok(Cow::Borrowed(self))
}
#[inline]
fn into_z_str<'b>(self) -> io::Result<Cow<'b, ZStr>>
where
Self: 'b,
{
Ok(Cow::Borrowed(self))
}
#[inline]
fn into_with_z_str<T, F>(self, f: F) -> io::Result<T>
where
Self: Sized,
F: FnOnce(&ZStr) -> io::Result<T>,
{
f(self)
}
}
impl Arg for ZString {
#[inline]
fn as_str(&self) -> io::Result<&str> {
self.to_str().map_err(|_utf8_err| io::Error::INVAL)
}
#[inline]
fn to_string_lossy(&self) -> Cow<'_, str> {
ZStr::to_string_lossy(self)
}
#[inline]
fn as_cow_z_str(&self) -> io::Result<Cow<'_, ZStr>> {
Ok(Cow::Borrowed(self))
}
#[inline]
fn into_z_str<'b>(self) -> io::Result<Cow<'b, ZStr>>
where
Self: 'b,
{
Ok(Cow::Owned(self))
}
#[inline]
fn into_with_z_str<T, F>(self, f: F) -> io::Result<T>
where
Self: Sized,
F: FnOnce(&ZStr) -> io::Result<T>,
{
f(&self)
}
}
impl<'a> Arg for Cow<'a, str> {
#[inline]
fn as_str(&self) -> io::Result<&str> {
Ok(self)
}
#[inline]
fn to_string_lossy(&self) -> Cow<'_, str> {
Cow::Borrowed(self)
}
#[inline]
fn as_cow_z_str(&self) -> io::Result<Cow<'_, ZStr>> {
Ok(Cow::Owned(
ZString::new(self.as_ref()).map_err(|_cstr_err| io::Error::INVAL)?,
))
}
#[inline]
fn into_z_str<'b>(self) -> io::Result<Cow<'b, ZStr>>
where
Self: 'b,
{
Ok(Cow::Owned(
match self {
Cow::Owned(s) => ZString::new(s),
Cow::Borrowed(s) => ZString::new(s),
}
.map_err(|_cstr_err| io::Error::INVAL)?,
))
}
#[inline]
fn into_with_z_str<T, F>(self, f: F) -> io::Result<T>
where
Self: Sized,
F: FnOnce(&ZStr) -> io::Result<T>,
{
with_z_str(self.as_bytes(), f)
}
}
#[cfg(feature = "std")]
impl<'a> Arg for Cow<'a, OsStr> {
#[inline]
fn as_str(&self) -> io::Result<&str> {
(**self).to_str().ok_or(io::Error::INVAL)
}
#[inline]
fn to_string_lossy(&self) -> Cow<'_, str> {
(**self).to_string_lossy()
}
#[inline]
fn as_cow_z_str(&self) -> io::Result<Cow<'_, ZStr>> {
Ok(Cow::Owned(
ZString::new(self.as_bytes()).map_err(|_cstr_err| io::Error::INVAL)?,
))
}
#[inline]
fn into_z_str<'b>(self) -> io::Result<Cow<'b, ZStr>>
where
Self: 'b,
{
Ok(Cow::Owned(
match self {
Cow::Owned(os) => ZString::new(os.into_vec()),
Cow::Borrowed(os) => ZString::new(os.as_bytes()),
}
.map_err(|_cstr_err| io::Error::INVAL)?,
))
}
#[inline]
fn into_with_z_str<T, F>(self, f: F) -> io::Result<T>
where
Self: Sized,
F: FnOnce(&ZStr) -> io::Result<T>,
{
with_z_str(self.as_bytes(), f)
}
}
impl<'a> Arg for Cow<'a, ZStr> {
#[inline]
fn as_str(&self) -> io::Result<&str> {
self.to_str().map_err(|_utf8_err| io::Error::INVAL)
}
#[inline]
fn to_string_lossy(&self) -> Cow<'_, str> {
let borrow: &ZStr = core::borrow::Borrow::borrow(self);
borrow.to_string_lossy()
}
#[inline]
fn as_cow_z_str(&self) -> io::Result<Cow<'_, ZStr>> {
Ok(Cow::Borrowed(self))
}
#[inline]
fn into_z_str<'b>(self) -> io::Result<Cow<'b, ZStr>>
where
Self: 'b,
{
Ok(self)
}
#[inline]
fn into_with_z_str<T, F>(self, f: F) -> io::Result<T>
where
Self: Sized,
F: FnOnce(&ZStr) -> io::Result<T>,
{
f(&self)
}
}
#[cfg(feature = "std")]
impl<'a> Arg for Component<'a> {
#[inline]
fn as_str(&self) -> io::Result<&str> {
self.as_os_str().to_str().ok_or(io::Error::INVAL)
}
#[inline]
fn to_string_lossy(&self) -> Cow<'_, str> {
self.as_os_str().to_string_lossy()
}
#[inline]
fn as_cow_z_str(&self) -> io::Result<Cow<'_, ZStr>> {
Ok(Cow::Owned(
ZString::new(self.as_os_str().as_bytes()).map_err(|_cstr_err| io::Error::INVAL)?,
))
}
#[inline]
fn into_z_str<'b>(self) -> io::Result<Cow<'b, ZStr>>
where
Self: 'b,
{
Ok(Cow::Owned(
ZString::new(self.as_os_str().as_bytes()).map_err(|_cstr_err| io::Error::INVAL)?,
))
}
#[inline]
fn into_with_z_str<T, F>(self, f: F) -> io::Result<T>
where
Self: Sized,
F: FnOnce(&ZStr) -> io::Result<T>,
{
with_z_str(self.as_os_str().as_bytes(), f)
}
}
#[cfg(feature = "std")]
impl<'a> Arg for Components<'a> {
#[inline]
fn as_str(&self) -> io::Result<&str> {
self.as_path().to_str().ok_or(io::Error::INVAL)
}
#[inline]
fn to_string_lossy(&self) -> Cow<'_, str> {
self.as_path().to_string_lossy()
}
#[inline]
fn as_cow_z_str(&self) -> io::Result<Cow<'_, ZStr>> {
Ok(Cow::Owned(
ZString::new(self.as_path().as_os_str().as_bytes())
.map_err(|_cstr_err| io::Error::INVAL)?,
))
}
#[inline]
fn into_z_str<'b>(self) -> io::Result<Cow<'b, ZStr>>
where
Self: 'b,
{
Ok(Cow::Owned(
ZString::new(self.as_path().as_os_str().as_bytes())
.map_err(|_cstr_err| io::Error::INVAL)?,
))
}
#[inline]
fn into_with_z_str<T, F>(self, f: F) -> io::Result<T>
where
Self: Sized,
F: FnOnce(&ZStr) -> io::Result<T>,
{
with_z_str(self.as_path().as_os_str().as_bytes(), f)
}
}
#[cfg(feature = "std")]
impl<'a> Arg for Iter<'a> {
#[inline]
fn as_str(&self) -> io::Result<&str> {
self.as_path().to_str().ok_or(io::Error::INVAL)
}
#[inline]
fn to_string_lossy(&self) -> Cow<'_, str> {
self.as_path().to_string_lossy()
}
#[inline]
fn as_cow_z_str(&self) -> io::Result<Cow<'_, ZStr>> {
Ok(Cow::Owned(
ZString::new(self.as_path().as_os_str().as_bytes())
.map_err(|_cstr_err| io::Error::INVAL)?,
))
}
#[inline]
fn into_z_str<'b>(self) -> io::Result<Cow<'b, ZStr>>
where
Self: 'b,
{
Ok(Cow::Owned(
ZString::new(self.as_path().as_os_str().as_bytes())
.map_err(|_cstr_err| io::Error::INVAL)?,
))
}
#[inline]
fn into_with_z_str<T, F>(self, f: F) -> io::Result<T>
where
Self: Sized,
F: FnOnce(&ZStr) -> io::Result<T>,
{
with_z_str(self.as_path().as_os_str().as_bytes(), f)
}
}
impl Arg for &[u8] {
#[inline]
fn as_str(&self) -> io::Result<&str> {
str::from_utf8(self).map_err(|_utf8_err| io::Error::INVAL)
}
#[inline]
fn to_string_lossy(&self) -> Cow<'_, str> {
String::from_utf8_lossy(self)
}
#[inline]
fn as_cow_z_str(&self) -> io::Result<Cow<'_, ZStr>> {
Ok(Cow::Owned(
ZString::new(*self).map_err(|_cstr_err| io::Error::INVAL)?,
))
}
#[inline]
fn into_z_str<'b>(self) -> io::Result<Cow<'b, ZStr>>
where
Self: 'b,
{
Ok(Cow::Owned(
ZString::new(self).map_err(|_cstr_err| io::Error::INVAL)?,
))
}
#[inline]
fn into_with_z_str<T, F>(self, f: F) -> io::Result<T>
where
Self: Sized,
F: FnOnce(&ZStr) -> io::Result<T>,
{
with_z_str(self, f)
}
}
impl Arg for &Vec<u8> {
#[inline]
fn as_str(&self) -> io::Result<&str> {
str::from_utf8(self).map_err(|_utf8_err| io::Error::INVAL)
}
#[inline]
fn to_string_lossy(&self) -> Cow<'_, str> {
String::from_utf8_lossy(self)
}
#[inline]
fn as_cow_z_str(&self) -> io::Result<Cow<'_, ZStr>> {
Ok(Cow::Owned(
ZString::new(self.as_slice()).map_err(|_cstr_err| io::Error::INVAL)?,
))
}
#[inline]
fn into_z_str<'b>(self) -> io::Result<Cow<'b, ZStr>>
where
Self: 'b,
{
Ok(Cow::Owned(
ZString::new(self.as_slice()).map_err(|_cstr_err| io::Error::INVAL)?,
))
}
#[inline]
fn into_with_z_str<T, F>(self, f: F) -> io::Result<T>
where
Self: Sized,
F: FnOnce(&ZStr) -> io::Result<T>,
{
with_z_str(self, f)
}
}
impl Arg for Vec<u8> {
#[inline]
fn as_str(&self) -> io::Result<&str> {
str::from_utf8(self).map_err(|_utf8_err| io::Error::INVAL)
}
#[inline]
fn to_string_lossy(&self) -> Cow<'_, str> {
String::from_utf8_lossy(self)
}
#[inline]
fn as_cow_z_str(&self) -> io::Result<Cow<'_, ZStr>> {
Ok(Cow::Owned(
ZString::new(self.as_slice()).map_err(|_cstr_err| io::Error::INVAL)?,
))
}
#[inline]
fn into_z_str<'b>(self) -> io::Result<Cow<'b, ZStr>>
where
Self: 'b,
{
Ok(Cow::Owned(
ZString::new(self).map_err(|_cstr_err| io::Error::INVAL)?,
))
}
#[inline]
fn into_with_z_str<T, F>(self, f: F) -> io::Result<T>
where
Self: Sized,
F: FnOnce(&ZStr) -> io::Result<T>,
{
f(&ZString::new(self).map_err(|_cstr_err| io::Error::INVAL)?)
}
}
#[cfg(feature = "itoa")]
impl Arg for DecInt {
#[inline]
fn as_str(&self) -> io::Result<&str> {
Ok(self.as_str())
}
#[inline]
fn to_string_lossy(&self) -> Cow<'_, str> {
Cow::Borrowed(self.as_str())
}
#[inline]
fn as_cow_z_str(&self) -> io::Result<Cow<'_, ZStr>> {
Ok(Cow::Owned(
ZString::new(self.as_bytes()).map_err(|_cstr_err| io::Error::INVAL)?,
))
}
#[inline]
fn into_z_str<'b>(self) -> io::Result<Cow<'b, ZStr>>
where
Self: 'b,
{
Ok(Cow::Owned(
ZString::new(self.as_bytes()).map_err(|_cstr_err| io::Error::INVAL)?,
))
}
#[inline]
fn into_with_z_str<T, F>(self, f: F) -> io::Result<T>
where
Self: Sized,
F: FnOnce(&ZStr) -> io::Result<T>,
{
f(self.as_z_str())
}
}
#[inline]
fn with_z_str<T, F>(bytes: &[u8], f: F) -> io::Result<T>
where
F: FnOnce(&ZStr) -> io::Result<T>,
{
if bytes.len() >= SMALL_PATH_BUFFER_SIZE {
return with_z_str_slow_path(bytes, f);
}
let mut buffer: [u8; SMALL_PATH_BUFFER_SIZE] = [0_u8; SMALL_PATH_BUFFER_SIZE];
buffer[..bytes.len()].copy_from_slice(bytes);
f(ZStr::from_bytes_with_nul(&buffer[..=bytes.len()]).map_err(|_cstr_err| io::Error::INVAL)?)
}
#[cold]
fn with_z_str_slow_path<T, F>(bytes: &[u8], f: F) -> io::Result<T>
where
F: FnOnce(&ZStr) -> io::Result<T>,
{
f(&ZString::new(bytes).map_err(|_cstr_err| io::Error::INVAL)?)
}