step/providers/slice/slice.go

55 lines
1.3 KiB
Go

package slice
import "reflect"
import "html/template"
import "git.tebibyte.media/sashakoshka/step"
const hiddenPrefix = "."
var _ step.FuncProvider = new(Provider)
// Provider provides slice functions.
type Provider struct {
}
// Package fulfills the step.Provider interface.
func (this *Provider) Package () string {
return "slice"
}
// FuncMap fulfills the step.FuncProvider interface.
func (this *Provider) FuncMap () template.FuncMap {
return template.FuncMap {
"list": funcList,
"append": funcAppend,
}
}
func funcList (items ...reflect.Value) (reflect.Value, error) {
if len(items) == 0 { return reflect.Value { }, nil }
ty := items[0].Type()
list := reflect.MakeSlice(ty, len(items), len(items))
for index, item := range items {
if item.Type().AssignableTo(ty) {
return reflect.Value { }, step.ErrTypeMismatch
}
dest := list.Index(index)
dest.Set(item)
}
return list, nil
}
func funcAppend (slice reflect.Value, items ...reflect.Value) (reflect.Value, error) {
if slice.Type().Kind() != reflect.Slice {
return reflect.Value { }, step.ErrTypeMismatch
}
if len(items) == 0 { return reflect.Value { }, nil }
ty := slice.Type().Elem()
end := slice.Len() + len(items)
list := reflect.MakeSlice(ty, end, end)
boundary := reflect.Copy(list, slice)
reflect.Copy(list.Slice(boundary, end), reflect.ValueOf(items))
return list, nil
}