summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authortroido <troido@protonmail.com>2020-05-19 15:06:45 +0200
committertroido <troido@protonmail.com>2020-05-19 15:06:45 +0200
commitdac89209fdde17e2e4fdf89768e814945a8cea62 (patch)
tree8713ca53fd85b1c88a9263197fa7306766747e19
parent0d382ea19f8f964c35761f6a3ff80bc9bfc25375 (diff)
better json parsing using serde_json::value::from_value
-rw-r--r--content/encyclopediae/default_encyclopedia.json19
-rw-r--r--content/encyclopediae/npcs.json19
-rw-r--r--src/assemblage.rs37
-rw-r--r--src/components/interactable.rs26
-rw-r--r--src/componentwrapper.rs3
-rw-r--r--src/controls.rs5
-rw-r--r--src/item.rs15
-rw-r--r--src/roomtemplate.rs2
8 files changed, 62 insertions, 64 deletions
diff --git a/content/encyclopediae/default_encyclopedia.json b/content/encyclopediae/default_encyclopedia.json
index 118b9cd..18cf967 100644
--- a/content/encyclopediae/default_encyclopedia.json
+++ b/content/encyclopediae/default_encyclopedia.json
@@ -90,25 +90,6 @@
["Interactable", {"action": ["interaction", ["say", "Good morning there, World"]]}]
]
},
- "dude": {
- "sprite": "human",
- "height": 1.5,
- "flags": ["Occupied"],
- "components": [
- ["Interactable", {"action": ["interaction", ["reply", "did you say '{}'?"]]}]
- ]
- },
- "trader": {
- "sprite": "human",
- "height": 1.5,
- "components": [
- ["Interactable", {"action": ["interaction", ["exchange", ["buy ", {
- "pebble": [["radish", "radish"], ["pebble"]],
- "radishseed": [["radish"], ["radishseed", "radishseed"]],
- "carrotseed": [["radish"], ["carrotseed"]]
- }]]]}]
- ]
- },
"quarry": {
"sprite": "quarry",
"height": 2,
diff --git a/content/encyclopediae/npcs.json b/content/encyclopediae/npcs.json
index cef6f0b..bfaa6fe 100644
--- a/content/encyclopediae/npcs.json
+++ b/content/encyclopediae/npcs.json
@@ -73,6 +73,25 @@
["Movable", {"cooldown": 3}],
["Faction", {"faction": "neutral"}]
]
+ },
+ "dude": {
+ "sprite": "human",
+ "height": 1.5,
+ "flags": ["Occupied"],
+ "components": [
+ ["Interactable", {"action": ["interaction", ["reply", "did you say '{}'?"]]}]
+ ]
+ },
+ "trader": {
+ "sprite": "human",
+ "height": 1.5,
+ "components": [
+ ["Interactable", {"action": ["interaction", ["exchange", ["buy ", {
+ "pebble": [["radish", "radish"], ["pebble"]],
+ "radishseed": [["radish"], ["radishseed", "radishseed"]],
+ "carrotseed": [["radish"], ["carrotseed"]]
+ }]]]}]
+ ]
}
}
}
diff --git a/src/assemblage.rs b/src/assemblage.rs
index 96e44e9..f9090db 100644
--- a/src/assemblage.rs
+++ b/src/assemblage.rs
@@ -1,6 +1,6 @@
use std::collections::HashMap;
-use serde_json::{Value, json};
+use serde_json::{Value, json, value};
use crate::{
componentparameter::ComponentParameter,
parameter::{Parameter, ParameterType},
@@ -53,14 +53,12 @@ impl Assemblage {
if let Some(name) = tup.as_str() {
components.push((ComponentType::from_str(name).ok_or(perr!("{} not a valid componenttype", name))?, HashMap::new()));
} else {
- let name = tup
- .get(0).ok_or(perr!("index 0 not in component"))?
- .as_str().ok_or(perr!("component name not a string"))?;
- let comptype = ComponentType::from_str(name).ok_or(perr!("{} not a valid componenttype", name))?;
+ let (name, params) = value::from_value::<(String, HashMap<String, Value>)>(tup.clone()).map_err(|e| perr!("invalid component definition: {:?}", e))?;
+ let comptype = ComponentType::from_str(&name).ok_or(perr!("{} not a valid componenttype", name))?;
let mut parameters: HashMap<String, ComponentParameter> = HashMap::new();
- for (key, value) in tup.get(1).ok_or(perr!("index 1 not in component"))?.as_object().ok_or(perr!("component parameters not a json object: {:?}", tup.get(1)))? {
- let param = ComponentParameter::from_json(value)?;
- parameters.insert(key.clone(), param);
+ for (key, value) in params.into_iter() {
+ let param = ComponentParameter::from_json(&value)?;
+ parameters.insert(key, param);
}
components.push((comptype, parameters));
}
@@ -118,25 +116,12 @@ impl Assemblage {
arguments: Self::parse_definition_arguments(val.get("arguments").unwrap_or(&json!([])))?,
components: Self::parse_definition_components(&json_components)?,
save: val.get("save").unwrap_or(&json!(true)).as_bool().ok_or(perr!("assemblage save not a bool"))?,
- extract: val
- .get("extract")
- .unwrap_or(&json!({}))
- .as_object().ok_or(perr!("assemblage extract not a bool"))?
+ extract: value::from_value::<HashMap<String, (ComponentType, String)>>(
+ val.get("extract").unwrap_or(&json!({})).clone()
+ ).map_err(|e| perr!("invalid assemblage extract: {:?}", e))?
.into_iter()
- .map(|(argname, val)| {
- Ok((
- argname.to_string(),
- ComponentType::from_str(
- val
- .get(0).ok_or(perr!("index 0 not in extract value"))?
- .as_str().ok_or(perr!("extract component name not a string"))?
- ).ok_or(perr!("extract invalid component name"))?,
- val.get(1)
- .ok_or(perr!("index 1 not in extract value"))?
- .as_str().ok_or(perr!("extract member name not a string"))?.to_string()
- ))
- })
- .collect::<PResult<Vec<(String, ComponentType, String)>>>()?
+ .map(|(name, (comp, field))| (name, comp, field))
+ .collect()
};
Ok(assemblage)
}
diff --git a/src/components/interactable.rs b/src/components/interactable.rs
index 757e27e..d97b742 100644
--- a/src/components/interactable.rs
+++ b/src/components/interactable.rs
@@ -1,5 +1,6 @@
use std::collections::HashMap;
+use serde_json;
use serde_json::{Value};
use specs::{
Component,
@@ -33,20 +34,17 @@ impl Interactable {
"trigger" => Trigger(Trigger::from_str(arg.as_str()?)?),
"say" => Say(arg.as_str()?.to_string()),
"reply" => Reply(arg.as_str()?.to_string()),
- "exchange" => Exchange(
- arg.get(0)?.as_str()?.to_string(),
- arg.get(1)?
- .as_object()?
- .iter()
- .map(|(id, ex)| {
- let exchange = Exchange {
- cost: ex.get(0)?.as_array()?.iter().map(|i| Some(ItemId(i.as_str()?.to_string()))).collect::<Option<Vec<ItemId>>>()?,
- offer: ex.get(1)?.as_array()?.iter().map(|i| Some(ItemId(i.as_str()?.to_string()))).collect::<Option<Vec<ItemId>>>()?
- };
- Some((id.clone(), exchange))
- })
- .collect::<Option<HashMap<String, Exchange>>>()?
- ),
+ "exchange" => {
+ let (prefix, change) = serde_json::value::from_value::<
+ (String, HashMap<String, (Vec<ItemId>, Vec<ItemId>)>)
+ >(arg.clone()).ok()?;
+ Exchange(
+ prefix,
+ change.into_iter().map(
+ |(id, (cost, offer))| (id, Exchange{cost, offer})
+ ).collect::<HashMap<String, Exchange>>()
+ )
+ },
"visit" => Visit(RoomId::from_str(arg.as_str()?)),
"mine" => Mine(Stat::from_str(arg.as_str()?)?),
_ => None?
diff --git a/src/componentwrapper.rs b/src/componentwrapper.rs
index ee2f22f..218c5c3 100644
--- a/src/componentwrapper.rs
+++ b/src/componentwrapper.rs
@@ -1,5 +1,6 @@
use std::collections::{HashMap, HashSet};
+use serde::Deserialize;
use specs::Builder;
use rand::Rng;
@@ -58,7 +59,7 @@ macro_rules! components {
}
}
}
- #[derive(Debug, PartialEq, Eq, Clone, Copy)]
+ #[derive(Debug, PartialEq, Eq, Clone, Copy, Deserialize)]
pub enum ComponentType {
$(
$comp,
diff --git a/src/controls.rs b/src/controls.rs
index 48d71ae..8f2c79c 100644
--- a/src/controls.rs
+++ b/src/controls.rs
@@ -1,15 +1,18 @@
+use serde::{Serialize, Deserialize};
use serde_json::{Value, json};
use specs::Entity;
use crate::{PlayerId, Pos};
-#[derive(Debug, Clone, Copy, PartialEq, Eq)]
+#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
+#[serde(rename_all="lowercase")]
pub enum Direction {
North,
South,
East,
West,
+ #[serde(rename="")]
None
}
diff --git a/src/item.rs b/src/item.rs
index e4dbb34..0e8661a 100644
--- a/src/item.rs
+++ b/src/item.rs
@@ -1,20 +1,31 @@
use std::collections::HashSet;
+use std::str::FromStr;
+use serde;
+use serde::Deserialize;
use serde_json::{Value};
use crate::{
Template,
components::{
Flag,
equipment::Equippable
- }
+ },
+ errors::{ParseError}
};
-#[derive(Debug, Default, PartialEq, Eq, Clone, Hash)]
+#[derive(Debug, Default, PartialEq, Eq, Clone, Hash, Deserialize)]
pub struct ItemId(pub String);
+impl FromStr for ItemId {
+ type Err = ParseError;
+ fn from_str(s: &str) -> Result<Self, Self::Err> {
+ Ok(Self(s.to_string()))
+ }
+}
+
#[derive(Debug, Clone)]
pub struct Item {
pub ent: Template,
diff --git a/src/roomtemplate.rs b/src/roomtemplate.rs
index 2614441..87c94fe 100644
--- a/src/roomtemplate.rs
+++ b/src/roomtemplate.rs
@@ -22,7 +22,7 @@ impl RoomTemplate {
pub fn from_json(jsonroom: &Value) -> PResult<RoomTemplate>{
let size = (
- jsonroom.get("width").ok_or(perr!("no with"))?.as_i64().ok_or(perr!("with not a number"))?,
+ jsonroom.get("width").ok_or(perr!("no width"))?.as_i64().ok_or(perr!("width not a number"))?,
jsonroom.get("height").ok_or(perr!("no height"))?.as_i64().ok_or(perr!("height not a number"))?
);
let spawn = Pos::from_json(jsonroom.get("spawn").ok_or(perr!("no spawn"))?).ok_or(perr!("spawn not a pos"))?;