summaryrefslogtreecommitdiff
path: root/src/componentparameter.rs
diff options
context:
space:
mode:
authortroido <troido@protonmail.com>2020-09-21 02:33:19 +0200
committertroido <troido@protonmail.com>2020-09-21 02:33:19 +0200
commit5ce9b012a7987f4085057f4f0b0af35e76810a7a (patch)
treea99418b5aec06d6be28e22150bce85d3c40b8ee7 /src/componentparameter.rs
parentb6a4c7b2d383755402e5e2c6f60d9a75a899b809 (diff)
parent455867294cc849bff2c0829a7464e71e79a0dcae (diff)
Merge branch 'interact' into master
Diffstat (limited to 'src/componentparameter.rs')
-rw-r--r--src/componentparameter.rs151
1 files changed, 0 insertions, 151 deletions
diff --git a/src/componentparameter.rs b/src/componentparameter.rs
deleted file mode 100644
index 333c6e1..0000000
--- a/src/componentparameter.rs
+++ /dev/null
@@ -1,151 +0,0 @@
-
-use std::collections::HashMap;
-use rand::Rng;
-use serde_json::Value;
-use crate::{
- parameter::{Parameter, ParameterType},
- Template,
- Result,
- aerr,
- PResult,
- perr
-};
-
-const MAX_NESTING: usize = 5;
-
-
-#[derive(Debug, PartialEq, Clone)]
-pub enum ComponentParameter {
- Constant(Parameter),
- Argument(String),
- Random(Vec<ComponentParameter>),
- Concat(Vec<ComponentParameter>),
- If(Box<ComponentParameter>, Box<ComponentParameter>, Box<ComponentParameter>),
- TemplateSelf,
- TemplateName
-}
-
-impl ComponentParameter {
-
- pub fn evaluate(&self, arguments: &HashMap<&str, Parameter>, template: &Template) -> Option<Parameter> {
- self.evaluate_(arguments, template, 0)
- }
-
- fn evaluate_(&self, arguments: &HashMap<&str, Parameter>, template: &Template, nesting: usize) -> Option<Parameter> {
- if nesting > MAX_NESTING {
- return None;
- }
- match self {
- Self::Constant(val) => {
- Some(val.clone())
- }
- Self::Argument(argname) => {
- Some(arguments.get(argname.as_str())?.clone())
- }
- Self::Random(options) => {
- let r = rand::thread_rng().gen_range(0, options.len());
- options[r].evaluate_(arguments, template, nesting + 1)
- }
- Self::Concat(options) => {
- let mut string = String::new();
- for option in options {
- if let Parameter::String(s) = option.evaluate_(arguments, template, nesting+1)? {
- string.push_str(&s);
- } else {
- return None;
- }
- }
- Some(Parameter::String(string))
- }
- Self::If(condition, thenval, elseval) => {
- if let Parameter::Bool(b) = condition.evaluate_(arguments, template, nesting+1)? {
- if b {
- thenval.evaluate_(arguments, template, nesting+1)
- } else {
- elseval.evaluate_(arguments, template, nesting+1)
- }
- } else {
- None
- }
- }
- Self::TemplateSelf => Some(Parameter::Template(template.clone())),
- Self::TemplateName => Some(Parameter::String(template.name.0.clone())),
-
- }
- }
-
- 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) {
- Ok(Self::Constant(Parameter::from_typed_json(paramtype, paramvalue).ok_or_else(||
- perr!("failed to parse parameter constant: {:?} {:?}", paramtype, paramvalue)
- )?))
- } else {
- match typename {
- "A" | "arg" => {
- let argname = paramvalue.as_str().ok_or(perr!("argument parameter not a string"))?.to_string();
- Ok(Self::Argument(argname))
- },
- "random" => {
- let optionvalues = paramvalue.as_array().ok_or(perr!("random argument not an array"))?;
- let mut options = Vec::new();
- for option in optionvalues {
- options.push(Self::from_json(option)?)
- }
- Ok(Self::Random(options))
- },
- "concat" => {
- let values = paramvalue.as_array().ok_or(perr!("concat argument not an array"))?;
- let mut options = Vec::new();
- for option in values {
- options.push(Self::from_json(option)?)
- }
- Ok(Self::Concat(options))
- },
- "if" => {
- Ok(Self::If(
- Box::new(Self::from_json(paramvalue.get(0).ok_or(perr!("if does not have condition"))?)?),
- Box::new(Self::from_json(paramvalue.get(1).ok_or(perr!("if does not have then value"))?)?),
- Box::new(Self::from_json(paramvalue.get(2).ok_or(perr!("if does not have else value"))?)?)
- ))
- }
- "self" => Ok(Self::TemplateSelf),
- "name" => Ok(Self::TemplateName),
- _ => Err(perr!("unknown compparam type '{}'", typename))
- }
- }
- }
-
- 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 {} 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 {
- if param.get_type(arguments)? != typ {
- return Err(aerr!("inconsistent parameter types in random"));
- }
- }
- typ
- },
- Self::If(condition, thenval, elseval) => {
- if condition.get_type(arguments)? != ParameterType::Bool {
- return Err(aerr!("if condition is not a bool"));
- }
- let typ: ParameterType = thenval.get_type(arguments)?;
- if elseval.get_type(arguments)? != typ {
- return Err(aerr!("inconsistent parameter types in if"));
- }
- typ
- },
- Self::Concat(_s) => ParameterType::String,
- Self::TemplateSelf => ParameterType::Template,
- Self::TemplateName => ParameterType::String
- })
- }
-}