• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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