refactor(loader): A3 — unificar loader, eliminar duplicación
El loader vivía partido: arje-brain/loader.rs cargaba EntityCards Y Rules, mientras brahman-cards tenía su propia infra de card-loading. Resolución por linaje: - Card-loading (load_card_file, extract_card_from_json) → brahman-cards (entity_loader.rs). Toda card-loading del ecosistema vive ahí. - Rule-loading (load_rules_file, extract_rules_from_json) → arje-brain-rules (loader.rs), junto a la definición de Rule. - arje-brain/loader.rs eliminado. arje-brain re-exporta ambos para compat de consumidores (arje-zero). cargo check --workspace verde. Tests: 13 arje-brain-rules + 31 brahman-cards. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,40 @@
|
||||
//! Loader de `EntityCard` (≡ `brahman_card::Card`) desde archivos JSON.
|
||||
//!
|
||||
//! Card-loading consolidado: antes vivía duplicado en `arje-brain/loader.rs`.
|
||||
//! La fuente de verdad del shape es Rust + serde; en disco se guarda JSON
|
||||
//! crudo. Toda card-loading del ecosistema vive ahora en `brahman-cards`.
|
||||
|
||||
use brahman_card::Card as EntityCard;
|
||||
use std::path::Path;
|
||||
|
||||
/// Carga una `EntityCard` desde un archivo JSON. Pasa por
|
||||
/// `EntityCard::validate()` antes de devolver — falla rápida.
|
||||
pub fn load_card_file(path: &Path) -> anyhow::Result<EntityCard> {
|
||||
let raw = std::fs::read_to_string(path)?;
|
||||
let card = extract_card_from_json(&raw)?;
|
||||
card.validate()
|
||||
.map_err(|e| anyhow::anyhow!("Card inválida ({}): {e}", path.display()))?;
|
||||
Ok(card)
|
||||
}
|
||||
|
||||
/// Extrae una `EntityCard` de JSON. Acepta:
|
||||
/// 1. Object directamente serializable como EntityCard.
|
||||
/// 2. Object dict con un único valor que sea EntityCard (compat con
|
||||
/// salidas de generadores que envuelven en `{"seed": {...}}`).
|
||||
pub fn extract_card_from_json(raw: &str) -> anyhow::Result<EntityCard> {
|
||||
let v: serde_json::Value = serde_json::from_str(raw)?;
|
||||
let direct_err = match serde_json::from_value::<EntityCard>(v.clone()) {
|
||||
Ok(c) => return Ok(c),
|
||||
Err(e) => e,
|
||||
};
|
||||
if let serde_json::Value::Object(map) = v {
|
||||
for (_, vv) in map {
|
||||
if let Ok(c) = serde_json::from_value::<EntityCard>(vv) {
|
||||
return Ok(c);
|
||||
}
|
||||
}
|
||||
}
|
||||
// Propagamos el error del intento directo: es el caso típico (JSON
|
||||
// top-level = EntityCard) y su mensaje apunta al campo que rompió.
|
||||
anyhow::bail!("JSON no contiene una EntityCard válida: {direct_err}")
|
||||
}
|
||||
Reference in New Issue
Block a user