use std::path::Path;
use prikk_error::{PrikkError, Result};
mod directory;
#[cfg(any(target_os = "linux", target_os = "macos", target_os = "windows"))]
mod failpoints;
#[cfg(target_os = "linux")]
mod linux;
#[cfg(target_os = "macos")]
mod macos;
#[cfg(any(
all(test, not(target_os = "windows")),
not(any(target_os = "linux", target_os = "macos", target_os = "windows"))
))]
mod none;
mod read;
mod regular;
#[cfg(target_os = "windows")]
mod windows;
#[cfg(target_os = "windows")]
mod windows_authority;
pub(crate) use directory::MutationRoot;
pub(crate) use read::{
EntryKind, RootFileStat, inspect_entry, list_directory, read_file_if_exists,
read_file_required, stat_file_state_if_exists,
};
use crate::fsutil::contract::DurabilityContract;
#[cfg(target_os = "linux")]
pub(crate) use linux::LinuxDurability;
#[cfg(target_os = "macos")]
pub(crate) use macos::MacosDurability;
#[cfg(any(
all(test, not(target_os = "windows")),
not(any(target_os = "linux", target_os = "macos", target_os = "windows"))
))]
pub(crate) use none::NoDurability;
#[cfg(target_os = "windows")]
pub(crate) use windows::WindowsDurability;
#[cfg(all(test, target_os = "windows"))]
pub(crate) use failpoints::set_anchor_verification_barrier as set_anchor_verification_barrier_for_test;
#[cfg(all(
test,
any(target_os = "linux", target_os = "macos", target_os = "windows")
))]
pub(crate) use failpoints::{
Point as TestFailPoint, fail_once as fail_once_for_test,
set_directory_create_barrier as set_directory_create_barrier_for_test,
};
#[cfg(all(
test,
any(target_os = "linux", target_os = "macos", target_os = "windows")
))]
pub(crate) use failpoints::fail_after as fail_after_for_test;
#[cfg(target_os = "linux")]
const ACTIVE_DURABILITY: LinuxDurability = LinuxDurability;
#[cfg(target_os = "macos")]
const ACTIVE_DURABILITY: MacosDurability = MacosDurability;
#[cfg(target_os = "windows")]
const ACTIVE_DURABILITY: WindowsDurability = WindowsDurability;
#[cfg(not(any(target_os = "linux", target_os = "macos", target_os = "windows")))]
const ACTIVE_DURABILITY: NoDurability = NoDurability;
pub(crate) fn write_file_atomically(
root: &MutationRoot,
relative: &Path,
bytes: &[u8],
) -> Result<()> {
ACTIVE_DURABILITY.atomic_replace(root, relative, bytes)
}
pub(crate) fn write_worktree_file_atomically(
root: &MutationRoot,
relative: &Path,
bytes: &[u8],
) -> Result<()> {
write_file_atomically(root, relative, bytes)
}
pub(crate) fn append_file_required(
root: &MutationRoot,
relative: &Path,
bytes: &[u8],
) -> Result<()> {
ACTIVE_DURABILITY.durable_append(root, relative, bytes)
}
pub(crate) fn truncate_existing_file_required(
root: &MutationRoot,
relative: &Path,
len: u64,
) -> Result<()> {
ACTIVE_DURABILITY.durable_truncate(root, relative, len)
}
pub(crate) fn set_regular_file_mode_required(
root: &MutationRoot,
relative: &Path,
mode: u32,
) -> Result<()> {
ACTIVE_DURABILITY.set_permission_bits(root, relative, mode)
}
pub(crate) fn truncate_file_empty_required(root: &MutationRoot, relative: &Path) -> Result<()> {
ACTIVE_DURABILITY.durable_truncate_to_empty(root, relative)
}
pub(crate) fn create_new_file_required(
root: &MutationRoot,
relative: &Path,
bytes: &[u8],
) -> std::io::Result<()> {
ACTIVE_DURABILITY.create_exclusive(root, relative, bytes)
}
pub(crate) fn remove_file_required(root: &MutationRoot, relative: &Path) -> Result<()> {
remove_file_if_present_required(root, relative).map(|_| ())
}
pub(crate) fn remove_file_if_present_required(
root: &MutationRoot,
relative: &Path,
) -> Result<bool> {
ACTIVE_DURABILITY.remove_if_present(root, relative)
}
pub(crate) fn remove_file_cleanup_best_effort(root: &MutationRoot, relative: &Path) {
let _ = remove_file_required(root, relative);
}
pub(crate) fn remove_worktree_file_required(root: &MutationRoot, relative: &Path) -> Result<()> {
remove_file_required(root, relative)
}
pub(crate) fn ensure_directory_required(root: &MutationRoot, relative: &Path) -> Result<()> {
ACTIVE_DURABILITY.ensure_directory(root, relative)
}
pub(crate) fn sync_directory_required(root: &MutationRoot, relative: &Path) -> Result<()> {
ACTIVE_DURABILITY.durable_directory_entry(root, relative)
}
#[cfg(any(target_os = "linux", target_os = "macos"))]
fn io_error(error: rustix::io::Errno) -> PrikkError {
PrikkError::from(std::io::Error::from(error))
}
#[cfg(any(target_os = "linux", target_os = "macos", target_os = "windows"))]
fn prikk_to_io(error: PrikkError) -> std::io::Error {
std::io::Error::other(error.to_string())
}
#[cfg(any(
all(test, not(target_os = "windows")),
not(any(target_os = "linux", target_os = "macos", target_os = "windows"))
))]
fn unsupported_mutation<T>() -> Result<T> {
Err(PrikkError::Io(
"repository mutation requires Linux, macOS, or Windows root-scoped filesystem \
capabilities"
.to_string(),
))
}