use anyhow::Result;
use std::path::PathBuf;
use crate::config::Config;
use crate::network::SpeedTestResult;
const MAX_HISTORY_ENTRIES: usize = 1000;
pub fn history_path() -> Result<PathBuf> {
Ok(Config::config_dir()?.join("history.json"))
}
pub fn load_history() -> Result<Vec<SpeedTestResult>> {
let path = history_path()?;
if !path.exists() {
return Ok(Vec::new());
}
let content = std::fs::read_to_string(&path)?;
let history: Vec<SpeedTestResult> = serde_json::from_str(&content)?;
Ok(history)
}
pub fn save_history(history: &[SpeedTestResult]) -> Result<()> {
let path = history_path()?;
if let Some(parent) = path.parent() {
std::fs::create_dir_all(parent)?;
}
let content = serde_json::to_string_pretty(history)?;
std::fs::write(path, content)?;
Ok(())
}
pub fn add_to_history(result: SpeedTestResult) -> Result<()> {
let mut history = load_history()?;
history.push(result);
if history.len() > MAX_HISTORY_ENTRIES {
history = history.split_off(history.len() - MAX_HISTORY_ENTRIES);
}
save_history(&history)?;
Ok(())
}
pub fn clear_history() -> Result<()> {
let path = history_path()?;
if path.exists() {
std::fs::remove_file(path)?;
}
Ok(())
}
#[allow(dead_code)]
pub fn get_last_result() -> Result<Option<SpeedTestResult>> {
let history = load_history()?;
Ok(history.into_iter().last())
}
#[allow(dead_code)]
pub fn get_history_range(
start: chrono::DateTime<chrono::Utc>,
end: chrono::DateTime<chrono::Utc>,
) -> Result<Vec<SpeedTestResult>> {
let history = load_history()?;
Ok(history
.into_iter()
.filter(|r| r.timestamp >= start && r.timestamp <= end)
.collect())
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_history_path() {
let path = history_path();
assert!(path.is_ok());
}
}