1#![allow(dead_code)]
2
3#[cfg(unix)]
4use std::os::unix::io::RawFd;
5use std::{
6 io,
7 mem::{transmute, MaybeUninit},
8 num::Saturating,
9 pin::Pin,
10 sync::PoisonError,
11};
12#[cfg(windows)]
13use windows_sys::Win32::Foundation::{HANDLE, INVALID_HANDLE_VALUE};
14
15pub(crate) trait Sealed {}
18pub(crate) trait DebugExpectExt: Sized {
19 fn debug_expect(self, msg: &str);
20}
21
22pub(crate) static LOCK_POISON: &str = "unexpected lock poison";
23pub(crate) fn poison_error<T>(_: PoisonError<T>) -> io::Error { io::Error::other(LOCK_POISON) }
24
25pub(crate) trait OrErrno<T>: Sized {
26 fn true_or_errno(self, f: impl FnOnce() -> T) -> io::Result<T>;
27 #[inline(always)]
28 fn true_val_or_errno(self, value: T) -> io::Result<T> { self.true_or_errno(|| value) }
29 fn false_or_errno(self, f: impl FnOnce() -> T) -> io::Result<T>;
30 #[inline(always)]
31 fn false_val_or_errno(self, value: T) -> io::Result<T> { self.true_or_errno(|| value) }
32}
33impl<B: ToBool, T> OrErrno<T> for B {
34 #[inline]
35 fn true_or_errno(self, f: impl FnOnce() -> T) -> io::Result<T> {
36 if self.to_bool() {
37 Ok(f())
38 } else {
39 Err(io::Error::last_os_error())
40 }
41 }
42 fn false_or_errno(self, f: impl FnOnce() -> T) -> io::Result<T> {
43 if !self.to_bool() {
44 Ok(f())
45 } else {
46 Err(io::Error::last_os_error())
47 }
48 }
49}
50
51#[cfg(unix)]
52pub(crate) trait FdOrErrno: Sized {
53 fn fd_or_errno(self) -> io::Result<Self>;
54}
55#[cfg(unix)]
56impl FdOrErrno for RawFd {
57 #[inline]
58 fn fd_or_errno(self) -> io::Result<Self> { (self != -1).true_val_or_errno(self) }
59}
60
61#[cfg(windows)]
62pub(crate) trait HandleOrErrno: Sized {
63 fn handle_or_errno(self) -> io::Result<Self>;
64}
65#[cfg(windows)]
66impl HandleOrErrno for HANDLE {
67 #[inline]
68 fn handle_or_errno(self) -> io::Result<Self> {
69 (self != INVALID_HANDLE_VALUE).true_val_or_errno(self)
70 }
71}
72
73pub(crate) trait ToBool {
74 fn to_bool(self) -> bool;
75}
76impl ToBool for bool {
77 #[inline(always)]
78 fn to_bool(self) -> bool { self }
79}
80impl ToBool for i32 {
81 #[inline(always)]
82 fn to_bool(self) -> bool { self != 0 }
83}
84
85pub(crate) trait BoolExt {
86 fn to_i32(self) -> i32;
87 fn to_usize(self) -> usize;
88}
89impl BoolExt for bool {
90 #[inline(always)] #[rustfmt::skip] fn to_i32(self) -> i32 {
92 if self { 1 } else { 0 }
93 }
94 #[inline(always)] #[rustfmt::skip]
95 fn to_usize(self) -> usize {
96 if self { 1 } else { 0 }
97 }
98}
99
100pub(crate) trait AsPtr {
101 #[inline(always)]
102 fn as_ptr(&self) -> *const Self { self }
103}
104impl<T: ?Sized> AsPtr for T {}
105
106pub(crate) trait AsMutPtr {
107 #[inline(always)]
108 fn as_mut_ptr(&mut self) -> *mut Self { self }
109}
110impl<T: ?Sized> AsMutPtr for T {}
111
112impl<T, E: std::fmt::Debug> DebugExpectExt for Result<T, E> {
113 #[inline]
114 #[track_caller]
115 fn debug_expect(self, msg: &str) {
116 if cfg!(debug_assertions) {
117 self.expect(msg);
118 }
119 }
120}
121impl<T> DebugExpectExt for Option<T> {
122 #[inline]
123 #[track_caller]
124 fn debug_expect(self, msg: &str) {
125 if cfg!(debug_assertions) {
126 self.expect(msg);
127 }
128 }
129}
130
131pub(crate) trait NumExt: Sized {
132 #[inline]
133 fn saturate(self) -> Saturating<Self> { Saturating(self) }
134}
135impl<T> NumExt for T {}
136
137pub(crate) trait SubUsizeExt: TryInto<usize> + Sized {
138 fn to_usize(self) -> usize;
139}
140pub(crate) trait SubIsizeExt: TryInto<usize> + Sized {
141 fn to_isize(self) -> isize;
142}
143macro_rules! impl_subsize {
144 ($src:ident to usize) => {
145 impl SubUsizeExt for $src {
146 #[inline(always)]
147 #[allow(clippy::as_conversions)]
148 fn to_usize(self) -> usize {
149 self as usize
150 }
151 }
152 };
153 ($src:ident to isize) => {
154 impl SubIsizeExt for $src {
155 #[inline(always)]
156 #[allow(clippy::as_conversions)]
157 fn to_isize(self) -> isize {
158 self as isize
159 }
160 }
161 };
162 ($($src:ident to $dst:ident)+) => {$(
163 impl_subsize!($src to $dst);
164 )+};
165}
166impl_subsize! {
168 u8 to usize
169 u16 to usize
170 u32 to usize
171 i8 to isize
172 i16 to isize
173 i32 to isize
174 u8 to isize
175 u16 to isize
176}
177
178pub(crate) trait RawOsErrorExt {
180 fn eeq(self, other: u32) -> bool;
181}
182impl RawOsErrorExt for Option<i32> {
183 #[inline(always)]
184 #[allow(clippy::as_conversions)]
185 fn eeq(self, other: u32) -> bool {
186 match self {
187 Some(n) => n as u32 == other,
188 None => false,
189 }
190 }
191}
192
193#[inline(always)]
194pub(crate) fn weaken_buf_init<T>(r: &[T]) -> &[MaybeUninit<T>] {
195 unsafe {
196 transmute(r)
198 }
199}
200#[inline(always)]
201pub(crate) fn weaken_buf_init_mut<T>(r: &mut [T]) -> &mut [MaybeUninit<T>] {
202 unsafe {
203 transmute(r)
205 }
206}
207
208#[inline(always)]
209pub(crate) unsafe fn assume_slice_init<T>(r: &[MaybeUninit<T>]) -> &[T] {
210 unsafe {
211 transmute(r)
213 }
214}
215
216pub(crate) trait UnpinExt: Unpin {
217 #[inline]
218 fn pin(&mut self) -> Pin<&mut Self> { Pin::new(self) }
219}
220impl<T: Unpin + ?Sized> UnpinExt for T {}