summaryrefslogtreecommitdiff
path: root/src/template.rs
blob: c2f905f3b70d40dfb08a54627e599e37a6f5b3c7 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81


use std::collections::HashMap;
use serde_json::{json, Value};
use crate::{
	parameter::Parameter,
	PResult,
	perr
};

#[derive(Debug, PartialEq, Eq, Clone, Hash)]
pub struct EntityType(pub String);

#[derive(Debug, Clone, PartialEq)]
pub struct Template {
	pub name: EntityType,
	pub args: Vec<Parameter>,
	pub kwargs: HashMap<String, Parameter>,
	pub save: bool
}


impl Template {
	
	pub fn new(name: &str, kwargs: HashMap<String, Parameter>) -> Self {
		Self {
			name: EntityType(name.to_string()),
			args: Vec::new(),
			kwargs,
			save: true
		}
	}
	
	pub fn empty(name: &str) -> Self {
		Self::new(name, HashMap::new())
	}
	
	pub fn from_entity_type(typ: EntityType) -> Self {
		Self {
			name: typ,
			args: Vec::new(),
			kwargs: HashMap::new(),
			save: true
		}
	}
	
	pub fn unsaved(mut self) -> Self {
		self.save = false;
		self
	}
	
	pub fn from_json(val: &Value) -> PResult<Template> {
		if val.is_string(){
			return Ok(Self::empty(val.as_str().unwrap()));
		}
		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"))? {
			args.push(Parameter::guess_from_json(arg).ok_or(perr!("template arg not a parameter"))?);
		}
		let mut kwargs = HashMap::new();
		for (key, arg) in val.get("kwargs").unwrap_or(&json!({})).as_object().ok_or(perr!("template kwargs not a json object"))? {
			kwargs.insert(key.to_string(), Parameter::guess_from_json(arg).ok_or(perr!("template arg not a parameter"))?);
		}
		let save = val.get("save").unwrap_or(&json!(true)).as_bool().ok_or(perr!("save not a bool"))?;
		Ok(Template {name, args, kwargs, save})
	}
	
	pub fn to_json(&self) -> Value {
		if self.args.is_empty() && self.kwargs.is_empty() {
			return json!(self.name.0);
		}
		let jsonargs: Vec<Value> = self.args.iter().map(|a| a.to_json()).collect();
		let jsonkwargs: HashMap<&String, Value> = self.kwargs.iter().map(|(k, a)| (k, a.to_json())).collect();
		json!({
			"type": self.name.0,
			"args": jsonargs,
			"kwargs": jsonkwargs
		})
	}
}