diff options
Diffstat (limited to 'src')
| -rw-r--r-- | src/assemblage.rs | 2 | ||||
| -rw-r--r-- | src/componentparameter.rs | 5 | ||||
| -rw-r--r-- | src/componentwrapper.rs | 10 | ||||
| -rw-r--r-- | src/encyclopedia.rs | 23 | ||||
| -rw-r--r-- | src/parameter.rs | 7 | ||||
| -rw-r--r-- | src/savestate.rs | 2 | ||||
| -rw-r--r-- | src/template.rs | 15 |
7 files changed, 46 insertions, 18 deletions
diff --git a/src/assemblage.rs b/src/assemblage.rs index 8f36556..e453471 100644 --- a/src/assemblage.rs +++ b/src/assemblage.rs @@ -142,7 +142,7 @@ impl Assemblage { pub fn validate(&self) -> Result<()> { for (comptype, parameters) in &self.components { for (paramname, paramtype) in comptype.parameters() { - let param = parameters.get(paramname).ok_or(aerr!("missing parameter"))?; + let param = parameters.get(paramname).ok_or(aerr!("missing parameter {} in {:?}", paramname, self))?; let actualtype = param.get_type(&self.arguments)?; if actualtype != paramtype { return Err(aerr!("parameter type incorrect")); diff --git a/src/componentparameter.rs b/src/componentparameter.rs index 73c7b30..47c9a26 100644 --- a/src/componentparameter.rs +++ b/src/componentparameter.rs @@ -63,6 +63,9 @@ impl ComponentParameter { } pub fn from_json(value: &Value) -> PResult<Self> { + if !value.is_array() { + return Ok(Self::Constant(Parameter::guess_from_json(value).ok_or(perr!("invalid component parameter {:?}", value))?)); + } let paramvalue = value.get(1).ok_or(perr!("index 1 not in component parameter"))?; let typename = value.get(0).ok_or(perr!("index 0 not in component parameter"))?.as_str().ok_or(perr!("compparam type not a string"))?; if let Some(paramtype) = ParameterType::from_str(typename) { @@ -101,7 +104,7 @@ impl ComponentParameter { pub fn get_type(&self, arguments: &[(String, ParameterType, Option<Parameter>)]) -> Result<ParameterType>{ Ok(match self { Self::Constant(param) => param.paramtype(), - Self::Argument(argname) => arguments.iter().find(|(n, _t, _d)| n == argname).ok_or(aerr!("unknown argument name"))?.1, + Self::Argument(argname) => arguments.iter().find(|(n, _t, _d)| n == argname).ok_or(aerr!("unknown argument name {} in {:?}", argname, arguments))?.1, Self::Random(options) => { let typ: ParameterType = options.get(0).ok_or(aerr!("random has no options"))?.get_type(arguments)?; for param in options { diff --git a/src/componentwrapper.rs b/src/componentwrapper.rs index d00b592..4b9401a 100644 --- a/src/componentwrapper.rs +++ b/src/componentwrapper.rs @@ -189,18 +189,18 @@ components!( loot .iter() .map(|param| {match param { - Parameter::Template(template) => Some((template.clone(), 1.0)), + Parameter::Template(template) => Ok((template.clone(), 1.0)), Parameter::List(l) => { if l.len() == 2 { if let (Parameter::Template(template), Parameter::Float(chance)) = (l[0].clone(), l[1].clone()) { - return Some((template.clone(), chance)) + return Ok((template.clone(), chance)) } } - None? + Err(aerr!("loot list elements as list must only contain a template and a float: {:?}", l))? }, - _ => None? + _ => Err(aerr!("loot list elements must be a template or a list: {:?}", param))? }}) - .collect::<Option<Vec<(Template, f64)>>>().ok_or(aerr!("invalid loot definition"))? + .collect::<Result<Vec<(Template, f64)>>>()? } }; Grow ( diff --git a/src/encyclopedia.rs b/src/encyclopedia.rs index c378b84..d396e0f 100644 --- a/src/encyclopedia.rs +++ b/src/encyclopedia.rs @@ -12,7 +12,8 @@ use crate::{ item::Item, item::ItemAction, PResult, - perr + perr, + parameter::Parameter }; #[derive(Default, Clone)] @@ -79,6 +80,26 @@ impl Encyclopedia { Ok((id, item)) }) .collect::<PResult<HashMap<ItemId, Item>>>()?; + for (name, v) in + val + .get("templates") + .unwrap_or(&json!({})) + .as_object().ok_or(perr!("templates not a json dict: {:?}", val.get("templates")))? + .iter() { + let enttype = EntityType(v + .get(0).ok_or(perr!("index 0 not in subtitution template"))? + .as_str().ok_or(perr!("subtitution origin name not a string"))? + .to_string()); + let values = v.get(1).ok_or(perr!("index 0 not in subtitution template"))?; + let mut assemblage = assemblages.get(&enttype).ok_or(perr!("template name '{:?}' points not an assemblage", enttype))?.clone(); + for arg in assemblage.arguments.iter_mut() { + if let Some(x) = values.get(&arg.0) { + let param = Parameter::from_typed_json(arg.1, x).ok_or(perr!("subtitution parameter has wrong type"))?; + arg.2 = Some(param); + } + } + assemblages.insert(EntityType(name.to_string()), assemblage); + } Ok(Encyclopedia{ assemblages, diff --git a/src/parameter.rs b/src/parameter.rs index a7419ed..196f5fe 100644 --- a/src/parameter.rs +++ b/src/parameter.rs @@ -70,15 +70,15 @@ parameters!( Template (Template) template, v (Template::from_json(v).ok()?) (v.to_json()); Interaction (Interactable) interaction, _v (Interactable::from_json(_v)?) (panic!("interactions can't be serialized")); Bool (bool) bool, v (v.as_bool()?) (json!(v)); - List (Vec<Parameter>) list, _v + List (Vec<Parameter>) list, v ({ - _v + v .as_array()? .iter() .map(|item| Parameter::guess_from_json(item)) .collect::<Option<Vec<Parameter>>>()? }) - (panic!("can not serialise parameter list")); + (json!(["list", v.iter().map(Parameter::to_json).collect::<Vec<Value>>()])); ); @@ -108,7 +108,6 @@ impl Parameter { } else if val.is_object(){ ParameterType::Template } else { - println!("{:?}", val); return None }; Self::from_typed_json(typ, val) diff --git a/src/savestate.rs b/src/savestate.rs index 4482fca..c3b79cb 100644 --- a/src/savestate.rs +++ b/src/savestate.rs @@ -4,8 +4,6 @@ use serde_json::{json, Value}; use crate::{ Pos, Template, - Result, - aerr, PResult, perr }; diff --git a/src/template.rs b/src/template.rs index c2f905f..850a323 100644 --- a/src/template.rs +++ b/src/template.rs @@ -49,10 +49,17 @@ impl Template { self } - pub fn from_json(val: &Value) -> PResult<Template> { - if val.is_string(){ - return Ok(Self::empty(val.as_str().unwrap())); - } + pub fn from_json(v: &Value) -> PResult<Template> { + let val = match v { + Value::String(s) => json!({"type": s}), + Value::Array(_) => json!({ + "type": v.get(0).ok_or(perr!("index 0 not in template array {:?}", v))?, + "kwargs": v.get(1).ok_or(perr!("index 1 not in template array {:?}", v))? + }), + Value::Object(_) => v.clone(), + _ => Err(perr!("invalid template {:?}", v))? + }; + let name = EntityType(val.get("type").ok_or(perr!("template doesn't have 'type'"))?.as_str().ok_or(perr!("template type not a string"))?.to_string()); let mut args = Vec::new(); for arg in val.get("args").unwrap_or(&json!([])).as_array().ok_or(perr!("template args not an array"))? { |
