From 523a635dc88bc7890a0e1d3c062a8165259761d6 Mon Sep 17 00:00:00 2001 From: troido Date: Thu, 24 Sep 2020 09:38:18 +0200 Subject: don't try to read into the json data structure all manually --- src/template.rs | 95 +++++++++++++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 92 insertions(+), 3 deletions(-) (limited to 'src/template.rs') diff --git a/src/template.rs b/src/template.rs index 7422465..da758b6 100644 --- a/src/template.rs +++ b/src/template.rs @@ -2,23 +2,62 @@ use std::collections::HashMap; use serde_json::{json, Value}; +use serde::{Serialize, Deserialize}; + use crate::{ parameter::Parameter, PResult, perr }; -#[derive(Debug, PartialEq, Eq, Clone, Hash)] +#[derive(Debug, PartialEq, Eq, Clone, Hash, Serialize, Deserialize)] pub struct EntityType(pub String); -#[derive(Debug, Clone, Copy, Hash, PartialEq, Eq)] +#[derive(Debug, Clone, Copy, Hash, PartialEq, Eq, Serialize, Deserialize)] +#[serde(from="Option", into="Option")] pub enum SaveOption { Default, False, Always } -#[derive(Debug, Clone, PartialEq)] +impl From> for SaveOption { + fn from(b: Option) -> Self { + match b { + Some(true) => Self::Always, + Some(false) => Self::False, + None => Self::Default + } + } +} +impl Into> for SaveOption { + fn into(self) -> Option { + match self { + Self::Always => Some(true), + Self::False => Some(false), + Self::Default => None + } + } +} + +#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)] +#[serde(untagged)] +enum TemplateSave { + Name(EntityType), + Full{ + #[serde(rename = "type")] + name: EntityType, + #[serde(default, skip_serializing_if = "Vec::is_empty")] + args: Vec, + #[serde(default, skip_serializing_if = "HashMap::is_empty")] + kwargs: HashMap, + #[serde(default, skip_serializing_if = "Option::is_none")] + save: Option + } +} + +#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)] +#[serde(from="TemplateSave", into="TemplateSave")] pub struct Template { pub name: EntityType, pub args: Vec, @@ -27,6 +66,36 @@ pub struct Template { } +impl From for Template { + fn from(ts: TemplateSave) -> Self { + match ts { + TemplateSave::Name(name) => Self{name, args: Vec::new(), kwargs: HashMap::new(), save: SaveOption::Default}, + TemplateSave::Full{name, args, kwargs, save} => Self{name, args, kwargs, save: match save { + Some(true) => SaveOption::Always, + Some(false) => SaveOption::False, + None => SaveOption::Default + }} + } + } +} +impl Into for Template { + fn into(self) -> TemplateSave { + if self.args.is_empty() && self.kwargs.is_empty() && self.save == SaveOption::Default { + return TemplateSave::Name(self.name); + } + TemplateSave::Full { + name: self.name, + args: self.args, + kwargs: self.kwargs, + save: match self.save { + SaveOption::Always => Some(true), + SaveOption::False => Some(false), + SaveOption::Default => None + } + } + } +} + impl Template { pub fn new(name: &str, kwargs: HashMap) -> Self { @@ -121,3 +190,23 @@ impl Template { }) } } + +#[cfg(test)] +mod tests { + use super::*; + use crate::hashmap; + + + #[test] + fn template_from_string(){ + assert_eq!(Template::deserialize(json!("grass")).unwrap(), Template::empty("grass")); + } + + #[test] + fn template_with_kwarg(){ + assert_eq!( + Template::deserialize(json!({"type": "wall", "kwargs": {"health": 50}})).unwrap(), + Template::new("wall", hashmap!{"health".to_string() => Parameter::Int(50)}) + ); + } +} -- cgit