Use map[string]any for vars

This commit is contained in:
Elara 2023-11-01 12:00:44 -07:00
parent 38420f5c6a
commit 4530664371
4 changed files with 26 additions and 42 deletions

View File

@ -18,16 +18,13 @@
package salix package salix
import ( import "sync"
"reflect"
"sync"
)
// Namespace represents a collection of templates that can include each other // Namespace represents a collection of templates that can include each other
type Namespace struct { type Namespace struct {
mu sync.Mutex mu sync.Mutex
tmpls map[string]Template tmpls map[string]Template
vars map[string]reflect.Value vars map[string]any
tags map[string]Tag tags map[string]Tag
escapeHTML *bool escapeHTML *bool
@ -37,7 +34,7 @@ type Namespace struct {
func New() *Namespace { func New() *Namespace {
return &Namespace{ return &Namespace{
tmpls: map[string]Template{}, tmpls: map[string]Template{},
vars: map[string]reflect.Value{}, vars: map[string]any{},
tags: map[string]Tag{}, tags: map[string]Tag{},
} }
} }
@ -46,14 +43,7 @@ func New() *Namespace {
func (n *Namespace) WithVarMap(m map[string]any) *Namespace { func (n *Namespace) WithVarMap(m map[string]any) *Namespace {
n.mu.Lock() n.mu.Lock()
defer n.mu.Unlock() defer n.mu.Unlock()
n.vars = m
n.vars = map[string]reflect.Value{}
if m != nil {
for k, v := range m {
n.vars[k] = reflect.ValueOf(v)
}
}
return n return n
} }
@ -90,7 +80,7 @@ func (n *Namespace) GetTemplate(name string) (Template, bool) {
} }
// getVar tries to get a variable from the namespace's variable map // getVar tries to get a variable from the namespace's variable map
func (n *Namespace) getVar(name string) (reflect.Value, bool) { func (n *Namespace) getVar(name string) (any, bool) {
n.mu.Lock() n.mu.Lock()
defer n.mu.Unlock() defer n.mu.Unlock()
v, ok := n.vars[name] v, ok := n.vars[name]

View File

@ -24,7 +24,6 @@ import (
"io/fs" "io/fs"
"os" "os"
"path/filepath" "path/filepath"
"reflect"
"strings" "strings"
"go.elara.ws/salix/ast" "go.elara.ws/salix/ast"
@ -55,7 +54,7 @@ func (n *Namespace) ParseWithName(name string, r io.Reader) (Template, error) {
name: name, name: name,
ast: astVal.([]ast.Node), ast: astVal.([]ast.Node),
tags: map[string]Tag{}, tags: map[string]Tag{},
vars: map[string]reflect.Value{}, vars: map[string]any{},
} }
performWhitespaceMutations(t.ast) performWhitespaceMutations(t.ast)

View File

@ -61,18 +61,13 @@ type Template struct {
escapeHTML *bool escapeHTML *bool
tags map[string]Tag tags map[string]Tag
vars map[string]reflect.Value vars map[string]any
macros map[string][]ast.Node macros map[string][]ast.Node
} }
// WithVarMap returns a copy of the template with its variable map set to m. // WithVarMap returns a copy of the template with its variable map set to m.
func (t Template) WithVarMap(m map[string]any) Template { func (t Template) WithVarMap(m map[string]any) Template {
t.vars = map[string]reflect.Value{} t.vars = m
if m != nil {
for k, v := range m {
t.vars[k] = reflect.ValueOf(v)
}
}
return t return t
} }
@ -202,7 +197,7 @@ func (t *Template) getValue(node ast.Node, local map[string]any) (any, error) {
if err != nil { if err != nil {
return nil, err return nil, err
} }
return val.Interface(), nil return val, nil
case ast.String: case ast.String:
return node.Value, nil return node.Value, nil
case ast.Float: case ast.Float:
@ -253,11 +248,11 @@ func (t *Template) unwrapASTValue(node ast.Value, local map[string]any) (any, er
// getVar tries to get a variable from the local map. If it's not found, // getVar tries to get a variable from the local map. If it's not found,
// it'll try the global variable map. If it doesn't exist in either map, // it'll try the global variable map. If it doesn't exist in either map,
// it will return an error. // it will return an error.
func (t *Template) getVar(id ast.Ident, local map[string]any) (reflect.Value, error) { func (t *Template) getVar(id ast.Ident, local map[string]any) (any, error) {
if local != nil { if local != nil {
v, ok := local[id.Value] v, ok := local[id.Value]
if ok { if ok {
return reflect.ValueOf(v), nil return v, nil
} }
} }
@ -327,7 +322,7 @@ func (t *Template) execFuncCall(fc ast.FuncCall, local map[string]any) (any, err
if err != nil { if err != nil {
return nil, t.posError(fc, "%w: %s", ErrNoSuchFunc, fc.Name.Value) return nil, t.posError(fc, "%w: %s", ErrNoSuchFunc, fc.Name.Value)
} }
return t.execFunc(fn, fc, fc.Params, local) return t.execFunc(reflect.ValueOf(fn), fc, fc.Params, local)
} }
// getIndex tries to evaluate an ast.Index node by indexing the underlying value. // getIndex tries to evaluate an ast.Index node by indexing the underlying value.
@ -471,7 +466,7 @@ func (t *Template) evalVariableOr(vo ast.VariableOr, local map[string]any) (any,
if err != nil { if err != nil {
return t.getValue(vo.Or, local) return t.getValue(vo.Or, local)
} }
return val.Interface(), nil return val, nil
} }
func (t *Template) handleAssignment(a ast.Assignment, local map[string]any) error { func (t *Template) handleAssignment(a ast.Assignment, local map[string]any) error {

26
vars.go
View File

@ -23,19 +23,19 @@ import (
"strings" "strings"
) )
var globalVars = map[string]reflect.Value{ var globalVars = map[string]any{
"len": reflect.ValueOf(tmplLen), "len": tmplLen,
"toUpper": reflect.ValueOf(strings.ToUpper), "toUpper": strings.ToUpper,
"toLower": reflect.ValueOf(strings.ToLower), "toLower": strings.ToLower,
"hasPrefix": reflect.ValueOf(strings.HasPrefix), "hasPrefix": strings.HasPrefix,
"trimPrefix": reflect.ValueOf(strings.TrimPrefix), "trimPrefix": strings.TrimPrefix,
"hasSuffix": reflect.ValueOf(strings.HasSuffix), "hasSuffix": strings.HasSuffix,
"trimSuffix": reflect.ValueOf(strings.TrimSuffix), "trimSuffix": strings.TrimSuffix,
"trimSpace": reflect.ValueOf(strings.TrimSpace), "trimSpace": strings.TrimSpace,
"equalFold": reflect.ValueOf(strings.EqualFold), "equalFold": strings.EqualFold,
"count": reflect.ValueOf(strings.Count), "count": strings.Count,
"split": reflect.ValueOf(strings.Split), "split": strings.Split,
"join": reflect.ValueOf(strings.Join), "join": strings.Join,
} }
func tmplLen(v any) int { func tmplLen(v any) int {