use std::path::Path;
#[cfg(windows)]
-mod internal {
- pub use std::os::windows::fs::{symlink_file, symlink_dir};
- pub use std::fs::remove_dir as remove_symlink_dir;
- use std::fs;
- use std::io;
- use std::mem;
- use std::path::Path;
-
- #[inline]
- pub fn symlink_auto<P: AsRef<Path>, Q: AsRef<Path>>(src: P, dst: Q) -> io::Result<()> {
- if fs::metadata(src.as_ref())?.is_dir() {
- symlink_dir(src.as_ref(), dst.as_ref())
- } else {
- symlink_file(src.as_ref(), dst.as_ref())
- }
- }
-
- // Copied from the Rust standard library, src/libstd/sys/windows/fs.rs, because it’s an
- // implementation detail that isn’t currently exposed in the public interface; I decided to do
- // it this way rather than depending on the Debug implementation (which likewise could change).
- #[derive(PartialEq)]
- enum FileType {
- Dir, File, SymlinkFile, SymlinkDir, ReparsePoint, MountPoint,
- }
-
- impl FileType {
- pub fn is_symlink_dir(&self) -> bool {
- *self == FileType::SymlinkDir || *self == FileType::MountPoint
- }
- }
-
- #[inline]
- pub fn remove_symlink_auto<P: AsRef<Path>>(path: P) -> io::Result<()> {
- // We need to know whether it’s wrapping a SymlinkFile or SymlinkDir, but in the interests
- // of consistency this crucial information is concealed. This is why unsafe transmutation
- // is necessary: to determine whether it’s a symlink file or a symlink dir.
- let file_type = fs::metadata(path.as_ref())?.file_type();
- let fs_imp_file_type = unsafe { mem::transmute::<fs::FileType, FileType>(file_type) };
- if fs_imp_file_type.is_symlink_dir() {
- fs::remove_dir(path)
- } else if file_type.is_symlink() {
- fs::remove_file(path)
- } else {
- Err(io::Error::new(io::ErrorKind::InvalidInput, "path is not a symlink"))
- }
- }
-}
+#[path = "windows/mod.rs"]
+mod internal;
#[cfg(any(target_os = "redox", unix))]
mod internal {