You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
As generics don't seem to be supported by text/template yet I produced the following: (Or does anyone know what other library I should be looking at?)
Would something like this be accepted into the project?
package main
import (
"errors""fmt""os""reflect""text/template"
)
var (
ErrInputFuncMustTake0or1Arguments=errors.New("expected second parameter function to take 0 or 1 parameters")
ErrExpectedFirstParameterToBeSlice=errors.New("expected first parameter to be an slice")
ErrExpected2ndArgumentToBeFunction=errors.New("expected second parameter to be a function")
ErrExpectedSecondReturnToBeError=errors.New("expected second return type to be assignable to error")
ErrExpectedSecondArgumentToBeFunction=errors.New("expected second return of function f to take 1 or 2 parameters instead")
ErrExpected2ReturnTypes=errors.New("expected return with 1 or 2 arguments of types (any, error?)")
)
funcMapTemplateFunc(arrayany, fany) (any, error) {
av:=reflect.ValueOf(array)
ifav.Kind() !=reflect.Slice {
returnarray, fmt.Errorf("%w not %s", ErrExpectedFirstParameterToBeSlice, av.Kind())
}
fv:=reflect.ValueOf(f)
iffv.Kind() !=reflect.Func {
returnarray, ErrExpected2ndArgumentToBeFunction
}
varfvfpt reflect.Typeswitchfv.Type().NumIn() {
case0:
case1:
fvfpt=fv.Type().In(0)
default:
returnarray, ErrInputFuncMustTake0or1Arguments
}
varfvfrt reflect.Typeswitchfv.Type().NumOut() {
case1:
fvfrt=fv.Type().Out(0)
case2:
fvsrt:=fv.Type().Out(1)
if!fvsrt.AssignableTo(reflect.TypeOf(error(nil))) {
returnarray, fmt.Errorf("%w instead got: %s", ErrExpectedSecondReturnToBeError, fvsrt)
}
default:
returnarray, fmt.Errorf("%w got: %d", ErrExpectedSecondArgumentToBeFunction, fv.Type().NumOut())
}
l:=av.Len()
ra:=make([]reflect.Value, l)
varnewType reflect.Type=fvfrttoan:=reflect.TypeOf(any(nil))
fori:=0; i<l; i++ {
varr []reflect.Valueswitchfv.Type().NumIn() {
case1:
iffvfpt!=nil {
ev:=av.Index(i)
if!ev.Type().AssignableTo(fvfpt) {
returnnil, fmt.Errorf("item %d not assignable to: %s", i, fvfpt)
}
r=fv.Call([]reflect.Value{ev})
break
}
fallthroughcase0:
r=fv.Call([]reflect.Value{})
default:
returnarray, ErrInputFuncMustTake0or1Arguments
}
ifr==nil {
continue
}
iflen(r) !=1&&len(r) !=2 {
returnarray, fmt.Errorf("f execution number %d returned: %d results %w", i, len(r), ErrExpected2ReturnTypes)
}
iflen(r) ==2&&!r[1].IsNil() {
returnnil, fmt.Errorf("f execution number %d returned: %w", i, r[1].Interface().(error))
}
rt:=reflect.TypeOf(r[0])
ifnewType==nil {
newType=rt
} elseifrt!=newType&&!rt.AssignableTo(newType) {
rt=toan
}
ra[i] =r[0]
}
ifnewType==nil {
returnra, nil
}
nra:=reflect.MakeSlice(reflect.SliceOf(newType), l, l)
fori, e:=rangera {
nra.Index(i).Set(e)
}
returnnra.Interface(), nil
}
funcmain() {
// Create a template.funcs:=map[string]any{
"map": MapTemplateFunc,
"inc": func(iint) int {
returni+1
},
"odd": func(iint) bool {
returni%2==1
},
}
tmpl:=template.Must(template.New("").Funcs(funcs).Parse(` {{ map $.Data $.Funcs.inc }} {{ map $.Data $.Funcs.odd }} `))
// Create some data to be used in the template.data:=struct {
Data []intFuncsmap[string]any
}{
Data: []int{1, 2, 3, 4},
Funcs: funcs,
}
// Execute the template with the data.err:=tmpl.Execute(os.Stdout, data)
iferr!=nil {
fmt.Println(err)
}
}
It would be unreasonable for functions like this to match some of the clauses here:
We followed these principles to decide which functions to add and how to implement them:
Use template functions to build layout. The following
types of operations are within the domain of template functions:
Formatting
Layout
Simple type conversions
Utilities that assist in handling common formatting and layout needs (e.g. arithmetic)
Template functions should not return errors unless there is no way to print
a sensible value. For example, converting a string to an integer should not
produce an error if conversion fails. Instead, it should display a default
value.
Simple math is necessary for grid layouts, pagers, and so on. Complex math
(anything other than arithmetic) should be done outside of templates.
The text was updated successfully, but these errors were encountered:
As generics don't seem to be supported by
text/template
yet I produced the following: (Or does anyone know what other library I should be looking at?)Would something like this be accepted into the project?
It would be unreasonable for functions like this to match some of the clauses here:
We followed these principles to decide which functions to add and how to implement them:
The text was updated successfully, but these errors were encountered: