1
2
3
4
5
6
7
8
9
10
11
12
13
14
15 package jsonschema
16
17 import (
18 "fmt"
19
20 "gopkg.in/yaml.v3"
21 )
22
23 const indentation = " "
24
25 func renderMappingNode(node *yaml.Node, indent string) (result string) {
26 result = "{\n"
27 innerIndent := indent + indentation
28 for i := 0; i < len(node.Content); i += 2 {
29
30 key := node.Content[i].Value
31 result += fmt.Sprintf("%s\"%+v\": ", innerIndent, key)
32
33 value := node.Content[i+1]
34 switch value.Kind {
35 case yaml.ScalarNode:
36 result += "\"" + value.Value + "\""
37 case yaml.MappingNode:
38 result += renderMappingNode(value, innerIndent)
39 case yaml.SequenceNode:
40 result += renderSequenceNode(value, innerIndent)
41 default:
42 result += fmt.Sprintf("???MapItem(Key:%+v, Value:%T)", value, value)
43 }
44 if i < len(node.Content)-2 {
45 result += ","
46 }
47 result += "\n"
48 }
49
50 result += indent + "}"
51 return result
52 }
53
54 func renderSequenceNode(node *yaml.Node, indent string) (result string) {
55 result = "[\n"
56 innerIndent := indent + indentation
57 for i := 0; i < len(node.Content); i++ {
58 item := node.Content[i]
59 switch item.Kind {
60 case yaml.ScalarNode:
61 result += innerIndent + "\"" + item.Value + "\""
62 case yaml.MappingNode:
63 result += innerIndent + renderMappingNode(item, innerIndent) + ""
64 default:
65 result += innerIndent + fmt.Sprintf("???ArrayItem(%+v)", item)
66 }
67 if i < len(node.Content)-1 {
68 result += ","
69 }
70 result += "\n"
71 }
72 result += indent + "]"
73 return result
74 }
75
76 func renderStringArray(array []string, indent string) (result string) {
77 result = "[\n"
78 innerIndent := indent + indentation
79 for i, item := range array {
80 result += innerIndent + "\"" + item + "\""
81 if i < len(array)-1 {
82 result += ","
83 }
84 result += "\n"
85 }
86 result += indent + "]"
87 return result
88 }
89
90
91 func Render(node *yaml.Node) string {
92 if node.Kind == yaml.DocumentNode {
93 if len(node.Content) == 1 {
94 return Render(node.Content[0])
95 }
96 } else if node.Kind == yaml.MappingNode {
97 return renderMappingNode(node, "") + "\n"
98 } else if node.Kind == yaml.SequenceNode {
99 return renderSequenceNode(node, "") + "\n"
100 }
101 return ""
102 }
103
104 func (object *SchemaNumber) nodeValue() *yaml.Node {
105 if object.Integer != nil {
106 return nodeForInt64(*object.Integer)
107 } else if object.Float != nil {
108 return nodeForFloat64(*object.Float)
109 } else {
110 return nil
111 }
112 }
113
114 func (object *SchemaOrBoolean) nodeValue() *yaml.Node {
115 if object.Schema != nil {
116 return object.Schema.nodeValue()
117 } else if object.Boolean != nil {
118 return nodeForBoolean(*object.Boolean)
119 } else {
120 return nil
121 }
122 }
123
124 func nodeForStringArray(array []string) *yaml.Node {
125 content := make([]*yaml.Node, 0)
126 for _, item := range array {
127 content = append(content, nodeForString(item))
128 }
129 return nodeForSequence(content)
130 }
131
132 func nodeForSchemaArray(array []*Schema) *yaml.Node {
133 content := make([]*yaml.Node, 0)
134 for _, item := range array {
135 content = append(content, item.nodeValue())
136 }
137 return nodeForSequence(content)
138 }
139
140 func (object *StringOrStringArray) nodeValue() *yaml.Node {
141 if object.String != nil {
142 return nodeForString(*object.String)
143 } else if object.StringArray != nil {
144 return nodeForStringArray(*(object.StringArray))
145 } else {
146 return nil
147 }
148 }
149
150 func (object *SchemaOrStringArray) nodeValue() *yaml.Node {
151 if object.Schema != nil {
152 return object.Schema.nodeValue()
153 } else if object.StringArray != nil {
154 return nodeForStringArray(*(object.StringArray))
155 } else {
156 return nil
157 }
158 }
159
160 func (object *SchemaOrSchemaArray) nodeValue() *yaml.Node {
161 if object.Schema != nil {
162 return object.Schema.nodeValue()
163 } else if object.SchemaArray != nil {
164 return nodeForSchemaArray(*(object.SchemaArray))
165 } else {
166 return nil
167 }
168 }
169
170 func (object *SchemaEnumValue) nodeValue() *yaml.Node {
171 if object.String != nil {
172 return nodeForString(*object.String)
173 } else if object.Bool != nil {
174 return nodeForBoolean(*object.Bool)
175 } else {
176 return nil
177 }
178 }
179
180 func nodeForNamedSchemaArray(array *[]*NamedSchema) *yaml.Node {
181 content := make([]*yaml.Node, 0)
182 for _, pair := range *(array) {
183 content = appendPair(content, pair.Name, pair.Value.nodeValue())
184 }
185 return nodeForMapping(content)
186 }
187
188 func nodeForNamedSchemaOrStringArray(array *[]*NamedSchemaOrStringArray) *yaml.Node {
189 content := make([]*yaml.Node, 0)
190 for _, pair := range *(array) {
191 content = appendPair(content, pair.Name, pair.Value.nodeValue())
192 }
193 return nodeForMapping(content)
194 }
195
196 func nodeForSchemaEnumArray(array *[]SchemaEnumValue) *yaml.Node {
197 content := make([]*yaml.Node, 0)
198 for _, item := range *array {
199 content = append(content, item.nodeValue())
200 }
201 return nodeForSequence(content)
202 }
203
204 func nodeForMapping(content []*yaml.Node) *yaml.Node {
205 return &yaml.Node{
206 Kind: yaml.MappingNode,
207 Content: content,
208 }
209 }
210
211 func nodeForSequence(content []*yaml.Node) *yaml.Node {
212 return &yaml.Node{
213 Kind: yaml.SequenceNode,
214 Content: content,
215 }
216 }
217
218 func nodeForString(value string) *yaml.Node {
219 return &yaml.Node{
220 Kind: yaml.ScalarNode,
221 Tag: "!!str",
222 Value: value,
223 }
224 }
225
226 func nodeForBoolean(value bool) *yaml.Node {
227 return &yaml.Node{
228 Kind: yaml.ScalarNode,
229 Tag: "!!bool",
230 Value: fmt.Sprintf("%t", value),
231 }
232 }
233
234 func nodeForInt64(value int64) *yaml.Node {
235 return &yaml.Node{
236 Kind: yaml.ScalarNode,
237 Tag: "!!int",
238 Value: fmt.Sprintf("%d", value),
239 }
240 }
241
242 func nodeForFloat64(value float64) *yaml.Node {
243 return &yaml.Node{
244 Kind: yaml.ScalarNode,
245 Tag: "!!float",
246 Value: fmt.Sprintf("%f", value),
247 }
248 }
249
250 func appendPair(nodes []*yaml.Node, name string, value *yaml.Node) []*yaml.Node {
251 nodes = append(nodes, nodeForString(name))
252 nodes = append(nodes, value)
253 return nodes
254 }
255
256 func (schema *Schema) nodeValue() *yaml.Node {
257 n := &yaml.Node{Kind: yaml.MappingNode}
258 content := make([]*yaml.Node, 0)
259 if schema.Title != nil {
260 content = appendPair(content, "title", nodeForString(*schema.Title))
261 }
262 if schema.ID != nil {
263 content = appendPair(content, "id", nodeForString(*schema.ID))
264 }
265 if schema.Schema != nil {
266 content = appendPair(content, "$schema", nodeForString(*schema.Schema))
267 }
268 if schema.Type != nil {
269 content = appendPair(content, "type", schema.Type.nodeValue())
270 }
271 if schema.Items != nil {
272 content = appendPair(content, "items", schema.Items.nodeValue())
273 }
274 if schema.Description != nil {
275 content = appendPair(content, "description", nodeForString(*schema.Description))
276 }
277 if schema.Required != nil {
278 content = appendPair(content, "required", nodeForStringArray(*schema.Required))
279 }
280 if schema.AdditionalProperties != nil {
281 content = appendPair(content, "additionalProperties", schema.AdditionalProperties.nodeValue())
282 }
283 if schema.PatternProperties != nil {
284 content = appendPair(content, "patternProperties", nodeForNamedSchemaArray(schema.PatternProperties))
285 }
286 if schema.Properties != nil {
287 content = appendPair(content, "properties", nodeForNamedSchemaArray(schema.Properties))
288 }
289 if schema.Dependencies != nil {
290 content = appendPair(content, "dependencies", nodeForNamedSchemaOrStringArray(schema.Dependencies))
291 }
292 if schema.Ref != nil {
293 content = appendPair(content, "$ref", nodeForString(*schema.Ref))
294 }
295 if schema.MultipleOf != nil {
296 content = appendPair(content, "multipleOf", schema.MultipleOf.nodeValue())
297 }
298 if schema.Maximum != nil {
299 content = appendPair(content, "maximum", schema.Maximum.nodeValue())
300 }
301 if schema.ExclusiveMaximum != nil {
302 content = appendPair(content, "exclusiveMaximum", nodeForBoolean(*schema.ExclusiveMaximum))
303 }
304 if schema.Minimum != nil {
305 content = appendPair(content, "minimum", schema.Minimum.nodeValue())
306 }
307 if schema.ExclusiveMinimum != nil {
308 content = appendPair(content, "exclusiveMinimum", nodeForBoolean(*schema.ExclusiveMinimum))
309 }
310 if schema.MaxLength != nil {
311 content = appendPair(content, "maxLength", nodeForInt64(*schema.MaxLength))
312 }
313 if schema.MinLength != nil {
314 content = appendPair(content, "minLength", nodeForInt64(*schema.MinLength))
315 }
316 if schema.Pattern != nil {
317 content = appendPair(content, "pattern", nodeForString(*schema.Pattern))
318 }
319 if schema.AdditionalItems != nil {
320 content = appendPair(content, "additionalItems", schema.AdditionalItems.nodeValue())
321 }
322 if schema.MaxItems != nil {
323 content = appendPair(content, "maxItems", nodeForInt64(*schema.MaxItems))
324 }
325 if schema.MinItems != nil {
326 content = appendPair(content, "minItems", nodeForInt64(*schema.MinItems))
327 }
328 if schema.UniqueItems != nil {
329 content = appendPair(content, "uniqueItems", nodeForBoolean(*schema.UniqueItems))
330 }
331 if schema.MaxProperties != nil {
332 content = appendPair(content, "maxProperties", nodeForInt64(*schema.MaxProperties))
333 }
334 if schema.MinProperties != nil {
335 content = appendPair(content, "minProperties", nodeForInt64(*schema.MinProperties))
336 }
337 if schema.Enumeration != nil {
338 content = appendPair(content, "enum", nodeForSchemaEnumArray(schema.Enumeration))
339 }
340 if schema.AllOf != nil {
341 content = appendPair(content, "allOf", nodeForSchemaArray(*schema.AllOf))
342 }
343 if schema.AnyOf != nil {
344 content = appendPair(content, "anyOf", nodeForSchemaArray(*schema.AnyOf))
345 }
346 if schema.OneOf != nil {
347 content = appendPair(content, "oneOf", nodeForSchemaArray(*schema.OneOf))
348 }
349 if schema.Not != nil {
350 content = appendPair(content, "not", schema.Not.nodeValue())
351 }
352 if schema.Definitions != nil {
353 content = appendPair(content, "definitions", nodeForNamedSchemaArray(schema.Definitions))
354 }
355 if schema.Default != nil {
356
357 }
358 if schema.Format != nil {
359 content = appendPair(content, "format", nodeForString(*schema.Format))
360 }
361 n.Content = content
362 return n
363 }
364
365
366 func (schema *Schema) JSONString() string {
367 node := schema.nodeValue()
368 return Render(node)
369 }
370
View as plain text