| 1 | //! Platform-independent platform abstraction |
| 2 | //! |
| 3 | //! This is the platform-independent portion of the standard library's |
| 4 | //! platform abstraction layer, whereas `std::sys` is the |
| 5 | //! platform-specific portion. |
| 6 | //! |
| 7 | //! The relationship between `std::sys_common`, `std::sys` and the |
| 8 | //! rest of `std` is complex, with dependencies going in all |
| 9 | //! directions: `std` depending on `sys_common`, `sys_common` |
| 10 | //! depending on `sys`, and `sys` depending on `sys_common` and `std`. |
| 11 | //! This is because `sys_common` not only contains platform-independent code, |
| 12 | //! but also code that is shared between the different platforms in `sys`. |
| 13 | //! Ideally all that shared code should be moved to `sys::common`, |
| 14 | //! and the dependencies between `std`, `sys_common` and `sys` all would form a dag. |
| 15 | //! Progress on this is tracked in #84187. |
| 16 | |
| 17 | #![allow (missing_docs)] |
| 18 | #![allow (missing_debug_implementations)] |
| 19 | |
| 20 | #[cfg (test)] |
| 21 | mod tests; |
| 22 | |
| 23 | pub mod wstr; |
| 24 | pub mod wtf8; |
| 25 | |
| 26 | // common error constructors |
| 27 | |
| 28 | /// A trait for viewing representations from std types |
| 29 | #[doc (hidden)] |
| 30 | #[allow (dead_code)] // not used on all platforms |
| 31 | pub trait AsInner<Inner: ?Sized> { |
| 32 | fn as_inner(&self) -> &Inner; |
| 33 | } |
| 34 | |
| 35 | /// A trait for viewing representations from std types |
| 36 | #[doc (hidden)] |
| 37 | #[allow (dead_code)] // not used on all platforms |
| 38 | pub trait AsInnerMut<Inner: ?Sized> { |
| 39 | fn as_inner_mut(&mut self) -> &mut Inner; |
| 40 | } |
| 41 | |
| 42 | /// A trait for extracting representations from std types |
| 43 | #[doc (hidden)] |
| 44 | pub trait IntoInner<Inner> { |
| 45 | fn into_inner(self) -> Inner; |
| 46 | } |
| 47 | |
| 48 | /// A trait for creating std types from internal representations |
| 49 | #[doc (hidden)] |
| 50 | pub trait FromInner<Inner> { |
| 51 | fn from_inner(inner: Inner) -> Self; |
| 52 | } |
| 53 | |
| 54 | // Computes (value*numer)/denom without overflow, as long as both |
| 55 | // (numer*denom) and the overall result fit into i64 (which is the case |
| 56 | // for our time conversions). |
| 57 | #[allow (dead_code)] // not used on all platforms |
| 58 | pub fn mul_div_u64(value: u64, numer: u64, denom: u64) -> u64 { |
| 59 | let q: u64 = value / denom; |
| 60 | let r: u64 = value % denom; |
| 61 | // Decompose value as (value/denom*denom + value%denom), |
| 62 | // substitute into (value*numer)/denom and simplify. |
| 63 | // r < denom, so (denom*numer) is the upper bound of (r*numer) |
| 64 | q * numer + r * numer / denom |
| 65 | } |
| 66 | |
| 67 | pub fn ignore_notfound<T>(result: crate::io::Result<T>) -> crate::io::Result<()> { |
| 68 | match result { |
| 69 | Err(err: Error) if err.kind() == crate::io::ErrorKind::NotFound => Ok(()), |
| 70 | Ok(_) => Ok(()), |
| 71 | Err(err: Error) => Err(err), |
| 72 | } |
| 73 | } |
| 74 | |