Skip to content

Commit

Permalink
Support JSON Marshal/Unmarshal (#77)
Browse files Browse the repository at this point in the history
Support JSON Marshal/Unmarshal
  • Loading branch information
hunshcn committed Feb 24, 2024
1 parent 03d34d8 commit 05e6ac2
Show file tree
Hide file tree
Showing 2 changed files with 60 additions and 3 deletions.
28 changes: 25 additions & 3 deletions regexp.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,8 +18,12 @@ import (
"github.com/dlclark/regexp2/syntax"
)

// Default timeout used when running regexp matches -- "forever"
var DefaultMatchTimeout = time.Duration(math.MaxInt64)
var (
// DefaultMatchTimeout used when running regexp matches -- "forever"
DefaultMatchTimeout = time.Duration(math.MaxInt64)
// DefaultUnmarshalOptions used when unmarshaling a regex from text
DefaultUnmarshalOptions = None
)

// Regexp is the representation of a compiled regular expression.
// A Regexp is safe for concurrent use by multiple goroutines.
Expand All @@ -43,7 +47,7 @@ type Regexp struct {
code *syntax.Code // compiled program

// cache of machines for running regexp
muRun sync.Mutex
muRun *sync.Mutex
runner []*runner
}

Expand Down Expand Up @@ -72,6 +76,7 @@ func Compile(expr string, opt RegexOptions) (*Regexp, error) {
capsize: code.Capsize,
code: code,
MatchTimeout: DefaultMatchTimeout,
muRun: &sync.Mutex{},
}, nil
}

Expand Down Expand Up @@ -371,3 +376,20 @@ func (re *Regexp) GroupNumberFromName(name string) int {

return -1
}

// MarshalText implements [encoding.TextMarshaler]. The output
// matches that of calling the [Regexp.String] method.
func (re *Regexp) MarshalText() ([]byte, error) {
return []byte(re.String()), nil
}

// UnmarshalText implements [encoding.TextUnmarshaler] by calling
// [Compile] on the encoded value.
func (re *Regexp) UnmarshalText(text []byte) error {
newRE, err := Compile(string(text), DefaultUnmarshalOptions)
if err != nil {
return err
}
*re = *newRE
return nil
}
35 changes: 35 additions & 0 deletions regexp_test.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package regexp2

import (
"encoding/json"
"fmt"
"reflect"
"strings"
Expand Down Expand Up @@ -1329,3 +1330,37 @@ func TestParseShortSlashPEnd(t *testing.T) {
t.Fatalf("Expected match")
}
}

func TestMarshal(t *testing.T) {
re := MustCompile(`.*`, 0)
m, err := json.Marshal(re)
if err != nil {
t.Fatalf("Unexpected error: %v", err)
}
if string(m) != `".*"` {
t.Fatalf(`Expected ".*"`)
}
}

func TestUnMarshal(t *testing.T) {
DefaultUnmarshalOptions = IgnoreCase
bytes := []byte(`"^[abc]"`)
var re *Regexp
err := json.Unmarshal(bytes, &re)
if err != nil {
t.Fatalf("Unexpected error: %v", err)
}
if re.options != IgnoreCase {
t.Fatalf("Expected options ignore case")
}
if re.String() != `^[abc]` {
t.Fatalf(`Expected "^[abc]"`)
}
ok, err := re.MatchString("A")
if err != nil {
t.Fatalf("Unexpected error: %v", err)
}
if !ok {
t.Fatalf(`Expected match`)
}
}

0 comments on commit 05e6ac2

Please sign in to comment.