use crate::as_transparent;
use indexmap::IndexMap;
use reikland::Ignored;
use serde::{Deserialize, Deserializer, Serialize};
#[derive(Debug, Clone, Deserialize, Serialize)]
#[cfg_attr(test, serde(deny_unknown_fields))]
pub struct Item {
#[serde(rename = "@id")]
pub id: String,
#[serde(rename = "@id_number")]
pub id_number: u16,
#[serde(rename = "@real_name", deserialize_with = "as_transparent")]
pub real_name: String,
#[serde(rename = "@real_name_plural", deserialize_with = "as_transparent")]
pub real_name_plural: String,
#[serde(rename = "@pocket")]
pub pocket: u8,
#[serde(rename = "@price")]
pub price: u32,
#[serde(rename = "@real_description", deserialize_with = "as_transparent")]
pub real_description: String,
#[serde(rename = "@field_use")]
pub field_use: u8,
#[serde(rename = "@battle_use")]
pub battle_use: u8,
#[serde(rename = "@type")]
pub ty: u8,
#[serde(rename = "@move")]
pub mov: Option<String>,
}
#[derive(Debug, Clone, Serialize)]
pub struct ItemDex(pub Vec<Item>);
impl<'de> serde::Deserialize<'de> for ItemDex {
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
where
D: Deserializer<'de>,
{
reikland::DualKeyVec::<(Item, Ignored)>::deserialize(deserializer)
.map(|reikland::DualKeyVec(mut d)| {
d.sort_by_key(|(i, _)| i.id_number);
d.into_iter().map(|(i, _)| i).collect()
})
.map(ItemDex)
}
}
#[derive(Debug, Clone, Serialize)]
pub struct ItemMap(pub IndexMap<String, Item>);
impl<'de> serde::Deserialize<'de> for ItemMap {
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
where
D: Deserializer<'de>,
{
ItemDex::deserialize(deserializer)
.map(|ItemDex(v)| ItemMap(v.into_iter().map(|i| (i.id.clone(), i)).collect()))
}
}
#[cfg(test)]
mod tests {
use crate::test::PathTracked;
use super::*;
const ITEMS_DAT: &[u8] = include_bytes!("../InfiniteFusion/Data/items.dat");
#[test]
fn deserialize_items_dat_vec() {
let PathTracked(dex) = reikland::from_bytes::<PathTracked<ItemDex>>(ITEMS_DAT)
.unwrap_or_else(|e| panic!("items.dat failed to deserialize: {e}"));
assert!(!dex.0.is_empty());
assert_repel(dex.0.first().unwrap());
}
#[test]
fn deserialize_items_dat_map() {
let PathTracked(dex) = reikland::from_bytes::<PathTracked<ItemMap>>(ITEMS_DAT)
.unwrap_or_else(|e| panic!("items.dat failed to deserialize: {e}"));
assert!(!dex.0.is_empty());
assert_repel(dex.0.first().unwrap().1);
}
fn assert_repel(i: &Item) {
assert_eq!(i.id, "REPEL");
assert_eq!(i.id_number, 1);
assert_eq!(i.real_name, "Repel");
assert_eq!(i.real_name_plural, "Repels");
assert_eq!(i.pocket, 1);
assert_eq!(i.price, 300);
assert_eq!(i.field_use, 2);
assert_eq!(i.battle_use, 0);
assert_eq!(i.ty, 0);
assert!(i.mov.is_none());
}
}