FEATURE: allow tuples to have true or false as field names.

this allows selects where the condiotion is a boolean and you can choose
the true or false branch.
This commit is contained in:
Jeremy Wall 2018-11-26 23:03:11 -06:00
parent 4305fe0bcd
commit fe4bb1c9d7
4 changed files with 30 additions and 4 deletions

View File

@ -212,9 +212,10 @@ Conditionals
UCG supports a limited conditional expression called a select. A select
expression starts with the `select` keyword and is followed by a an expression
resolving to a string naming the field to select, an expression resolving to
the default value, and finally a tuple literal to select the field from. If the
field selected is not in the tuple then the default value will be used.
resolving to a string or boolean naming the field to select, an expression
resolving to the default value, and finally a tuple literal to select the field
from. If the field selected is not in the tuple then the default value will be
used.
```
let want = "baz";
@ -230,6 +231,11 @@ select "quack", "quux", {
baz = "foo",
fuzz = "bang",
}; // result will be "quux"
let ifresult = select true, NULL, {
true = "true result",
false = "false result",
}; // result will be "true result"
```
Macros

View File

@ -37,4 +37,13 @@ assert |
|;
assert |
condmacro("invalid") == {output = NULL};
|;
let iflike = select true, "default", {
true = "I was true",
false = "I was false",
};
assert |
iflike == "I was true";
|;

View File

@ -1132,6 +1132,17 @@ impl<'a> Builder<'a> {
}
// Otherwise return the default.
return self.eval_expr(def_expr);
} else if let &Val::Boolean(b) = v.deref() {
for &(ref fname, ref val_expr) in fields.iter() {
if &fname.fragment == "true" && b {
// Fourth return the result of evaluating that field.
return self.eval_expr(val_expr);
} else if &fname.fragment == "false" && !b {
return self.eval_expr(val_expr);
}
}
// Otherwise return the default.
return self.eval_expr(def_expr);
} else {
return Err(Box::new(error::BuildError::new(
format!(

View File

@ -301,7 +301,7 @@ make_fn!(
make_fn!(
field_value<SliceIter<Token>, (Token, Expression)>,
do_each!(
field => wrap_err!(either!(match_type!(BAREWORD), match_type!(STR)),
field => wrap_err!(either!(match_type!(BOOLEAN), match_type!(BAREWORD), match_type!(STR)),
"Field names must be a bareword or a string."),
_ => punct!("="),
value => expression,