Christoffer Martinsson 6ad522f27c
All checks were successful
Build and Release / build-and-release (push) Successful in 50s
Optimize performance and reduce binary size
- Remove tokio async runtime dependency (~2MB reduction)
- Optimize fuzzy search to avoid string allocations
- Optimize incremental search to only rebuild tree when needed
- Extract duplicate scrolling logic to helper function
- Replace magic numbers with named constants
- Fix terminal cleanup to run even on error
- Fix context menu item count mismatch
- Remove unused metadata fields (duration, codec, hash)
2025-12-11 19:27:50 +01:00

87 lines
2.6 KiB
Rust

use anyhow::{Context, Result};
use serde::{Deserialize, Serialize};
use std::collections::HashMap;
use std::fs;
use std::path::{Path, PathBuf};
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct FileMetadata {
pub path: PathBuf,
pub size: u64,
pub is_video: bool,
pub is_audio: bool,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct FileTreeNode {
pub name: String,
pub path: PathBuf,
pub is_dir: bool,
pub children: Vec<FileTreeNode>,
pub metadata: Option<FileMetadata>,
}
#[derive(Debug, Serialize, Deserialize)]
pub struct Cache {
pub file_tree: Vec<FileTreeNode>,
pub metadata: HashMap<PathBuf, FileMetadata>,
}
impl Cache {
pub fn new() -> Self {
Self {
file_tree: Vec::new(),
metadata: HashMap::new(),
}
}
pub fn load(cache_dir: &Path) -> Result<Self> {
let tree_path = cache_dir.join("file_tree.json");
let metadata_path = cache_dir.join("metadata.json");
if !tree_path.exists() || !metadata_path.exists() {
return Ok(Self::new());
}
let tree_data = fs::read_to_string(&tree_path)
.context("Failed to read file_tree.json")?;
let file_tree: Vec<FileTreeNode> = serde_json::from_str(&tree_data)
.context("Failed to parse file_tree.json")?;
let metadata_data = fs::read_to_string(&metadata_path)
.context("Failed to read metadata.json")?;
let metadata: HashMap<PathBuf, FileMetadata> = serde_json::from_str(&metadata_data)
.context("Failed to parse metadata.json")?;
Ok(Self {
file_tree,
metadata,
})
}
pub fn save(&self, cache_dir: &Path) -> Result<()> {
fs::create_dir_all(cache_dir)
.context("Failed to create cache directory")?;
let tree_path = cache_dir.join("file_tree.json");
let tree_data = serde_json::to_string_pretty(&self.file_tree)
.context("Failed to serialize file_tree")?;
fs::write(&tree_path, tree_data)
.context("Failed to write file_tree.json")?;
let metadata_path = cache_dir.join("metadata.json");
let metadata_data = serde_json::to_string_pretty(&self.metadata)
.context("Failed to serialize metadata")?;
fs::write(&metadata_path, metadata_data)
.context("Failed to write metadata.json")?;
Ok(())
}
}
pub fn get_cache_dir() -> Result<PathBuf> {
let cache_home = dirs::cache_dir()
.context("Failed to get cache directory")?;
Ok(cache_home.join("cm-player"))
}