use core::hint::cold_path;
use std::{fs, io, path::Path};
use widestring::WideCString;
use windows_sys::Win32::{
Foundation::FALSE,
Storage::FileSystem::{MOVE_FILE_FLAGS, MOVEFILE_REPLACE_EXISTING, MoveFileExW},
};
use crate::crt_fd;
pub type RawMode = u32;
pub fn make_dir(
dir_fd: Option<crt_fd::Borrowed<'_>>,
path: impl AsRef<Path>,
_mode: RawMode,
) -> io::Result<()> {
debug_assert!(dir_fd.is_none());
fs::create_dir(path)
}
#[inline]
pub fn rename(
from: impl AsRef<Path>,
#[cfg_attr(not(debug_assertions), expect(unused_variables))] from_fd: Option<
crt_fd::Borrowed<'_>,
>,
to: impl AsRef<Path>,
#[cfg_attr(not(debug_assertions), expect(unused_variables))] to_fd: Option<
crt_fd::Borrowed<'_>,
>,
) -> io::Result<()> {
debug_assert!(from_fd.is_none());
debug_assert!(to_fd.is_none());
rename_impl(from, to, 0)
}
#[inline]
pub fn replace(
from: impl AsRef<Path>,
#[cfg_attr(not(debug_assertions), expect(unused_variables))] from_fd: Option<
crt_fd::Borrowed<'_>,
>,
to: impl AsRef<Path>,
#[cfg_attr(not(debug_assertions), expect(unused_variables))] to_fd: Option<
crt_fd::Borrowed<'_>,
>,
) -> io::Result<()> {
debug_assert!(from_fd.is_none());
debug_assert!(to_fd.is_none());
rename_impl(from, to, MOVEFILE_REPLACE_EXISTING)
}
fn rename_impl(
from: impl AsRef<Path>,
to: impl AsRef<Path>,
flags: MOVE_FILE_FLAGS,
) -> io::Result<()> {
let from = WideCString::from_os_str(from.as_ref())
.map_err(io::Error::other)?
.into_vec_with_nul();
let to = WideCString::from_os_str(to.as_ref())
.map_err(io::Error::other)?
.into_vec_with_nul();
let success = unsafe {
MoveFileExW(from.as_ptr(), to.as_ptr(), flags)
};
if success != FALSE {
Ok(())
} else {
cold_path();
Err(io::Error::last_os_error())
}
}