diff options
| author | troido <troido@protonmail.com> | 2020-09-24 18:58:49 +0200 |
|---|---|---|
| committer | troido <troido@protonmail.com> | 2020-09-24 18:58:49 +0200 |
| commit | 13b53f3e89bcd6d33a534403162d1b09502bec70 (patch) | |
| tree | 32347d20893a5c901e64a7003262b5212966ecb1 | |
| parent | 5ae2f9040324baaeaed3f91a84662425cb6186dc (diff) | |
even more serde stuff
| -rw-r--r-- | src/components/equipment.rs | 6 | ||||
| -rw-r--r-- | src/controls.rs | 32 | ||||
| -rw-r--r-- | src/gameserver.rs | 3 | ||||
| -rw-r--r-- | src/item.rs | 2 | ||||
| -rw-r--r-- | src/parameter.rs | 2 | ||||
| -rw-r--r-- | src/pos.rs | 8 |
6 files changed, 18 insertions, 35 deletions
diff --git a/src/components/equipment.rs b/src/components/equipment.rs index d87502d..cbd482c 100644 --- a/src/components/equipment.rs +++ b/src/components/equipment.rs @@ -90,10 +90,10 @@ mod tests { } #[test] - fn equippable_from_json() { + fn equippable_deserialize() { assert_eq!( - Equippable::from_json(&json!({"slot": "hand", "stats": {"strength": 10}})), - Some(Equippable {slot: Slot::Hand, stats: hashmap!(Stat::Strength => 10), sprite: None}) + Equippable::deserialize(&json!({"slot": "hand", "stats": {"strength": 10}})).unwrap(), + Equippable {slot: Slot::Hand, stats: hashmap!(Stat::Strength => 10), sprite: None} ); } diff --git a/src/controls.rs b/src/controls.rs index 8f2c79c..bdbed98 100644 --- a/src/controls.rs +++ b/src/controls.rs @@ -1,6 +1,6 @@ -use serde::{Serialize, Deserialize}; +use serde::{Serialize, Deserialize, Deserializer, de}; use serde_json::{Value, json}; use specs::Entity; use crate::{PlayerId, Pos}; @@ -17,20 +17,6 @@ pub enum Direction { } impl Direction { - fn from_json(val: &Value) -> Option<Direction>{ - match val { - Value::String(txt) => match txt.as_str() { - "north" => Some(Direction::North), - "south" => Some(Direction::South), - "east" => Some(Direction::East), - "west"=> Some(Direction::West), - "" => Some(Direction::None), - _ => None - } - Value::Null => Some(Direction::None), - _ => None - } - } pub fn to_position(self) -> Pos { match self { @@ -55,14 +41,18 @@ pub enum Control { } +impl<'de> Deserialize<'de> for Control { + fn deserialize<D>(deserializer: D) -> Result<Self, D::Error> + where D: Deserializer<'de> { + let val = Value::deserialize(deserializer)?; + Self::from_json(&val).ok_or(de::Error::custom(format!("invalid control {:?}", val))) + } +} impl Control { - pub fn from_json(val: &Value) -> Option<Control>{ + fn from_json(val: &Value) -> Option<Control>{ if let Value::String(control_type) = val.get(0)? { match control_type.as_str() { - "move" => match Direction::from_json(val.get(1)?) { - Some(dir) => Some(Control::Move(dir)), - None => None - }, + "move" => Direction::deserialize(val.get(1)?).map(|dir| Control::Move(dir)).ok(), "take" => Some(Control::Take(val.get(1).unwrap_or(&json!(0)).as_u64().map(|idx| idx as usize))), "drop" => Some(Control::Drop(val.get(1)?.as_u64().unwrap_or(0) as usize)), "use" => Some({ @@ -102,7 +92,7 @@ impl Control { } fn parse_directions(val: &Value) -> Option<Vec<Direction>> { - val.as_array()?.into_iter().map(Direction::from_json).collect() + val.as_array()?.into_iter().map(|v|Direction::deserialize(v).ok()).collect() } #[derive(Debug, Clone)] diff --git a/src/gameserver.rs b/src/gameserver.rs index 5c20b13..7910d99 100644 --- a/src/gameserver.rs +++ b/src/gameserver.rs @@ -4,6 +4,7 @@ use std::collections::HashMap; use std::io; use serde_json::{Value, json}; +use serde::{Deserialize}; use unicode_categories::UnicodeCategories; use crate::{ @@ -180,7 +181,7 @@ impl GameServer { } Message::Input(inp) => { let player = self.players.get(&id).ok_or(merr!(action, "Set a name before you send any other messages"))?; - let control = Control::from_json(&inp).ok_or(merr!(action, &format!("unknown action: {}", inp)))?; + let control = Control::deserialize(&inp).map_err(|err| merr!(action, &format!("unknown action {} {}", inp, err)))?; Ok(Some(Action::Input(player.clone(), control))) } } diff --git a/src/item.rs b/src/item.rs index 4fdb4b8..2e14606 100644 --- a/src/item.rs +++ b/src/item.rs @@ -50,7 +50,7 @@ mod tests { use serde_json::json; #[test] - fn equip_from_json() { + fn equip_deserialise() { assert_eq!( ItemAction::deserialize(&json!({"equip": {"slot": "hand", "stats": {"strength": 10}}})).unwrap(), ItemAction::Equip(Equippable {slot: Slot::Hand, stats: hashmap!(Stat::Strength => 10), sprite: Option::None}) diff --git a/src/parameter.rs b/src/parameter.rs index 3667394..d3f7ace 100644 --- a/src/parameter.rs +++ b/src/parameter.rs @@ -67,7 +67,7 @@ macro_rules! parameters { parameters!( String (String) string, v (v.as_str().ok_or(perr!("{:?} not a string", v))?.to_string()) (json!(v)); Int (i64) int, v (v.as_i64().ok_or(perr!("{:?} not an int", v))?) (json!(v)); - Pos (Pos) pos, v (Pos::from_json(v).ok_or(perr!("{:?} not a pos", v))?) (json!(v)); + Pos (Pos) pos, v (Pos::deserialize(v).map_err(|e| perr!("{:?} not a pos {}", v, e))?) (json!(v)); Float (f64) float, v (v.as_f64().ok_or(perr!("{:?} not an float", v))?) (json!(v)); Template (Template) template, v (Template::deserialize(v).map_err(|e| perr!("template json error {:?}", e))?) (json!(["template", v])); Bool (bool) bool, v (v.as_bool().ok_or(perr!("{:?} not a bool", v))?) (json!(v)); @@ -1,7 +1,6 @@ use std::ops::{Add, Sub}; -use serde_json::Value; use serde::{Serialize, Serializer, Deserialize, Deserializer}; use crate::util::clamp; @@ -31,13 +30,6 @@ impl Pos { } } - pub fn from_json(val: &Value) -> Option<Self>{ - Some(Pos { - x: val.get(0)?.as_i64()?, - y: val.get(1)?.as_i64()? - }) - } - pub fn distance_to(&self, other: Pos) -> i64 { let d = other - *self; d.x.abs() + d.y.abs() |
