use std::fs;
use std::path::PathBuf;
use console::Term;
use dialoguer::theme::ColorfulTheme;
use dialoguer::Confirm;
use crate::cmd::CommitTitleDescription;
const RECOVERY_FILE: &str = "lastmessage.toml";
const RECOVERY_DIR: &str = "gitmoji-rs";
#[derive(Debug, derive_more::Error, derive_more::Display, derive_more::From)]
#[non_exhaustive]
pub enum RecoveryError {
#[display("Cannot find base directories for recovery file")]
#[from(ignore)]
NoBaseDirectories,
#[display("Cannot read recovery file: {_0}")]
Read(std::io::Error),
#[display("Cannot write recovery file: {_0}")]
#[from(ignore)]
Write(std::io::Error),
#[display("Cannot serialize recovery data: {_0}")]
Serialize(toml_edit::ser::Error),
#[display("Cannot deserialize recovery data: {_0}")]
Deserialize(toml_edit::de::Error),
}
type Result<T> = std::result::Result<T, RecoveryError>;
fn recovery_file_path() -> Result<PathBuf> {
let base_dirs = directories::BaseDirs::new().ok_or(RecoveryError::NoBaseDirectories)?;
let path = base_dirs.cache_dir().join(RECOVERY_DIR).join(RECOVERY_FILE);
Ok(path)
}
pub fn ask(
term: &Term,
recovered: &CommitTitleDescription,
) -> std::result::Result<bool, dialoguer::Error> {
Confirm::with_theme(&ColorfulTheme::default())
.with_prompt(format!(
"Last commit failed. Reuse recovered commit message \"{}\"?",
recovered.title
))
.default(true)
.interact_on(term)
}
pub fn write(params: &CommitTitleDescription) -> Result<()> {
let path = recovery_file_path()?;
if let Some(dir) = path.parent() {
fs::create_dir_all(dir).map_err(RecoveryError::Write)?;
}
let content = toml_edit::ser::to_string(params)?;
fs::write(path, content).map_err(RecoveryError::Write)?;
Ok(())
}
pub fn read() -> Result<Option<CommitTitleDescription>> {
let path = recovery_file_path()?;
if !path.exists() {
return Ok(None);
}
let content = fs::read_to_string(&path)?;
let params = toml_edit::de::from_str(&content)?;
Ok(Some(params))
}
pub fn clear() -> Result<()> {
let path = recovery_file_path()?;
if path.exists() {
fs::remove_file(path)?;
}
Ok(())
}