@@ -15,40 +15,39 @@ import (
1515
1616// For constructs a JSON schema object for the given type argument.
1717//
18- // It is a convenience for ForType.
19- func For [T any ]() (* Schema , error ) {
20- return ForType (reflect .TypeFor [T ]())
21- }
22-
23- // ForType constructs a JSON schema object for the given type.
2418// It translates Go types into compatible JSON schema types, as follows:
25- // - strings have schema type "string"
26- // - bools have schema type "boolean"
27- // - signed and unsigned integer types have schema type "integer"
28- // - floating point types have schema type "number"
29- // - slices and arrays have schema type "array", and a corresponding schema
30- // for items
31- // - maps with string key have schema type "object", and corresponding
32- // schema for additionalProperties
33- // - structs have schema type "object", and disallow additionalProperties.
19+ // - Strings have schema type "string".
20+ // - Bools have schema type "boolean".
21+ // - Signed and unsigned integer types have schema type "integer".
22+ // - Floating point types have schema type "number".
23+ // - Slices and arrays have schema type "array", and a corresponding schema
24+ // for items.
25+ // - Maps with string key have schema type "object", and corresponding
26+ // schema for additionalProperties.
27+ // - Structs have schema type "object", and disallow additionalProperties.
3428// Their properties are derived from exported struct fields, using the
35- // struct field json name. Fields that are marked "omitempty" are
29+ // struct field JSON name. Fields that are marked "omitempty" are
3630// considered optional; all other fields become required properties.
3731//
38- // It returns an error if t contains (possibly recursively) any of the following Go
32+ // For returns an error if t contains (possibly recursively) any of the following Go
3933// types, as they are incompatible with the JSON schema spec.
4034// - maps with key other than 'string'
4135// - function types
4236// - complex numbers
4337// - unsafe pointers
4438//
45- // The cannot be any cycles in the types.
46- // TODO(rfindley): we could perhaps just skip these incompatible fields.
47- func ForType (t reflect.Type ) (* Schema , error ) {
48- return typeSchema (t )
39+ // The types must not have cycles.
40+ func For [T any ]() (* Schema , error ) {
41+ // TODO: consider skipping incompatible fields, instead of failing.
42+ s , err := forType (reflect .TypeFor [T ]())
43+ if err != nil {
44+ var z T
45+ return nil , fmt .Errorf ("For[%T](): %w" , z , err )
46+ }
47+ return s , nil
4948}
5049
51- func typeSchema (t reflect.Type ) (* Schema , error ) {
50+ func forType (t reflect.Type ) (* Schema , error ) {
5251 // Follow pointers: the schema for *T is almost the same as for T, except that
5352 // an explicit JSON "null" is allowed for the pointer.
5453 allowNull := false
@@ -82,14 +81,14 @@ func typeSchema(t reflect.Type) (*Schema, error) {
8281 return nil , fmt .Errorf ("unsupported map key type %v" , t .Key ().Kind ())
8382 }
8483 s .Type = "object"
85- s .AdditionalProperties , err = typeSchema (t .Elem ())
84+ s .AdditionalProperties , err = forType (t .Elem ())
8685 if err != nil {
8786 return nil , fmt .Errorf ("computing map value schema: %v" , err )
8887 }
8988
9089 case reflect .Slice , reflect .Array :
9190 s .Type = "array"
92- s .Items , err = typeSchema (t .Elem ())
91+ s .Items , err = forType (t .Elem ())
9392 if err != nil {
9493 return nil , fmt .Errorf ("computing element schema: %v" , err )
9594 }
@@ -115,7 +114,7 @@ func typeSchema(t reflect.Type) (*Schema, error) {
115114 if s .Properties == nil {
116115 s .Properties = make (map [string ]* Schema )
117116 }
118- s .Properties [info .Name ], err = typeSchema (field .Type )
117+ s .Properties [info .Name ], err = forType (field .Type )
119118 if err != nil {
120119 return nil , err
121120 }
0 commit comments