char/avril

(wip) why'd you have to go and make things so complicaaaaated?

git clone https://git.t4t.associates/char/avril

Charlotte Somrearrange libs into lib and extensions into extsf4a0f5b

main
1.4 KiB41 linesraw
1use cap_fs_ext::DirExt;
2use cap_std::fs::Dir;
3use std::ffi::OsString;
4use std::io;
5use std::path::{Component, Path, PathBuf};
6
7pub fn parent(path: &Path) -> io::Result<(Dir, OsString)> {
8    let mut root = PathBuf::new();
9    let mut names = Vec::new();
10    for component in path.components() {
11        match component {
12            Component::Prefix(_) | Component::RootDir => root.push(component.as_os_str()),
13            Component::Normal(name) => names.push(name),
14            _ => {
15                return Err(io::Error::new(
16                    io::ErrorKind::InvalidInput,
17                    "Expected a resolved filesystem path",
18                ));
19            }
20        }
21    }
22    let name = names.pop().unwrap_or_else(|| std::ffi::OsStr::new("."));
23    let mut directory = Dir::open_ambient_dir(root, cap_std::ambient_authority())?;
24    for name in names {
25        directory = match directory.open_dir_nofollow(name) {
26            Ok(directory) => directory,
27            Err(_)
28                if directory
29                    .symlink_metadata(name)
30                    .is_ok_and(|metadata| metadata.is_symlink()) =>
31            {
32                return Err(io::Error::new(
33                    io::ErrorKind::NotFound,
34                    "Symbolic link changed or has a missing target",
35                ));
36            }
37            Err(error) => return Err(error),
38        };
39    }
40    Ok((directory, name.to_owned()))
41}