// dict-set-context.go package text import ( "fmt" "strings" sq "github.com/kballard/go-shellquote" "git.portale-stac.it/go-pkg/utils" ) type DictSetFlag uint16 const ( KeepVar = DictSetFlag(1 << iota) ) const ( pipeValueKey = "." pipeNameKey = "_" ) type DictSetContext struct { BaseExpander flags DictSetFlag varStores []map[string]string localStore map[string]string } func NewDictSetContext(flags DictSetFlag, varStores ...map[string]string) *DictSetContext { return NewDictSetContextV(flags, varStores) } func NewDictSetContextV(flags DictSetFlag, varStores []map[string]string) *DictSetContext { ctx := &DictSetContext{ flags: flags, varStores: varStores, localStore: make(map[string]string, 10), } (&ctx.BaseExpander).Init() return ctx } func (self *DictSetContext) GetVar(name string) (value string, exists bool) { if value, exists = self.localStore[name]; !exists { value, exists = findInStores(name, self.varStores) } return } func (self *DictSetContext) SetVar(name string, value string) (repeatedValue string) { self.localStore[name] = value return value } func findInStores(key string, stores []map[string]string) (value string, found bool) { for _, vars := range stores { if vars != nil { if value, found = vars[key]; found { break } } } return } func (self *DictSetContext) Handle(spec string, scanFlags ScannerFlag) (value string, err error) { var found bool var rawValue string if len(spec) > 0 { //parts := utils.SplitByRune(spec, '|', -1) parts := utils.ScopedSplitByRune(spec, '|', `'"{`, `'"}`, -1) name := parts[0] parts = parts[1:] if len(name) > 0 { if scanFlags&DirectValue != 0 { rawValue = name found = true } else { rawValue, found = findInStores(name, self.varStores) } } self.SetVar(pipeNameKey, name) // NOTE Maybe this line can be deleted origVarFound := found for _, part := range parts { var expandedPart string self.varStores[0][pipeValueKey] = rawValue self.SetVar(pipeValueKey, rawValue) if expandedPart, err = Scan(self, part); err != nil { break } self.SetVar(pipeNameKey, name) if rawValue, err = self.evalContent(origVarFound, rawValue, expandedPart); err != nil { break } origVarFound = true } if err == nil { if len(rawValue) == 0 && (self.flags&KeepVar) != 0 { value = Var(name) } else { value = rawValue } } } if err == nil && len(value) == 0 && (scanFlags&ValueRequired) != 0 { err = fmt.Errorf("the variable specification %q requires a value", spec) } return } func (self *DictSetContext) evalContent(varFound bool, rawValue string, alternateValue string) (value string, err error) { var args []string if args, err = sq.Split(alternateValue); err != nil { return } if len(args) == 0 { value = rawValue } else { op := args[0] if strings.HasPrefix(op, "__") { var f ExpanderFunc if f, err = self.GetFunc(op); err == nil { value, err = f(self, rawValue, args[1:]) } } else if varFound { value = rawValue } else { value = alternateValue } } return }