conch_runtime_pshaw/env/
fd_opener.rs1use crate::env::SubEnvironment;
2use crate::io::{FileDesc, Pipe as OsPipe};
3use std::fs::OpenOptions;
4use std::io;
5use std::path::Path;
6use std::sync::Arc;
7
8#[derive(Debug, PartialEq, Eq, Clone)]
10pub struct Pipe<T> {
11 pub reader: T,
13 pub writer: T,
15}
16
17pub trait FileDescOpener {
19 type OpenedFileHandle;
21
22 fn open_path(&mut self, path: &Path, opts: &OpenOptions) -> io::Result<Self::OpenedFileHandle>;
24 fn open_pipe(&mut self) -> io::Result<Pipe<Self::OpenedFileHandle>>;
26}
27
28impl<'a, T: ?Sized + FileDescOpener> FileDescOpener for &'a mut T {
29 type OpenedFileHandle = T::OpenedFileHandle;
30
31 fn open_path(&mut self, path: &Path, opts: &OpenOptions) -> io::Result<Self::OpenedFileHandle> {
32 (**self).open_path(path, opts)
33 }
34
35 fn open_pipe(&mut self) -> io::Result<Pipe<Self::OpenedFileHandle>> {
36 (**self).open_pipe()
37 }
38}
39
40#[derive(Default, Debug, Clone, Copy, PartialEq, Eq)]
42pub struct FileDescOpenerEnv;
43
44impl FileDescOpenerEnv {
45 pub fn new() -> Self {
47 Self {}
48 }
49}
50
51impl SubEnvironment for FileDescOpenerEnv {
52 fn sub_env(&self) -> Self {
53 *self
54 }
55}
56
57impl FileDescOpener for FileDescOpenerEnv {
58 type OpenedFileHandle = FileDesc;
59
60 fn open_path(&mut self, path: &Path, opts: &OpenOptions) -> io::Result<Self::OpenedFileHandle> {
61 opts.open(path).map(FileDesc::from)
62 }
63
64 fn open_pipe(&mut self) -> io::Result<Pipe<Self::OpenedFileHandle>> {
65 OsPipe::new().map(|pipe| Pipe {
66 reader: pipe.reader,
67 writer: pipe.writer,
68 })
69 }
70}
71
72#[derive(Default, Debug, Clone, PartialEq, Eq)]
75pub struct ArcFileDescOpenerEnv<O> {
76 opener: O,
77}
78
79impl<O> ArcFileDescOpenerEnv<O> {
80 pub fn new(opener: O) -> Self {
82 Self { opener }
83 }
84}
85
86impl<O: SubEnvironment> SubEnvironment for ArcFileDescOpenerEnv<O> {
87 fn sub_env(&self) -> Self {
88 Self {
89 opener: self.opener.sub_env(),
90 }
91 }
92}
93
94impl<O: FileDescOpener> FileDescOpener for ArcFileDescOpenerEnv<O> {
95 type OpenedFileHandle = Arc<O::OpenedFileHandle>;
96
97 fn open_path(&mut self, path: &Path, opts: &OpenOptions) -> io::Result<Self::OpenedFileHandle> {
98 self.opener.open_path(path, opts).map(Arc::new)
99 }
100
101 fn open_pipe(&mut self) -> io::Result<Pipe<Self::OpenedFileHandle>> {
102 self.opener.open_pipe().map(|pipe| Pipe {
103 reader: Arc::new(pipe.reader),
104 writer: Arc::new(pipe.writer),
105 })
106 }
107}