Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
27 changes: 27 additions & 0 deletions fixtures/keynamed_with_original_names.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
{
"$schema": "https://json-schema.org/draft/2020-12/schema",
"$id": "https://github.com/invopop/jsonschema/key-namer-with-original-field-named",
"$ref": "#/$defs/KeyNamerWithOriginalFieldNamed",
"$defs": {
"KeyNamerWithOriginalFieldNamed": {
"properties": {
"ThisWasLeftAsIs": {
"type": "string"
},
"coming_from_json": {
"type": "boolean"
},
"AAA": {
"type": "string"
}
},
"additionalProperties": false,
"type": "object",
"required": [
"ThisWasLeftAsIs",
"coming_from_json",
"AAA"
]
}
}
}
8 changes: 8 additions & 0 deletions reflect.go
Original file line number Diff line number Diff line change
Expand Up @@ -140,6 +140,12 @@ type Reflector struct {
// If a json tag is present, KeyNamer will receive the tag's name as an argument, not the original key name.
KeyNamer func(string) string

// KeyNamerWithOriginalFieldName allows customizing of key names.
// This is like KeyNamer, except it passes in the name it potentially extracted from the json tag as well as
// the original field's name. Has no effect if KeyNamer set.
// First argument is the original go field name, second is the one extracted from the json tag
KeyNamerWithOriginalFieldName func(string, string) string

// AdditionalFields allows adding structfields for a given type
AdditionalFields func(reflect.Type) []reflect.StructField

Expand Down Expand Up @@ -1055,6 +1061,8 @@ func (r *Reflector) reflectFieldName(f reflect.StructField) (string, bool, bool,
name = ""
} else if r.KeyNamer != nil {
name = r.KeyNamer(name)
} else if r.KeyNamerWithOriginalFieldName != nil {
name = r.KeyNamerWithOriginalFieldName(f.Name, jsonTags[0])
}

return name, false, required, nullable
Expand Down
24 changes: 24 additions & 0 deletions reflect_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -312,6 +312,12 @@ type KeyNamed struct {
RenamedByComputation int `jsonschema_description:"Description was preserved"`
}

type KeyNamerWithOriginalFieldNamed struct {
ThisWasLeftAsIs string
ComesFromJSON bool `json:"coming_from_json"`
A string `json:"bbb"`
}

type SchemaExtendTestBase struct {
FirstName string `json:"FirstName"`
LastName string `json:"LastName"`
Expand Down Expand Up @@ -468,6 +474,24 @@ func TestSchemaGeneration(t *testing.T) {
return "unknown case"
},
}, "fixtures/keynamed.json"},
{&KeyNamerWithOriginalFieldNamed{}, &Reflector{
KeyNamerWithOriginalFieldName: func(fieldName string, tagName string) string {
key := fieldName + ":" + tagName
switch key {
case "ThisWasLeftAsIs:":
return fieldName
case "ComesFromJSON:coming_from_json":
return tagName
case "A:bbb":
b := strings.Builder{}
for i := 0; i < len(tagName); i++ {
b.WriteString(fieldName)
}
return b.String()
}
return "unknown case"
},
}, "fixtures/keynamed_with_original_names.json"},
{MapType{}, &Reflector{}, "fixtures/map_type.json"},
{ArrayType{}, &Reflector{}, "fixtures/array_type.json"},
{SchemaExtendTest{}, &Reflector{}, "fixtures/custom_type_extend.json"},
Expand Down