1 package parser 2 3 import ( 4 // "fmt" 5 6 // "github.com/juju/errors" 7 "github.com/noirbizarre/gonja/nodes" 8 "github.com/noirbizarre/gonja/tokens" 9 ) 10 11 // FilterFunction is the type filter functions must fulfil 12 // type FilterFunction func(in *Value, params *VarArgs) (out *Value, err *Error) 13 14 // MustApplyFilter behaves like ApplyFilter, but panics on an error. 15 // func MustApplyFilter(name string, value *Value, params *VarArgs) *Value { 16 // val, err := ApplyFilter(name, value, params) 17 // if err != nil { 18 // panic(err) 19 // } 20 // return val 21 // } 22 23 // // ApplyFilter applies a filter to a given value using the given parameters. 24 // // Returns a *gonja.Value or an error. 25 // func ApplyFilter(name string, value *Value, params *VarArgs) (*Value, *Error) { 26 // fn, existing := filters[name] 27 // if !existing { 28 // return nil, &Error{ 29 // Sender: "applyfilter", 30 // OrigError: errors.Errorf("Filter with name '%s' not found.", name), 31 // } 32 // } 33 34 // // // Make sure param is a *Value 35 // // if param == nil { 36 // // param = AsValue(nil) 37 // // } 38 39 // return fn(value, params) 40 // } 41 42 // type filterCall struct { 43 // token *Token 44 45 // name string 46 // args []Expression 47 // kwargs map[string]Expression 48 49 // filterFunc FilterFunction 50 // } 51 52 // func (fc *filterCall) Execute(v *Value, ctx *ExecutionContext) (*Value, *Error) { 53 // params := &VarArgs{ 54 // Args: []*Value{}, 55 // KwArgs: map[string]*Value{}, 56 // } 57 // var err *Error 58 59 // for _, param := range fc.args { 60 // value, err := param.Evaluate(ctx) 61 // if err != nil { 62 // return nil, err 63 // } 64 // params.Args = append(params.Args, value) 65 // } 66 67 // for key, param := range fc.kwargs { 68 // value, err := param.Evaluate(ctx) 69 // if err != nil { 70 // return nil, err 71 // } 72 // params.KwArgs[key] = value 73 // } 74 75 // filteredValue, err := fc.filterFunc(v, params) 76 // if err != nil { 77 // return nil, err.updateFromTokenIfNeeded(ctx.template, fc.token) 78 // } 79 // return filteredValue, nil 80 // } 81 82 // Filter = IDENT | IDENT ":" FilterArg | IDENT "|" Filter 83 func (p *Parser) ParseFilter() (*nodes.FilterCall, error) { 84 identToken := p.Match(tokens.Name) 85 86 // Check filter ident 87 if identToken == nil { 88 return nil, p.Error("Filter name must be an identifier.", p.Current()) 89 } 90 91 filter := &nodes.FilterCall{ 92 Token: identToken, 93 Name: identToken.Val, 94 Args: []nodes.Expression{}, 95 Kwargs: map[string]nodes.Expression{}, 96 } 97 98 // // Get the appropriate filter function and bind it 99 // filterFn, exists := filters[identToken.Val] 100 // if !exists { 101 // return nil, p.Error(fmt.Sprintf("Filter '%s' does not exist.", identToken.Val), identToken) 102 // } 103 104 // filter.filterFunc = filterFn 105 106 // Check for filter-argument (2 tokens needed: ':' ARG) 107 if p.Match(tokens.Lparen) != nil { 108 if p.Peek(tokens.VariableEnd) != nil { 109 return nil, p.Error("Filter parameter required after '('.", nil) 110 } 111 112 for p.Match(tokens.Comma) != nil || p.Match(tokens.Rparen) == nil { 113 // TODO: Handle multiple args and kwargs 114 v, err := p.ParseExpression() 115 if err != nil { 116 return nil, err 117 } 118 119 if p.Match(tokens.Assign) != nil { 120 key := v.Position().Val 121 value, errValue := p.ParseExpression() 122 if errValue != nil { 123 return nil, errValue 124 } 125 filter.Kwargs[key] = value 126 } else { 127 filter.Args = append(filter.Args, v) 128 } 129 } 130 } 131 132 return filter, nil 133 } 134