1*bb4ee6a4SAndroid Build Coastguard Worker // Copyright 2020 The ChromiumOS Authors 2*bb4ee6a4SAndroid Build Coastguard Worker // Use of this source code is governed by a BSD-style license that can be 3*bb4ee6a4SAndroid Build Coastguard Worker // found in the LICENSE file. 4*bb4ee6a4SAndroid Build Coastguard Worker 5*bb4ee6a4SAndroid Build Coastguard Worker use std::fs::File; 6*bb4ee6a4SAndroid Build Coastguard Worker use std::io; 7*bb4ee6a4SAndroid Build Coastguard Worker use std::ops::Deref; 8*bb4ee6a4SAndroid Build Coastguard Worker use std::ops::DerefMut; 9*bb4ee6a4SAndroid Build Coastguard Worker 10*bb4ee6a4SAndroid Build Coastguard Worker use base::AsRawDescriptor; 11*bb4ee6a4SAndroid Build Coastguard Worker use base::RawDescriptor; 12*bb4ee6a4SAndroid Build Coastguard Worker #[cfg(any(target_os = "android", target_os = "linux"))] 13*bb4ee6a4SAndroid Build Coastguard Worker use base::UnixSeqpacket; 14*bb4ee6a4SAndroid Build Coastguard Worker 15*bb4ee6a4SAndroid Build Coastguard Worker use crate::sys::platform::AsyncErrorSys; 16*bb4ee6a4SAndroid Build Coastguard Worker 17*bb4ee6a4SAndroid Build Coastguard Worker #[remain::sorted] 18*bb4ee6a4SAndroid Build Coastguard Worker #[derive(Debug, thiserror::Error)] 19*bb4ee6a4SAndroid Build Coastguard Worker pub enum AsyncError { 20*bb4ee6a4SAndroid Build Coastguard Worker #[error("An error with an EventAsync: {0}")] 21*bb4ee6a4SAndroid Build Coastguard Worker EventAsync(base::Error), 22*bb4ee6a4SAndroid Build Coastguard Worker #[error("IO error: {0}")] 23*bb4ee6a4SAndroid Build Coastguard Worker Io(std::io::Error), 24*bb4ee6a4SAndroid Build Coastguard Worker #[error("Platform-specific error: {0}")] 25*bb4ee6a4SAndroid Build Coastguard Worker SysVariants(#[from] AsyncErrorSys), 26*bb4ee6a4SAndroid Build Coastguard Worker } 27*bb4ee6a4SAndroid Build Coastguard Worker 28*bb4ee6a4SAndroid Build Coastguard Worker pub type AsyncResult<T> = std::result::Result<T, AsyncError>; 29*bb4ee6a4SAndroid Build Coastguard Worker 30*bb4ee6a4SAndroid Build Coastguard Worker impl From<AsyncError> for io::Error { from(e: AsyncError) -> Self31*bb4ee6a4SAndroid Build Coastguard Worker fn from(e: AsyncError) -> Self { 32*bb4ee6a4SAndroid Build Coastguard Worker match e { 33*bb4ee6a4SAndroid Build Coastguard Worker AsyncError::EventAsync(e) => e.into(), 34*bb4ee6a4SAndroid Build Coastguard Worker AsyncError::Io(e) => e, 35*bb4ee6a4SAndroid Build Coastguard Worker AsyncError::SysVariants(e) => e.into(), 36*bb4ee6a4SAndroid Build Coastguard Worker } 37*bb4ee6a4SAndroid Build Coastguard Worker } 38*bb4ee6a4SAndroid Build Coastguard Worker } 39*bb4ee6a4SAndroid Build Coastguard Worker 40*bb4ee6a4SAndroid Build Coastguard Worker /// Marker trait signifying that the implementor is suitable for use with 41*bb4ee6a4SAndroid Build Coastguard Worker /// cros_async. Examples of this include File, and base::net::UnixSeqpacket. 42*bb4ee6a4SAndroid Build Coastguard Worker /// 43*bb4ee6a4SAndroid Build Coastguard Worker /// (Note: it'd be really nice to implement a TryFrom for any implementors, and 44*bb4ee6a4SAndroid Build Coastguard Worker /// remove our factory functions. Unfortunately 45*bb4ee6a4SAndroid Build Coastguard Worker /// <https://github.com/rust-lang/rust/issues/50133> makes that too painful.) 46*bb4ee6a4SAndroid Build Coastguard Worker pub trait IntoAsync: AsRawDescriptor {} 47*bb4ee6a4SAndroid Build Coastguard Worker 48*bb4ee6a4SAndroid Build Coastguard Worker impl IntoAsync for File {} 49*bb4ee6a4SAndroid Build Coastguard Worker #[cfg(any(target_os = "android", target_os = "linux"))] 50*bb4ee6a4SAndroid Build Coastguard Worker impl IntoAsync for UnixSeqpacket {} 51*bb4ee6a4SAndroid Build Coastguard Worker 52*bb4ee6a4SAndroid Build Coastguard Worker /// Simple wrapper struct to implement IntoAsync on foreign types. 53*bb4ee6a4SAndroid Build Coastguard Worker pub struct AsyncWrapper<T>(T); 54*bb4ee6a4SAndroid Build Coastguard Worker 55*bb4ee6a4SAndroid Build Coastguard Worker impl<T> AsyncWrapper<T> { 56*bb4ee6a4SAndroid Build Coastguard Worker /// Create a new `AsyncWrapper` that wraps `val`. new(val: T) -> Self57*bb4ee6a4SAndroid Build Coastguard Worker pub fn new(val: T) -> Self { 58*bb4ee6a4SAndroid Build Coastguard Worker AsyncWrapper(val) 59*bb4ee6a4SAndroid Build Coastguard Worker } 60*bb4ee6a4SAndroid Build Coastguard Worker 61*bb4ee6a4SAndroid Build Coastguard Worker /// Consumes the `AsyncWrapper`, returning the inner struct. into_inner(self) -> T62*bb4ee6a4SAndroid Build Coastguard Worker pub fn into_inner(self) -> T { 63*bb4ee6a4SAndroid Build Coastguard Worker self.0 64*bb4ee6a4SAndroid Build Coastguard Worker } 65*bb4ee6a4SAndroid Build Coastguard Worker } 66*bb4ee6a4SAndroid Build Coastguard Worker 67*bb4ee6a4SAndroid Build Coastguard Worker impl<T> Deref for AsyncWrapper<T> { 68*bb4ee6a4SAndroid Build Coastguard Worker type Target = T; 69*bb4ee6a4SAndroid Build Coastguard Worker deref(&self) -> &T70*bb4ee6a4SAndroid Build Coastguard Worker fn deref(&self) -> &T { 71*bb4ee6a4SAndroid Build Coastguard Worker &self.0 72*bb4ee6a4SAndroid Build Coastguard Worker } 73*bb4ee6a4SAndroid Build Coastguard Worker } 74*bb4ee6a4SAndroid Build Coastguard Worker 75*bb4ee6a4SAndroid Build Coastguard Worker impl<T> DerefMut for AsyncWrapper<T> { deref_mut(&mut self) -> &mut T76*bb4ee6a4SAndroid Build Coastguard Worker fn deref_mut(&mut self) -> &mut T { 77*bb4ee6a4SAndroid Build Coastguard Worker &mut self.0 78*bb4ee6a4SAndroid Build Coastguard Worker } 79*bb4ee6a4SAndroid Build Coastguard Worker } 80*bb4ee6a4SAndroid Build Coastguard Worker 81*bb4ee6a4SAndroid Build Coastguard Worker impl<T: AsRawDescriptor> AsRawDescriptor for AsyncWrapper<T> { as_raw_descriptor(&self) -> RawDescriptor82*bb4ee6a4SAndroid Build Coastguard Worker fn as_raw_descriptor(&self) -> RawDescriptor { 83*bb4ee6a4SAndroid Build Coastguard Worker self.0.as_raw_descriptor() 84*bb4ee6a4SAndroid Build Coastguard Worker } 85*bb4ee6a4SAndroid Build Coastguard Worker } 86*bb4ee6a4SAndroid Build Coastguard Worker 87*bb4ee6a4SAndroid Build Coastguard Worker impl<T: AsRawDescriptor> IntoAsync for AsyncWrapper<T> {} 88