Skip to content

Commit

Permalink
process only unprocessed tags in recursion
Browse files Browse the repository at this point in the history
  • Loading branch information
candiduslynx committed Sep 26, 2023
1 parent 73900b4 commit 910f04b
Show file tree
Hide file tree
Showing 3 changed files with 23 additions and 7 deletions.
3 changes: 3 additions & 0 deletions fixtures/array_handling.json
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,9 @@
"ArrayHandler": {
"properties": {
"min_len": {
"default": [
"qwerty"
],
"items": {
"type": "string",
"minLength": 2
Expand Down
25 changes: 19 additions & 6 deletions reflect.go
Original file line number Diff line number Diff line change
Expand Up @@ -658,7 +658,7 @@ func (t *Schema) structKeywordsFromTags(f reflect.StructField, parent *Schema, p
t.Description = f.Tag.Get("jsonschema_description")

tags := splitOnUnescapedCommas(f.Tag.Get("jsonschema"))
t.genericKeywords(tags, parent, propertyName)
tags = t.genericKeywords(tags, parent, propertyName)

switch t.Type {
case "string":
Expand All @@ -677,7 +677,8 @@ func (t *Schema) structKeywordsFromTags(f reflect.StructField, parent *Schema, p
}

// read struct tags for generic keywords
func (t *Schema) genericKeywords(tags []string, parent *Schema, propertyName string) { //nolint:gocyclo
func (t *Schema) genericKeywords(tags []string, parent *Schema, propertyName string) []string {

Check failure on line 680 in reflect.go

View workflow job for this annotation

GitHub Actions / golangci-lint

cyclomatic complexity 29 of func `(*Schema).genericKeywords` is high (> 20) (gocyclo)
unprocessed := make([]string, 0, len(tags))
for _, tag := range tags {
nameValue := strings.Split(tag, "=")
if len(nameValue) == 2 {
Expand Down Expand Up @@ -773,9 +774,12 @@ func (t *Schema) genericKeywords(tags []string, parent *Schema, propertyName str
Type: ty,
})
}
default:
unprocessed = append(unprocessed, tag)
}
}
}
return unprocessed
}

// read struct tags for boolean type keywords
Expand Down Expand Up @@ -886,6 +890,8 @@ func (t *Schema) numericalKeywords(tags []string) {
// read struct tags for array type keywords
func (t *Schema) arrayKeywords(tags []string) {
var defaultValues []any

unprocessedTags := make([]string, 0, len(tags))
for _, tag := range tags {
nameValue := strings.Split(tag, "=")
if len(nameValue) == 2 {
Expand All @@ -905,24 +911,31 @@ func (t *Schema) arrayKeywords(tags []string) {
t.Items.Format = val
case "pattern":
t.Items.Pattern = val
default:
unprocessedTags = append(unprocessedTags, tag) // left for further processing by underlying type
}
}
}
if len(defaultValues) > 0 {
t.Default = defaultValues
}

if len(unprocessedTags) == 0 {
// we don't have anything else to process
return
}

switch t.Items.Type {
case "string":
t.Items.stringKeywords(tags)
t.Items.stringKeywords(unprocessedTags)
case "number":
t.Items.numericalKeywords(tags)
t.Items.numericalKeywords(unprocessedTags)
case "integer":
t.Items.numericalKeywords(tags)
t.Items.numericalKeywords(unprocessedTags)
case "array":
// explicitly don't support traversal for the [][]..., as it's unclear where the array tags belong
case "boolean":
t.Items.booleanKeywords(tags)
t.Items.booleanKeywords(unprocessedTags)
}
}

Expand Down
2 changes: 1 addition & 1 deletion reflect_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -591,7 +591,7 @@ func TestNumberHandling(t *testing.T) {

func TestArrayHandling(t *testing.T) {
type ArrayHandler struct {
MinLen []string `json:"min_len" jsonschema:"minLength=2"`
MinLen []string `json:"min_len" jsonschema:"minLength=2,default=qwerty"`
MinVal []float64 `json:"min_val" jsonschema:"minimum=2.5"`
}

Expand Down

0 comments on commit 910f04b

Please sign in to comment.