github.com/MontFerret/ferret@v0.18.0/pkg/runtime/expressions/operators/regexp.go (about)

     1  package operators
     2  
     3  import (
     4  	"context"
     5  	"regexp"
     6  
     7  	"github.com/MontFerret/ferret/pkg/runtime/core"
     8  	"github.com/MontFerret/ferret/pkg/runtime/values"
     9  )
    10  
    11  type (
    12  	RegexpOperatorVariant int
    13  
    14  	RegexpOperator struct {
    15  		*baseOperator
    16  		variant RegexpOperatorVariant
    17  	}
    18  )
    19  
    20  const (
    21  	RegexpOperatorVariantNegative RegexpOperatorVariant = 0
    22  	RegexpOperatorVariantPositive RegexpOperatorVariant = 1
    23  )
    24  
    25  var regexpVariants = map[string]RegexpOperatorVariant{
    26  	"!~": RegexpOperatorVariantNegative,
    27  	"=~": RegexpOperatorVariantPositive,
    28  }
    29  
    30  func NewRegexpOperator(
    31  	src core.SourceMap,
    32  	left core.Expression,
    33  	right core.Expression,
    34  	operatorStr string,
    35  ) (*RegexpOperator, error) {
    36  	variant, exists := regexpVariants[operatorStr]
    37  
    38  	if !exists {
    39  		return nil, core.Error(core.ErrInvalidArgument, "operator")
    40  	}
    41  
    42  	return &RegexpOperator{
    43  		&baseOperator{
    44  			src,
    45  			left,
    46  			right,
    47  		},
    48  		variant,
    49  	}, nil
    50  }
    51  
    52  func (operator *RegexpOperator) Type() RegexpOperatorVariant {
    53  	return operator.variant
    54  }
    55  
    56  func (operator *RegexpOperator) Exec(ctx context.Context, scope *core.Scope) (core.Value, error) {
    57  	left, err := operator.left.Exec(ctx, scope)
    58  
    59  	if err != nil {
    60  		return nil, err
    61  	}
    62  
    63  	right, err := operator.right.Exec(ctx, scope)
    64  
    65  	if err != nil {
    66  		return nil, err
    67  	}
    68  
    69  	return operator.Eval(ctx, left, right)
    70  }
    71  
    72  func (operator *RegexpOperator) Eval(_ context.Context, left, right core.Value) (core.Value, error) {
    73  	leftStr := left.String()
    74  	rightStr := right.String()
    75  
    76  	r, err := regexp.Compile(rightStr)
    77  
    78  	if err != nil {
    79  		return values.None, err
    80  	}
    81  
    82  	if operator.variant == RegexpOperatorVariantPositive {
    83  		return values.NewBoolean(r.MatchString(leftStr)), nil
    84  	}
    85  
    86  	return values.NewBoolean(!r.MatchString(leftStr)), nil
    87  }