cros_async/
io_ext.rs

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
5use std::fs::File;
6use std::io;
7use std::ops::Deref;
8use std::ops::DerefMut;
9
10use base::AsRawDescriptor;
11use base::RawDescriptor;
12#[cfg(any(target_os = "android", target_os = "linux"))]
13use base::UnixSeqpacket;
14
15use crate::sys::platform::AsyncErrorSys;
16
17#[remain::sorted]
18#[derive(Debug, thiserror::Error)]
19pub 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
28pub type AsyncResult<T> = std::result::Result<T, AsyncError>;
29
30impl From<AsyncError> for io::Error {
31    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.)
46pub trait IntoAsync: AsRawDescriptor {}
47
48impl IntoAsync for File {}
49#[cfg(any(target_os = "android", target_os = "linux"))]
50impl IntoAsync for UnixSeqpacket {}
51
52/// Simple wrapper struct to implement IntoAsync on foreign types.
53pub struct AsyncWrapper<T>(T);
54
55impl<T> AsyncWrapper<T> {
56    /// Create a new `AsyncWrapper` that wraps `val`.
57    pub fn new(val: T) -> Self {
58        AsyncWrapper(val)
59    }
60
61    /// Consumes the `AsyncWrapper`, returning the inner struct.
62    pub fn into_inner(self) -> T {
63        self.0
64    }
65}
66
67impl<T> Deref for AsyncWrapper<T> {
68    type Target = T;
69
70    fn deref(&self) -> &T {
71        &self.0
72    }
73}
74
75impl<T> DerefMut for AsyncWrapper<T> {
76    fn deref_mut(&mut self) -> &mut T {
77        &mut self.0
78    }
79}
80
81impl<T: AsRawDescriptor> AsRawDescriptor for AsyncWrapper<T> {
82    fn as_raw_descriptor(&self) -> RawDescriptor {
83        self.0.as_raw_descriptor()
84    }
85}
86
87impl<T: AsRawDescriptor> IntoAsync for AsyncWrapper<T> {}