Support for default values ${var=default} in interpolation variables.

This commit is contained in:
Alec Thomas
2019-09-24 13:33:20 +10:00
parent f7d3d9bfb5
commit 9a1f499155
3 changed files with 13 additions and 10 deletions
+3 -2
View File
@@ -416,10 +416,11 @@ default values.
Variables are in the form: Variables are in the form:
${<name>} ${<name>}
${<name>=<default>}
Variables are set with the `Vars{"key": "value", ...}` option. Undefined Variables are set with the `Vars{"key": "value", ...}` option. Undefined
variable references in the grammar will result in an error at construction variable references in the grammar without a default will result in an error at
time. construction time.
Variables can also be set via the `set:"K=V"` tag. In this case, those variables will be available for that Variables can also be set via the `set:"K=V"` tag. In this case, those variables will be available for that
node and all children. This is useful for composition by allowing the same struct to be reused. node and all children. This is useful for composition by allowing the same struct to be reused.
+7 -4
View File
@@ -5,19 +5,22 @@ import (
"regexp" "regexp"
) )
var interpolationRegex = regexp.MustCompile(`(\${[[:alpha:]_][[:word:]]*})|(\$)|([^$]+)`) var interpolationRegex = regexp.MustCompile(`((?:\${([[:alpha:]_][[:word:]]*))(?:=([^}]+))?})|(\$)|([^$]+)`)
// Interpolate variables from vars into s for substrings in the form ${var}. // Interpolate variables from vars into s for substrings in the form ${var} or ${var=default}.
func interpolate(s string, vars map[string]string) (string, error) { func interpolate(s string, vars map[string]string) (string, error) {
out := "" out := ""
matches := interpolationRegex.FindAllStringSubmatch(s, -1) matches := interpolationRegex.FindAllStringSubmatch(s, -1)
for _, match := range matches { for _, match := range matches {
if match[1] != "" { if name := match[2]; name != "" {
name := match[1][2 : len(match[1])-1]
value, ok := vars[name] value, ok := vars[name]
if !ok { if !ok {
// No default value.
if match[3] == "" {
return "", fmt.Errorf("undefined variable ${%s}", name) return "", fmt.Errorf("undefined variable ${%s}", name)
} }
value = match[3]
}
out += value out += value
} else { } else {
out += match[0] out += match[0]
+1 -2
View File
@@ -8,10 +8,9 @@ import (
func TestInterpolate(t *testing.T) { func TestInterpolate(t *testing.T) {
vars := map[string]string{ vars := map[string]string{
"name": "Bobby Brown",
"age": "35", "age": "35",
} }
actual, err := interpolate("${name} is ${age} years old", vars) actual, err := interpolate("${name=Bobby Brown} is ${age} years old", vars)
require.NoError(t, err) require.NoError(t, err)
require.Equal(t, `Bobby Brown is 35 years old`, actual) require.Equal(t, `Bobby Brown is 35 years old`, actual)
} }