From 9eb11d13e74d021665e82447f143f8e18918e9cb Mon Sep 17 00:00:00 2001 From: Viacheslav Poturaev Date: Fri, 29 Sep 2023 13:09:09 +0200 Subject: [PATCH] Add ParentSchema to intercept prop params (#97) --- context.go | 1 + reflect.go | 10 ++++++---- reflect_test.go | 45 +++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 52 insertions(+), 4 deletions(-) diff --git a/context.go b/context.go index 9c8a274..2674ab6 100644 --- a/context.go +++ b/context.go @@ -77,6 +77,7 @@ type InterceptPropParams struct { Name string Field reflect.StructField PropertySchema *Schema + ParentSchema *Schema Processed bool } diff --git a/reflect.go b/reflect.go index 164b6e4..adf861a 100644 --- a/reflect.go +++ b/reflect.go @@ -957,10 +957,11 @@ func (r *Reflector) walkProperties(v reflect.Value, parent *Schema, rc *ReflectC if rc.interceptProp != nil { if err := rc.interceptProp(InterceptPropParams{ - Context: rc, - Path: rc.Path, - Name: propName, - Field: field, + Context: rc, + Path: rc.Path, + Name: propName, + Field: field, + ParentSchema: parent, }); err != nil { if errors.Is(err, ErrSkipProperty) { rc.Path = rc.Path[:len(rc.Path)-1] @@ -1026,6 +1027,7 @@ func (r *Reflector) walkProperties(v reflect.Value, parent *Schema, rc *ReflectC Name: propName, Field: field, PropertySchema: &propertySchema, + ParentSchema: parent, Processed: true, }); err != nil { if errors.Is(err, ErrSkipProperty) { diff --git a/reflect_test.go b/reflect_test.go index 112eeb0..035c27c 100644 --- a/reflect_test.go +++ b/reflect_test.go @@ -1679,3 +1679,48 @@ func TestReflector_Reflect_nullable(t *testing.T) { "type":"object" }`, s) } + +func TestReflector_Reflect_customTags(t *testing.T) { + r := jsonschema.Reflector{} + + type My struct { + Foo string `json:"foo" validate:"required" description:"This is foo."` + } + + type Parent struct { + MySlice []*My `json:"my,omitempty" validate:"required" description:"The required array."` + } + + s, err := r.Reflect(Parent{}, jsonschema.InterceptProp(func(params jsonschema.InterceptPropParams) error { + if !params.Processed { + return nil + } + + if v, ok := params.Field.Tag.Lookup("validate"); ok { + if strings.Contains(v, "required") { + params.ParentSchema.Required = append(params.ParentSchema.Required, params.Name) + } + } + + return nil + })) + require.NoError(t, err) + + assertjson.EqMarshal(t, `{ + "required":["my"], + "definitions":{ + "JsonschemaGoTestMy":{ + "required":["foo"], + "properties":{"foo":{"description":"This is foo.","type":"string"}}, + "type":"object" + } + }, + "properties":{ + "my":{ + "description":"The required array.", + "items":{"$ref":"#/definitions/JsonschemaGoTestMy"},"type":"array" + } + }, + "type":"object" + }`, s) +}