1use alloc::borrow::ToOwned;
2use sys::ffi::FileOptions;
3
4use crate::api;
5use crate::Path;
6use crate::error::ApiError;
7
8
9pub trait FileOptionsExt: Into<FileOptions> {
12 fn new() -> Self;
14
15 fn read(self, read: bool) -> Self;
16 fn read_data(self, read: bool) -> Self;
17
18 fn write(self, write: bool) -> Self;
19 fn append(self, append: bool) -> Self;
20
21 fn is_empty(&self) -> bool;
22 fn is_read(&self) -> bool;
23 fn is_read_data(&self) -> bool;
24 fn is_write(&self) -> bool;
25 fn is_append(&self) -> bool;
26
27 fn is_read_any(&self) -> bool;
28 fn is_write_any(&self) -> bool;
29}
30
31pub trait OpenOptions: Into<FileOptions> {
32 fn open<P: AsRef<Path>>(&self, path: P) -> Result<crate::file::File<api::Cache>, ApiError>;
34
35 fn open_using<Api: api::Api, P: AsRef<Path>>(&self,
37 api: Api,
38 path: P)
39 -> Result<crate::file::File<Api>, ApiError>;
40}
41
42impl OpenOptions for FileOptions {
43 #[inline(always)]
44 fn open<P: AsRef<Path>>(&self, path: P) -> Result<crate::file::File<api::Cache>, ApiError> {
45 crate::ops::open(api::Cache::default(), path, self.to_owned())
46 }
47
48 #[inline(always)]
49 fn open_using<Api: api::Api, P: AsRef<Path>>(&self,
50 api: Api,
51 path: P)
52 -> Result<crate::file::File<Api>, ApiError> {
53 crate::ops::open(api, path, self.to_owned())
54 }
55}
56
57
58impl FileOptionsExt for FileOptions {
59 fn new() -> Self { FileOptions(0) }
60
61 fn read(mut self, read: bool) -> Self {
63 if read {
64 self.0 |= FileOptions::kFileRead.0;
65 } else {
66 self.0 &= 255 - FileOptions::kFileRead.0;
67 }
68 self
69 }
70
71 fn read_data(mut self, read: bool) -> Self {
73 if read {
74 self.0 |= FileOptions::kFileReadData.0;
75 } else {
76 self.0 &= 255 - FileOptions::kFileReadData.0;
77 }
78 self
79 }
80
81 fn write(mut self, write: bool) -> Self {
83 if write {
84 self.0 |= FileOptions::kFileWrite.0;
85 } else {
86 self.0 &= 255 - FileOptions::kFileWrite.0;
87 }
88 self
89 }
90
91 fn append(mut self, append: bool) -> Self {
93 if append {
94 self.0 |= FileOptions::kFileAppend.0;
95 } else {
96 self.0 &= 255 - FileOptions::kFileAppend.0;
97 }
98 self
99 }
100
101
102 fn is_empty(&self) -> bool { self.0 == 0 }
103 fn is_read(&self) -> bool { (self.0 & FileOptions::kFileRead.0) != 0 }
104 fn is_read_data(&self) -> bool { (self.0 & FileOptions::kFileReadData.0) != 0 }
105 fn is_write(&self) -> bool { (self.0 & FileOptions::kFileWrite.0) != 0 }
106 fn is_append(&self) -> bool { (self.0 & FileOptions::kFileAppend.0) != 0 }
107
108 fn is_read_any(&self) -> bool { self.is_read() || self.is_read_data() }
109 fn is_write_any(&self) -> bool { self.is_write() || self.is_append() }
110}
111
112#[cfg(test)]
113mod tests {
114 use super::{FileOptionsExt, FileOptions};
115 use FileOptions as FO;
116
117 #[test]
118 fn fo_empty() {
119 let fo = FO::new();
120 assert!(fo.is_empty());
121 assert_eq!(fo.0, 0);
122 assert!(!fo.is_read());
123 assert!(!fo.is_read_data());
124 assert!(!fo.is_write());
125 assert!(!fo.is_append());
126 }
127
128 #[test]
129 fn fo_read() {
130 let fo = FO::new().read(true);
131 assert_eq!(fo.0, FO::kFileRead.0);
132 assert!(fo.is_read());
133 assert!(!fo.is_read_data());
134 assert!(!fo.is_write());
135 assert!(!fo.is_append());
136 assert!(!fo.is_empty());
137 }
138
139 #[test]
140 fn fo_read_data() {
141 let fo = FO::new().read_data(true);
142 assert_ne!(fo.0, FO::kFileRead.0);
143 assert_eq!(fo.0, FO::kFileReadData.0);
144 assert!(!fo.is_read());
145 assert!(fo.is_read_data());
146 assert!(!fo.is_write());
147 assert!(!fo.is_append());
148 assert!(!fo.is_empty());
149
150 let fo = FO::new().read(true).read_data(true);
151 assert_ne!(fo.0, FO::kFileRead.0);
152 assert_ne!(fo.0, FO::kFileReadData.0);
153 assert!(fo.is_read());
154 assert!(fo.is_read_data());
155 assert!(!fo.is_write());
156 assert!(!fo.is_append());
157 assert!(!fo.is_empty());
158 }
159
160 #[test]
161 fn fo_many() {
162 let fo = FO::new().read(true)
163 .write(true)
164 .read_data(true)
165 .append(true)
166 .read(false)
167 .append(false);
168 assert!(!fo.is_read());
169 assert!(fo.is_read_data());
170 assert!(fo.is_write());
171 assert!(!fo.is_append());
172 assert!(!fo.is_empty());
173 }
174}