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
use crate::env;
use crate::ffi::OsStr;
use crate::io;
use crate::path::{Path, PathBuf, Prefix};
#[inline]
pub fn is_sep_byte(b: u8) -> bool {
b == b'/'
}
#[inline]
pub fn is_verbatim_sep(b: u8) -> bool {
b == b'/'
}
#[inline]
pub fn parse_prefix(_: &OsStr) -> Option<Prefix<'_>> {
None
}
pub const MAIN_SEP_STR: &str = "/";
pub const MAIN_SEP: char = '/';
/// 在不改变其语义的情况下,使 POSIX 路径成为绝对路径。
pub(crate) fn absolute(path: &Path) -> io::Result<PathBuf> {
// 这主要是收集 `Path::components` 的包装器,但与 POSIX 规范冲突的情况除外。
//
// 请参见 4.13 路径名解析,IEEE Std 1003.1-2017
// https://pubs.opengroup.org/onlinepubs/9699919799/basedefs/V1_chap04.html#tag_04_13
// 获取组件,跳过多余的前导 "." 组件 (如果存在)。
let mut components = path.strip_prefix(".").unwrap_or(path).components();
let path_os = path.as_os_str().bytes();
let mut normalized = if path.is_absolute() {
// ` 如果路径名以两个连续的 <slash> 字符,前导后的第一个组件 <slash> 字符可以以实现定义的方式解释,尽管有两个以上的前导 <slash> 字符应被视为单个 <slash>
//
// character."
//
//
if path_os.starts_with(b"//") && !path_os.starts_with(b"///") {
components.next();
PathBuf::from("//")
} else {
PathBuf::new()
}
} else {
env::current_dir()?
};
normalized.extend(components);
// "Interfaces using pathname resolution may specify additional constraints when a pathname that does not name an existing directory contains at least one non- <slash> character and contains one or more trailing <slash> characters".
//
// 尾随 <slash> 如果 "a symbolic link is encountered during pathname resolution" 也是有意义的。
//
//
//
if path_os.ends_with(b"/") {
normalized.push("");
}
Ok(normalized)
}