From 910f04b01376491cb56d1f8493c357223c890cd2 Mon Sep 17 00:00:00 2001 From: candiduslynx Date: Tue, 26 Sep 2023 20:11:17 +0300 Subject: [PATCH] process only unprocessed tags in recursion --- fixtures/array_handling.json | 3 +++ reflect.go | 25 +++++++++++++++++++------ reflect_test.go | 2 +- 3 files changed, 23 insertions(+), 7 deletions(-) diff --git a/fixtures/array_handling.json b/fixtures/array_handling.json index 8b55d88..b90ceeb 100644 --- a/fixtures/array_handling.json +++ b/fixtures/array_handling.json @@ -6,6 +6,9 @@ "ArrayHandler": { "properties": { "min_len": { + "default": [ + "qwerty" + ], "items": { "type": "string", "minLength": 2 diff --git a/reflect.go b/reflect.go index a6f99ff..3d4bebf 100644 --- a/reflect.go +++ b/reflect.go @@ -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": @@ -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 { + unprocessed := make([]string, 0, len(tags)) for _, tag := range tags { nameValue := strings.Split(tag, "=") if len(nameValue) == 2 { @@ -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 @@ -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 { @@ -905,6 +911,8 @@ 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 } } } @@ -912,17 +920,22 @@ func (t *Schema) arrayKeywords(tags []string) { 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) } } diff --git a/reflect_test.go b/reflect_test.go index e97cdb9..d463097 100644 --- a/reflect_test.go +++ b/reflect_test.go @@ -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"` }