Line data Source code
1 : //! Enum-dispatch to the `OpenOptions` type of the respective [`super::IoEngineKind`];
2 :
3 : use std::os::fd::OwnedFd;
4 : use std::path::Path;
5 :
6 : use super::io_engine::IoEngine;
7 :
8 : #[derive(Debug, Clone)]
9 : pub struct OpenOptions {
10 : write: bool,
11 : inner: Inner,
12 : }
13 : #[derive(Debug, Clone)]
14 : enum Inner {
15 : StdFs(std::fs::OpenOptions),
16 : #[cfg(target_os = "linux")]
17 : TokioEpollUring(tokio_epoll_uring::ops::open_at::OpenOptions),
18 : }
19 :
20 : impl Default for OpenOptions {
21 38256 : fn default() -> Self {
22 38256 : let inner = match super::io_engine::get() {
23 0 : IoEngine::NotSet => panic!("io engine not set"),
24 19128 : IoEngine::StdFs => Inner::StdFs(std::fs::OpenOptions::new()),
25 : #[cfg(target_os = "linux")]
26 : IoEngine::TokioEpollUring => {
27 19128 : Inner::TokioEpollUring(tokio_epoll_uring::ops::open_at::OpenOptions::new())
28 : }
29 : };
30 38256 : Self {
31 38256 : write: false,
32 38256 : inner,
33 38256 : }
34 38256 : }
35 : }
36 :
37 : impl OpenOptions {
38 38256 : pub fn new() -> OpenOptions {
39 38256 : Self::default()
40 38256 : }
41 :
42 29724 : pub(super) fn is_write(&self) -> bool {
43 29724 : self.write
44 29724 : }
45 :
46 25380 : pub fn read(&mut self, read: bool) -> &mut OpenOptions {
47 25380 : match &mut self.inner {
48 12690 : Inner::StdFs(x) => {
49 12690 : let _ = x.read(read);
50 12690 : }
51 : #[cfg(target_os = "linux")]
52 12690 : Inner::TokioEpollUring(x) => {
53 12690 : let _ = x.read(read);
54 12690 : }
55 : }
56 25380 : self
57 25380 : }
58 :
59 20880 : pub fn write(&mut self, write: bool) -> &mut OpenOptions {
60 20880 : self.write = write;
61 20880 : match &mut self.inner {
62 10440 : Inner::StdFs(x) => {
63 10440 : let _ = x.write(write);
64 10440 : }
65 : #[cfg(target_os = "linux")]
66 10440 : Inner::TokioEpollUring(x) => {
67 10440 : let _ = x.write(write);
68 10440 : }
69 : }
70 20880 : self
71 20880 : }
72 :
73 37068 : pub fn create(&mut self, create: bool) -> &mut OpenOptions {
74 37068 : match &mut self.inner {
75 18534 : Inner::StdFs(x) => {
76 18534 : let _ = x.create(create);
77 18534 : }
78 : #[cfg(target_os = "linux")]
79 18534 : Inner::TokioEpollUring(x) => {
80 18534 : let _ = x.create(create);
81 18534 : }
82 : }
83 37068 : self
84 37068 : }
85 :
86 57852 : pub fn create_new(&mut self, create_new: bool) -> &mut OpenOptions {
87 57852 : match &mut self.inner {
88 28926 : Inner::StdFs(x) => {
89 28926 : let _ = x.create_new(create_new);
90 28926 : }
91 : #[cfg(target_os = "linux")]
92 28926 : Inner::TokioEpollUring(x) => {
93 28926 : let _ = x.create_new(create_new);
94 28926 : }
95 : }
96 57852 : self
97 57852 : }
98 :
99 37068 : pub fn truncate(&mut self, truncate: bool) -> &mut OpenOptions {
100 37068 : match &mut self.inner {
101 18534 : Inner::StdFs(x) => {
102 18534 : let _ = x.truncate(truncate);
103 18534 : }
104 : #[cfg(target_os = "linux")]
105 18534 : Inner::TokioEpollUring(x) => {
106 18534 : let _ = x.truncate(truncate);
107 18534 : }
108 : }
109 37068 : self
110 37068 : }
111 :
112 1170173 : pub(in crate::virtual_file) async fn open(&self, path: &Path) -> std::io::Result<OwnedFd> {
113 1170173 : match &self.inner {
114 588550 : Inner::StdFs(x) => x.open(path).map(|file| file.into()),
115 : #[cfg(target_os = "linux")]
116 581623 : Inner::TokioEpollUring(x) => {
117 581623 : let system = super::io_engine::tokio_epoll_uring_ext::thread_local_system().await;
118 581623 : system.open(path, x).await.map_err(|e| match e {
119 0 : tokio_epoll_uring::Error::Op(e) => e,
120 0 : tokio_epoll_uring::Error::System(system) => {
121 0 : std::io::Error::new(std::io::ErrorKind::Other, system)
122 : }
123 581623 : })
124 : }
125 : }
126 1170173 : }
127 : }
128 :
129 : impl std::os::unix::prelude::OpenOptionsExt for OpenOptions {
130 0 : fn mode(&mut self, mode: u32) -> &mut OpenOptions {
131 0 : match &mut self.inner {
132 0 : Inner::StdFs(x) => {
133 0 : let _ = x.mode(mode);
134 0 : }
135 : #[cfg(target_os = "linux")]
136 0 : Inner::TokioEpollUring(x) => {
137 0 : let _ = x.mode(mode);
138 0 : }
139 : }
140 0 : self
141 0 : }
142 :
143 0 : fn custom_flags(&mut self, flags: i32) -> &mut OpenOptions {
144 0 : match &mut self.inner {
145 0 : Inner::StdFs(x) => {
146 0 : let _ = x.custom_flags(flags);
147 0 : }
148 : #[cfg(target_os = "linux")]
149 0 : Inner::TokioEpollUring(x) => {
150 0 : let _ = x.custom_flags(flags);
151 0 : }
152 : }
153 0 : self
154 0 : }
155 : }
|