use super::*;
#[cfg(any(target_os = "linux", test))]
pub(super) fn write_pairing_uri(path: &Path, uri: &str) -> Result<()> {
let parent = path
.parent()
.filter(|parent| !parent.as_os_str().is_empty())
.unwrap_or_else(|| Path::new("."));
fs::create_dir_all(parent).with_context(|| format!("failed to create {}", parent.display()))?;
let name = path
.file_name()
.and_then(|name| name.to_str())
.unwrap_or("pairing-uri");
let temp = parent.join(format!(
".{name}.tmp-{}-{}",
std::process::id(),
SystemTime::now()
.duration_since(UNIX_EPOCH)
.map_or(0, |duration| duration.as_nanos())
));
let mut options = OpenOptions::new();
options.create_new(true).write(true);
#[cfg(unix)]
options.mode(0o600);
let mut file = options
.open(&temp)
.with_context(|| format!("failed to create {}", temp.display()))?;
let write_result = (|| -> Result<()> {
file.write_all(uri.as_bytes())?;
file.write_all(b"\n")?;
file.sync_all()?;
drop(file);
fs::rename(&temp, path)
.with_context(|| format!("failed to replace pairing URI file {}", path.display()))?;
Ok(())
})();
if write_result.is_err() {
let _ = fs::remove_file(&temp);
}
write_result
}
#[cfg(any(target_os = "linux", test))]
pub(super) fn remove_pairing_uri(path: &Path) -> Result<()> {
match fs::remove_file(path) {
Ok(()) => Ok(()),
Err(error) if error.kind() == std::io::ErrorKind::NotFound => Ok(()),
Err(error) => Err(error)
.with_context(|| format!("failed to remove pairing URI file {}", path.display())),
}
}