use std::io::Write;
use std::path::PathBuf;
use crate::error::{BzrError, Result};
pub(super) struct TempFile {
pub(super) path: PathBuf,
}
impl Drop for TempFile {
fn drop(&mut self) {
if let Err(e) = std::fs::remove_file(&self.path) {
tracing::debug!(path = %self.path.display(), "failed to remove temp file: {e}");
}
}
}
pub(super) fn create_tempfile(prefix: &str, initial_content: &str) -> Result<TempFile> {
let dir = std::env::temp_dir();
let path = dir.join(format!("bzr-{prefix}-{}.txt", std::process::id()));
let mut file = std::fs::File::create(&path)?;
file.write_all(initial_content.as_bytes())?;
drop(file);
Ok(TempFile { path })
}
pub(super) fn launch(initial: &str, prefix: &str) -> Result<String> {
let editor = std::env::var("EDITOR").unwrap_or_else(|_| "vi".into());
let tmpfile = create_tempfile(prefix, initial)?;
let status = std::process::Command::new(&editor)
.arg(&tmpfile.path)
.status()?;
if !status.success() {
return Err(BzrError::InputValidation(format!(
"{editor} exited with error"
)));
}
let content = std::fs::read_to_string(&tmpfile.path)?;
Ok(content)
}
#[cfg(test)]
#[path = "editor_tests.rs"]
mod tests;