1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
use crate::{error::*, File, FileType};
use std::{
fs,
path::{Path, PathBuf},
};
pub fn collect_directory_children(
path: impl AsRef<Path>,
follow_symlinks: bool,
) -> FSResult<Vec<File>> {
let path = path.as_ref();
if !path.exists() {
return Err(FSError::new(
FSErrorKind::NotFoundError,
path.into(),
"while trying to read directory content",
));
}
if !FileType::from_path_shallow(&path, follow_symlinks)?.is_dir() {
return Err(FSError::new(
FSErrorKind::NotADirectoryError,
path.into(),
"while trying to read directory content",
));
}
let dirs = fs::read_dir(&path);
let dirs = dirs.map_err(|source| {
FSError::new(
FSErrorKind::ReadError(source),
path.into(),
"while trying to read directory content",
)
})?;
let mut children = vec![];
for entry in dirs {
let entry = entry.map_err(|source| {
FSError::new(
FSErrorKind::ReadError(source),
path.into(),
"error while reading directory for specific entry",
)
})?;
let file = File::new_from_path(&entry.path(), follow_symlinks)?;
children.push(file);
}
Ok(children)
}
pub fn symlink_target(path: impl AsRef<Path>) -> FSResult<PathBuf> {
let path = path.as_ref();
if !path.exists() {
return Err(FSError::new(
FSErrorKind::NotFoundError,
path.into(),
"while trying to read symlink target path",
));
}
if !FileType::from_path_shallow(path, false)?.is_symlink() {
return Err(FSError::new(
FSErrorKind::NotASymlinkError,
path.into(),
"while trying to read symlink target path",
));
}
let target = fs::read_link(&path);
let target = target.map_err(|source| {
FSError::new(
FSErrorKind::ReadError(source),
path.into(),
"while trying to read symlink target path",
)
})?;
Ok(target)
}
pub fn fs_filetype_from_path(
path: impl AsRef<Path>,
follow_symlink: bool,
) -> FSResult<fs::FileType> {
let path = path.as_ref();
if !path.exists() {
return Err(FSError::new(FSErrorKind::NotFoundError, path.into(), ""));
}
let metadata_function = if follow_symlink {
fs::metadata
} else {
fs::symlink_metadata
};
let metadata = metadata_function(path);
let metadata = metadata.map_err(|source| {
FSError::new(
FSErrorKind::ReadError(source),
path.to_path_buf(),
"Unable to gather type information of file at",
)
})?;
Ok(metadata.file_type())
}