Skip to content

Commit 8566f02

Browse files
committed
Add support for enums w/o needing to manually specify variations
1 parent 2165f11 commit 8566f02

File tree

3 files changed

+60
-11
lines changed

3 files changed

+60
-11
lines changed

docparse/jsonschema.go

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -110,6 +110,7 @@ const (
110110
paramOmitEmpty = "omitempty"
111111
paramReadOnly = "readonly"
112112
paramOmitDoc = "omitdoc"
113+
paramEnum = "enum"
113114
)
114115

115116
func setTags(name, fName string, p *Schema, tags []string) error {
@@ -129,6 +130,9 @@ func setTags(name, fName string, p *Schema, tags []string) error {
129130
case paramReadOnly:
130131
t := true
131132
p.Readonly = &t
133+
case paramEnum:
134+
// For this type of enum, we figure out the variations based on the type.
135+
p.Type = "enum"
132136

133137
// Various string formats.
134138
// https://tools.ietf.org/html/draft-handrews-json-schema-validation-01#section-7.3
@@ -274,6 +278,15 @@ start:
274278

275279
// Simple identifiers such as "string", "int", "MyType", etc.
276280
case *ast.Ident:
281+
if p.Type == "enum" && len(p.Enum) == 0 {
282+
if variations, err := getEnumVariations(ref.File, pkg, typ.Name); len(variations) > 0 {
283+
p.Enum = variations
284+
return &p, nil
285+
} else if err != nil {
286+
return nil, err
287+
}
288+
}
289+
277290
mappedType, mappedFormat := MapType(prog, pkg+"."+typ.Name)
278291
if mappedType == "" {
279292
// Only check for canonicalType if this isn't mapped.
@@ -443,6 +456,33 @@ start:
443456
return &p, nil
444457
}
445458

459+
// Helper function to extract enum variations from a file.
460+
func getEnumVariations(currentFile, pkgPath, typeName string) ([]string, error) {
461+
resolvedPath, pkg, err := resolvePackage(currentFile, pkgPath)
462+
if err != nil {
463+
return nil, fmt.Errorf("could not resolve package: %v", err)
464+
}
465+
decls, err := getDecls(pkg, resolvedPath)
466+
if err != nil {
467+
return nil, err
468+
}
469+
var variations []string
470+
for _, decl := range decls {
471+
if decl.vs == nil {
472+
continue
473+
}
474+
if exprToString(decl.vs.Type) != typeName {
475+
continue
476+
}
477+
if len(decl.vs.Values) == 0 {
478+
continue
479+
}
480+
variations = append(variations, exprToString(decl.vs.Values[0]))
481+
}
482+
483+
return variations, nil
484+
}
485+
446486
func dropTypePointers(typ ast.Expr) ast.Expr {
447487
var t *ast.StarExpr
448488
var ok bool

docparse/jsonschema_test.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@ func TestFieldToProperty(t *testing.T) {
2222
"sliceP": {Type: "array", Items: &Schema{Type: "string"}},
2323
"cstr": {Type: "string"},
2424
"cstrP": {Type: "string"},
25+
"enumStr": {Type: "enum", Enum: []string{"a", "b", "c"}},
2526
"bar": {Reference: "a.bar"},
2627
"barP": {Reference: "a.bar"},
2728
"pkg": {Reference: "mail.Address"},

docparse/testdata/src/a/a.go

Lines changed: 19 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -11,17 +11,19 @@ import "net/mail"
1111
type foo struct {
1212
// Documented str field.
1313
// Newline.
14-
str string
15-
byt []byte
16-
r rune
17-
b bool // Inline docs.
18-
fl float64
19-
err error
20-
strP *string
21-
slice []string
22-
sliceP []*string
23-
cstr customStr
24-
cstrP *customStr
14+
str string
15+
byt []byte
16+
r rune
17+
b bool // Inline docs.
18+
fl float64
19+
err error
20+
strP *string
21+
slice []string
22+
sliceP []*string
23+
cstr customStr
24+
cstrP *customStr
25+
// {enum}
26+
enumStr customStr
2527
bar bar
2628
barP *bar
2729
pkg mail.Address
@@ -43,6 +45,12 @@ type nested struct {
4345

4446
type customStr string
4547

48+
const (
49+
customStrA customStr = "a"
50+
customStrB customStr = "b"
51+
customStrC customStr = "c"
52+
)
53+
4654
// Document me bar!
4755
type bar struct {
4856
str string

0 commit comments

Comments
 (0)