use std::io::{Error, Result, Write};
use std::path::Path;
use atomicwrites::{AllowOverwrite, AtomicFile};
use semver::Version;
use crate::common::universal_io::{OkNotFound as _, UioResult, UniversalReadFs, read_whole_via};
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_universal<Fs: UniversalReadFs>(fs: &Fs, dir_path: &Path) -> UioResult<Option<Version>> {
let version_file = dir_path.join(VERSION_FILE);
read_whole_via(fs, &version_file, |bytes| {
std::str::from_utf8(&bytes)
.map_err(Error::other)?
.parse::<Version>()
.map_err(|err| {
Error::other(format!("Can't parse version from {version_file:?}: {err}")).into()
})
})
.ok_not_found()
}
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}")))
}
}