extern crate alloc;
use alloc::borrow::Cow;
#[cfg(feature = "std")]
use std::{
ffi::{OsStr, OsString},
path::{Path, PathBuf},
};
#[macro_export]
macro_rules! nonzero {
(0 $_:ident) => {
compile_error!("`0` passed to `nonzero!`")
};
($n:literal) => {
core::num::NonZero::new($n).unwrap()
};
}
#[cfg(feature = "std")]
pub(crate) unsafe fn bytes_as_path(bytes: &[u8]) -> &std::path::Path {
std::path::Path::new(std::ffi::OsStr::from_encoded_bytes_unchecked(bytes))
}
pub fn eq<T: PartialEq<Other>, Other>(x: T) -> impl Fn(&Other) -> bool {
move |y| &x == y
}
pub fn ne<T: PartialEq<Other>, Other>(x: T) -> impl Fn(&Other) -> bool {
move |y| &x != y
}
pub unsafe trait PathLike<'data>: Sized {
fn into_path_bytes(self) -> Cow<'data, [u8]>;
#[cfg(feature = "std")]
fn into_path(self) -> Cow<'data, Path> {
match self.into_path_bytes() {
Cow::Borrowed(x) => unsafe { bytes_as_path(x) }.into(),
Cow::Owned(x) => {
PathBuf::from(unsafe { OsString::from_encoded_bytes_unchecked(x) }).into()
}
}
}
}
macro_rules! impl_path_like {
(<$data:lifetime> for $t:ty: $self:ident => $res:expr) => {
unsafe impl<$data> PathLike<$data> for $t {
fn into_path_bytes(self) -> Cow<'data, [u8]> {let $self = self; $res.into()}
}
};
(owned $owned:ty: $self:ident => $res:expr) => {
unsafe impl PathLike<'static> for $owned {
fn into_path_bytes(self) -> Cow<'static, [u8]> {let $self = self; $res.into()}
}
};
(
$(for $owned:ty[$borrowed:ty]:
$self:ident => $res:expr;
box $bself:ident => $bres:expr;
ref $rself:ident => $rres:expr;
)+
) => {
$(
impl_path_like!(owned $owned: $self => $res);
impl_path_like!(owned Box<$borrowed>: $bself => $bres);
impl_path_like!(<'data> for &'data $owned: $rself => $rres);
impl_path_like!(<'data> for &'data $borrowed: $rself => $rres);
impl_path_like!(<'data> for &'data Box<$borrowed>: $rself => $rres);
impl_path_like!(<'data> for &'data Cow<'data, $borrowed>: $rself => $rres);
unsafe impl<'data> PathLike<'data> for Cow<'data, $borrowed> {
fn into_path_bytes(self) -> Cow<'data, [u8]> {
match self {
Cow::Owned($self) => $res.into(),
Cow::Borrowed($rself) => $rres.into(),
}
}
}
)+
};
}
impl_path_like! {
for String[str]:
x => x.into_bytes();
box x => x.into_boxed_bytes().into_vec();
ref x => x.as_bytes();
}
#[cfg(feature = "std")]
impl_path_like! {
for PathBuf[Path]:
x => x.into_os_string().into_encoded_bytes();
box x => x.into_path_buf().into_os_string().into_encoded_bytes();
ref x => x.as_os_str().as_encoded_bytes();
for OsString[OsStr]:
x => x.into_encoded_bytes();
box x => x.into_os_string().into_encoded_bytes();
ref x => x.as_encoded_bytes();
}
#[macro_export]
macro_rules! any {
($first:expr, $($rest:expr),* $(, $(else: $map_rest:expr)?)?) => {
$first $(.or($rest))* $($(.or_map_rest($map_rest))?)?
};
}
#[macro_export]
macro_rules! match_out {
{
$($p:pat => $e:expr),+ $(,)?
} => {
|i, o| match o {
$($p => $e.parse(i)),+
}
};
}
#[macro_export]
macro_rules! seq {
($first:expr, $($rest:expr),* $(,)?) => {
$first $(.and($rest))*
};
}