2019-07-09 14:19:53 -04:00
|
|
|
package operators
|
|
|
|
|
|
|
|
|
|
import (
|
|
|
|
|
"context"
|
|
|
|
|
"github.com/MontFerret/ferret/pkg/runtime/core"
|
|
|
|
|
"github.com/MontFerret/ferret/pkg/runtime/values"
|
|
|
|
|
"regexp"
|
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
type (
|
2021-10-16 17:24:54 -04:00
|
|
|
RegexpOperatorVariant int
|
|
|
|
|
|
|
|
|
|
RegexpOperator struct {
|
2019-07-09 14:19:53 -04:00
|
|
|
*baseOperator
|
2021-10-16 17:24:54 -04:00
|
|
|
variant RegexpOperatorVariant
|
2019-07-09 14:19:53 -04:00
|
|
|
}
|
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
const (
|
2021-10-16 17:24:54 -04:00
|
|
|
RegexpOperatorVariantNegative RegexpOperatorVariant = 0
|
|
|
|
|
RegexpOperatorVariantPositive RegexpOperatorVariant = 1
|
2019-07-09 14:19:53 -04:00
|
|
|
)
|
|
|
|
|
|
2021-10-16 17:24:54 -04:00
|
|
|
var regexpVariants = map[string]RegexpOperatorVariant{
|
|
|
|
|
"!~": RegexpOperatorVariantNegative,
|
|
|
|
|
"=~": RegexpOperatorVariantPositive,
|
2019-07-09 14:19:53 -04:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func NewRegexpOperator(
|
|
|
|
|
src core.SourceMap,
|
|
|
|
|
left core.Expression,
|
|
|
|
|
right core.Expression,
|
2021-10-16 17:24:54 -04:00
|
|
|
operatorStr string,
|
2019-07-09 14:19:53 -04:00
|
|
|
) (*RegexpOperator, error) {
|
2021-10-16 17:24:54 -04:00
|
|
|
variant, exists := regexpVariants[operatorStr]
|
2019-07-09 14:19:53 -04:00
|
|
|
|
|
|
|
|
if !exists {
|
|
|
|
|
return nil, core.Error(core.ErrInvalidArgument, "operator")
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return &RegexpOperator{
|
|
|
|
|
&baseOperator{
|
|
|
|
|
src,
|
|
|
|
|
left,
|
|
|
|
|
right,
|
|
|
|
|
},
|
2021-10-16 17:24:54 -04:00
|
|
|
variant,
|
2019-07-09 14:19:53 -04:00
|
|
|
}, nil
|
|
|
|
|
}
|
|
|
|
|
|
2021-10-16 17:24:54 -04:00
|
|
|
func (operator *RegexpOperator) Type() RegexpOperatorVariant {
|
|
|
|
|
return operator.variant
|
2019-07-09 14:19:53 -04:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func (operator *RegexpOperator) Exec(ctx context.Context, scope *core.Scope) (core.Value, error) {
|
|
|
|
|
left, err := operator.left.Exec(ctx, scope)
|
|
|
|
|
|
|
|
|
|
if err != nil {
|
|
|
|
|
return nil, err
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
right, err := operator.right.Exec(ctx, scope)
|
|
|
|
|
|
|
|
|
|
if err != nil {
|
|
|
|
|
return nil, err
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return operator.Eval(ctx, left, right)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func (operator *RegexpOperator) Eval(_ context.Context, left, right core.Value) (core.Value, error) {
|
|
|
|
|
leftStr := left.String()
|
|
|
|
|
rightStr := right.String()
|
|
|
|
|
|
|
|
|
|
r, err := regexp.Compile(rightStr)
|
|
|
|
|
|
|
|
|
|
if err != nil {
|
|
|
|
|
return values.None, err
|
|
|
|
|
}
|
|
|
|
|
|
2021-10-16 17:24:54 -04:00
|
|
|
if operator.variant == RegexpOperatorVariantPositive {
|
2019-07-09 14:19:53 -04:00
|
|
|
return values.NewBoolean(r.MatchString(leftStr)), nil
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return values.NewBoolean(!r.MatchString(leftStr)), nil
|
|
|
|
|
}
|