1#![doc(html_root_url = "https://docs.rs/fs-err/2.11.0")]
70#![deny(missing_debug_implementations, missing_docs)]
71#![cfg_attr(docsrs, feature(doc_cfg))]
72
73mod dir;
74mod errors;
75mod file;
76mod open_options;
77pub mod os;
78mod path;
79#[cfg(feature = "tokio")]
80#[cfg_attr(docsrs, doc(cfg(feature = "tokio")))]
81pub mod tokio;
82
83use std::fs;
84use std::io::{self, Read, Write};
85use std::path::{Path, PathBuf};
86
87use errors::{Error, ErrorKind, SourceDestError, SourceDestErrorKind};
88
89pub use dir::*;
90pub use file::*;
91pub use open_options::OpenOptions;
92pub use path::PathExt;
93
94pub fn read<P: AsRef<Path>>(path: P) -> io::Result<Vec<u8>> {
98 let path = path.as_ref();
99 let mut file = file::open(path).map_err(|err_gen| err_gen(path.to_path_buf()))?;
100 let mut bytes = Vec::with_capacity(initial_buffer_size(&file));
101 file.read_to_end(&mut bytes)
102 .map_err(|err| Error::build(err, ErrorKind::Read, path))?;
103 Ok(bytes)
104}
105
106pub fn read_to_string<P: AsRef<Path>>(path: P) -> io::Result<String> {
110 let path = path.as_ref();
111 let mut file = file::open(path).map_err(|err_gen| err_gen(path.to_path_buf()))?;
112 let mut string = String::with_capacity(initial_buffer_size(&file));
113 file.read_to_string(&mut string)
114 .map_err(|err| Error::build(err, ErrorKind::Read, path))?;
115 Ok(string)
116}
117
118pub fn write<P: AsRef<Path>, C: AsRef<[u8]>>(path: P, contents: C) -> io::Result<()> {
122 let path = path.as_ref();
123 file::create(path)
124 .map_err(|err_gen| err_gen(path.to_path_buf()))?
125 .write_all(contents.as_ref())
126 .map_err(|err| Error::build(err, ErrorKind::Write, path))
127}
128
129pub fn copy<P, Q>(from: P, to: Q) -> io::Result<u64>
134where
135 P: AsRef<Path>,
136 Q: AsRef<Path>,
137{
138 let from = from.as_ref();
139 let to = to.as_ref();
140 fs::copy(from, to)
141 .map_err(|source| SourceDestError::build(source, SourceDestErrorKind::Copy, from, to))
142}
143
144pub fn create_dir<P>(path: P) -> io::Result<()>
148where
149 P: AsRef<Path>,
150{
151 let path = path.as_ref();
152 fs::create_dir(path).map_err(|source| Error::build(source, ErrorKind::CreateDir, path))
153}
154
155pub fn create_dir_all<P>(path: P) -> io::Result<()>
159where
160 P: AsRef<Path>,
161{
162 let path = path.as_ref();
163 fs::create_dir_all(path).map_err(|source| Error::build(source, ErrorKind::CreateDir, path))
164}
165
166pub fn remove_dir<P>(path: P) -> io::Result<()>
170where
171 P: AsRef<Path>,
172{
173 let path = path.as_ref();
174 fs::remove_dir(path).map_err(|source| Error::build(source, ErrorKind::RemoveDir, path))
175}
176
177pub fn remove_dir_all<P>(path: P) -> io::Result<()>
181where
182 P: AsRef<Path>,
183{
184 let path = path.as_ref();
185 fs::remove_dir_all(path).map_err(|source| Error::build(source, ErrorKind::RemoveDir, path))
186}
187
188pub fn remove_file<P>(path: P) -> io::Result<()>
192where
193 P: AsRef<Path>,
194{
195 let path = path.as_ref();
196 fs::remove_file(path).map_err(|source| Error::build(source, ErrorKind::RemoveFile, path))
197}
198
199pub fn metadata<P: AsRef<Path>>(path: P) -> io::Result<fs::Metadata> {
203 let path = path.as_ref();
204 fs::metadata(path).map_err(|source| Error::build(source, ErrorKind::Metadata, path))
205}
206
207pub fn canonicalize<P: AsRef<Path>>(path: P) -> io::Result<PathBuf> {
212 let path = path.as_ref();
213 fs::canonicalize(path).map_err(|source| Error::build(source, ErrorKind::Canonicalize, path))
214}
215
216pub fn hard_link<P: AsRef<Path>, Q: AsRef<Path>>(src: P, dst: Q) -> io::Result<()> {
220 let src = src.as_ref();
221 let dst = dst.as_ref();
222 fs::hard_link(src, dst)
223 .map_err(|source| SourceDestError::build(source, SourceDestErrorKind::HardLink, src, dst))
224}
225
226pub fn read_link<P: AsRef<Path>>(path: P) -> io::Result<PathBuf> {
230 let path = path.as_ref();
231 fs::read_link(path).map_err(|source| Error::build(source, ErrorKind::ReadLink, path))
232}
233
234pub fn rename<P: AsRef<Path>, Q: AsRef<Path>>(from: P, to: Q) -> io::Result<()> {
238 let from = from.as_ref();
239 let to = to.as_ref();
240 fs::rename(from, to)
241 .map_err(|source| SourceDestError::build(source, SourceDestErrorKind::Rename, from, to))
242}
243
244#[deprecated = "replaced with std::os::unix::fs::symlink and \
246std::os::windows::fs::{symlink_file, symlink_dir}"]
247pub fn soft_link<P: AsRef<Path>, Q: AsRef<Path>>(src: P, dst: Q) -> io::Result<()> {
248 let src = src.as_ref();
249 let dst = dst.as_ref();
250 #[allow(deprecated)]
251 fs::soft_link(src, dst)
252 .map_err(|source| SourceDestError::build(source, SourceDestErrorKind::SoftLink, src, dst))
253}
254
255pub fn symlink_metadata<P: AsRef<Path>>(path: P) -> io::Result<fs::Metadata> {
259 let path = path.as_ref();
260 fs::symlink_metadata(path)
261 .map_err(|source| Error::build(source, ErrorKind::SymlinkMetadata, path))
262}
263
264pub fn set_permissions<P: AsRef<Path>>(path: P, perm: fs::Permissions) -> io::Result<()> {
268 let path = path.as_ref();
269 fs::set_permissions(path, perm)
270 .map_err(|source| Error::build(source, ErrorKind::SetPermissions, path))
271}
272
273fn initial_buffer_size(file: &std::fs::File) -> usize {
274 file.metadata().map(|m| m.len() as usize + 1).unwrap_or(0)
275}
276
277pub(crate) use private::Sealed;
278mod private {
279 pub trait Sealed {}
280
281 impl Sealed for crate::File {}
282 impl Sealed for std::path::Path {}
283 impl Sealed for crate::OpenOptions {}
284}