xref: /aosp_15_r20/external/crosvm/cros_async/src/io_ext.rs (revision bb4ee6a4ae7042d18b07a98463b9c8b875e44b39)
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