use std::sync::LazyLock;
use regex::Regex;
use serde::{Deserialize, Serialize};
use crate::tile_component::{BaseTerrain, Feature, TerrainType};
pub trait Name {
fn name(&self) -> String;
}
#[derive(Serialize, Deserialize, Debug, Default)]
pub struct Yields {
#[serde(default)]
pub food: i8,
#[serde(default)]
pub production: i8,
#[serde(default)]
pub science: i8,
#[serde(default)]
pub gold: i8,
#[serde(default)]
pub culture: i8,
#[serde(default)]
pub faith: i8,
#[serde(default)]
pub happiness: i8,
}
#[derive(Debug, Serialize, Deserialize)]
#[serde(rename_all = "camelCase")]
pub struct RequiredTerrain {
#[serde(default = "default_terrain_type")]
pub terrain_type: Vec<TerrainType>,
#[serde(default = "default_base_terrain")]
pub base_terrain: Vec<BaseTerrain>,
pub feature: Option<Vec<Feature>>,
river: Option<bool>,
#[serde(default)]
pub freshwater: Option<bool>,
#[serde(default)]
pub extra_conditions: Vec<String>,
}
impl Default for RequiredTerrain {
fn default() -> Self {
Self {
terrain_type: vec![TerrainType::Flatland, TerrainType::Hill],
base_terrain: vec![
BaseTerrain::Grassland,
BaseTerrain::Plain,
BaseTerrain::Desert,
BaseTerrain::Tundra,
BaseTerrain::Snow,
],
feature: None,
river: None,
freshwater: None,
extra_conditions: Vec::new(),
}
}
}
fn default_terrain_type() -> Vec<TerrainType> {
vec![TerrainType::Flatland, TerrainType::Hill]
}
fn default_base_terrain() -> Vec<BaseTerrain> {
vec![
BaseTerrain::Grassland,
BaseTerrain::Plain,
BaseTerrain::Desert,
BaseTerrain::Tundra,
BaseTerrain::Snow,
]
}
#[derive(Debug)]
pub struct Unique {
pub placeholder_text: String,
pub params: Vec<String>,
pub conditionals: Vec<Unique>,
}
impl Unique {
pub fn new(unique: &str) -> Self {
static PARAMS_REGEX: LazyLock<Regex> = LazyLock::new(|| Regex::new(r"\[(.+?)\]").unwrap());
static CONDITION_REGEX: LazyLock<Regex> =
LazyLock::new(|| Regex::new(r"<([^>]*)>").unwrap());
let unique_without_conditionals = CONDITION_REGEX.replace_all(unique, "");
let unique_without_conditionals = unique_without_conditionals.trim();
let placeholder_text = PARAMS_REGEX
.replace_all(unique_without_conditionals, "[]")
.to_string();
let params = PARAMS_REGEX
.captures_iter(unique_without_conditionals)
.map(|cap| cap[1].to_owned())
.collect();
let conditionals = CONDITION_REGEX
.captures_iter(unique)
.map(|cap| Self::new(&cap[1]))
.collect();
Self {
placeholder_text,
params,
conditionals,
}
}
}