1use crate::error::Result;
2use crate::gen::fs;
3use std::ffi::OsStr;
4use std::path::{Component, Path, PathBuf};
5
6pub(crate) fn manifest_dir() -> Result<PathBuf> {
7 crate::env_os("CARGO_MANIFEST_DIR").map(PathBuf::from)
8}
9
10pub(crate) fn out_dir() -> Result<PathBuf> {
11 crate::env_os("OUT_DIR").map(PathBuf::from)
12}
13
14pub(crate) fn local_relative_path(path: &Path) -> PathBuf {
19 let mut rel_path = PathBuf::new();
20 for component in path.components() {
21 match component {
22 Component::Prefix(_) | Component::RootDir | Component::CurDir => {}
23 Component::ParentDir => drop(rel_path.pop()), Component::Normal(name) => rel_path.push(name),
25 }
26 }
27 rel_path
28}
29
30pub(crate) trait PathExt {
31 fn with_appended_extension(&self, suffix: impl AsRef<OsStr>) -> PathBuf;
32}
33
34impl PathExt for Path {
35 fn with_appended_extension(&self, suffix: impl AsRef<OsStr>) -> PathBuf {
36 let mut file_name = self.file_name().unwrap().to_owned();
37 file_name.push(suffix);
38 self.with_file_name(file_name)
39 }
40}
41
42#[cfg(unix)]
43pub(crate) fn symlink_or_copy(
44 path_for_symlink: impl AsRef<Path>,
45 _path_for_copy: impl AsRef<Path>,
46 link: impl AsRef<Path>,
47) -> fs::Result<()> {
48 fs::symlink_file(path_for_symlink, link)
49}
50
51#[cfg(windows)]
52pub(crate) fn symlink_or_copy(
53 path_for_symlink: impl AsRef<Path>,
54 path_for_copy: impl AsRef<Path>,
55 link: impl AsRef<Path>,
56) -> fs::Result<()> {
57 let path_for_symlink = path_for_symlink.as_ref();
60 let link = link.as_ref();
61 if fs::symlink_file(path_for_symlink, link).is_err() {
62 let path_for_copy = path_for_copy.as_ref();
63 fs::copy(path_for_copy, link)?;
64 }
65 Ok(())
66}
67
68#[cfg(not(any(unix, windows)))]
69pub(crate) fn symlink_or_copy(
70 _path_for_symlink: impl AsRef<Path>,
71 path_for_copy: impl AsRef<Path>,
72 copy: impl AsRef<Path>,
73) -> fs::Result<()> {
74 fs::copy(path_for_copy, copy)?;
75 Ok(())
76}