use std::path::{Path, PathBuf};
use crate::error::{IoContext, Result};
pub(crate) fn hex(bytes: &[u8]) -> String {
use std::fmt::Write;
let mut s = String::with_capacity(bytes.len() * 2);
for b in bytes {
let _ = write!(s, "{b:02x}");
}
s
}
#[allow(dead_code)]
pub(crate) fn atomic_write(path: &Path, bytes: &[u8]) -> Result<()> {
if let Some(parent) = path.parent().filter(|p| !p.as_os_str().is_empty()) {
std::fs::create_dir_all(parent).io_ctx(|| format!("creating {}", parent.display()))?;
}
let tmp = tmp_sibling(path);
std::fs::write(&tmp, bytes).io_ctx(|| format!("writing {}", tmp.display()))?;
if let Err(source) = std::fs::rename(&tmp, path) {
let _ = std::fs::remove_file(&tmp);
return Err(crate::error::Error::Io { context: format!("renaming {} -> {}", tmp.display(), path.display()), source });
}
Ok(())
}
#[allow(dead_code)]
fn tmp_sibling(path: &Path) -> PathBuf {
let mut name = path.file_name().map(|n| n.to_os_string()).unwrap_or_default();
name.push(format!(".tmp.{:016x}.{}", fastrand::u64(..), std::process::id()));
path.with_file_name(name)
}