github.com/go-graphite/carbonapi@v0.17.0/pkg/parser/define.go (about)

     1  package parser
     2  
     3  import (
     4  	"strings"
     5  	"text/template"
     6  )
     7  
     8  type defineStruct struct {
     9  	tpl *template.Template
    10  }
    11  
    12  var defineMap = &defineStruct{tpl: template.New("define")}
    13  
    14  // Define new template
    15  func Define(name, tmpl string) error {
    16  	return defineMap.define(name, tmpl)
    17  }
    18  
    19  func defineCleanUp() {
    20  	defineMap = &defineStruct{tpl: template.New("define")}
    21  }
    22  
    23  func (d *defineStruct) define(name, tmpl string) error {
    24  	t := d.tpl.New(name)
    25  	_, err := t.Parse(tmpl)
    26  	return err
    27  }
    28  
    29  func (d *defineStruct) expandExpr(exp *expr) (*expr, error) {
    30  	if exp == nil {
    31  		return exp, nil
    32  	}
    33  
    34  	var err error
    35  
    36  	if exp.etype == EtName || exp.etype == EtFunc {
    37  		t := d.tpl.Lookup(exp.target)
    38  		if t != nil {
    39  			var b strings.Builder
    40  			args := make([]string, len(exp.args))
    41  			for i := 0; i < len(exp.args); i++ {
    42  				args[i] = exp.args[i].ToString()
    43  			}
    44  			kwargs := make(map[string]string)
    45  			for k, v := range exp.namedArgs {
    46  				kwargs[k] = v.ToString()
    47  			}
    48  			data := map[string]interface{}{
    49  				"argString": exp.argString,
    50  				"args":      args,
    51  				"kwargs":    kwargs,
    52  			}
    53  			err = t.Execute(&b, data)
    54  			if err != nil {
    55  				return exp, err
    56  			}
    57  			newExp, _, err := parseExprInner(b.String())
    58  			if err != nil {
    59  				return exp, err
    60  			}
    61  			exp = newExp.(*expr)
    62  		}
    63  	}
    64  
    65  	for i := 0; i < len(exp.args); i++ {
    66  		exp.args[i], err = d.expandExpr(exp.args[i])
    67  		if err != nil {
    68  			return exp, err
    69  		}
    70  	}
    71  
    72  	for k, v := range exp.namedArgs {
    73  		exp.namedArgs[k], err = d.expandExpr(v)
    74  		if err != nil {
    75  			return exp, err
    76  		}
    77  	}
    78  
    79  	return exp, nil
    80  }
    81  
    82  func (d *defineStruct) Expand(v Expr) (Expr, error) {
    83  	exp, ok := v.(*expr)
    84  	if !ok {
    85  		return v, nil
    86  	}
    87  	return d.expandExpr(exp)
    88  }