// Copyright (c) 2024 Celestino Amoroso (celestino.amoroso@gmail.com). // All rights reserved. // expander-context.go package text import ( "errors" "fmt" "strconv" "strings" "git.portale-stac.it/go-pkg/golang" ) type ExpanderFunc func(ctx ExpanderContext, varValue string, args []string) (result string, err error) type ExpanderFuncBlock struct { name string expFunc ExpanderFunc minArgs int maxArgs int description string } func (self *ExpanderFuncBlock) CheckNumArgs(n int) (ok bool) { ok = (self.minArgs < 0 || n >= self.minArgs) && (self.maxArgs < 0 || n <= self.maxArgs) return } func (self *ExpanderFuncBlock) synopsys(sb *strings.Builder) { if self.minArgs < 0 && self.maxArgs < 0 { sb.WriteString("[...]") } else { var i int for i = 0; i < self.minArgs; i++ { if i > 0 { sb.WriteByte(' ') } sb.WriteString("arg") sb.WriteString(strconv.Itoa(i + 1)) } if self.maxArgs < 0 { sb.WriteString("...") } else if i < self.maxArgs { for j := i; j < self.maxArgs; j++ { if j > 0 { sb.WriteByte(' ') } sb.WriteString("[arg") sb.WriteString(strconv.Itoa(j + 1)) } for j := i; j < self.maxArgs; j++ { sb.WriteByte(']') } } } } func (self *ExpanderFuncBlock) String() string { var sb strings.Builder sb.WriteString(self.name) sb.WriteByte(' ') self.synopsys(&sb) if len(self.description) > 0 { sb.WriteString(" -- ") if len(self.description) > 80 { sb.WriteString(self.description[0:80]) sb.WriteString("...") } else { sb.WriteString(self.description) } } return sb.String() } type ExpanderContext interface { VariableHandler GetFunc(name string) (f ExpanderFunc, err error) AddFunc(name string, f ExpanderFunc, minArgs, maxArgs int, description string) GetVar(name string) (value string, exists bool) SetVar(name string, value string) (repeatedValue string) } type BaseExpander struct { functions map[string]*ExpanderFuncBlock } func (self *BaseExpander) GetVar(name string) (value string, exists bool) { return } func (self *BaseExpander) SetVar(name string, value string) (repeatedValue string) { return value } func NewExpander() *BaseExpander { return &BaseExpander{ functions: make(map[string]*ExpanderFuncBlock), } } func (self *BaseExpander) Init() { if self.functions == nil { self.functions = make(map[string]*ExpanderFuncBlock) } } func (self *BaseExpander) GetFunc(name string) (f ExpanderFunc, err error) { var ok bool var info *ExpanderFuncBlock if info, ok = self.functions[name]; !ok { err = fmt.Errorf("unknown function %q", name) } else { f = info.expFunc } return } func (self *BaseExpander) AddFunc(name string, f ExpanderFunc, minArgs, maxArgs int, description string) { self.functions[name] = &ExpanderFuncBlock{ name: name, expFunc: f, minArgs: minArgs, maxArgs: maxArgs, description: description, } } func (self *BaseExpander) Handle(varSpec string, flags ScannerFlag) (value string, err error) { err = errors.New("maybe you did somwthing wrong") return } func (self *BaseExpander) IterateFunc(op func(funcInfo *ExpanderFuncBlock) (err error)) (err error) { if op != nil { err = golang.IterateSortedMap(self.functions, func(key string, info *ExpanderFuncBlock) error { return op(info) }) } return }