Skip to content

Commit

Permalink
feature: allow custom regexp impl
Browse files Browse the repository at this point in the history
  • Loading branch information
santhosh-tekuri committed Aug 4, 2023
1 parent f2cc8ae commit bbc9f89
Show file tree
Hide file tree
Showing 2 changed files with 43 additions and 8 deletions.
46 changes: 41 additions & 5 deletions compiler.go
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,12 @@ type Compiler struct {
// If nil, package global LoadURL is used.
LoadURL func(s string) (io.ReadCloser, error)

// CompileRegex comples given regular expression.
// Defaults to golang's regexp implementation.
//
// NOTE: If you are overriding this, also ensure to override "regex" Format.

This comment has been minimized.

Copy link
@tschaub

tschaub Nov 28, 2023

Can you help me make sense of this comment? I'm trying to understand how to also override "regex" Format.

CompileRegex func(s string) (Regexp, error)

// Formats can be registered by adding to this map. Key is format name,
// value is function that knows how to validate that format.
Formats map[string]func(interface{}) bool
Expand Down Expand Up @@ -87,9 +93,13 @@ func MustCompileString(url, schema string) *Schema {
// behavior change Compiler.Draft value
func NewCompiler() *Compiler {
return &Compiler{
Draft: latest,
resources: make(map[string]*resource),
Formats: make(map[string]func(interface{}) bool),
Draft: latest,
resources: make(map[string]*resource),
Formats: make(map[string]func(interface{}) bool),
CompileRegex: func(s string) (Regexp, error) {
re, err := regexp.Compile(s)
return (*goRegexp)(re), err
},
Decoders: make(map[string]func(string) ([]byte, error)),
MediaTypes: make(map[string]func([]byte) error),
extensions: make(map[string]extension),
Expand Down Expand Up @@ -461,7 +471,11 @@ func (c *Compiler) compileMap(r *resource, stack []schemaRef, sref schemaRef, re
s.MinLength, s.MaxLength = loadInt("minLength"), loadInt("maxLength")

if pattern, ok := m["pattern"]; ok {
s.Pattern = regexp.MustCompile(pattern.(string))
var err error
s.Pattern, err = c.CompileRegex(pattern.(string))
if err != nil {
panic("regex Format and compiler.CompileRegex are incompatible")
}
}

if r.draft.version >= 2019 {
Expand Down Expand Up @@ -538,7 +552,7 @@ func (c *Compiler) compileMap(r *resource, stack []schemaRef, sref schemaRef, re

if patternProps, ok := m["patternProperties"]; ok {
patternProps := patternProps.(map[string]interface{})
s.PatternProperties = make(map[*regexp.Regexp]*Schema, len(patternProps))
s.PatternProperties = make(map[Regexp]*Schema, len(patternProps))
for pattern := range patternProps {
s.PatternProperties[regexp.MustCompile(pattern)], err = compile(nil, "patternProperties/"+escape(pattern))
if err != nil {
Expand Down Expand Up @@ -810,3 +824,25 @@ func keywordLocation(stack []schemaRef, path string) string {
}
return loc
}

// Regexp --

// Regexp is the representation of a compiled regular expression.
// A Regexp is safe for concurrent use by multiple goroutines.
type Regexp interface {
// MatchString reports whether the string s contains any match of the regular expression.
MatchString(s string) bool

// String returns the source text used to compile the regular expression.
String() string
}

type goRegexp regexp.Regexp

func (re *goRegexp) MatchString(s string) bool {
return (*regexp.Regexp)(re).MatchString(s)
}

func (re *goRegexp) String() string {
return (*regexp.Regexp)(re).String()
}
5 changes: 2 additions & 3 deletions schema.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,6 @@ import (
"hash/maphash"
"math/big"
"net/url"
"regexp"
"sort"
"strconv"
"strings"
Expand Down Expand Up @@ -52,7 +51,7 @@ type Schema struct {
Properties map[string]*Schema
PropertyNames *Schema
RegexProperties bool // property names must be valid regex. used only in draft4 as workaround in metaschema.
PatternProperties map[*regexp.Regexp]*Schema
PatternProperties map[Regexp]*Schema
AdditionalProperties interface{} // nil or bool or *Schema.
Dependencies map[string]interface{} // map value is *Schema or []string.
DependentRequired map[string][]string
Expand All @@ -76,7 +75,7 @@ type Schema struct {
// string validations
MinLength int // -1 if not specified.
MaxLength int // -1 if not specified.
Pattern *regexp.Regexp
Pattern Regexp
ContentEncoding string
decoder func(string) ([]byte, error)
ContentMediaType string
Expand Down

0 comments on commit bbc9f89

Please sign in to comment.