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 }