From 48571ee1ee3c616a24b0364fcaa63a9df6c1b52f Mon Sep 17 00:00:00 2001 From: Glenn Lewis <6598971+gmlewis@users.noreply.github.com> Date: Thu, 12 Jan 2023 20:45:34 -0500 Subject: [PATCH 1/5] Add support for oneof_ref Signed-off-by: Glenn Lewis <6598971+gmlewis@users.noreply.github.com> --- README.md | 1 + examples_test.go | 11 +++++++++++ reflect.go | 11 +++++++++++ 3 files changed, 23 insertions(+) diff --git a/README.md b/README.md index 100ad0c..7db6041 100644 --- a/README.md +++ b/README.md @@ -37,6 +37,7 @@ type TestUser struct { BirthDate time.Time `json:"birth_date,omitempty" jsonschema:"oneof_required=date"` YearOfBirth string `json:"year_of_birth,omitempty" jsonschema:"oneof_required=year"` Metadata interface{} `json:"metadata,omitempty" jsonschema:"oneof_type=string;array"` + IPAddress interface{} `json:"ipAddress,omitempty" jsonschema:"oneof_ref=#/$defs/ipv4;#/$defs/ipv6"` FavColor string `json:"fav_color,omitempty" jsonschema:"enum=red,enum=green,enum=blue"` } ``` diff --git a/examples_test.go b/examples_test.go index 82cae05..9db9dcf 100644 --- a/examples_test.go +++ b/examples_test.go @@ -16,6 +16,7 @@ type SampleUser struct { BirthDate time.Time `json:"birth_date,omitempty" jsonschema:"oneof_required=date"` YearOfBirth string `json:"year_of_birth,omitempty" jsonschema:"oneof_required=year"` Metadata interface{} `json:"metadata,omitempty" jsonschema:"oneof_type=string;array"` + IPAddress interface{} `json:"ipAddress,omitempty" jsonschema:"oneof_ref=#/$defs/ipv4;#/$defs/ipv6"` FavColor string `json:"fav_color,omitempty" jsonschema:"enum=red,enum=green,enum=blue"` } @@ -93,6 +94,16 @@ func ExampleReflect() { // } // ] // }, + // "ipAddress": { + // "oneOf": [ + // { + // "$ref": "#/$defs/ipv4" + // }, + // { + // "$ref": "#/$defs/ipv6" + // } + // ] + // }, // "fav_color": { // "type": "string", // "enum": [ diff --git a/reflect.go b/reflect.go index 6ebc6be..2471a96 100644 --- a/reflect.go +++ b/reflect.go @@ -720,6 +720,17 @@ func (t *Schema) genericKeywords(tags []string, parent *Schema, propertyName str parent.AnyOf = append(parent.AnyOf, typeFound) } typeFound.Required = append(typeFound.Required, propertyName) + case "oneof_ref": + if t.OneOf == nil { + t.OneOf = make([]*Schema, 0, 1) + } + t.Ref = "" + refs := strings.Split(nameValue[1], ";") + for _, r := range refs { + t.OneOf = append(t.OneOf, &Schema{ + Ref: r, + }) + } case "oneof_type": if t.OneOf == nil { t.OneOf = make([]*Schema, 0, 1) From 05f99e8bf6a738e369d0465fc3dfc454318ba256 Mon Sep 17 00:00:00 2001 From: Glenn Lewis <6598971+gmlewis@users.noreply.github.com> Date: Tue, 17 Jan 2023 12:27:06 -0500 Subject: [PATCH 2/5] Support []any with oneof_ref Signed-off-by: Glenn Lewis <6598971+gmlewis@users.noreply.github.com> --- README.md | 1 + examples_test.go | 14 ++++++++++++++ reflect.go | 12 ++++++++---- 3 files changed, 23 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index 7db6041..dc75a66 100644 --- a/README.md +++ b/README.md @@ -38,6 +38,7 @@ type TestUser struct { YearOfBirth string `json:"year_of_birth,omitempty" jsonschema:"oneof_required=year"` Metadata interface{} `json:"metadata,omitempty" jsonschema:"oneof_type=string;array"` IPAddress interface{} `json:"ipAddress,omitempty" jsonschema:"oneof_ref=#/$defs/ipv4;#/$defs/ipv6"` + IPAddresses []interface{} `json:"ipAddresses,omitempty" jsonschema:"oneof_ref=#/$defs/ipv4;#/$defs/ipv6"` FavColor string `json:"fav_color,omitempty" jsonschema:"enum=red,enum=green,enum=blue"` } ``` diff --git a/examples_test.go b/examples_test.go index 9db9dcf..d155336 100644 --- a/examples_test.go +++ b/examples_test.go @@ -17,6 +17,7 @@ type SampleUser struct { YearOfBirth string `json:"year_of_birth,omitempty" jsonschema:"oneof_required=year"` Metadata interface{} `json:"metadata,omitempty" jsonschema:"oneof_type=string;array"` IPAddress interface{} `json:"ipAddress,omitempty" jsonschema:"oneof_ref=#/$defs/ipv4;#/$defs/ipv6"` + IPAddresses []interface{} `json:"ipAddresses,omitempty" jsonschema:"oneof_ref=#/$defs/ipv4;#/$defs/ipv6"` FavColor string `json:"fav_color,omitempty" jsonschema:"enum=red,enum=green,enum=blue"` } @@ -104,6 +105,19 @@ func ExampleReflect() { // } // ] // }, + // "ipAddresses": { + // "items": { + // "oneOf": [ + // { + // "$ref": "#/$defs/ipv4" + // }, + // { + // "$ref": "#/$defs/ipv6" + // } + // ] + // }, + // "type": "array" + // }, // "fav_color": { // "type": "string", // "enum": [ diff --git a/reflect.go b/reflect.go index 2471a96..d487510 100644 --- a/reflect.go +++ b/reflect.go @@ -721,13 +721,17 @@ func (t *Schema) genericKeywords(tags []string, parent *Schema, propertyName str } typeFound.Required = append(typeFound.Required, propertyName) case "oneof_ref": - if t.OneOf == nil { - t.OneOf = make([]*Schema, 0, 1) + subSchema := t + if t.Items != nil { + subSchema = t.Items } - t.Ref = "" + if subSchema.OneOf == nil { + subSchema.OneOf = make([]*Schema, 0, 1) + } + subSchema.Ref = "" refs := strings.Split(nameValue[1], ";") for _, r := range refs { - t.OneOf = append(t.OneOf, &Schema{ + subSchema.OneOf = append(subSchema.OneOf, &Schema{ Ref: r, }) } From 4d51093309c191610231543f00cb87638dcfb2d8 Mon Sep 17 00:00:00 2001 From: Glenn Lewis <6598971+gmlewis@users.noreply.github.com> Date: Thu, 2 Feb 2023 09:51:30 -0500 Subject: [PATCH 3/5] Update README.md Signed-off-by: Glenn Lewis <6598971+gmlewis@users.noreply.github.com> --- README.md | 26 +++++++++++++++++++++++++- 1 file changed, 25 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index dc75a66..ba81c57 100644 --- a/README.md +++ b/README.md @@ -51,7 +51,8 @@ jsonschema.Reflect(&TestUser{}) ```json { - "$schema": "http://json-schema.org/draft/2020-12/schema", + "$schema": "https://json-schema.org/draft/2020-12/schema", + "$id": "https://github.com/invopop/jsonschema_test/sample-user", "$ref": "#/$defs/SampleUser", "$defs": { "SampleUser": { @@ -105,6 +106,29 @@ jsonschema.Reflect(&TestUser{}) } ] }, + "ipAddress": { + "oneOf": [ + { + "$ref": "#/$defs/ipv4" + }, + { + "$ref": "#/$defs/ipv6" + } + ] + }, + "ipAddresses": { + "items": { + "oneOf": [ + { + "$ref": "#/$defs/ipv4" + }, + { + "$ref": "#/$defs/ipv6" + } + ] + }, + "type": "array" + }, "fav_color": { "type": "string", "enum": ["red", "green", "blue"] From 3d1d723244d1164cc88eb31865ba84c782c3bee5 Mon Sep 17 00:00:00 2001 From: Glenn Lewis <6598971+gmlewis@users.noreply.github.com> Date: Mon, 26 Jun 2023 20:06:58 -0400 Subject: [PATCH 4/5] Address review feedback Signed-off-by: Glenn Lewis <6598971+gmlewis@users.noreply.github.com> --- README.md | 8 ++++---- examples_test.go | 8 ++++---- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/README.md b/README.md index ba81c57..fe0e2b8 100644 --- a/README.md +++ b/README.md @@ -37,8 +37,8 @@ type TestUser struct { BirthDate time.Time `json:"birth_date,omitempty" jsonschema:"oneof_required=date"` YearOfBirth string `json:"year_of_birth,omitempty" jsonschema:"oneof_required=year"` Metadata interface{} `json:"metadata,omitempty" jsonschema:"oneof_type=string;array"` - IPAddress interface{} `json:"ipAddress,omitempty" jsonschema:"oneof_ref=#/$defs/ipv4;#/$defs/ipv6"` - IPAddresses []interface{} `json:"ipAddresses,omitempty" jsonschema:"oneof_ref=#/$defs/ipv4;#/$defs/ipv6"` + IPAddress interface{} `json:"ip_address,omitempty" jsonschema:"oneof_ref=#/$defs/ipv4;#/$defs/ipv6"` + IPAddresses []interface{} `json:"ip_addresses,omitempty" jsonschema:"oneof_ref=#/$defs/ipv4;#/$defs/ipv6"` FavColor string `json:"fav_color,omitempty" jsonschema:"enum=red,enum=green,enum=blue"` } ``` @@ -106,7 +106,7 @@ jsonschema.Reflect(&TestUser{}) } ] }, - "ipAddress": { + "ip_address": { "oneOf": [ { "$ref": "#/$defs/ipv4" @@ -116,7 +116,7 @@ jsonschema.Reflect(&TestUser{}) } ] }, - "ipAddresses": { + "ip_addresses": { "items": { "oneOf": [ { diff --git a/examples_test.go b/examples_test.go index d155336..871491e 100644 --- a/examples_test.go +++ b/examples_test.go @@ -16,8 +16,8 @@ type SampleUser struct { BirthDate time.Time `json:"birth_date,omitempty" jsonschema:"oneof_required=date"` YearOfBirth string `json:"year_of_birth,omitempty" jsonschema:"oneof_required=year"` Metadata interface{} `json:"metadata,omitempty" jsonschema:"oneof_type=string;array"` - IPAddress interface{} `json:"ipAddress,omitempty" jsonschema:"oneof_ref=#/$defs/ipv4;#/$defs/ipv6"` - IPAddresses []interface{} `json:"ipAddresses,omitempty" jsonschema:"oneof_ref=#/$defs/ipv4;#/$defs/ipv6"` + IPAddress interface{} `json:"ip_address,omitempty" jsonschema:"oneof_ref=#/$defs/ipv4;#/$defs/ipv6"` + IPAddresses []interface{} `json:"ip_addresses,omitempty" jsonschema:"oneof_ref=#/$defs/ipv4;#/$defs/ipv6"` FavColor string `json:"fav_color,omitempty" jsonschema:"enum=red,enum=green,enum=blue"` } @@ -95,7 +95,7 @@ func ExampleReflect() { // } // ] // }, - // "ipAddress": { + // "ip_address": { // "oneOf": [ // { // "$ref": "#/$defs/ipv4" @@ -105,7 +105,7 @@ func ExampleReflect() { // } // ] // }, - // "ipAddresses": { + // "ip_addresses": { // "items": { // "oneOf": [ // { From 28cc7fb60085c791c2c3d1315ff5702cb73f52f4 Mon Sep 17 00:00:00 2001 From: Glenn Lewis <6598971+gmlewis@users.noreply.github.com> Date: Wed, 28 Jun 2023 08:49:03 -0400 Subject: [PATCH 5/5] Add unit test coverage Signed-off-by: Glenn Lewis <6598971+gmlewis@users.noreply.github.com> --- fixtures/oneof.json | 13 +++++++++++++ reflect_test.go | 1 + 2 files changed, 14 insertions(+) diff --git a/fixtures/oneof.json b/fixtures/oneof.json index c1daf0f..4860b05 100644 --- a/fixtures/oneof.json +++ b/fixtures/oneof.json @@ -82,6 +82,19 @@ }, "child": { "$ref": "#/$defs/ChildOneOf" + }, + "field6": { + "oneOf": [ + { + "$ref": "Outer" + }, + { + "$ref": "OuterNamed" + }, + { + "$ref": "OuterPtr" + } + ] } }, "additionalProperties": false, diff --git a/reflect_test.go b/reflect_test.go index c0d2c9f..13a96ca 100644 --- a/reflect_test.go +++ b/reflect_test.go @@ -138,6 +138,7 @@ type RootOneOf struct { Field3 interface{} `json:"field3" jsonschema:"oneof_type=string;array"` Field4 string `json:"field4" jsonschema:"oneof_required=group1"` Field5 ChildOneOf `json:"child"` + Field6 interface{} `json:"field6" jsonschema:"oneof_ref=Outer;OuterNamed;OuterPtr"` } type ChildOneOf struct {