Skip to content

Commit

Permalink
format: registration at compiler level
Browse files Browse the repository at this point in the history
  • Loading branch information
santhosh-tekuri committed Feb 4, 2023
1 parent ccf16be commit 0950b31
Show file tree
Hide file tree
Showing 2 changed files with 23 additions and 5 deletions.
17 changes: 15 additions & 2 deletions compiler.go
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,10 @@ type Compiler struct {
// If nil, package global LoadURL is used.
LoadURL func(s string) (io.ReadCloser, 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

// AssertFormat for specifications >= draft2019-09.
AssertFormat bool

Expand Down Expand Up @@ -74,7 +78,12 @@ func MustCompileString(url, schema string) *Schema {
// if '$schema' attribute is missing, it is treated as draft7. to change this
// behavior change Compiler.Draft value
func NewCompiler() *Compiler {
return &Compiler{Draft: latest, resources: make(map[string]*resource), extensions: make(map[string]extension)}
return &Compiler{
Draft: latest,
resources: make(map[string]*resource),
Formats: make(map[string]func(interface{}) bool),
extensions: make(map[string]extension),
}
}

// AddResource adds in-memory resource to the compiler.
Expand Down Expand Up @@ -635,7 +644,11 @@ func (c *Compiler) compileMap(r *resource, stack []schemaRef, sref schemaRef, re
if format, ok := m["format"]; ok {
s.Format = format.(string)
if r.draft.version < 2019 || c.AssertFormat || r.schema.meta.hasVocab("format-assertion") {
s.format, _ = Formats[s.Format]
if format, ok := c.Formats[s.Format]; ok {
s.format = format
} else {
s.format, _ = Formats[s.Format]
}
}
}

Expand Down
11 changes: 8 additions & 3 deletions example_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -84,7 +84,9 @@ func Example_fromStrings() {

// Example_userDefinedFormat shows how to define 'odd-number' format.
func Example_userDefinedFormat() {
jsonschema.Formats["odd-number"] = func(v interface{}) bool {
c := jsonschema.NewCompiler()
c.AssertFormat = true
c.Formats["odd-number"] = func(v interface{}) bool {
switch v := v.(type) {
case json.Number, float32, float64, int, int8, int32, int64, uint, uint8, uint32, uint64:
n, _ := strconv.ParseInt(fmt.Sprint(v), 10, 64)
Expand All @@ -95,13 +97,16 @@ func Example_userDefinedFormat() {
}

schema := `{
"$schema": "http://json-schema.org/draft-07/schema",
"type": "integer",
"format": "odd-number"
}`
instance := 5

sch, err := jsonschema.CompileString("schema.json", schema)
if err := c.AddResource("schema.json", strings.NewReader(schema)); err != nil {
log.Fatalf("%v", err)
}

sch, err := c.Compile("schema.json")
if err != nil {
log.Fatalf("%#v", err)
}
Expand Down

0 comments on commit 0950b31

Please sign in to comment.