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 --- 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 + 7 files changed, 31 insertions(+), 61 deletions(-) (limited to 'src') 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