Initial commit: MTG personal library catalog (Tauri v2 + React/TS)
Full working app with: - Rust core (mtgc-core): Scryfall ingester, nucleo fuzzy search, SQLite two-DB architecture (reference.db + library.db via ATTACH), criteria filters, deck ops - Tauri v2 shell exposing the core as typed IPC commands - React/TS frontend: card entry, library browser, deck editor - Features: fuzzy card search, color/CMC/type/commander-identity filters, tile/list view toggle, hover card previews, deck format + commander support, per-card location field, grouping by type/subtype/CMC/color, localStorage persistence for active tab/deck/grouping, Discord-inspired dark UI (#C8553D accent) Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
58
src-tauri/src/state.rs
Normal file
58
src-tauri/src/state.rs
Normal file
@@ -0,0 +1,58 @@
|
||||
//! App state: the open [`Catalog`] and fuzzy [`NameIndex`], plus the db paths.
|
||||
|
||||
use std::path::PathBuf;
|
||||
|
||||
use mtgc_core::{Catalog, NameIndex};
|
||||
|
||||
/// Managed application state, guarded by a `Mutex` in Tauri's state store.
|
||||
pub struct AppState {
|
||||
pub library_path: PathBuf,
|
||||
pub reference_path: PathBuf,
|
||||
pub catalog: Option<Catalog>,
|
||||
pub index: Option<NameIndex>,
|
||||
}
|
||||
|
||||
impl AppState {
|
||||
/// Initialize with default paths under the app data dir and open the catalog
|
||||
/// if a reference db already exists.
|
||||
pub fn new(data_dir: PathBuf) -> Self {
|
||||
let mut s = Self {
|
||||
library_path: data_dir.join("library.db"),
|
||||
reference_path: data_dir.join("reference.db"),
|
||||
catalog: None,
|
||||
index: None,
|
||||
};
|
||||
// Best-effort open; failures just leave the catalog unloaded.
|
||||
let _ = s.reopen();
|
||||
s
|
||||
}
|
||||
|
||||
/// (Re)open the catalog + rebuild the name index. Only opens when a reference
|
||||
/// db exists — attaching a non-existent file would create an empty (tableless)
|
||||
/// db and make every query fail.
|
||||
pub fn reopen(&mut self) -> Result<(), String> {
|
||||
if self.reference_path.exists() {
|
||||
let catalog = Catalog::open(&self.library_path, &self.reference_path)
|
||||
.map_err(|e| e.to_string())?;
|
||||
let index = catalog.build_name_index().map_err(|e| e.to_string())?;
|
||||
self.index = Some(index);
|
||||
self.catalog = Some(catalog);
|
||||
} else {
|
||||
self.catalog = None;
|
||||
self.index = None;
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub fn catalog(&self) -> Result<&Catalog, String> {
|
||||
self.catalog
|
||||
.as_ref()
|
||||
.ok_or_else(|| "Card data not loaded yet — click 'Download card data'.".to_string())
|
||||
}
|
||||
|
||||
pub fn index(&self) -> Result<&NameIndex, String> {
|
||||
self.index
|
||||
.as_ref()
|
||||
.ok_or_else(|| "Card data not loaded yet — click 'Download card data'.".to_string())
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user