validate ensures that the function name obtained from the parser exists within the internal functions catalog. It also validates the function signature to make sure required arguments are supplied. Finally, it checks the type of each argument with the expected one.
()
| 224 | // make sure required arguments are supplied. Finally, it |
| 225 | // checks the type of each argument with the expected one. |
| 226 | func (f *Function) validate() error { |
| 227 | fn, ok := funcs[strings.ToUpper(f.Name)] |
| 228 | if !ok { |
| 229 | return ErrUndefinedFunction(f.Name) |
| 230 | } |
| 231 | |
| 232 | if len(f.Args) < fn.Desc().RequiredArgs() || |
| 233 | len(f.Args) > len(fn.Desc().Args) { |
| 234 | return ErrFunctionSignature(fn.Desc(), len(f.Args)) |
| 235 | } |
| 236 | |
| 237 | validationFunc := fn.Desc().ArgsValidationFunc |
| 238 | if validationFunc != nil { |
| 239 | if err := validationFunc(f.ArgsSlice()); err != nil { |
| 240 | return err |
| 241 | } |
| 242 | } |
| 243 | |
| 244 | for i, expr := range f.Args { |
| 245 | arg := fn.Desc().Args[i] |
| 246 | typ := functions.Unknown |
| 247 | |
| 248 | switch reflect.TypeOf(expr) { |
| 249 | case reflect.TypeOf(&FieldLiteral{}): |
| 250 | typ = functions.Field |
| 251 | case reflect.TypeOf(&BoundFieldLiteral{}): |
| 252 | typ = functions.BoundField |
| 253 | case reflect.TypeOf(&BoundSegmentLiteral{}): |
| 254 | typ = functions.BoundSegment |
| 255 | case reflect.TypeOf(&BareBoundVariableLiteral{}): |
| 256 | typ = functions.BareBoundVariable |
| 257 | case reflect.TypeOf(&IPLiteral{}): |
| 258 | typ = functions.IP |
| 259 | case reflect.TypeOf(&StringLiteral{}): |
| 260 | typ = functions.String |
| 261 | case reflect.TypeOf(&IntegerLiteral{}): |
| 262 | typ = functions.Number |
| 263 | case reflect.TypeOf(&Function{}): |
| 264 | typ = functions.Func |
| 265 | case reflect.TypeOf(&ListLiteral{}): |
| 266 | typ = functions.Slice |
| 267 | case reflect.TypeOf(&BoolLiteral{}): |
| 268 | typ = functions.Bool |
| 269 | case reflect.TypeOf(&BinaryExpr{}), reflect.TypeOf(&ParenExpr{}), reflect.TypeOf(&NotExpr{}): |
| 270 | typ = functions.Expression |
| 271 | } |
| 272 | |
| 273 | if !arg.ContainsType(typ) { |
| 274 | return ErrArgumentTypeMismatch(i, arg.Keyword, fn.Name(), arg.Types) |
| 275 | } |
| 276 | } |
| 277 | |
| 278 | return nil |
| 279 | } |
| 280 | |
| 281 | // SequenceExpr represents a single binary expression within the sequence. |
| 282 | type SequenceExpr struct { |
no test coverage detected