You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 

90 lines
2.6 KiB

use schemars::JsonSchema;
use serde::{Deserialize, Serialize};
use std::collections::HashMap;
use std::path::PathBuf;
#[derive(Serialize, Deserialize, JsonSchema, Debug, Clone)]
pub struct Config {
pub name: String,
#[serde(default = "default_version")]
pub version: String,
#[serde(default)]
pub authors: Vec<String>,
pub script: String,
pub available_cards: HashMap<String, Card>,
pub piles: HashMap<String, Pile>,
pub player_piles: HashMap<String, Pile>,
}
fn default_version() -> String {
"0.0.0".into()
}
#[derive(Serialize, Deserialize, JsonSchema, Debug, Clone)]
pub struct Card {
pub image: PathBuf,
#[serde(flatten)]
pub other: HashMap<String, serde_json::Value>,
}
#[derive(Serialize, Deserialize, JsonSchema, Debug, Clone)]
pub struct Pile {
#[serde(default)]
pub cards: Vec<String>,
#[serde(flatten)]
pub other: HashMap<String, serde_json::Value>,
}
impl Pile {
pub fn from_rhai_map(map: rhai::Map) -> Result<Self, Box<rhai::EvalAltResult>> {
// println!("{}", map.get("cards")
// .ok_or("Pile doesn't have property cards")?.type_name());
let cards: Vec<String> =
rhai::serde::from_dynamic(map.get("cards").ok_or("Pile doesn't have property cards")?)?;
let other_fallible: Vec<Result<(String, serde_json::Value), Box<rhai::EvalAltResult>>> =
map.into_iter()
.map(|(x, v)| (x.to_string(), v))
.filter(|(s, _)| s != &"cards".to_string())
.map(|(k, v)| Ok((k, rhai::serde::from_dynamic::<serde_json::Value>(&v)?)))
.collect();
let mut other = HashMap::new();
for x in other_fallible {
let (k, v) = x?;
other.insert(k, v);
}
Ok(Self { cards, other })
}
}
impl Config {
pub fn load<P: AsRef<std::path::Path> + std::fmt::Debug>(file: P) -> Self {
serde_json::from_reader(std::fs::File::open(&file).unwrap())
.map_err(|e| {
log::error!(
"Malformed game defintion file @ {}",
file.as_ref().display()
);
log::error!("JSON Error: {}", e);
panic!()
})
.unwrap()
}
}
pub fn setup() {
if cfg!(debug_assertions) {
if let Ok(e) = std::env::var("CARGO_MANIFEST_DIR") {
std::fs::write(
AsRef::<std::path::Path>::as_ref(&e)
.join("schema")
.join("game-config.json"),
serde_json::to_string_pretty(&schemars::schema_for!(Config)).unwrap(),
)
.unwrap()
}
}
}