bashbrew/pkg/templatelib/lib.go

100 lines
2.8 KiB
Go

package templatelib
import (
"encoding/json"
"fmt"
"reflect"
"strings"
"text/template"
)
func swapStringsFuncBoolArgsOrder(a func(string, string) bool) func(string, string) bool {
return func(str1 string, str2 string) bool {
return a(str2, str1)
}
}
func thingsActionFactory(name string, actOnFirst bool, action func([]interface{}, interface{}) interface{}) func(args ...interface{}) interface{} {
return func(args ...interface{}) interface{} {
if len(args) < 1 {
panic(fmt.Sprintf(`%q requires at least one argument`, name))
}
actArgs := []interface{}{}
for _, val := range args {
v := reflect.ValueOf(val)
switch v.Kind() {
case reflect.Slice, reflect.Array:
for i := 0; i < v.Len(); i++ {
actArgs = append(actArgs, v.Index(i).Interface())
}
default:
actArgs = append(actArgs, v.Interface())
}
}
var arg interface{}
if actOnFirst {
arg = actArgs[0]
actArgs = actArgs[1:]
} else {
arg = actArgs[len(actArgs)-1]
actArgs = actArgs[:len(actArgs)-1]
}
return action(actArgs, arg)
}
}
func stringsActionFactory(name string, actOnFirst bool, action func([]string, string) string) func(args ...interface{}) interface{} {
return thingsActionFactory(name, actOnFirst, func(args []interface{}, arg interface{}) interface{} {
str := arg.(string)
strs := []string{}
for _, val := range args {
strs = append(strs, val.(string))
}
return action(strs, str)
})
}
func stringsModifierActionFactory(a func(string, string) string) func([]string, string) string {
return func(strs []string, str string) string {
for _, mod := range strs {
str = a(str, mod)
}
return str
}
}
// TODO write some tests for these
var FuncMap = template.FuncMap{
"hasPrefix": swapStringsFuncBoolArgsOrder(strings.HasPrefix),
"hasSuffix": swapStringsFuncBoolArgsOrder(strings.HasSuffix),
"ternary": func(truthy interface{}, falsey interface{}, val interface{}) interface{} {
if t, ok := template.IsTrue(val); !ok {
panic(fmt.Sprintf(`template.IsTrue(%+v) says things are NOT OK`, val))
} else if t {
return truthy
} else {
return falsey
}
},
"first": thingsActionFactory("first", true, func(args []interface{}, arg interface{}) interface{} { return arg }),
"last": thingsActionFactory("last", false, func(args []interface{}, arg interface{}) interface{} { return arg }),
"json": func(v interface{}) (string, error) {
j, err := json.Marshal(v)
return string(j), err
},
"join": stringsActionFactory("join", true, strings.Join),
"trimPrefixes": stringsActionFactory("trimPrefixes", false, stringsModifierActionFactory(strings.TrimPrefix)),
"trimSuffixes": stringsActionFactory("trimSuffixes", false, stringsModifierActionFactory(strings.TrimSuffix)),
"replace": stringsActionFactory("replace", false, func(strs []string, str string) string {
return strings.NewReplacer(strs...).Replace(str)
}),
}