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
use std::{
    fs,
    path::{Path, PathBuf},
};

use file_type_enum::FileType as FileTypeEnum;

use crate::error::*;

/// Follow symlink at `path` in one level, and return the new path.
///
/// # Errors:
/// - If `path` does not exist
/// - If `path` is not a symlink
/// - If `Io::Error` from `fs::read_link(path)`
pub fn symlink_follow<P: AsRef<Path>>(path: P) -> Result<PathBuf> {
    let path = path.as_ref();
    if !path.exists() {
        return Err(Error::NotFoundError(path.to_path_buf()));
        // "while trying to read symlink target path",
    }

    if !FileTypeEnum::from_path(path)?.is_symlink() {
        return Err(Error::NotASymlinkError(path.to_path_buf()));
        // "while trying to read symlink target path",
    }

    let target = fs::read_link(&path)?;

    Ok(target)
}