conch_runtime_pshaw/env/async_io/
unwrapper.rs

1use crate::env::{AsyncIoEnvironment, SubEnvironment};
2use crate::io::{FileDesc, FileDescWrapper};
3use futures_core::future::BoxFuture;
4use std::borrow::Cow;
5use std::io;
6use std::sync::Arc;
7
8/// An `AsyncIoEnvironment` implementation which attempts to unwrap `Arc<FileDesc>`
9/// handles before delegating to another `AsyncIoEnvironment` implementation.
10///
11/// If the `Arc` cannot be efficiently unwrapped, the underlying `FileDesc` will
12/// be duplicated.
13#[derive(Default, Debug, Clone, PartialEq, Eq)]
14pub struct ArcUnwrappingAsyncIoEnv<T> {
15    async_io: T,
16}
17
18impl<T> ArcUnwrappingAsyncIoEnv<T> {
19    /// Create a new environment with a provided implementation for delegating operations.
20    pub fn new(env: T) -> Self {
21        Self { async_io: env }
22    }
23}
24
25impl<T: SubEnvironment> SubEnvironment for ArcUnwrappingAsyncIoEnv<T> {
26    fn sub_env(&self) -> Self {
27        Self {
28            async_io: self.async_io.sub_env(),
29        }
30    }
31}
32
33impl<T> AsyncIoEnvironment for ArcUnwrappingAsyncIoEnv<T>
34where
35    T: AsyncIoEnvironment<IoHandle = FileDesc>,
36{
37    type IoHandle = Arc<T::IoHandle>;
38
39    fn read_all(&mut self, fd: Self::IoHandle) -> BoxFuture<'static, io::Result<Vec<u8>>> {
40        match fd.try_unwrap() {
41            Ok(fd) => self.async_io.read_all(fd),
42            Err(e) => Box::pin(async { Err(e) }),
43        }
44    }
45
46    fn write_all<'a>(
47        &mut self,
48        fd: Self::IoHandle,
49        data: Cow<'a, [u8]>,
50    ) -> BoxFuture<'a, io::Result<()>> {
51        match fd.try_unwrap() {
52            Ok(fd) => self.async_io.write_all(fd, data),
53            Err(e) => Box::pin(async { Err(e) }),
54        }
55    }
56
57    fn write_all_best_effort(&mut self, fd: Self::IoHandle, data: Vec<u8>) {
58        if let Ok(fd) = fd.try_unwrap() {
59            self.async_io.write_all_best_effort(fd, data);
60        }
61    }
62}