// Parses expression in the go language into Failover predicates
func parseExpression(in string) (hpredicate, error) {
	p, err := predicate.NewParser(predicate.Def{
		Operators: predicate.Operators{
			AND: and,
			OR:  or,
			EQ:  eq,
			NEQ: neq,
			LT:  lt,
			GT:  gt,
			LE:  le,
			GE:  ge,
		},
		Functions: map[string]interface{}{
			"RequestMethod":  requestMethod,
			"IsNetworkError": isNetworkError,
			"Attempts":       attempts,
			"ResponseCode":   responseCode,
		},
	})
	if err != nil {
		return nil, err
	}
	out, err := p.Parse(in)
	if err != nil {
		return nil, err
	}
	pr, ok := out.(hpredicate)
	if !ok {
		return nil, fmt.Errorf("expected predicate, got %T", out)
	}
	return pr, nil
}
func parse(expression string, result *match) (matcher, error) {
	p, err := predicate.NewParser(predicate.Def{
		Functions: map[string]interface{}{
			"Host":       hostTrieMatcher,
			"HostRegexp": hostRegexpMatcher,

			"Path":       pathTrieMatcher,
			"PathRegexp": pathRegexpMatcher,

			"Method":       methodTrieMatcher,
			"MethodRegexp": methodRegexpMatcher,

			"Header":       headerTrieMatcher,
			"HeaderRegexp": headerRegexpMatcher,
		},
		Operators: predicate.Operators{
			AND: newAndMatcher,
		},
	})
	if err != nil {
		return nil, err
	}
	out, err := p.Parse(expression)
	if err != nil {
		return nil, err
	}
	m, ok := out.(matcher)
	if !ok {
		return nil, fmt.Errorf("unknown result type: %T", out)
	}
	m.setMatch(result)
	return m, nil
}