1 // Copyright 2020 The ChromiumOS Authors 2 // Use of this source code is governed by a BSD-style license that can be 3 // found in the LICENSE file. 4 5 use std::fs::File; 6 use std::io; 7 use std::ops::Deref; 8 use std::ops::DerefMut; 9 10 use base::AsRawDescriptor; 11 use base::RawDescriptor; 12 #[cfg(unix)] 13 use base::UnixSeqpacket; 14 use remain::sorted; 15 use thiserror::Error as ThisError; 16 17 #[cfg(unix)] 18 #[sorted] 19 #[derive(ThisError, Debug)] 20 pub enum Error { 21 /// An error with EventAsync. 22 #[error("An error with an EventAsync: {0}")] 23 EventAsync(base::Error), 24 /// An error with a polled(FD) source. 25 #[error("An error with a poll source: {0}")] 26 Poll(crate::sys::unix::poll_source::Error), 27 /// An error with a uring source. 28 #[error("An error with a uring source: {0}")] 29 Uring(crate::sys::unix::uring_executor::Error), 30 } 31 32 #[cfg(windows)] 33 #[sorted] 34 #[derive(ThisError, Debug)] 35 pub enum Error { 36 #[error("An error with an EventAsync: {0}")] 37 EventAsync(base::Error), 38 #[error("An error with a handle executor: {0}")] 39 HandleExecutor(crate::sys::windows::handle_executor::Error), 40 #[error("An error with a handle source: {0}")] 41 HandleSource(crate::sys::windows::handle_source::Error), 42 #[error("An error with a handle source: {0}")] 43 OverlappedSource(crate::sys::windows::overlapped_source::Error), 44 } 45 46 pub type Result<T> = std::result::Result<T, Error>; 47 48 #[cfg(unix)] 49 impl From<crate::sys::unix::uring_executor::Error> for Error { from(err: crate::sys::unix::uring_executor::Error) -> Self50 fn from(err: crate::sys::unix::uring_executor::Error) -> Self { 51 Error::Uring(err) 52 } 53 } 54 55 #[cfg(unix)] 56 impl From<crate::sys::unix::poll_source::Error> for Error { from(err: crate::sys::unix::poll_source::Error) -> Self57 fn from(err: crate::sys::unix::poll_source::Error) -> Self { 58 Error::Poll(err) 59 } 60 } 61 62 #[cfg(unix)] 63 impl From<Error> for io::Error { from(e: Error) -> Self64 fn from(e: Error) -> Self { 65 use Error::*; 66 match e { 67 EventAsync(e) => e.into(), 68 Poll(e) => e.into(), 69 Uring(e) => e.into(), 70 } 71 } 72 } 73 74 #[cfg(windows)] 75 impl From<Error> for io::Error { from(e: Error) -> Self76 fn from(e: Error) -> Self { 77 use Error::*; 78 match e { 79 EventAsync(e) => e.into(), 80 HandleExecutor(e) => e.into(), 81 HandleSource(e) => e.into(), 82 OverlappedSource(e) => e.into(), 83 } 84 } 85 } 86 87 #[cfg(windows)] 88 impl From<crate::sys::windows::handle_source::Error> for Error { from(err: crate::sys::windows::handle_source::Error) -> Self89 fn from(err: crate::sys::windows::handle_source::Error) -> Self { 90 Error::HandleSource(err) 91 } 92 } 93 94 #[cfg(windows)] 95 impl From<crate::sys::windows::handle_executor::Error> for Error { from(err: crate::sys::windows::handle_executor::Error) -> Self96 fn from(err: crate::sys::windows::handle_executor::Error) -> Self { 97 Error::HandleExecutor(err) 98 } 99 } 100 101 /// Marker trait signifying that the implementor is suitable for use with 102 /// cros_async. Examples of this include File, and base::net::UnixSeqpacket. 103 /// 104 /// (Note: it'd be really nice to implement a TryFrom for any implementors, and 105 /// remove our factory functions. Unfortunately 106 /// <https://github.com/rust-lang/rust/issues/50133> makes that too painful.) 107 pub trait IntoAsync: AsRawDescriptor {} 108 109 impl IntoAsync for File {} 110 #[cfg(unix)] 111 impl IntoAsync for UnixSeqpacket {} 112 113 /// Simple wrapper struct to implement IntoAsync on foreign types. 114 pub struct AsyncWrapper<T>(T); 115 116 impl<T> AsyncWrapper<T> { 117 /// Create a new `AsyncWrapper` that wraps `val`. new(val: T) -> Self118 pub fn new(val: T) -> Self { 119 AsyncWrapper(val) 120 } 121 122 /// Consumes the `AsyncWrapper`, returning the inner struct. into_inner(self) -> T123 pub fn into_inner(self) -> T { 124 self.0 125 } 126 } 127 128 impl<T> Deref for AsyncWrapper<T> { 129 type Target = T; 130 deref(&self) -> &T131 fn deref(&self) -> &T { 132 &self.0 133 } 134 } 135 136 impl<T> DerefMut for AsyncWrapper<T> { deref_mut(&mut self) -> &mut T137 fn deref_mut(&mut self) -> &mut T { 138 &mut self.0 139 } 140 } 141 142 impl<T: AsRawDescriptor> AsRawDescriptor for AsyncWrapper<T> { as_raw_descriptor(&self) -> RawDescriptor143 fn as_raw_descriptor(&self) -> RawDescriptor { 144 self.0.as_raw_descriptor() 145 } 146 } 147 148 impl<T: AsRawDescriptor> IntoAsync for AsyncWrapper<T> {} 149