Skip to content

Commit

Permalink
Add control to skip unsupported properties during reflection (#55)
Browse files Browse the repository at this point in the history
  • Loading branch information
vearutop authored Sep 22, 2022
1 parent 917967d commit ddafeed
Show file tree
Hide file tree
Showing 3 changed files with 54 additions and 5 deletions.
18 changes: 13 additions & 5 deletions context.go
Original file line number Diff line number Diff line change
Expand Up @@ -110,11 +110,6 @@ func StripDefinitionNamePrefix(prefix ...string) func(rc *ReflectContext) {
}
}

// SkipEmbeddedMapsSlices disables shortcutting into embedded maps and slices.
func SkipEmbeddedMapsSlices(rc *ReflectContext) {
rc.SkipEmbeddedMapsSlices = true
}

// PropertyNameMapping enables property name mapping from a struct field name.
func PropertyNameMapping(mapping map[string]string) func(rc *ReflectContext) {
return func(rc *ReflectContext) {
Expand All @@ -127,6 +122,16 @@ func ProcessWithoutTags(rc *ReflectContext) {
rc.ProcessWithoutTags = true
}

// SkipEmbeddedMapsSlices disables shortcutting into embedded maps and slices.
func SkipEmbeddedMapsSlices(rc *ReflectContext) {
rc.SkipEmbeddedMapsSlices = true
}

// SkipUnsupportedProperties skips properties with unsupported types (func, chan, etc...) instead of failing.
func SkipUnsupportedProperties(rc *ReflectContext) {
rc.SkipUnsupportedProperties = true
}

// ReflectContext accompanies single reflect operation.
type ReflectContext struct {
// Context allows communicating user data between reflection steps.
Expand Down Expand Up @@ -176,6 +181,9 @@ type ReflectContext struct {
// SkipNonConstraints disables parsing of `default` and `example` field tags.
SkipNonConstraints bool

// SkipUnsupportedProperties skips properties with unsupported types (func, chan, etc...) instead of failing.
SkipUnsupportedProperties bool

Path []string
definitions map[refl.TypeString]Schema // list of all definition objects
definitionRefs map[refl.TypeString]Ref
Expand Down
20 changes: 20 additions & 0 deletions reflect.go
Original file line number Diff line number Diff line change
Expand Up @@ -194,6 +194,22 @@ func checkSchemaSetup(v reflect.Value, s *Schema) (bool, error) {
//
// These interfaces allow exposing particular schema keywords:
// Titled, Described, Enum, NamedEnum.
//
// Available options:
//
// CollectDefinitions
// DefinitionsPrefix
// PropertyNameTag
// InterceptType
// InterceptProperty
// InlineRefs
// RootNullable
// RootRef
// StripDefinitionNamePrefix
// PropertyNameMapping
// ProcessWithoutTags
// SkipEmbeddedMapsSlices
// SkipUnsupportedProperties
func (r *Reflector) Reflect(i interface{}, options ...func(rc *ReflectContext)) (Schema, error) {
rc := ReflectContext{}
rc.Context = context.Background()
Expand Down Expand Up @@ -667,6 +683,10 @@ func (r *Reflector) kindSwitch(t reflect.Type, v reflect.Value, schema *Schema,
case reflect.Interface:
schema.Type = nil
default:
if rc.SkipUnsupportedProperties {
return ErrSkipProperty
}

return fmt.Errorf("%s: type is not supported: %s", strings.Join(rc.Path[1:], "."), t.String())
}

Expand Down
21 changes: 21 additions & 0 deletions reflect_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -976,6 +976,27 @@ func TestReflector_Reflect_processWithoutTags_true(t *testing.T) {
}`), s)
}

func TestReflector_Reflect_processWithoutTags_tolerateUnknownTypes(t *testing.T) {
type Test struct {
Foo string
Bar int
Baz bool `json:"baz"`
Fun func()
Chan chan bool
qux string
}

r := jsonschema.Reflector{}

s, err := r.Reflect(Test{}, jsonschema.ProcessWithoutTags, jsonschema.SkipUnsupportedProperties)
assert.NoError(t, err)

assertjson.EqualMarshal(t, []byte(`{
"properties":{"Bar":{"type":"integer"},"Foo":{"type":"string"},"baz":{"type":"boolean"}},
"type":"object"
}`), s)
}

func TestReflector_Reflect_processWithoutTags_false(t *testing.T) {
type Test struct {
Foo string
Expand Down

0 comments on commit ddafeed

Please sign in to comment.