use std::io::{Error, Read, Result, Write};
use std::path::Path;
use atomicwrites::{AllowOverwrite, AtomicFile};
use fs_err::File;
use semver::Version;
pub const VERSION_FILE: &str = "version.info";
pub trait StorageVersion {
fn current_raw() -> &'static str;
fn current() -> Version {
Self::current_raw().parse().expect("Can't parse version")
}
fn load(dir_path: &Path) -> Result<Option<Version>> {
let version_file = dir_path.join(VERSION_FILE);
let mut contents = String::new();
let mut file = match File::open(&version_file) {
Ok(file) => file,
Err(err) if err.kind() == std::io::ErrorKind::NotFound => {
return Ok(None);
}
Err(err) => return Err(err),
};
file.read_to_string(&mut contents)?;
let version = contents.parse().map_err(|err| {
Error::other(format!("Can't parse version from {version_file:?}: {err}"))
})?;
Ok(Some(version))
}
fn save(dir_path: &Path) -> Result<()> {
let version_file = dir_path.join(VERSION_FILE);
let af = AtomicFile::new(&version_file, AllowOverwrite);
let current_version = Self::current_raw();
af.write(|f| f.write_all(current_version.as_bytes()))
.map_err(|err| Error::other(format!("Can't write {version_file:?}: {err}")))
}
}