use serde::Deserialize;
use toml::Spanned;
#[derive(Clone, Copy, Debug, Default, PartialEq, Eq, Deserialize)]
#[cfg_attr(feature = "schema", derive(schemars::JsonSchema))]
#[serde(rename_all = "lowercase")]
pub(super) enum FormatEntry {
#[default]
Number,
Signed,
Percent,
}
#[derive(Clone, Debug, PartialEq, Deserialize)]
#[cfg_attr(feature = "schema", derive(schemars::JsonSchema))]
#[serde(deny_unknown_fields)]
pub(super) struct StatEntry {
pub(super) label: String,
pub(super) value: i32,
#[serde(default)]
pub(super) format: FormatEntry,
}
#[derive(Clone, Copy, Debug, PartialEq, Eq, Deserialize)]
#[cfg_attr(feature = "schema", derive(schemars::JsonSchema))]
#[serde(deny_unknown_fields)]
pub(super) struct MeterEntry {
pub(super) max: u16,
pub(super) start: Option<u16>,
}
#[derive(Clone, Debug, PartialEq, Eq, Deserialize)]
#[cfg_attr(feature = "schema", derive(schemars::JsonSchema))]
#[serde(deny_unknown_fields)]
pub(super) struct IconEntry {
pub(super) tint: Option<[u8; 3]>,
pub(super) amount: Option<u8>,
pub(super) like: Option<String>,
pub(super) png: Option<String>,
}
#[derive(Clone, Debug, PartialEq, Deserialize)]
#[cfg_attr(feature = "schema", derive(schemars::JsonSchema))]
#[serde(deny_unknown_fields)]
pub(super) struct ItemEntry {
pub(super) id: String,
pub(super) like: String,
pub(super) name: Option<String>,
pub(super) description: Option<String>,
pub(super) debug_name: Option<String>,
pub(super) meter: Option<MeterEntry>,
#[serde(default)]
pub(super) stats: Vec<StatEntry>,
pub(super) icon: Option<IconEntry>,
}
#[derive(Clone, Debug, PartialEq, Eq, Deserialize)]
#[cfg_attr(feature = "schema", derive(schemars::JsonSchema))]
#[serde(deny_unknown_fields)]
pub(super) struct RecipeEntry {
pub(super) id: String,
pub(super) like: String,
pub(super) output: String,
#[serde(default = "one")]
pub(super) count: u32,
#[serde(default = "one")]
pub(super) cost: u32,
pub(super) workshop: Option<String>,
}
pub(super) const fn one() -> u32 {
1
}
#[derive(Clone, Copy, Debug, PartialEq, Eq, Deserialize)]
#[cfg_attr(feature = "schema", derive(schemars::JsonSchema))]
#[serde(deny_unknown_fields)]
pub(super) struct StationRecipeEntry {
pub(super) cost: u32,
}
#[derive(Clone, Debug, PartialEq, Eq, Deserialize)]
#[cfg_attr(feature = "schema", derive(schemars::JsonSchema))]
#[serde(deny_unknown_fields)]
pub(super) struct WorkshopEntry {
pub(super) id: String,
pub(super) like: String,
pub(super) name: Option<String>,
pub(super) description: Option<String>,
pub(super) recipe: Option<StationRecipeEntry>,
pub(super) debug_name: Option<String>,
}
#[derive(Clone, Debug, PartialEq, Eq, Deserialize)]
#[cfg_attr(feature = "schema", derive(schemars::JsonSchema))]
#[serde(untagged)]
pub(super) enum FromEntry {
One(String),
Many(Vec<String>),
}
#[derive(Clone, Debug, PartialEq, Deserialize)]
#[cfg_attr(feature = "schema", derive(schemars::JsonSchema))]
#[serde(deny_unknown_fields)]
pub(super) struct DropEntry {
pub(super) items: Vec<String>,
pub(super) chance: f64,
pub(super) from: FromEntry,
pub(super) count: Option<[u16; 2]>,
pub(super) meter: Option<[u16; 2]>,
}
#[derive(Debug, Default, Deserialize)]
#[serde(deny_unknown_fields)]
pub(super) struct ItemsFile {
#[serde(default)]
pub(super) item: Vec<Spanned<ItemEntry>>,
}
#[derive(Debug, Default, Deserialize)]
#[serde(deny_unknown_fields)]
pub(super) struct RecipesFile {
#[serde(default)]
pub(super) recipe: Vec<Spanned<RecipeEntry>>,
}
#[derive(Debug, Default, Deserialize)]
#[serde(deny_unknown_fields)]
pub(super) struct WorkshopsFile {
#[serde(default)]
pub(super) workshop: Vec<Spanned<WorkshopEntry>>,
}
#[derive(Debug, Default, Deserialize)]
#[serde(deny_unknown_fields)]
pub(super) struct LootFile {
#[serde(default)]
pub(super) drop: Vec<Spanned<DropEntry>>,
}
#[cfg(feature = "schema")]
#[must_use]
pub fn schemas() -> Vec<(&'static str, String)> {
use super::manifest::PackManifest;
use super::{ITEMS_FILE, LOOT_FILE, MANIFEST_FILE, RECIPES_FILE, WORKSHOPS_FILE};
#[derive(schemars::JsonSchema)]
#[schemars(deny_unknown_fields)]
#[expect(dead_code, reason = "only its schema is read")]
struct Items {
item: Option<Vec<ItemEntry>>,
}
#[derive(schemars::JsonSchema)]
#[schemars(deny_unknown_fields)]
#[expect(dead_code, reason = "only its schema is read")]
struct Recipes {
recipe: Option<Vec<RecipeEntry>>,
}
#[derive(schemars::JsonSchema)]
#[schemars(deny_unknown_fields)]
#[expect(dead_code, reason = "only its schema is read")]
struct Workshops {
workshop: Option<Vec<WorkshopEntry>>,
}
#[derive(schemars::JsonSchema)]
#[schemars(deny_unknown_fields)]
#[expect(dead_code, reason = "only its schema is read")]
struct Loot {
drop: Option<Vec<DropEntry>>,
}
let json = |schema: schemars::Schema| serde_json::to_string_pretty(&schema).unwrap_or_default();
vec![
(MANIFEST_FILE, json(schemars::schema_for!(PackManifest))),
(ITEMS_FILE, json(schemars::schema_for!(Items))),
(RECIPES_FILE, json(schemars::schema_for!(Recipes))),
(WORKSHOPS_FILE, json(schemars::schema_for!(Workshops))),
(LOOT_FILE, json(schemars::schema_for!(Loot))),
]
}