From 5ae2f9040324baaeaed3f91a84662425cb6186dc Mon Sep 17 00:00:00 2001 From: troido Date: Thu, 24 Sep 2020 17:12:39 +0200 Subject: more serde (de)serialisation --- content/encyclopediae/crops.json | 14 ++++----- content/encyclopediae/default_encyclopedia.json | 39 +++++++++++++------------ src/components/equipment.rs | 29 ++++-------------- src/encyclopedia.rs | 2 +- src/item.rs | 35 ++++++---------------- src/parameter.rs | 6 ++-- src/savestate.rs | 1 + src/sprite.rs | 18 +++++++----- src/template.rs | 1 + 9 files changed, 58 insertions(+), 87 deletions(-) diff --git a/content/encyclopediae/crops.json b/content/encyclopediae/crops.json index 7e493b3..1fc5ea0 100644 --- a/content/encyclopediae/crops.json +++ b/content/encyclopediae/crops.json @@ -151,13 +151,13 @@ } }, "items": { - "radishseed": {"sprite": "seed", "action": ["build", ["plantedradishseed", ["Floor", "Soil"], ["Occupied", "Blocking"]]]}, - "radish": {"sprite": "food", "action": ["eat", 3]}, - "radishes": {"sprite": "food", "name": "radish", "entity": "radish", "action": ["eat", 3]}, - "eldritch_radish": {"sprite": "food", "name": "eldritch_radish", "action": ["eat", 20]}, - "carrotseed": {"sprite": "seed", "action": ["build", ["plantedcarrotseed", ["Floor", "Soil"], ["Occupied", "Blocking"]]]}, - "carrot": {"sprite": "food", "action": ["eat", 5]}, - "cottonseed": {"sprite": "seed", "action": ["build", ["plantedcottonseed", ["Floor", "Soil"], ["Occupied", "Blocking"]]]}, + "radishseed": {"sprite": "seed", "action": {"build": ["plantedradishseed", ["Floor", "Soil"], ["Occupied", "Blocking"]]}}, + "radish": {"sprite": "food", "action": {"eat": 3}}, + "radishes": {"sprite": "food", "name": "radish", "entity": "radish", "action": {"eat": 3}}, + "eldritch_radish": {"sprite": "food", "name": "eldritch_radish", "action": {"eat": 20}}, + "carrotseed": {"sprite": "seed", "action": {"build": ["plantedcarrotseed", ["Floor", "Soil"], ["Occupied", "Blocking"]]}}, + "carrot": {"sprite": "food", "action": {"eat": 5}}, + "cottonseed": {"sprite": "seed", "action": {"build": ["plantedcottonseed", ["Floor", "Soil"], ["Occupied", "Blocking"]]}}, "cotton": {"sprite": "cotton"}, "cottonyarn": {"sprite": "cottonyarn"}, "cottoncloth": {"sprite": "cottoncloth"} diff --git a/content/encyclopediae/default_encyclopedia.json b/content/encyclopediae/default_encyclopedia.json index 8ea6bcc..573fbfa 100644 --- a/content/encyclopediae/default_encyclopedia.json +++ b/content/encyclopediae/default_encyclopedia.json @@ -155,70 +155,71 @@ }, "items": { "pebble": {}, - "stone": {"action": ["build", ["builtwall", ["Floor"], ["Blocking"]]]}, - "sword": {"action": ["equip", { + "stone": {"action": {"build": ["builtwall", ["Floor"], ["Blocking"]]}}, + "sword": {"action": {"equip": { "slot": "hand", "stats": {"strength": 5} - }]}, + }}}, "eldritch_sword": { "sprite": "sword", "name": "eldritch sword", - "action": ["equip", { + "action": {"equip": { "slot": "hand", "stats": {"strength": 500} - }] + }} }, - "club": {"action": ["equip", { + "club": {"action": {"equip": { "slot": "hand", "stats": {"strength": 3} - }]}, + }}}, "armour": { "sprite": "armour", - "action": ["equip", { + "action": {"equip": { "slot": "body", "stats": {"defence": 3} - }]}, + }} + }, "pickaxe": { "sprite": "sword", - "action": ["equip", { + "action": {"equip": { "slot": "hand", "stats": {"mining": 5} - }] + }} }, "reddye": {"sprite": "bag"}, "greendye": {"sprite": "bag"}, "bluedye": {"sprite": "bag"}, "cape": { "sprite": "armour", - "action": ["equip", { + "action": {"equip": { "slot": "back", "stats": {}, "sprite": "grayplayer" - }] + }} }, "redcape": { "sprite": "armour", - "action": ["equip", { + "action": {"equip": { "slot": "back", "stats": {}, "sprite": "redplayer" - }] + }} }, "greencape": { "sprite": "armour", - "action": ["equip", { + "action": {"equip": { "slot": "back", "stats": {}, "sprite": "greenplayer" - }] + }} }, "bluecape": { "sprite": "armour", - "action": ["equip", { + "action": {"equip": { "slot": "back", "stats": {}, "sprite": "blueplayer" - }] + }} } } } diff --git a/src/components/equipment.rs b/src/components/equipment.rs index 0e93902..d87502d 100644 --- a/src/components/equipment.rs +++ b/src/components/equipment.rs @@ -1,6 +1,6 @@ use std::collections::HashMap; -use serde_json::Value; +use serde::{Serialize, Deserialize}; use specs::{ Component, HashMapStorage @@ -10,7 +10,8 @@ use crate::{ }; -#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] +#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Serialize, Deserialize)] +#[serde(rename_all = "lowercase")] pub enum Slot { Hand, Body, @@ -29,7 +30,8 @@ impl Slot { } -#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] +#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Serialize, Deserialize)] +#[serde(rename_all = "lowercase")] pub enum Stat { Strength, Defence, @@ -48,32 +50,13 @@ impl Stat { } -#[derive(Debug, Clone, PartialEq)] +#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)] pub struct Equippable { pub slot: Slot, pub stats: HashMap, pub sprite: Option } -impl Equippable { - pub fn from_json(val: &Value) -> Option { - Some(Equippable{ - slot: Slot::from_str(val.get("slot")?.as_str()?)?, - stats: val - .get("stats")? - .as_object()? - .into_iter() - .map(|(k, v)| - Some((Stat::from_str(k.as_str())?, v.as_i64()?)) - ) - .collect::>>()?, - sprite: if let Some(spr) = val.get("sprite") { - Some(Sprite{name: spr.as_str()?.to_string()}) - } else {None} - }) - } -} - #[derive(Component, Debug, Clone)] diff --git a/src/encyclopedia.rs b/src/encyclopedia.rs index 8acd7e9..379378c 100644 --- a/src/encyclopedia.rs +++ b/src/encyclopedia.rs @@ -73,7 +73,7 @@ impl Encyclopedia { }, action: if let Some(action) = v.get("action") { - ItemAction::from_json(action).ok_or(perr!("failed to parse ItemAction: {:?}", v))? + ItemAction::deserialize(action).map_err(|e| perr!("failed to parse ItemAction {:?} {:?}", v, e))? } else { ItemAction::None } diff --git a/src/item.rs b/src/item.rs index a663634..4fdb4b8 100644 --- a/src/item.rs +++ b/src/item.rs @@ -3,8 +3,7 @@ use std::collections::HashSet; use std::str::FromStr; use serde; -use serde::Deserialize; -use serde_json::{Value}; +use serde::{Deserialize, Serialize}; use crate::{ Template, components::{ @@ -33,7 +32,8 @@ pub struct Item { pub action: ItemAction } -#[derive(Debug, Clone, PartialEq)] +#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)] +#[serde(rename_all = "lowercase")] pub enum ItemAction { Eat(i64), Build(Template, HashSet, HashSet), @@ -41,26 +41,6 @@ pub enum ItemAction { None } -use ItemAction::{Eat, Build, Equip, None}; - -impl ItemAction { - - pub fn from_json(val: &Value) -> Option { - let typ = val.get(0)?; - let arg = val.get(1)?; - Some(match typ.as_str()? { - "eat" => Eat(arg.as_i64()?), - "build" => Build( - Template::deserialize(arg.get(0)?).ok()?, - arg.get(1)?.as_array()?.iter().map(|v| Flag::from_str(v.as_str()?).ok()).collect::>>()?, - arg.get(2)?.as_array()?.iter().map(|v| Flag::from_str(v.as_str()?).ok()).collect::>>()? - ), - "none" => None, - "equip" => Equip(Equippable::from_json(arg)?), - _ => {return Option::None} - }) - } -} #[cfg(test)] mod tests { @@ -72,11 +52,14 @@ mod tests { #[test] fn equip_from_json() { assert_eq!( - ItemAction::from_json(&json!(["equip", {"slot": "hand", "stats": {"strength": 10}}])), - Some(ItemAction::Equip(Equippable {slot: Slot::Hand, stats: hashmap!(Stat::Strength => 10), sprite: Option::None})) + ItemAction::deserialize(&json!({"equip": {"slot": "hand", "stats": {"strength": 10}}})).unwrap(), + ItemAction::Equip(Equippable {slot: Slot::Hand, stats: hashmap!(Stat::Strength => 10), sprite: Option::None}) ); + } + #[test] + fn invalid_stat() { assert_eq!( - ItemAction::from_json(&json!(["equip", {"slot": "hand", "stats": {"attack": 50}}])), + ItemAction::deserialize(&json!({"equip": {"slot": "hand", "stats": {"attack": 50}}})).ok(), Option::None ); } diff --git a/src/parameter.rs b/src/parameter.rs index 6facc40..3667394 100644 --- a/src/parameter.rs +++ b/src/parameter.rs @@ -118,15 +118,13 @@ impl Parameter { impl Serialize for Parameter { fn serialize(&self, serializer: S) -> Result - where S: Serializer, - { + where S: Serializer { self.to_json().serialize(serializer) } } impl<'de> Deserialize<'de> for Parameter { fn deserialize(deserializer: D) -> Result - where D: Deserializer<'de>, - { + where D: Deserializer<'de> { Self::guess_from_json(&Value::deserialize(deserializer)?).map_err(|e| de::Error::custom(e.text)) } } diff --git a/src/savestate.rs b/src/savestate.rs index a81235f..160a251 100644 --- a/src/savestate.rs +++ b/src/savestate.rs @@ -42,6 +42,7 @@ impl<'de> Deserialize<'de> for SaveState { mod tests{ use super::*; use crate::hashmap; + use serde_json::json; #[test] fn test_empty_deserialize(){ diff --git a/src/sprite.rs b/src/sprite.rs index 0e08b86..d5f65a0 100644 --- a/src/sprite.rs +++ b/src/sprite.rs @@ -1,5 +1,5 @@ -use serde::{Serialize, Serializer}; +use serde::{Serialize, Serializer, Deserialize, Deserializer}; #[derive(Debug, Clone, PartialEq, Hash, Eq)] pub struct Sprite { @@ -7,10 +7,14 @@ pub struct Sprite { } impl Serialize for Sprite { - fn serialize(&self, serializer: S) -> Result - where - S: Serializer, - { - serializer.serialize_str(self.name.as_str()) - } + fn serialize(&self, serializer: S) -> Result + where S: Serializer { + serializer.serialize_str(self.name.as_str()) + } +} +impl<'de> Deserialize<'de> for Sprite { + fn deserialize(deserializer: D) -> Result + where D: Deserializer<'de> { + Ok(Self{name: String::deserialize(deserializer)?}) + } } diff --git a/src/template.rs b/src/template.rs index 66d58b9..dc0e8b8 100644 --- a/src/template.rs +++ b/src/template.rs @@ -126,6 +126,7 @@ impl Template { mod tests { use super::*; use crate::hashmap; + use serde_json::json; #[test] -- cgit