1 use std::{fs, io, path::PathBuf};
2 #[derive(Clone, Debug)]
3 /// Wrapper around [`std::fs::OpenOptions`](https://doc.rust-lang.org/std/fs/struct.OpenOptions.html)
4 pub struct OpenOptions(fs::OpenOptions);
5 
6 impl OpenOptions {
7     /// Creates a blank new set of options ready for configuration.
8     ///
9     /// Wrapper for [`std::fs::OpenOptions::new`](https://doc.rust-lang.org/std/fs/struct.OpenOptions.html#method.new)
10     #[allow(clippy::new_without_default)]
new() -> Self11     pub fn new() -> Self {
12         OpenOptions(fs::OpenOptions::new())
13     }
14 
15     /// Sets the option for read access.
16     ///
17     /// Wrapper for [`std::fs::OpenOptions::read`](https://doc.rust-lang.org/std/fs/struct.OpenOptions.html#method.read)
read(&mut self, read: bool) -> &mut Self18     pub fn read(&mut self, read: bool) -> &mut Self {
19         self.0.read(read);
20         self
21     }
22 
23     /// Sets the option for write access.
24     ///
25     /// Wrapper for [`std::fs::OpenOptions::write`](https://doc.rust-lang.org/std/fs/struct.OpenOptions.html#method.write)
write(&mut self, write: bool) -> &mut Self26     pub fn write(&mut self, write: bool) -> &mut Self {
27         self.0.write(write);
28         self
29     }
30 
31     /// Sets the option for the append mode.
32     ///
33     /// Wrapper for [`std::fs::OpenOptions::append`](https://doc.rust-lang.org/std/fs/struct.OpenOptions.html#method.append)
append(&mut self, append: bool) -> &mut Self34     pub fn append(&mut self, append: bool) -> &mut Self {
35         self.0.append(append);
36         self
37     }
38 
39     /// Sets the option for truncating a previous file.
40     ///
41     /// Wrapper for [`std::fs::OpenOptions::truncate`](https://doc.rust-lang.org/std/fs/struct.OpenOptions.html#method.truncate)
truncate(&mut self, truncate: bool) -> &mut Self42     pub fn truncate(&mut self, truncate: bool) -> &mut Self {
43         self.0.truncate(truncate);
44         self
45     }
46 
47     /// Sets the option to create a new file, or open it if it already exists.
48     ///
49     /// Wrapper for [`std::fs::OpenOptions::create`](https://doc.rust-lang.org/std/fs/struct.OpenOptions.html#method.create)
create(&mut self, create: bool) -> &mut Self50     pub fn create(&mut self, create: bool) -> &mut Self {
51         self.0.create(create);
52         self
53     }
54 
55     /// Sets the option to create a new file, failing if it already exists.
56     ///
57     /// Wrapper for [`std::fs::OpenOptions::create_new`](https://doc.rust-lang.org/std/fs/struct.OpenOptions.html#method.create_new)
create_new(&mut self, create_new: bool) -> &mut Self58     pub fn create_new(&mut self, create_new: bool) -> &mut Self {
59         self.0.create_new(create_new);
60         self
61     }
62 
63     /// Opens a file at `path` with the options specified by `self`.
64     ///
65     /// Wrapper for [`std::fs::OpenOptions::open`](https://doc.rust-lang.org/std/fs/struct.OpenOptions.html#method.open)
open<P>(&self, path: P) -> io::Result<crate::File> where P: Into<PathBuf>,66     pub fn open<P>(&self, path: P) -> io::Result<crate::File>
67     where
68         P: Into<PathBuf>,
69     {
70         // We have to either duplicate the logic or call the deprecated method here.
71         // We can't let the deprecated function call this method, because we can't construct
72         // `&fs_err::OpenOptions` from `&fs::OpenOptions` without cloning
73         // (although cloning would probably be cheap).
74         #[allow(deprecated)]
75         crate::File::from_options(path.into(), self.options())
76     }
77 }
78 
79 /// Methods added by fs-err that are not available on
80 /// [`std::fs::OpenOptions`](https://doc.rust-lang.org/stable/std/fs/struct.OpenOptions.html).
81 impl OpenOptions {
82     /// Constructs `Self` from [`std::fs::OpenOptions`](https://doc.rust-lang.org/stable/std/fs/struct.OpenOptions.html)
from_options(options: fs::OpenOptions) -> Self83     pub fn from_options(options: fs::OpenOptions) -> Self {
84         Self(options)
85     }
86 
87     /// Returns a reference to the underlying [`std::fs::OpenOptions`](https://doc.rust-lang.org/stable/std/fs/struct.OpenOptions.html).
88     ///
89     /// Note that calling `open()` on this reference will NOT give you the improved errors from fs-err.
options(&self) -> &fs::OpenOptions90     pub fn options(&self) -> &fs::OpenOptions {
91         &self.0
92     }
93 
94     /// Returns a mutable reference to the underlying [`std::fs::OpenOptions`](https://doc.rust-lang.org/stable/std/fs/struct.OpenOptions.html).
95     ///
96     /// This allows you to change settings that don't yet have wrappers in fs-err.
97     /// Note that calling `open()` on this reference will NOT give you the improved errors from fs-err.
options_mut(&mut self) -> &mut fs::OpenOptions98     pub fn options_mut(&mut self) -> &mut fs::OpenOptions {
99         &mut self.0
100     }
101 }
102 
103 #[cfg(unix)]
104 mod unix {
105     use crate::os::unix::fs::OpenOptionsExt;
106     use std::os::unix::fs::OpenOptionsExt as _;
107     impl OpenOptionsExt for crate::OpenOptions {
mode(&mut self, mode: u32) -> &mut Self108         fn mode(&mut self, mode: u32) -> &mut Self {
109             self.options_mut().mode(mode);
110             self
111         }
112 
custom_flags(&mut self, flags: i32) -> &mut Self113         fn custom_flags(&mut self, flags: i32) -> &mut Self {
114             self.options_mut().custom_flags(flags);
115             self
116         }
117     }
118 }
119 
120 #[cfg(windows)]
121 mod windows {
122     use crate::os::windows::fs::OpenOptionsExt;
123     use std::os::windows::fs::OpenOptionsExt as _;
124 
125     impl OpenOptionsExt for crate::OpenOptions {
access_mode(&mut self, access: u32) -> &mut Self126         fn access_mode(&mut self, access: u32) -> &mut Self {
127             self.options_mut().access_mode(access);
128             self
129         }
130 
share_mode(&mut self, val: u32) -> &mut Self131         fn share_mode(&mut self, val: u32) -> &mut Self {
132             self.options_mut().share_mode(val);
133             self
134         }
custom_flags(&mut self, flags: u32) -> &mut Self135         fn custom_flags(&mut self, flags: u32) -> &mut Self {
136             self.options_mut().custom_flags(flags);
137             self
138         }
139 
attributes(&mut self, val: u32) -> &mut Self140         fn attributes(&mut self, val: u32) -> &mut Self {
141             self.options_mut().attributes(val);
142             self
143         }
144 
security_qos_flags(&mut self, flags: u32) -> &mut Self145         fn security_qos_flags(&mut self, flags: u32) -> &mut Self {
146             self.options_mut().security_qos_flags(flags);
147             self
148         }
149     }
150 }
151