"id/schema.go" did not exist on "4b6aa6f3b735446e02593a4d5730146e48e62eee"
Select Git revision
collaborator.go
builder.go 3.25 KiB
package template
import (
"bytes"
"context"
"text/template"
"git.perx.ru/perxis/perxis-go/pkg/content"
)
type Builder struct {
ctx context.Context
cnt *content.Content
SpaceID string
EnvID string
funcs template.FuncMap
data map[string]interface{}
}
func NewBuilder(cnt *content.Content, space, env string) *Builder {
return &Builder{
ctx: context.Background(),
cnt: cnt,
SpaceID: space,
EnvID: env,
funcs: make(template.FuncMap),
}
}
func (b *Builder) getFuncs() template.FuncMap {
return template.FuncMap{
"lookup": getLookup(b),
"system": getSystem(b),
}
}
func (b *Builder) WithData(data map[string]interface{}) *Builder {
bld := *b
bld.data = data
return &bld
}
func (b *Builder) WithKV(kv ...any) *Builder {
bld := *b
if bld.data == nil {
bld.data = make(map[string]interface{}, 10)
}
for i := 0; i < len(kv)-1; i += 2 {
k, _ := kv[i].(string)
v := kv[i+1]
if k != "" && v != nil {
bld.data[k] = v
}
}
return &bld
}
func (b *Builder) GetData() map[string]interface{} {
return b.data
}
func (b *Builder) WithSpace(space, env string) *Builder {
bld := *b
bld.SpaceID = space
bld.EnvID = env
return &bld
}
func (b *Builder) WithContext(ctx context.Context) *Builder {
bld := *b
bld.ctx = ctx
return &bld
}
func (b *Builder) Context() context.Context {
return b.ctx
}
func (b *Builder) Template() *template.Template {
return template.New("main").Funcs(b.getFuncs())
}
func (b *Builder) Execute(str string, data ...any) (string, error) {
t := b.Template()
buf := new(bytes.Buffer)
t, err := t.Parse(str)
if err != nil {
return "", err
}
if err = t.Execute(buf, b.getData(data...)); err != nil {
return "", err
}
return buf.String(), nil
}
func (b *Builder) ExecuteList(str []string, data ...any) ([]string, error) {
t := b.Template()
result := make([]string, len(str))
buffer := new(bytes.Buffer)
for i, tmpl := range str {
if tmpl == "" {
continue
}
t, err := t.Parse(tmpl)
if err != nil {
return []string{}, err
}
if err = t.Execute(buffer, b.getData(data...)); err != nil {
return []string{}, err
}
result[i] = buffer.String()
buffer.Reset()
}
return result, nil
}
func (b *Builder) ExecuteMap(str map[string]interface{}, data ...any) (map[string]interface{}, error) {
result := make(map[string]interface{}, len(str))
for k, v := range str {
switch t := v.(type) {
case string:
value, err := b.Execute(t, data...)
if err != nil {
return nil, err
}
v = value
case []string:
values, err := b.ExecuteList(append([]string{k}, t...), data...)
if err != nil {
return nil, err
}
k = values[0]
vv := make([]interface{}, 0, len(t))
for _, val := range values[1:] {
vv = append(vv, val)
}
v = vv
}
result[k] = v
}
return result, nil
}
func (b *Builder) getData(data ...any) any {
if len(data) == 0 {
return b.data
}
var res map[string]interface{}
for _, v := range data {
if m, ok := v.(map[string]interface{}); ok && b.data != nil {
res = mergeMaps(b.data, m)
}
}
if res != nil {
return res
}
return data[0]
}
func mergeMaps(in ...map[string]interface{}) map[string]interface{} {
out := make(map[string]interface{})
for _, i := range in {
for k, v := range i {
out[k] = v
}
}
return out
}