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