use super::NamedWriteError;
use std::{fs, path::Path};
#[derive(Clone, Copy, Debug, Eq, PartialEq)]
pub enum PublicationMode {
Replace,
CreateNew,
}
#[derive(Clone, Copy, Debug, Eq, PartialEq)]
pub struct WriteOptions {
pub mode: PublicationMode,
pub permissions: u32,
}
pub fn write_typed_with<T, E>(
path: &Path,
options: WriteOptions,
produce: impl FnOnce(&mut fs::File) -> Result<T, E>,
) -> Result<T, NamedWriteError<E>> {
#[cfg(any(target_os = "linux", target_os = "android", target_vendor = "apple"))]
{
super::supported::commit_path_with_options(
path,
options,
|_, file| produce(file),
None::<fn(&Path, &T) -> Result<(), E>>,
|_, _| Ok(()),
)
}
#[cfg(not(any(target_os = "linux", target_os = "android", target_vendor = "apple")))]
{
let _ = (path, options, produce);
Err(NamedWriteError::before(std::io::Error::new(
std::io::ErrorKind::Unsupported,
"durable atomic file publication is unsupported",
)))
}
}
#[cfg(unix)]
pub fn write_at_with<T, E>(
parent: std::os::fd::BorrowedFd<'_>,
name: &std::ffi::OsStr,
options: WriteOptions,
produce: impl FnOnce(&mut fs::File) -> Result<T, E>,
) -> Result<T, NamedWriteError<E>> {
#[cfg(any(target_os = "linux", target_os = "android", target_vendor = "apple"))]
{
super::supported::commit_at_with_hook(
parent,
None,
name,
options,
|_, file| produce(file),
None::<fn(&Path, &T) -> Result<(), E>>,
|_, _| Ok(()),
)
}
#[cfg(not(any(target_os = "linux", target_os = "android", target_vendor = "apple")))]
{
let _ = (parent, name, options, produce);
Err(NamedWriteError::before(std::io::Error::new(
std::io::ErrorKind::Unsupported,
"durable atomic file publication is unsupported",
)))
}
}
pub fn write_validated_with<T, E>(
path: &Path,
options: WriteOptions,
produce: impl FnOnce(&mut fs::File) -> Result<T, E>,
admit: impl FnOnce(&Path, &T) -> Result<(), E>,
) -> Result<T, NamedWriteError<E>> {
#[cfg(any(target_os = "linux", target_os = "android", target_vendor = "apple"))]
{
let absolute = std::path::absolute(path).map_err(NamedWriteError::before)?;
super::supported::commit_path_with_options(
&absolute,
options,
|_, file| produce(file),
Some(admit),
|_, _| Ok(()),
)
}
#[cfg(not(any(target_os = "linux", target_os = "android", target_vendor = "apple")))]
{
let _ = (path, options, produce, admit);
Err(NamedWriteError::before(std::io::Error::new(
std::io::ErrorKind::Unsupported,
"durable atomic file publication is unsupported",
)))
}
}
#[cfg(all(
test,
any(target_os = "linux", target_os = "android", target_vendor = "apple")
))]
mod tests;