providers/slice: Make the slice functions way better

This commit is contained in:
Sasha Koshka 2024-12-08 19:20:18 -05:00
parent 947cbc1440
commit deb3d7e935

View File

@ -1,6 +1,6 @@
package slice package slice
import "fmt" import "reflect"
import "html/template" import "html/template"
import "git.tebibyte.media/sashakoshka/step" import "git.tebibyte.media/sashakoshka/step"
@ -16,50 +16,34 @@ type Provider struct {
// FuncMap fulfills the step.FuncProvider interface. // FuncMap fulfills the step.FuncProvider interface.
func (this *Provider) FuncMap () template.FuncMap { func (this *Provider) FuncMap () template.FuncMap {
return template.FuncMap { return template.FuncMap {
"sAppend": funcSAppend, "list": funcList,
"iAppend": funcIAppend, "append": funcAppend,
"fAppend": funcFAppend,
} }
} }
func funcSAppend (slice any, addition string) []string { func funcList (items ...reflect.Value) (reflect.Value, error) {
switch slice := slice.(type) { if len(items) == 0 { return reflect.Value { }, nil }
case []string: ty := items[0].Type()
newSlice := make([]string, len(slice) + 1) list := reflect.MakeSlice(ty, len(items), len(items))
copy(newSlice, slice) for index, item := range items {
newSlice[len(slice)] = addition if item.Type().AssignableTo(ty) {
return newSlice return reflect.Value { }, step.ErrTypeMismatch
case string: }
return []string { slice, addition } dest := list.Index(index)
default: dest.Set(item)
return funcSAppend(fmt.Sprint(slice), addition)
} }
return list, nil
} }
func funcIAppend (slice any, addition int) []int { func funcAppend (slice reflect.Value, items ...reflect.Value) (reflect.Value, error) {
switch slice := slice.(type) { if slice.Type().Kind() != reflect.Slice {
case []int: return reflect.Value { }, step.ErrTypeMismatch
newSlice := make([]int, len(slice) + 1)
copy(newSlice, slice)
newSlice[len(slice)] = addition
return newSlice
case int:
return []int { slice, addition }
default:
return funcIAppend(0, addition)
}
}
func funcFAppend (slice any, addition float64) []float64 {
switch slice := slice.(type) {
case []float64:
newSlice := make([]float64, len(slice) + 1)
copy(newSlice, slice)
newSlice[len(slice)] = addition
return newSlice
case float64:
return []float64 { slice, addition }
default:
return funcFAppend(0, addition)
} }
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
} }