| use std::fs; |
| use std::path::{Path, PathBuf}; |
|
|
| use anyhow::{Context, Result}; |
|
|
| const INSTALL_MARKER: &str = ".installed"; |
|
|
| pub(crate) struct InstallState<'a> { |
| directory: &'a Path, |
| source_id: &'a str, |
| } |
|
|
| impl<'a> InstallState<'a> { |
| pub(crate) fn new(directory: &'a Path, source_id: &'a str) -> Self { |
| Self { |
| directory, |
| source_id, |
| } |
| } |
|
|
| pub(crate) fn is_current(&self) -> bool { |
| matches!( |
| fs::read_to_string(self.marker_path()), |
| Ok(content) if content == self.source_id |
| ) |
| } |
|
|
| pub(crate) fn reset(&self) -> Result<()> { |
| if self.directory.exists() { |
| fs::remove_dir_all(self.directory) |
| .with_context(|| format!("failed to reset `{}`", self.directory.display()))?; |
| } |
| fs::create_dir_all(self.directory) |
| .with_context(|| format!("failed to create `{}`", self.directory.display()))?; |
| Ok(()) |
| } |
|
|
| pub(crate) fn commit(&self) -> Result<()> { |
| fs::write(self.marker_path(), self.source_id).with_context(|| { |
| format!( |
| "failed to write install marker in `{}`", |
| self.directory.display() |
| ) |
| }) |
| } |
|
|
| fn marker_path(&self) -> PathBuf { |
| self.directory.join(INSTALL_MARKER) |
| } |
| } |
|
|