Add index to map iteration
This commit is contained in:
parent
4501ef63d6
commit
d91eef09bf
32
for_tag.go
32
for_tag.go
@ -1,6 +1,7 @@
|
||||
package salix
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"reflect"
|
||||
|
||||
"go.elara.ws/salix/ast"
|
||||
@ -10,35 +11,27 @@ import (
|
||||
type forTag struct{}
|
||||
|
||||
func (ft forTag) Run(tc *TagContext, block, args []ast.Node) error {
|
||||
if len(args) == 0 || len(args) > 2 {
|
||||
if len(args) == 0 || len(args) > 3 {
|
||||
return tc.PosError(tc.Tag, "invalid argument amount")
|
||||
}
|
||||
|
||||
var expr ast.Expr
|
||||
if len(args) == 1 {
|
||||
expr2, ok := args[0].(ast.Expr)
|
||||
expr, ok := args[len(args)-1].(ast.Expr)
|
||||
if !ok {
|
||||
return tc.PosError(args[0], "invalid argument type: %T (expected ast.Expr)", args[0])
|
||||
}
|
||||
expr = expr2
|
||||
} else if len(args) == 2 {
|
||||
expr2, ok := args[1].(ast.Expr)
|
||||
if !ok {
|
||||
return tc.PosError(args[1], "invalid argument type: %T (expected ast.Expr)", args[1])
|
||||
}
|
||||
expr = expr2
|
||||
}
|
||||
|
||||
var vars []string
|
||||
var in reflect.Value
|
||||
|
||||
if len(args) == 2 {
|
||||
varName, ok := unwrap(args[0]).(ast.Ident)
|
||||
if len(args) > 1 {
|
||||
for _, arg := range args[:len(args)-1] {
|
||||
varName, ok := unwrap(arg).(ast.Ident)
|
||||
if !ok {
|
||||
return tc.PosError(args[0], "invalid argument type: %T (expected ast.Ident)", expr.First)
|
||||
return tc.PosError(arg, "invalid argument type: %T (expected ast.Ident)", expr.First)
|
||||
}
|
||||
vars = append(vars, varName.Value)
|
||||
}
|
||||
}
|
||||
|
||||
varName, ok := unwrap(expr.First).(ast.Ident)
|
||||
if !ok {
|
||||
@ -70,6 +63,8 @@ func (ft forTag) Run(tc *TagContext, block, args []ast.Node) error {
|
||||
} else if len(vars) == 2 {
|
||||
local[vars[0]] = i
|
||||
local[vars[1]] = in.Index(i).Interface()
|
||||
} else {
|
||||
return errors.New("slices and arrays can only use two for loop variables")
|
||||
}
|
||||
|
||||
err = tc.Execute(block, local)
|
||||
@ -80,18 +75,25 @@ func (ft forTag) Run(tc *TagContext, block, args []ast.Node) error {
|
||||
case reflect.Map:
|
||||
local := map[string]any{}
|
||||
iter := in.MapRange()
|
||||
i := 0
|
||||
for iter.Next() {
|
||||
if len(vars) == 1 {
|
||||
local[vars[0]] = iter.Value().Interface()
|
||||
} else if len(vars) == 2 {
|
||||
local[vars[0]] = iter.Key().Interface()
|
||||
local[vars[1]] = iter.Value().Interface()
|
||||
} else if len(vars) == 3 {
|
||||
local[vars[0]] = i
|
||||
local[vars[1]] = iter.Key().Interface()
|
||||
local[vars[2]] = iter.Value().Interface()
|
||||
}
|
||||
|
||||
err = tc.Execute(block, local)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
i++
|
||||
}
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user