modde_games/stardew/
saves.rs1use std::path::Path;
4
5use anyhow::{Context, Result};
6use smallvec::SmallVec;
7
8use crate::save_patterns::{CaptureSummary, PatternSaveTracker};
9use crate::traits::{DetectedSave, SaveTracker};
10
11pub struct StardewSaveTracker;
13
14pub static STARDEW_SAVE_TRACKER: StardewSaveTracker = StardewSaveTracker;
15
16const TRACKER: PatternSaveTracker = PatternSaveTracker {
17 prefix_rules: &[],
18 file_extensions: &[],
19 default_category: "farm",
20 recursive: false,
21 exclude_patterns: &["startup_preferences"],
22 label_extractor: |_, rel| Some(rel.to_string()),
23 summary: CaptureSummary::Default,
24};
25
26impl SaveTracker for StardewSaveTracker {
27 fn save_patterns(&self) -> SmallVec<[String; 2]> {
28 smallvec::smallvec!["*_*".into()]
29 }
30
31 fn detect_saves(&self, save_dir: &Path) -> Result<Vec<DetectedSave>> {
32 let mut saves = Vec::new();
33 if !save_dir.exists() {
34 return Ok(saves);
35 }
36 for entry in std::fs::read_dir(save_dir)
37 .with_context(|| format!("failed to read directory: {}", save_dir.display()))?
38 {
39 let entry = entry?;
40 if !entry.file_type()?.is_dir() {
41 continue;
42 }
43 let name = entry.file_name().to_string_lossy().to_string();
44 if !name.contains('_') {
45 continue;
46 }
47 let modified = entry
48 .metadata()
49 .and_then(|meta| meta.modified())
50 .unwrap_or(std::time::SystemTime::UNIX_EPOCH);
51 saves.push(DetectedSave {
52 rel_path: name.clone().into(),
53 category: std::borrow::Cow::Borrowed("farm"),
54 label: Some(name),
55 modified,
56 });
57 }
58 saves.sort_by(|a, b| b.modified.cmp(&a.modified));
59 Ok(saves)
60 }
61
62 fn exclude_patterns(&self) -> SmallVec<[String; 2]> {
63 TRACKER.exclude_patterns()
64 }
65
66 fn describe_capture(&self, saves: &[DetectedSave]) -> String {
67 TRACKER.describe_capture(saves)
68 }
69}