use crate::config::locator;
use chrono::{DateTime, Utc};
use jsonrpsee_core::Serialize;
use semver::Version;
use serde::Deserialize;
use serde_json;
use std::fs;
use super::data::project_dir;
const FILE_NAME: &str = "upgrade_check.json";
#[derive(Serialize, Deserialize, Debug, PartialEq)]
pub struct UpgradeCheck {
pub latest_check_time: DateTime<Utc>,
pub max_stable_version: Version,
pub max_version: Version,
}
impl Default for UpgradeCheck {
fn default() -> Self {
Self {
latest_check_time: DateTime::<Utc>::UNIX_EPOCH,
max_stable_version: Version::new(0, 0, 0),
max_version: Version::new(0, 0, 0),
}
}
}
impl UpgradeCheck {
pub fn load() -> Result<Self, locator::Error> {
let path = project_dir()
.map_err(|_| locator::Error::ProjectDirsError())?
.data_dir()
.join(FILE_NAME);
if !path.exists() {
return Ok(Self::default());
}
let data = fs::read(&path)
.map_err(|error| locator::Error::UpgradeCheckReadFailed { path, error })?;
Ok(serde_json::from_slice(data.as_slice())?)
}
pub fn save(&self) -> Result<(), locator::Error> {
let path = project_dir()
.map_err(|_| locator::Error::ProjectDirsError())?
.data_dir()
.join(FILE_NAME);
let path = locator::ensure_directory(path)?;
let data = serde_json::to_string(self).map_err(|_| locator::Error::ConfigSerialization)?;
fs::write(&path, data)
.map_err(|error| locator::Error::UpgradeCheckWriteFailed { path, error })
}
}
#[cfg(test)]
mod tests {
use super::*;
use std::env;
#[test]
fn test_upgrade_check_load_save() {
let temp_dir = tempfile::tempdir().unwrap();
env::set_var("XDG_DATA_HOME", temp_dir.path());
let default_check = UpgradeCheck::load().unwrap();
assert_eq!(default_check, UpgradeCheck::default());
assert_eq!(
default_check.latest_check_time,
DateTime::<Utc>::from_timestamp_millis(0).unwrap()
);
assert_eq!(default_check.max_stable_version, Version::new(0, 0, 0));
let saved_check = UpgradeCheck {
latest_check_time: DateTime::<Utc>::from_timestamp(1_234_567_890, 0).unwrap(),
max_stable_version: Version::new(1, 2, 3),
max_version: Version::parse("1.2.4-rc.1").unwrap(),
};
saved_check.save().unwrap();
let loaded_check = UpgradeCheck::load().unwrap();
assert_eq!(loaded_check, saved_check);
}
}