Files
studipsync/src/state.rs
2025-11-14 21:37:55 +01:00

86 lines
2.2 KiB
Rust

use crate::Result;
use serde::{Deserialize, Serialize};
use std::{
collections::HashMap,
fs,
path::{Path, PathBuf},
};
#[derive(Debug, Default, Serialize, Deserialize)]
pub struct StateFile {
#[serde(default)]
pub profiles: HashMap<String, ProfileState>,
}
#[derive(Debug, Default, Serialize, Deserialize)]
pub struct ProfileState {
#[serde(default)]
pub user_id: Option<String>,
#[serde(default)]
pub semesters: HashMap<String, SemesterState>,
#[serde(default)]
pub courses: HashMap<String, CourseState>,
#[serde(default)]
pub files: HashMap<String, FileState>,
}
#[derive(Debug, Default, Serialize, Deserialize, Clone)]
pub struct SemesterState {
pub id: String,
pub title: String,
pub key: String,
}
#[derive(Debug, Default, Serialize, Deserialize, Clone)]
pub struct CourseState {
pub id: String,
pub name: String,
pub semester_key: String,
#[serde(default)]
pub last_sync: Option<String>,
}
#[derive(Debug, Default, Serialize, Deserialize, Clone)]
pub struct FileState {
pub id: String,
#[serde(default)]
pub size: Option<u64>,
#[serde(default)]
pub checksum: Option<String>,
#[serde(default)]
pub last_downloaded: Option<String>,
#[serde(default)]
pub remote_modified: Option<String>,
#[serde(default)]
pub path_hint: Option<PathBuf>,
}
impl StateFile {
pub fn load_or_default(path: &Path) -> Result<Self> {
match fs::read_to_string(path) {
Ok(contents) => Ok(toml::from_str(&contents)?),
Err(err) if err.kind() == std::io::ErrorKind::NotFound => Ok(Self::default()),
Err(err) => Err(err.into()),
}
}
pub fn save(&self, path: &Path) -> Result<()> {
if let Some(parent) = path.parent() {
fs::create_dir_all(parent)?;
}
let contents = toml::to_string_pretty(self)?;
fs::write(path, contents)?;
Ok(())
}
pub fn profile_mut(&mut self, profile: &str) -> &mut ProfileState {
self.profiles
.entry(profile.to_string())
.or_insert_with(ProfileState::default)
}
pub fn profile(&self, profile: &str) -> Option<&ProfileState> {
self.profiles.get(profile)
}
}