Skip to content

Commit 827b164

Browse files
committed
Support JSON Marshal/Unmarshal
1 parent 03d34d8 commit 827b164

File tree

2 files changed

+58
-2
lines changed

2 files changed

+58
-2
lines changed

regexp.go

Lines changed: 23 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,10 @@ import (
1919
)
2020

2121
// Default timeout used when running regexp matches -- "forever"
22-
var DefaultMatchTimeout = time.Duration(math.MaxInt64)
22+
var (
23+
DefaultMatchTimeout = time.Duration(math.MaxInt64)
24+
DefaultUnmarshalOptions = None
25+
)
2326

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

4548
// cache of machines for running regexp
46-
muRun sync.Mutex
49+
muRun *sync.Mutex
4750
runner []*runner
4851
}
4952

@@ -72,6 +75,7 @@ func Compile(expr string, opt RegexOptions) (*Regexp, error) {
7275
capsize: code.Capsize,
7376
code: code,
7477
MatchTimeout: DefaultMatchTimeout,
78+
muRun: &sync.Mutex{},
7579
}, nil
7680
}
7781

@@ -371,3 +375,20 @@ func (re *Regexp) GroupNumberFromName(name string) int {
371375

372376
return -1
373377
}
378+
379+
// MarshalText implements [encoding.TextMarshaler]. The output
380+
// matches that of calling the [Regexp.String] method.
381+
func (re *Regexp) MarshalText() ([]byte, error) {
382+
return []byte(re.String()), nil
383+
}
384+
385+
// UnmarshalText implements [encoding.TextUnmarshaler] by calling
386+
// [Compile] on the encoded value.
387+
func (re *Regexp) UnmarshalText(text []byte) error {
388+
newRE, err := Compile(string(text), DefaultUnmarshalOptions)
389+
if err != nil {
390+
return err
391+
}
392+
*re = *newRE
393+
return nil
394+
}

regexp_test.go

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
package regexp2
22

33
import (
4+
"encoding/json"
45
"fmt"
56
"reflect"
67
"strings"
@@ -1329,3 +1330,37 @@ func TestParseShortSlashPEnd(t *testing.T) {
13291330
t.Fatalf("Expected match")
13301331
}
13311332
}
1333+
1334+
func TestMarshal(t *testing.T) {
1335+
re := MustCompile(`.*`, 0)
1336+
m, err := json.Marshal(re)
1337+
if err != nil {
1338+
t.Fatalf("Unexpected error: %v", err)
1339+
}
1340+
if string(m) != `".*"` {
1341+
t.Fatalf(`Expected ".*"`)
1342+
}
1343+
}
1344+
1345+
func TestUnMarshal(t *testing.T) {
1346+
DefaultUnmarshalOptions = IgnoreCase
1347+
bytes := []byte(`"^[abc]"`)
1348+
var re *Regexp
1349+
err := json.Unmarshal(bytes, &re)
1350+
if err != nil {
1351+
t.Fatalf("Unexpected error: %v", err)
1352+
}
1353+
if re.options != IgnoreCase {
1354+
t.Fatalf("Expected options ignore case")
1355+
}
1356+
if re.String() != `^[abc]` {
1357+
t.Fatalf(`Expected "^[abc]"`)
1358+
}
1359+
ok, err := re.MatchString("A")
1360+
if err != nil {
1361+
t.Fatalf("Unexpected error: %v", err)
1362+
}
1363+
if !ok {
1364+
t.Fatalf(`Expected match`)
1365+
}
1366+
}

0 commit comments

Comments
 (0)