Files
OpenFUT-Core/src/services/card_db.rs
T
funman300 1ffe0ffa9f Initial commit: OpenFUT Core
Offline Ultimate Team backend — game-independent REST API.

- 19 API endpoints: auth, profiles, clubs, cards, packs, squads,
  objectives, SBCs, match rewards, NPC market, statistics
- Axum + SQLite + SQLx with full migrations
- Weighted pack generator, SBC validation engine
- JSON-driven mod data (cards, packs, objectives, SBCs)
- 5 integration tests passing

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-25 14:54:51 -07:00

64 lines
2.0 KiB
Rust

use crate::models::card::CardDefinition;
use anyhow::{Context, Result};
use std::collections::HashMap;
use std::path::Path;
/// In-memory card registry loaded from data/cards/*.json
pub struct CardDb {
pub cards: HashMap<String, CardDefinition>,
}
impl CardDb {
pub fn load(data_dir: &str) -> Result<Self> {
let cards_dir = Path::new(data_dir).join("cards");
let mut cards = HashMap::new();
if !cards_dir.exists() {
tracing::warn!("Card data directory not found: {:?}", cards_dir);
return Ok(Self { cards });
}
for entry in std::fs::read_dir(&cards_dir)
.with_context(|| format!("reading cards dir {:?}", cards_dir))?
{
let entry = entry?;
let path = entry.path();
if path.extension().map(|e| e == "json").unwrap_or(false) {
let content = std::fs::read_to_string(&path)
.with_context(|| format!("reading {:?}", path))?;
let batch: Vec<CardDefinition> = serde_json::from_str(&content)
.with_context(|| format!("parsing {:?}", path))?;
for card in batch {
cards.insert(card.id.clone(), card);
}
}
}
tracing::info!("Loaded {} card definitions", cards.len());
Ok(Self { cards })
}
pub fn get(&self, id: &str) -> Option<&CardDefinition> {
self.cards.get(id)
}
#[allow(dead_code)]
pub fn by_rarity(&self, rarity: &str) -> Vec<&CardDefinition> {
self.cards
.values()
.filter(|c| {
let r = format!("{:?}", c.rarity).to_lowercase();
r == rarity || rarity == "any"
})
.collect()
}
pub fn all(&self) -> Vec<&CardDefinition> {
self.cards.values().collect()
}
pub fn by_min_overall(&self, min: u8) -> Vec<&CardDefinition> {
self.cards.values().filter(|c| c.overall >= min).collect()
}
}