diff options
| author | troido <troido@protonmail.com> | 2020-02-07 14:08:18 +0100 |
|---|---|---|
| committer | troido <troido@protonmail.com> | 2020-02-07 14:08:18 +0100 |
| commit | 70db58f688f0dbdd69231da570cf8dbb54e5ca81 (patch) | |
| tree | ab8d61357f17ebd30c15e7206dde110da0fd1579 | |
| parent | 45ed2cd201c79fae1c61a4f6f2982a9f5cfbceca (diff) | |
named stuff properly; added encyclopedia and template
| -rw-r--r-- | src/assemblage.rs | 303 | ||||
| -rw-r--r-- | src/assemblages.rs | 2 | ||||
| -rw-r--r-- | src/encyclopedia.rs | 41 | ||||
| -rw-r--r-- | src/main.rs | 25 | ||||
| -rw-r--r-- | src/oldassemblage.rs | 63 | ||||
| -rw-r--r-- | src/resources.rs | 2 | ||||
| -rw-r--r-- | src/room.rs | 4 | ||||
| -rw-r--r-- | src/systems/controlinput.rs | 10 | ||||
| -rw-r--r-- | src/template.rs | 267 |
9 files changed, 391 insertions, 326 deletions
diff --git a/src/assemblage.rs b/src/assemblage.rs index a81ce82..1e7eb44 100644 --- a/src/assemblage.rs +++ b/src/assemblage.rs @@ -1,63 +1,266 @@ +use std::collections::HashMap; +use serde_json::Value; +use super::componentparameter::ComponentParameter; +use super::parameter::{Parameter, ParameterType}; +use super::componentwrapper::{ComponentWrapper, ComponentType}; -use std::any::Any; - - -#[macro_export] -macro_rules! assemblage { - ($name:ident { $($arg:ident : $argt:ident ),* } ; $( $comp:expr ),* ) => { - #[derive(Debug, Clone, Default)] - pub struct $name {$( - pub $arg : $argt - )* } - impl Assemblage for $name { - fn build<'a>(&self, mut builder: specs::EntityBuilder<'a>) -> specs::EntityBuilder<'a>{ - $( - let $arg = &self.$arg; - )* - $( - builder = specs::Builder::with(builder, $comp); - )* - builder +#[derive(Debug, PartialEq)] +pub struct Assemblage { + pub arguments: Vec<(String, ParameterType, Option<Parameter>)>, + pub components: Vec<(ComponentType, HashMap<String, ComponentParameter>)> +} + +impl Assemblage { + + + fn parse_definition_arguments(args: &Value) -> Result<Vec<(String, ParameterType, Option<Parameter>)>, &'static str> { + let mut arguments: Vec<(String, ParameterType, Option<Parameter>)> = Vec::new(); + for arg in args.as_array().ok_or("arguments is not an array")? { + let tup = arg.as_array().ok_or("argument is not an array")?; + let key = tup.get(0).ok_or("argument has no name")?.as_str().ok_or("argument name is not a string")?.to_string(); + let typ = ParameterType::from_str(tup.get(1).ok_or("argument has no type")?.as_str().ok_or("argument type not a string")?).ok_or("failed to parse argument type")?; + let def = tup.get(2).ok_or("argument has no default")?; + if def.is_null() { + arguments.push((key.clone(), typ, None)); + } else { + arguments.push((key.clone(), typ, Some(Parameter::from_typed_json(typ, def).ok_or("invalid argument default")?))); } - - #[allow(unused_variables, unused_mut)] - fn init_from_json(&mut self, mut args: Vec<serde_json::Value>, kwargs: std::collections::HashMap<String, serde_json::Value>) { - $( - if args.len() > 0 { - let val = args.remove(0); - if let Some(actual_val) = super::unpack_json!($argt, val) { - self.$arg = actual_val; - } - } - )* - $( - if let Some(val) = kwargs.get(stringify!($arg)) { - if let Some(actual_val) = super::unpack_json!($argt, val) { - self.$arg = actual_val; - } - } - )* + } + Ok(arguments) + } + + fn parse_definition_components(comps: &Value) -> Result<Vec<(ComponentType, HashMap<String, ComponentParameter>)>, &'static str> { + let mut components = Vec::new(); + for tup in comps.as_array().ok_or("components is not a json array")? { + let comptype = ComponentType::from_str(tup + .get(0).ok_or("index 0 not in component")? + .as_str().ok_or("component name not a string")? + ).ok_or("not a valid componenttype")?; + let mut parameters: HashMap<String, ComponentParameter> = HashMap::new(); + for (key, value) in tup.get(1).ok_or("index 1 not in component")?.as_object().ok_or("component parameters not a json object")? { + let param = ComponentParameter::from_json(value)?; + parameters.insert(key.clone(), param); } + components.push((comptype, parameters)); } + Ok(components) + } + + fn validate(&self) -> Result<(), &'static str> { + for (comptype, parameters) in &self.components { + for (paramname, paramtype) in comptype.parameters() { + let param = parameters.get(paramname).ok_or("missing parameter")?; + let actualtype = param.get_type(&self.arguments)?; + if actualtype != paramtype { + return Err("parameter type incorrect"); + } + } + } + Ok(()) + } + + pub fn from_json(val: &Value) -> Result<Self, &'static str>{ + let assemblage = Self { + arguments: Self::parse_definition_arguments(val.get("arguments").ok_or("property 'arguments' not found")?)?, + components: Self::parse_definition_components(val.get("components").ok_or("property 'components' not found")?)? + }; + assemblage.validate()?; + Ok(assemblage) + } + + fn prepare_arguments(&self, args: &Vec<Parameter>, kwargs: &HashMap<String, Parameter>) -> Result<HashMap<&str, Parameter>, &str> { + let mut arguments: HashMap<&str, Parameter> = HashMap::new(); + for (idx, (name, typ, def)) in self.arguments.iter().enumerate() { + let value: Option<Parameter> = { + if let Some(val) = kwargs.get(name) { + Some(val.clone()) + } else if let Some(val) = args.get(idx) { + Some(val.clone()) + } else if let Some(val) = def { + Some(val.clone()) + } else { + None + } + }; + let param = value.ok_or("argument has no value")?; + if param.paramtype() != *typ { + return Err("argument has incorrect type"); + } + arguments.insert(name, param); + } + Ok(arguments) } -} -#[macro_export] -macro_rules! unpack_json { - (String, $val: ident) => { - if let Some(txt) = $val.as_str(){ - Some(txt.to_string()) - } else { - None + pub fn instantiate(&self, args: &Vec<Parameter>, kwargs: &HashMap<String, Parameter>) -> Result<Vec<ComponentWrapper>, &str>{ + let mut components: Vec<ComponentWrapper> = Vec::new(); + let arguments = self.prepare_arguments(args, kwargs)?; + for (comptype, compparams) in &self.components { + let mut compargs: HashMap<&str, Parameter> = HashMap::new(); + for (name, param) in compparams { + compargs.insert(name.as_str(), param.evaluate(&arguments).ok_or("argument not found")?); + } + components.push(ComponentWrapper::load_component(*comptype, compargs).ok_or("failed to load component")?); } + Ok(components) } } -pub trait Assemblage: Send + Sync + Any { - fn build<'a>(&self, builder: specs::EntityBuilder<'a>) -> specs::EntityBuilder<'a>; - fn init_from_json(&mut self, args: Vec<serde_json::Value>, kwargs: std::collections::HashMap<String, serde_json::Value>); -} - +#[cfg(test)] +mod tests { + use super::*; + use crate::hashmap; + use serde_json::json; + + + #[test] + fn empty_assemblage_from_json() { + assert_eq!( + Assemblage::from_json(&json!({ + "arguments": [], + "components": [] + })).unwrap(), + Assemblage{ + arguments: vec![], + components: vec![] + } + ); + } + + #[test] + fn grass_from_json(){ + let result = Assemblage::from_json(&json!({ + "arguments": [ + ["sprite", "string", "grass1"] + ], + "components": [ + ["Visible", { + "sprite": ["A", "sprite"], + "height": ["float", 0.1] + }] + ] + })).unwrap(); + let constructed = Assemblage{ + arguments: vec![("sprite".to_string(), ParameterType::String, Some(Parameter::String("grass1".to_string())))], + components: vec![ + (ComponentType::Visible, hashmap!( + "sprite".to_string() => ComponentParameter::Argument("sprite".to_string()), + "height".to_string() => ComponentParameter::Constant(Parameter::Float(0.1)) + )) + ] + }; + assert_eq!(result, constructed); + } + + #[test] + fn invalid_component_name(){ + let result = Assemblage::from_json(&json!({ + "arguments": [ + ["sprite", "string", null] + ], + "components": [ + ["visible", { // no capital so invalid + "sprite": ["A", "sprite"], + "height": ["float", 0.1] + }] + ] + })).unwrap_err(); + assert_eq!(result, "not a valid componenttype"); + } + + + + #[test] + fn invalid_parameter_type(){ + let result = Assemblage::from_json(&json!({ + "arguments": [ + ["sprite", "string", "grass1"] + ], + "components": [ + ["Visible", { + "sprite": ["A", "sprite"], + "height": ["string", "0.1"] + }] + ] + })).unwrap_err(); + assert_eq!(result, "parameter type incorrect"); + } + + #[test] + fn unknown_argument_name(){ + let result = Assemblage::from_json(&json!({ + "arguments": [ + ["sprite", "string", "grass1"] + ], + "components": [ + ["Visible", { + "sprite": ["A", "sprits"], + "height": ["float", 0.1] + }] + ] + })).unwrap_err(); + assert_eq!(result, "unknown argument name"); + } + + #[test] + fn wrong_argument_type(){ + let result = Assemblage::from_json(&json!({ + "arguments": [ + ["sprite", "int", 1] + ], + "components": [ + ["Visible", { + "sprite": ["A", "sprite"], + "height": ["float", 0.1] + }] + ] + })).unwrap_err(); + assert_eq!(result, "parameter type incorrect"); + } + + + + #[test] + fn wrong_argument_default(){ + let result = Assemblage::from_json(&json!({ + "arguments": [ + ["sprite", "string", 1] + ], + "components": [ + ["Visible", { + "sprite": ["A", "sprits"], + "height": ["float", 0.1] + }] + ] + })).unwrap_err(); + assert_eq!(result, "invalid argument default"); + } + + + #[test] + fn null_argument(){ + let result = Assemblage::from_json(&json!({ + "arguments": [ + ["sprite", "string", null] + ], + "components": [ + ["Visible", { + "sprite": ["A", "sprite"], + "height": ["float", 0.1] + }] + ] + })).unwrap(); + let constructed = Assemblage{ + arguments: vec![("sprite".to_string(), ParameterType::String, None)], + components: vec![ + (ComponentType::Visible, hashmap!( + "sprite".to_string() => ComponentParameter::Argument("sprite".to_string()), + "height".to_string() => ComponentParameter::Constant(Parameter::Float(0.1)) + )) + ] + }; + assert_eq!(result, constructed); + } +} diff --git a/src/assemblages.rs b/src/assemblages.rs index fc0831c..e8335f3 100644 --- a/src/assemblages.rs +++ b/src/assemblages.rs @@ -2,7 +2,7 @@ use rand::Rng; use super::components::{Visible, Blocking, Played}; use super::assemblage; -use super::assemblage::Assemblage; +use super::oldassemblage::Assemblage; assemblage!(Wall {}; Visible{sprite: "wall".to_string(), height: 2.0}, Blocking); diff --git a/src/encyclopedia.rs b/src/encyclopedia.rs new file mode 100644 index 0000000..17e9857 --- /dev/null +++ b/src/encyclopedia.rs @@ -0,0 +1,41 @@ + +use std::collections::HashMap; +use serde_json::Value; +use crate::assemblage::Assemblage; +use crate::componentwrapper::ComponentWrapper; +use crate::template::Template; + +#[derive(Default)] +pub struct Encyclopedia { + items: HashMap<String, Assemblage> +} + +impl Encyclopedia { + + pub fn new() -> Encyclopedia { + Encyclopedia { + items: HashMap::new() + } + } + + pub fn from_json(val: Value) -> Result<Encyclopedia, &'static str> { + let mut items = HashMap::new(); + for (k, v) in val.as_object().ok_or("encyclopedia not a json object")?.into_iter() { + items.insert(k.clone(), Assemblage::from_json(v)?); + } + Ok(Encyclopedia{items}) + } + + pub fn add_assemblage(&mut self, name: &str, assemblage: Assemblage) -> Result<(), &'static str> { + //todo: what if name exists + self.items.insert(name.to_string(), assemblage); + Ok(()) + } + + pub fn construct(&self, template: &Template) -> Result<Vec<ComponentWrapper>, &str> { + let assemblage = self.items.get(&template.name).ok_or("unknown assemblage name")?; + assemblage.instantiate(&template.args, &template.kwargs) + } + +} + diff --git a/src/main.rs b/src/main.rs index 1dda2d6..30ef0a4 100644 --- a/src/main.rs +++ b/src/main.rs @@ -3,7 +3,6 @@ use std::thread::sleep; use std::time::Duration; use std::path::Path; -use std::collections::HashMap; use serde_json::json; @@ -18,21 +17,22 @@ mod resources; mod systems; mod worldmessages; mod pos; -mod assemblage; -// mod load; +mod oldassemblage; mod componentwrapper; mod parameter; -mod template; +mod assemblage; mod componentparameter; +mod encyclopedia; +mod template; use self::gameserver::GameServer; use self::server::unixserver::UnixServer; use self::server::tcpserver::TcpServer; use self::server::Server; -use self::assemblages::{Grass}; use self::room::Room; use self::util::ToJson; -use self::template::{Template}; +use self::encyclopedia::Encyclopedia; +use self::template::Template; @@ -68,8 +68,8 @@ fn main() { fn gen_room<'a, 'b>(width: i32, height: i32) -> Room<'a, 'b> { let mut room = Room::new((width, height)); let assemblages = default_assemblages(); - let wall = assemblages["wall"].instantiate(Vec::new(), HashMap::new()).unwrap(); - let grass = &assemblages["grass"]; + let wall = assemblages.construct(&Template::empty("wall")).unwrap(); +// let grass = &assemblages["grass"]; for x in 0..width { room.add_complist(&wall, (x, 0)); room.add_complist(&wall, (x, height - 1)); @@ -80,14 +80,15 @@ fn gen_room<'a, 'b>(width: i32, height: i32) -> Room<'a, 'b> { } for x in 1..width-1 { for y in 1..height-1 { - room.add_complist(&grass.instantiate(Vec::new(), HashMap::new()).unwrap(), (x, y)); + let grass = assemblages.construct(&Template::empty("grass")).unwrap(); + room.add_complist(&grass, (x, y)); //&grass.instantiate(&Vec::new(), &HashMap::new()).unwrap(), (x, y)); } } room } -fn default_assemblages() -> HashMap<String, Template> { - json!({ +fn default_assemblages() -> Encyclopedia { + Encyclopedia::from_json(json!({ "wall": { "arguments": [], "components": [ @@ -115,6 +116,6 @@ fn default_assemblages() -> HashMap<String, Template> { }] ] } - }).as_object().unwrap().into_iter().map(|(k, v)| (k.clone(), Template::from_json(v).unwrap())).collect() + })).unwrap() } diff --git a/src/oldassemblage.rs b/src/oldassemblage.rs new file mode 100644 index 0000000..a81ce82 --- /dev/null +++ b/src/oldassemblage.rs @@ -0,0 +1,63 @@ + + +use std::any::Any; + + +#[macro_export] +macro_rules! assemblage { + ($name:ident { $($arg:ident : $argt:ident ),* } ; $( $comp:expr ),* ) => { + #[derive(Debug, Clone, Default)] + pub struct $name {$( + pub $arg : $argt + )* } + impl Assemblage for $name { + fn build<'a>(&self, mut builder: specs::EntityBuilder<'a>) -> specs::EntityBuilder<'a>{ + $( + let $arg = &self.$arg; + )* + $( + builder = specs::Builder::with(builder, $comp); + )* + builder + } + + #[allow(unused_variables, unused_mut)] + fn init_from_json(&mut self, mut args: Vec<serde_json::Value>, kwargs: std::collections::HashMap<String, serde_json::Value>) { + $( + if args.len() > 0 { + let val = args.remove(0); + if let Some(actual_val) = super::unpack_json!($argt, val) { + self.$arg = actual_val; + } + } + )* + $( + if let Some(val) = kwargs.get(stringify!($arg)) { + if let Some(actual_val) = super::unpack_json!($argt, val) { + self.$arg = actual_val; + } + } + )* + } + } + } +} + +#[macro_export] +macro_rules! unpack_json { + (String, $val: ident) => { + if let Some(txt) = $val.as_str(){ + Some(txt.to_string()) + } else { + None + } + } +} + + +pub trait Assemblage: Send + Sync + Any { + fn build<'a>(&self, builder: specs::EntityBuilder<'a>) -> specs::EntityBuilder<'a>; + fn init_from_json(&mut self, args: Vec<serde_json::Value>, kwargs: std::collections::HashMap<String, serde_json::Value>); +} + + diff --git a/src/resources.rs b/src/resources.rs index e8b4059..1fc4c17 100644 --- a/src/resources.rs +++ b/src/resources.rs @@ -4,7 +4,7 @@ use specs::Entity; use super::pos::Pos; use super::controls::Action; -use super::assemblage::Assemblage; +use super::oldassemblage::Assemblage; use super::worldmessages::WorldMessage; diff --git a/src/room.rs b/src/room.rs index f7e09bf..dc2c683 100644 --- a/src/room.rs +++ b/src/room.rs @@ -13,7 +13,7 @@ use specs::{ use super::controls::Action; use super::pos::Pos; use super::components::Position; -use super::assemblage::Assemblage; +use super::oldassemblage::Assemblage as OldAssemblage; use super::worldmessages::WorldMessage; use super::resources::{ Size, @@ -80,7 +80,7 @@ impl <'a, 'b>Room<'a, 'b> { self.world.fetch_mut::<Input>().actions = actions; } - pub fn add_obj(&mut self, template: &dyn Assemblage, (x, y): (i32, i32)) -> Entity { + pub fn add_obj(&mut self, template: &dyn OldAssemblage, (x, y): (i32, i32)) -> Entity { template.build(self.world.create_entity()).with(Position::new(Pos{x, y})).build() } diff --git a/src/systems/controlinput.rs b/src/systems/controlinput.rs index 6d07bc5..2de9d29 100644 --- a/src/systems/controlinput.rs +++ b/src/systems/controlinput.rs @@ -11,25 +11,25 @@ use specs::{ Join }; -use super::super::pos::Pos; +use crate::pos::Pos; -use super::super::components::{ +use crate::components::{ Controller, Played }; -use super::super::controls::{ +use crate::controls::{ Control, Action }; -use super::super::resources::{ +use crate::resources::{ Input, NewEntities }; -use super::super::assemblages::Player; +use crate::assemblages::Player; pub struct ControlInput; diff --git a/src/template.rs b/src/template.rs index bdf86b3..51bba8b 100644 --- a/src/template.rs +++ b/src/template.rs @@ -1,266 +1,23 @@ + use std::collections::HashMap; -use serde_json::Value; -use super::componentparameter::ComponentParameter; -use super::parameter::{Parameter, ParameterType}; -use super::componentwrapper::{ComponentWrapper, ComponentType}; +use crate::parameter::Parameter; -#[derive(Debug, PartialEq)] +#[derive(Debug)] pub struct Template { - pub arguments: Vec<(String, ParameterType, Option<Parameter>)>, - pub components: Vec<(ComponentType, HashMap<String, ComponentParameter>)> + pub name: String, + pub args: Vec<Parameter>, + pub kwargs: HashMap<String, Parameter> } -impl Template { - - fn parse_definition_arguments(args: &Value) -> Result<Vec<(String, ParameterType, Option<Parameter>)>, &'static str> { - let mut arguments: Vec<(String, ParameterType, Option<Parameter>)> = Vec::new(); - for arg in args.as_array().ok_or("arguments is not an array")? { - let tup = arg.as_array().ok_or("argument is not an array")?; - let key = tup.get(0).ok_or("argument has no name")?.as_str().ok_or("argument name is not a string")?.to_string(); - let typ = ParameterType::from_str(tup.get(1).ok_or("argument has no type")?.as_str().ok_or("argument type not a string")?).ok_or("failed to parse argument type")?; - let def = tup.get(2).ok_or("argument has no default")?; - if def.is_null() { - arguments.push((key.clone(), typ, None)); - } else { - arguments.push((key.clone(), typ, Some(Parameter::from_typed_json(typ, def).ok_or("invalid argument default")?))); - } - } - Ok(arguments) - } - - fn parse_definition_components(comps: &Value) -> Result<Vec<(ComponentType, HashMap<String, ComponentParameter>)>, &'static str> { - let mut components = Vec::new(); - for tup in comps.as_array().ok_or("components is not a json array")? { - let comptype = ComponentType::from_str(tup - .get(0).ok_or("index 0 not in component")? - .as_str().ok_or("component name not a string")? - ).ok_or("not a valid componenttype")?; - let mut parameters: HashMap<String, ComponentParameter> = HashMap::new(); - for (key, value) in tup.get(1).ok_or("index 1 not in component")?.as_object().ok_or("component parameters not a json object")? { - let param = ComponentParameter::from_json(value)?; - parameters.insert(key.clone(), param); - } - components.push((comptype, parameters)); - } - Ok(components) - } - - fn validate(&self) -> Result<(), &'static str> { - for (comptype, parameters) in &self.components { - for (paramname, paramtype) in comptype.parameters() { - let param = parameters.get(paramname).ok_or("missing parameter")?; - let actualtype = param.get_type(&self.arguments)?; - if actualtype != paramtype { - return Err("parameter type incorrect"); - } - } - } - Ok(()) - } - - pub fn from_json(val: &Value) -> Result<Template, &'static str>{ - let template = Template { - arguments: Self::parse_definition_arguments(val.get("arguments").ok_or("property 'arguments' not found")?)?, - components: Self::parse_definition_components(val.get("components").ok_or("property 'components' not found")?)? - }; - template.validate()?; - Ok(template) - } +impl Template { - fn prepare_arguments(&self, args: Vec<Parameter>, kwargs: HashMap<String, Parameter>) -> Result<HashMap<&str, Parameter>, &str> { - let mut arguments: HashMap<&str, Parameter> = HashMap::new(); - for (idx, (name, typ, def)) in self.arguments.iter().enumerate() { - let value: Option<Parameter> = { - if let Some(val) = kwargs.get(name) { - Some(val.clone()) - } else if let Some(val) = args.get(idx) { - Some(val.clone()) - } else if let Some(val) = def { - Some(val.clone()) - } else { - None - } - }; - let param = value.ok_or("argument has no value")?; - if param.paramtype() != *typ { - return Err("argument has incorrect type"); - } - arguments.insert(name, param); - } - Ok(arguments) - } - - pub fn instantiate(&self, args: Vec<Parameter>, kwargs: HashMap<String, Parameter>) -> Result<Vec<ComponentWrapper>, &str>{ - let mut components: Vec<ComponentWrapper> = Vec::new(); - let arguments = self.prepare_arguments(args, kwargs)?; - for (comptype, compparams) in &self.components { - let mut compargs: HashMap<&str, Parameter> = HashMap::new(); - for (name, param) in compparams { - compargs.insert(name.as_str(), param.evaluate(&arguments).ok_or("argument not found")?); - } - components.push(ComponentWrapper::load_component(*comptype, compargs).ok_or("failed to load component")?); + pub fn empty(name: &str) -> Self { + Self { + name: name.to_string(), + args: Vec::new(), + kwargs: HashMap::new() } - Ok(components) - } -} - - - -#[cfg(test)] -mod tests { - use super::*; - use crate::hashmap; - use serde_json::json; - - - #[test] - fn empty_template_from_json() { - assert_eq!( - Template::from_json(&json!({ - "arguments": [], - "components": [] - })).unwrap(), - Template{ - arguments: vec![], - components: vec![] - } - ); - } - - #[test] - fn grass_from_json(){ - let result = Template::from_json(&json!({ - "arguments": [ - ["sprite", "string", "grass1"] - ], - "components": [ - ["Visible", { - "sprite": ["A", "sprite"], - "height": ["float", 0.1] - }] - ] - })).unwrap(); - let constructed = Template{ - arguments: vec![("sprite".to_string(), ParameterType::String, Some(Parameter::String("grass1".to_string())))], - components: vec![ - (ComponentType::Visible, hashmap!( - "sprite".to_string() => ComponentParameter::Argument("sprite".to_string()), - "height".to_string() => ComponentParameter::Constant(Parameter::Float(0.1)) - )) - ] - }; - assert_eq!(result, constructed); - } - - #[test] - fn invalid_component_name(){ - let result = Template::from_json(&json!({ - "arguments": [ - ["sprite", "string", null] - ], - "components": [ - ["visible", { // no capital so invalid - "sprite": ["A", "sprite"], - "height": ["float", 0.1] - }] - ] - })).unwrap_err(); - assert_eq!(result, "not a valid componenttype"); - } - - - - #[test] - fn invalid_parameter_type(){ - let result = Template::from_json(&json!({ - "arguments": [ - ["sprite", "string", "grass1"] - ], - "components": [ - ["Visible", { - "sprite": ["A", "sprite"], - "height": ["string", "0.1"] - }] - ] - })).unwrap_err(); - assert_eq!(result, "parameter type incorrect"); - } - - #[test] - fn unknown_argument_name(){ - let result = Template::from_json(&json!({ - "arguments": [ - ["sprite", "string", "grass1"] - ], - "components": [ - ["Visible", { - "sprite": ["A", "sprits"], - "height": ["float", 0.1] - }] - ] - })).unwrap_err(); - assert_eq!(result, "unknown argument name"); - } - - #[test] - fn wrong_argument_type(){ - let result = Template::from_json(&json!({ - "arguments": [ - ["sprite", "int", 1] - ], - "components": [ - ["Visible", { - "sprite": ["A", "sprite"], - "height": ["float", 0.1] - }] - ] - })).unwrap_err(); - assert_eq!(result, "parameter type incorrect"); - } - - - - #[test] - fn wrong_argument_default(){ - let result = Template::from_json(&json!({ - "arguments": [ - ["sprite", "string", 1] - ], - "components": [ - ["Visible", { - "sprite": ["A", "sprits"], - "height": ["float", 0.1] - }] - ] - })).unwrap_err(); - assert_eq!(result, "invalid argument default"); - } - - - #[test] - fn null_argument(){ - let result = Template::from_json(&json!({ - "arguments": [ - ["sprite", "string", null] - ], - "components": [ - ["Visible", { - "sprite": ["A", "sprite"], - "height": ["float", 0.1] - }] - ] - })).unwrap(); - let constructed = Template{ - arguments: vec![("sprite".to_string(), ParameterType::String, None)], - components: vec![ - (ComponentType::Visible, hashmap!( - "sprite".to_string() => ComponentParameter::Argument("sprite".to_string()), - "height".to_string() => ComponentParameter::Constant(Parameter::Float(0.1)) - )) - ] - }; - assert_eq!(result, constructed); } } |
