1use core::fmt;
16
17use ax_io::{Result, SeekFrom, prelude::*};
18
19use crate::fops;
20
21pub type FileType = fops::FileType;
24
25pub type Permissions = fops::FilePerm;
27
28pub struct File {
30 inner: fops::File,
31}
32
33pub struct Metadata(fops::FileAttr);
35
36#[derive(Clone, Debug)]
38pub struct OpenOptions(fops::OpenOptions);
39
40impl Default for OpenOptions {
41 fn default() -> Self {
42 Self::new()
43 }
44}
45
46impl OpenOptions {
47 pub const fn new() -> Self {
49 OpenOptions(fops::OpenOptions::new())
50 }
51
52 pub fn read(&mut self, read: bool) -> &mut Self {
54 self.0.read(read);
55 self
56 }
57
58 pub fn write(&mut self, write: bool) -> &mut Self {
60 self.0.write(write);
61 self
62 }
63
64 pub fn append(&mut self, append: bool) -> &mut Self {
66 self.0.append(append);
67 self
68 }
69
70 pub fn truncate(&mut self, truncate: bool) -> &mut Self {
72 self.0.truncate(truncate);
73 self
74 }
75
76 pub fn create(&mut self, create: bool) -> &mut Self {
78 self.0.create(create);
79 self
80 }
81
82 pub fn create_new(&mut self, create_new: bool) -> &mut Self {
84 self.0.create_new(create_new);
85 self
86 }
87
88 pub fn open(&self, path: &str) -> Result<File> {
90 fops::File::open(path, &self.0).map(|inner| File { inner })
91 }
92}
93
94impl Metadata {
95 pub const fn file_type(&self) -> FileType {
97 self.0.file_type()
98 }
99
100 pub const fn is_dir(&self) -> bool {
104 self.0.is_dir()
105 }
106
107 pub const fn is_file(&self) -> bool {
111 self.0.is_file()
112 }
113
114 #[allow(clippy::len_without_is_empty)]
116 pub const fn len(&self) -> u64 {
117 self.0.size()
118 }
119
120 pub const fn permissions(&self) -> Permissions {
122 self.0.perm()
123 }
124
125 pub const fn size(&self) -> u64 {
127 self.0.size()
128 }
129
130 pub const fn blocks(&self) -> u64 {
132 self.0.blocks()
133 }
134}
135
136impl fmt::Debug for Metadata {
137 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
138 f.debug_struct("Metadata")
139 .field("file_type", &self.file_type())
140 .field("is_dir", &self.is_dir())
141 .field("is_file", &self.is_file())
142 .field("permissions", &self.permissions())
143 .finish_non_exhaustive()
144 }
145}
146
147impl File {
148 pub fn open(path: &str) -> Result<Self> {
150 OpenOptions::new().read(true).open(path)
151 }
152
153 pub fn create(path: &str) -> Result<Self> {
155 OpenOptions::new()
156 .write(true)
157 .create(true)
158 .truncate(true)
159 .open(path)
160 }
161
162 pub fn create_new(path: &str) -> Result<Self> {
164 OpenOptions::new()
165 .read(true)
166 .write(true)
167 .create_new(true)
168 .open(path)
169 }
170
171 pub fn options() -> OpenOptions {
173 OpenOptions::new()
174 }
175
176 pub fn set_len(&self, size: u64) -> Result<()> {
179 self.inner.truncate(size)
180 }
181
182 pub fn metadata(&self) -> Result<Metadata> {
184 self.inner.get_attr().map(Metadata)
185 }
186}
187
188impl Read for File {
189 fn read(&mut self, buf: &mut [u8]) -> Result<usize> {
190 self.inner.read(buf)
191 }
192}
193
194impl Write for File {
195 fn write(&mut self, buf: &[u8]) -> Result<usize> {
196 self.inner.write(buf)
197 }
198
199 fn flush(&mut self) -> Result<()> {
200 self.inner.flush()
201 }
202}
203
204impl Seek for File {
205 fn seek(&mut self, pos: SeekFrom) -> Result<u64> {
206 self.inner.seek(pos)
207 }
208}