github.com/dolthub/go-mysql-server@v0.18.0/internal/regex/regex.go (about)

     1  // Copyright 2020-2021 Dolthub, Inc.
     2  //
     3  // Licensed under the Apache License, Version 2.0 (the "License");
     4  // you may not use this file except in compliance with the License.
     5  // You may obtain a copy of the License at
     6  //
     7  //     http://www.apache.org/licenses/LICENSE-2.0
     8  //
     9  // Unless required by applicable law or agreed to in writing, software
    10  // distributed under the License is distributed on an "AS IS" BASIS,
    11  // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    12  // See the License for the specific language governing permissions and
    13  // limitations under the License.
    14  
    15  package regex
    16  
    17  import (
    18  	"github.com/go-kit/kit/metrics/discard"
    19  	errors "gopkg.in/src-d/go-errors.v1"
    20  )
    21  
    22  var (
    23  	// ErrRegexAlreadyRegistered is returned when there is a previously
    24  	// registered regex engine with the same name.
    25  	ErrRegexAlreadyRegistered = errors.NewKind("Regex engine already registered: %s")
    26  	// ErrRegexNameEmpty returned when the name is "".
    27  	ErrRegexNameEmpty = errors.NewKind("Regex engine name cannot be empty")
    28  	// ErrRegexNotFound returned when the regex engine is not registered.
    29  	ErrRegexNotFound = errors.NewKind("Regex engine not found: %s")
    30  
    31  	registry      map[string]Constructor
    32  	defaultEngine string
    33  )
    34  
    35  // Matcher interface is used to compare regexes with strings.
    36  type Matcher interface {
    37  	// Match returns true if the text matches the regular expression.
    38  	Match(text string) bool
    39  }
    40  
    41  // Disposer interface is used to release resources.
    42  // The interface should be implemented by all go binding for native C libraries
    43  type Disposer interface {
    44  	Dispose()
    45  }
    46  
    47  // DisposableMatcher implements both Disposer and Matcher
    48  type DisposableMatcher interface {
    49  	Matcher
    50  	Disposer
    51  }
    52  
    53  // Constructor creates a new Matcher.
    54  type Constructor func(re string) (Matcher, Disposer, error)
    55  
    56  var (
    57  	// CompileHistogram describes a regexp compile time.
    58  	CompileHistogram = discard.NewHistogram()
    59  
    60  	// MatchHistogram describes a regexp match time.
    61  	MatchHistogram = discard.NewHistogram()
    62  )
    63  
    64  // Register add a new regex engine to the registry.
    65  func Register(name string, c Constructor) error {
    66  	if registry == nil {
    67  		registry = make(map[string]Constructor)
    68  	}
    69  
    70  	if name == "" {
    71  		return ErrRegexNameEmpty.New()
    72  	}
    73  
    74  	_, ok := registry[name]
    75  	if ok {
    76  		return ErrRegexAlreadyRegistered.New(name)
    77  	}
    78  
    79  	registry[name] = c
    80  
    81  	return nil
    82  }
    83  
    84  // Engines returns the list of regex engines names.
    85  func Engines() []string {
    86  	var names []string
    87  
    88  	for n := range registry {
    89  		names = append(names, n)
    90  	}
    91  
    92  	return names
    93  }
    94  
    95  // New creates a new Matcher with the specified regex engine.
    96  func New(name, re string) (Matcher, Disposer, error) {
    97  	n, ok := registry[name]
    98  	if !ok {
    99  		return nil, nil, ErrRegexNotFound.New(name)
   100  	}
   101  
   102  	return n(re)
   103  }
   104  
   105  type disposableMatcher struct {
   106  	m Matcher
   107  	d Disposer
   108  }
   109  
   110  func (dm *disposableMatcher) Match(s string) bool {
   111  	return dm.m.Match(s)
   112  }
   113  
   114  func (dm *disposableMatcher) Dispose() {
   115  	dm.d.Dispose()
   116  }
   117  
   118  func NewDisposableMatcher(name, re string) (DisposableMatcher, error) {
   119  	m, d, err := New(name, re)
   120  
   121  	if err != nil {
   122  		return nil, err
   123  	}
   124  
   125  	return &disposableMatcher{m, d}, nil
   126  }
   127  
   128  // Default returns the default regex engine.
   129  func Default() string {
   130  	if defaultEngine != "" {
   131  		return defaultEngine
   132  	}
   133  	if _, ok := registry["go"]; ok {
   134  		return "go"
   135  	}
   136  
   137  	return "oniguruma"
   138  }
   139  
   140  // SetDefault sets the regex engine returned by Default.
   141  func SetDefault(name string) {
   142  	defaultEngine = name
   143  }