-
Notifications
You must be signed in to change notification settings - Fork 4
/
schema.go
137 lines (118 loc) · 3.48 KB
/
schema.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
package jsonschema
import (
"encoding/json"
"fmt"
"strings"
)
// rootSchema is the root schema where all sub schemas are added to.
// This holds the root `Config` structure of Caddy JSON config.
var rootSchema = NewSchema()
// NewSchema creates a new Schema. It's primarily for the
// convenience of initiating struct maps.
func NewSchema() *Schema {
return &Schema{
Definitions: make(map[string]*Schema),
Properties: make(map[string]*Schema),
}
}
// Schema is a structure for JSON schema.
// JSON encoding of a Schema gives a valid JSON schema.
// http://json-schema.org
type Schema struct {
Title string `json:"title,omitempty"`
Description string `json:"description,omitempty"`
MarkdownDescription string `json:"markdownDescription,omitempty"`
Type string `json:"type,omitempty"`
Ref string `json:"$ref,omitempty"`
ArrayItems *Schema `json:"items,omitempty"`
Definitions map[string]*Schema `json:"definitions,omitempty"`
Properties map[string]*Schema `json:"properties,omitempty"`
AdditionalProperties *Schema `json:"additionalProperties,omitempty"`
Required []string `json:"required,omitempty"`
Enum []string `json:"enum,omitempty"`
AdditionalItems bool `json:"additionalItems,omitempty"`
AllOf []*Schema `json:"allOf,omitempty"`
AnyOf []*Schema `json:"anyOf,omitempty"`
OneOf []*Schema `json:"oneOf,omitempty"`
If *Schema `json:"if,omitempty"`
Then *Schema `json:"then,omitempty"`
Else *Schema `json:"else,omitempty"`
Const string `json:"const,omitempty"`
// internal use for docs generation
goPkg string
description string
markdownDescription string
nullable bool
}
func godocLink(pkg string) string {
if pkg == "" {
return ""
}
// api json docs uses dot for typename
if i := strings.LastIndex(pkg, "."); i >= 0 {
pkg = pkg[:i] + "#" + pkg[i+1:]
}
return "https://pkg.go.dev/" + pkg
}
func markdownLink(title, link string) string {
if link == "" {
return ""
}
return fmt.Sprintf("[%s](%s)", title, link)
}
func description(typeName, fieldType, module string) string {
if fieldType == "" {
fieldType = "any"
}
info := fmt.Sprintf("%s: %s\nModule: %s", typeName, fieldType, module)
if module == "" {
info = fmt.Sprintf("%s: %s", typeName, fieldType)
}
return info
}
func markdownDescription(typeName, fieldType, module string) string {
if fieldType == "" {
fieldType = "any"
}
info := fmt.Sprintf("%s: `%s` \nModule: `%s`", typeName, fieldType, module)
if module == "" {
info = fmt.Sprintf("%s: `%s`", typeName, fieldType)
}
return info
}
func getType(typ string) string {
switch typ {
case "bool":
return "boolean"
case "int", "int8", "int16", "int32", "int64",
"uint", "uint8", "uint16", "uint32", "uint64":
return "number"
case "slice":
return "array"
case "any", "":
return ""
case "string", "array": // no transformation needed
return typ
}
return "object"
}
func (s *Schema) setType(typ string) {
s.Type = getType(typ)
}
func (s *Schema) setRef(moduleID string) {
s.Ref = "#/definitions/" + moduleID
}
// MarshalJSON allows to marshal Schema.Type as string or list
func (s Schema) MarshalJSON() ([]byte, error) {
type Alias Schema
if s.nullable {
return json.Marshal(struct {
Type []string `json:"type"`
Alias
}{
Type: []string{s.Type, "null"},
Alias: Alias(s),
})
}
return json.Marshal(Alias(s))
}