From 4871f98224ec238e3b86e3d949b543370d577be9 Mon Sep 17 00:00:00 2001 From: Viacheslav Poturaev Date: Sat, 2 Dec 2023 10:50:26 +0100 Subject: [PATCH] Add support for ptr receivers in (Raw)Exposer (#101) --- reflect.go | 31 +++++++++++++++--- reflect_test.go | 86 ++++++++++++++++++++++++++++--------------------- 2 files changed, 76 insertions(+), 41 deletions(-) diff --git a/reflect.go b/reflect.go index 4c356a2..f8e5fa3 100644 --- a/reflect.go +++ b/reflect.go @@ -127,10 +127,24 @@ func checkSchemaSetup(params InterceptSchemaParams) (bool, error) { vi = reflect.New(v.Type().Elem()).Interface() } + vpi := reflect.New(v.Type()).Interface() + reflectEnum(s, "", vi) - if exposer, ok := v.Interface().(Exposer); ok { - schema, err := exposer.JSONSchema() + var e Exposer + + if exposer, ok := vi.(Exposer); ok { + e = exposer + } + + if exposer, ok := vi.(Exposer); ok { + e = exposer + } else if exposer, ok := vpi.(Exposer); ok { + e = exposer + } + + if e != nil { + schema, err := e.JSONSchema() if err != nil { return true, err } @@ -140,8 +154,17 @@ func checkSchemaSetup(params InterceptSchemaParams) (bool, error) { return true, nil } - if exposer, ok := v.Interface().(RawExposer); ok { - schemaBytes, err := exposer.JSONSchemaBytes() + var re RawExposer + + // Checking if RawExposer is defined on a current value. + if exposer, ok := vi.(RawExposer); ok { + re = exposer + } else if exposer, ok := vpi.(RawExposer); ok { // Checking if RawExposer is defined on a pointer to current value. + re = exposer + } + + if re != nil { + schemaBytes, err := re.JSONSchemaBytes() if err != nil { return true, err } diff --git a/reflect_test.go b/reflect_test.go index c6566d8..e250e9a 100644 --- a/reflect_test.go +++ b/reflect_test.go @@ -542,6 +542,14 @@ func (ISOWeek) JSONSchemaBytes() ([]byte, error) { }`), nil } +// ISOWeek is an ISO week. +type PtrRawSchema string + +// JSONSchemaBytes returns JSON Schema definition. +func (*PtrRawSchema) JSONSchemaBytes() ([]byte, error) { + return []byte(`{"type": "string","examples": ["foo"]}`), nil +} + type ISOCountry string // JSONSchemaBytes returns JSON Schema definition. @@ -558,50 +566,54 @@ func (ISOCountry) JSONSchema() (jsonschema.Schema, error) { return s, nil } +type PtrSchema string + +// JSONSchemaBytes returns JSON Schema definition. +func (*PtrSchema) JSONSchema() (jsonschema.Schema, error) { + s := jsonschema.Schema{} + + s.AddType(jsonschema.String) + s.WithExamples("bar") + + return s, nil +} + func TestExposer(t *testing.T) { type Some struct { - Week ISOWeek `json:"week"` - Country ISOCountry `json:"country" deprecated:"true"` + Week ISOWeek `json:"week"` + PtrWeek *ISOWeek `json:"ptr_week"` + Raw PtrRawSchema `json:"raw"` + PtrRaw *PtrRawSchema `json:"ptr_raw"` + Country ISOCountry `json:"country" deprecated:"true"` + PtrCountry ISOCountry `json:"ptr_country" deprecated:"true"` + PtrExp PtrSchema `json:"ptr_exp"` } s, err := (&jsonschema.Reflector{}).Reflect(Some{}) require.NoError(t, err) - j, err := json.MarshalIndent(s, "", " ") - require.NoError(t, err) - - assertjson.Equal(t, []byte(`{ - "definitions": { - "JsonschemaGoTestISOCountry": { - "description": "ISO Country", - "examples": [ - "US" - ], - "maxLength": 2, - "minLength": 2, - "pattern": "^[a-zA-Z]{2}$", - "type": "string" - }, - "JsonschemaGoTestISOWeek": { - "description": "ISO Week", - "examples": [ - "2018-W43" - ], - "pattern": "^[0-9]{4}-W(0[1-9]|[1-4][0-9]|5[0-3])$", - "type": "string" - } - }, - "properties": { - "country": { - "$ref": "#/definitions/JsonschemaGoTestISOCountry", - "deprecated": true - }, - "week": { - "$ref": "#/definitions/JsonschemaGoTestISOWeek" - } - }, - "type": "object" - }`), j, string(j)) + assertjson.EqMarshal(t, `{ + "definitions":{ + "JsonschemaGoTestISOCountry":{ + "description":"ISO Country","examples":["US"],"maxLength":2,"minLength":2, + "pattern":"^[a-zA-Z]{2}$","type":"string" + }, + "JsonschemaGoTestISOWeek":{ + "description":"ISO Week","examples":["2018-W43"], + "pattern":"^[0-9]{4}-W(0[1-9]|[1-4][0-9]|5[0-3])$","type":"string" + } + }, + "properties":{ + "country":{"$ref":"#/definitions/JsonschemaGoTestISOCountry","deprecated":true}, + "ptr_country":{"$ref":"#/definitions/JsonschemaGoTestISOCountry","deprecated":true}, + "ptr_exp":{"examples":["bar"],"type":"string"}, + "ptr_raw":{"examples":["foo"],"type":["string","null"]}, + "ptr_week":{"$ref":"#/definitions/JsonschemaGoTestISOWeek"}, + "raw":{"examples":["foo"],"type":"string"}, + "week":{"$ref":"#/definitions/JsonschemaGoTestISOWeek"} + }, + "type":"object" + }`, s) } type Identity struct {