From 6da915f1869e93a0f6e576d5ac64f60043e4a932 Mon Sep 17 00:00:00 2001 From: Adam Bouqdib Date: Mon, 8 Jan 2024 23:59:24 +0000 Subject: [PATCH] fix: support json inline tag --- fixtures/inlining_tag.json | 17 +++++++++++++++++ reflect.go | 14 ++++++++++++++ reflect_test.go | 6 ++++++ 3 files changed, 37 insertions(+) create mode 100644 fixtures/inlining_tag.json diff --git a/fixtures/inlining_tag.json b/fixtures/inlining_tag.json new file mode 100644 index 0000000..12bc2f7 --- /dev/null +++ b/fixtures/inlining_tag.json @@ -0,0 +1,17 @@ +{ + "$schema": "https://json-schema.org/draft/2020-12/schema", + "$id": "https://github.com/invopop/jsonschema/outer-inlined", + "properties": { + "text": { + "type": "string" + }, + "Foo": { + "type": "string" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "Foo" + ] +} \ No newline at end of file diff --git a/reflect.go b/reflect.go index 3249c8c..0df85eb 100644 --- a/reflect.go +++ b/reflect.go @@ -976,6 +976,15 @@ func ignoredByJSONSchemaTags(tags []string) bool { return tags[0] == "-" } +func inlinedByJSONTags(tags []string) bool { + for _, tag := range tags[1:] { + if tag == "inline" { + return true + } + } + return false +} + // toJSONNumber converts string to *json.Number. // It'll aso return whether the number is valid. func toJSONNumber(s string) (json.Number, bool) { @@ -1037,6 +1046,11 @@ func (r *Reflector) reflectFieldName(f reflect.StructField) (string, bool, bool, } } + // As per JSON Marshal rules, inline nested structs that have `inline` tag. + if inlinedByJSONTags(jsonTags) { + return "", true, false, false + } + // Try to determine the name from the different combos name := f.Name if jsonTags[0] != "" { diff --git a/reflect_test.go b/reflect_test.go index 94b6018..e4a6fa3 100644 --- a/reflect_test.go +++ b/reflect_test.go @@ -176,6 +176,11 @@ type OuterNamed struct { Inner `json:"inner"` } +type OuterInlined struct { + Text `json:"text,omitempty"` + Inner `json:",inline"` +} + type OuterPtr struct { *Inner Text `json:",omitempty"` @@ -419,6 +424,7 @@ func TestSchemaGeneration(t *testing.T) { {&Outer{}, &Reflector{ExpandedStruct: true}, "fixtures/inlining_inheritance.json"}, {&OuterNamed{}, &Reflector{ExpandedStruct: true}, "fixtures/inlining_embedded.json"}, {&OuterNamed{}, &Reflector{ExpandedStruct: true, AssignAnchor: true}, "fixtures/inlining_embedded_anchored.json"}, + {&OuterInlined{}, &Reflector{ExpandedStruct: true}, "fixtures/inlining_tag.json"}, {&OuterPtr{}, &Reflector{ExpandedStruct: true}, "fixtures/inlining_ptr.json"}, {&MinValue{}, &Reflector{}, "fixtures/schema_with_minimum.json"}, {&TestNullable{}, &Reflector{}, "fixtures/nullable.json"},