…flector
Previously, in order to reference another type in your schema, you would have to do one of the following:
1. duplicate the schema declaration of that type inline in the schema, which is cumbersome for types with inferred reflection-based schemas
2. use a manual `$ref` in the schema, and ensure elsewhere in your code that you at some point visit the referenced type
3. create a reflector(), reflect on the type you want to reference, and introspect on the generated schema to pull out the type definition
- this is especially error-prone because you lose type information for _other_ referenced types, and you also run into infinite-recursion issues when dealing with cyclical types.
This change provides `JSONSchemaHandle(ReflectorHandle)`, a hook in the same vein as `JSONSchema() *jsonschema.Schema`, but with an api object to call back into the Reflector to get rhe schema handle for a type.
This allows the user to manually create complex schemas, e.g. using OneOf, AllOf, etc, while referencing other types from within their codebase, and still getting the automatic code-generation from those structs/enums.
```go
type ReflectorHandle struct {
SchemaFor func(t any) *Schema
SchemaForType func(t reflect.Type) *Schema
}
```
Usage:
```go
type TypeOne struct {
Type string `json:"type" jsonschema:"required,enum=one"`
OneField string `json:"oneField"`
}
type TypeTwo struct {
Type string `json:"type" jsonschema:"required,enum=two"`
TwoField string `json:"twoField"`
}
type RecursiveType struct {
Type string `json:"type" jsonschema:"required,enum=recursive"`
Self *RecursiveType `json:"self"`
}
func (HandleTest) JSONSchemaHandle(handle ReflectorHandle) *Schema {
schema := &Schema{
OneOf: []*Schema{
handle.SchemaFor(TypeOne{}),
handle.SchemaForType(reflect.TypeOf(TypeTwo{})),
handle.SchemaFor(RecursiveType{}),
},
}
return schema
}
```
Names are provisional -- I'm not very good at naming and willing to accept pretty much any suggestions