#![allow(dead_code)]
#[cfg(unix)]
use std::os::unix::io::RawFd;
use std::{
io,
mem::{transmute, MaybeUninit},
num::Saturating,
pin::Pin,
sync::PoisonError,
};
#[cfg(windows)]
use windows_sys::Win32::Foundation::{HANDLE, INVALID_HANDLE_VALUE};
pub(crate) trait Sealed {}
pub(crate) trait DebugExpectExt: Sized {
fn debug_expect(self, msg: &str);
}
pub(crate) static LOCK_POISON: &str = "unexpected lock poison";
pub(crate) fn poison_error<T>(_: PoisonError<T>) -> io::Error { io::Error::other(LOCK_POISON) }
pub(crate) trait OrErrno<T>: Sized {
fn true_or_errno(self, f: impl FnOnce() -> T) -> io::Result<T>;
#[inline(always)]
fn true_val_or_errno(self, value: T) -> io::Result<T> { self.true_or_errno(|| value) }
fn false_or_errno(self, f: impl FnOnce() -> T) -> io::Result<T>;
#[inline(always)]
fn false_val_or_errno(self, value: T) -> io::Result<T> { self.true_or_errno(|| value) }
}
impl<B: ToBool, T> OrErrno<T> for B {
#[inline]
fn true_or_errno(self, f: impl FnOnce() -> T) -> io::Result<T> {
if self.to_bool() {
Ok(f())
} else {
Err(io::Error::last_os_error())
}
}
fn false_or_errno(self, f: impl FnOnce() -> T) -> io::Result<T> {
if !self.to_bool() {
Ok(f())
} else {
Err(io::Error::last_os_error())
}
}
}
#[cfg(unix)]
pub(crate) trait FdOrErrno: Sized {
fn fd_or_errno(self) -> io::Result<Self>;
}
#[cfg(unix)]
impl FdOrErrno for RawFd {
#[inline]
fn fd_or_errno(self) -> io::Result<Self> { (self != -1).true_val_or_errno(self) }
}
#[cfg(windows)]
pub(crate) trait HandleOrErrno: Sized {
fn handle_or_errno(self) -> io::Result<Self>;
}
#[cfg(windows)]
impl HandleOrErrno for HANDLE {
#[inline]
fn handle_or_errno(self) -> io::Result<Self> {
(self != INVALID_HANDLE_VALUE).true_val_or_errno(self)
}
}
pub(crate) trait ToBool {
fn to_bool(self) -> bool;
}
impl ToBool for bool {
#[inline(always)]
fn to_bool(self) -> bool { self }
}
impl ToBool for i32 {
#[inline(always)]
fn to_bool(self) -> bool { self != 0 }
}
pub(crate) trait BoolExt {
fn to_i32(self) -> i32;
fn to_usize(self) -> usize;
}
impl BoolExt for bool {
#[inline(always)] #[rustfmt::skip] fn to_i32(self) -> i32 {
if self { 1 } else { 0 }
}
#[inline(always)] #[rustfmt::skip]
fn to_usize(self) -> usize {
if self { 1 } else { 0 }
}
}
pub(crate) trait AsPtr {
#[inline(always)]
fn as_ptr(&self) -> *const Self { self }
}
impl<T: ?Sized> AsPtr for T {}
pub(crate) trait AsMutPtr {
#[inline(always)]
fn as_mut_ptr(&mut self) -> *mut Self { self }
}
impl<T: ?Sized> AsMutPtr for T {}
impl<T, E: std::fmt::Debug> DebugExpectExt for Result<T, E> {
#[inline]
#[track_caller]
fn debug_expect(self, msg: &str) {
if cfg!(debug_assertions) {
self.expect(msg);
}
}
}
impl<T> DebugExpectExt for Option<T> {
#[inline]
#[track_caller]
fn debug_expect(self, msg: &str) {
if cfg!(debug_assertions) {
self.expect(msg);
}
}
}
pub(crate) trait NumExt: Sized {
#[inline]
fn saturate(self) -> Saturating<Self> { Saturating(self) }
}
impl<T> NumExt for T {}
pub(crate) trait SubUsizeExt: TryInto<usize> + Sized {
fn to_usize(self) -> usize;
}
pub(crate) trait SubIsizeExt: TryInto<usize> + Sized {
fn to_isize(self) -> isize;
}
macro_rules! impl_subsize {
($src:ident to usize) => {
impl SubUsizeExt for $src {
#[inline(always)]
#[allow(clippy::as_conversions)]
fn to_usize(self) -> usize {
self as usize
}
}
};
($src:ident to isize) => {
impl SubIsizeExt for $src {
#[inline(always)]
#[allow(clippy::as_conversions)]
fn to_isize(self) -> isize {
self as isize
}
}
};
($($src:ident to $dst:ident)+) => {$(
impl_subsize!($src to $dst);
)+};
}
impl_subsize! {
u8 to usize
u16 to usize
u32 to usize
i8 to isize
i16 to isize
i32 to isize
u8 to isize
u16 to isize
}
pub(crate) trait RawOsErrorExt {
fn eeq(self, other: u32) -> bool;
}
impl RawOsErrorExt for Option<i32> {
#[inline(always)]
#[allow(clippy::as_conversions)]
fn eeq(self, other: u32) -> bool {
match self {
Some(n) => n as u32 == other,
None => false,
}
}
}
#[inline(always)]
pub(crate) fn weaken_buf_init<T>(r: &[T]) -> &[MaybeUninit<T>] {
unsafe {
transmute(r)
}
}
#[inline(always)]
pub(crate) fn weaken_buf_init_mut<T>(r: &mut [T]) -> &mut [MaybeUninit<T>] {
unsafe {
transmute(r)
}
}
#[inline(always)]
pub(crate) unsafe fn assume_slice_init<T>(r: &[MaybeUninit<T>]) -> &[T] {
unsafe {
transmute(r)
}
}
pub(crate) trait UnpinExt: Unpin {
#[inline]
fn pin(&mut self) -> Pin<&mut Self> { Pin::new(self) }
}
impl<T: Unpin + ?Sized> UnpinExt for T {}