18
18
ErrNotImplemented = errors .New ("not implemented" )
19
19
)
20
20
21
+ type fieldWriter struct {
22
+ errWriter
23
+ propertiesCount int
24
+ }
25
+
26
+ // Wrap IO writer so we can consolidate error handling
27
+ // in a single place. Also track properties written
28
+ // so we know when to emit a separator.
21
29
type errWriter struct {
22
- w io.Writer
23
- err error
30
+ w io.Writer // writer instance
31
+ err error // track errors
32
+ }
33
+
34
+ // comma optionally outputs a comma.
35
+ // Invoke this when you're about to write a property.
36
+ // Tracks how many have been written and emits if not the first.
37
+ func (fw * fieldWriter ) comma () {
38
+ if fw .propertiesCount > 0 {
39
+ fw .writeString ("," )
40
+ }
41
+ fw .propertiesCount ++
42
+ }
43
+
44
+ func (fw * fieldWriter ) resetPropertiesCount () {
45
+ fw .propertiesCount = 0
46
+ }
47
+
48
+ // Compatibility with io.Writer interface
49
+ func (ew errWriter ) Write (p []byte ) (int , error ) {
50
+ if ew .err != nil {
51
+ return 0 , ew .err
52
+ }
53
+ return ew .w .Write (p )
24
54
}
25
55
26
56
func (ew errWriter ) writeFormat (format string , a ... interface {}) {
@@ -37,7 +67,7 @@ func (ew errWriter) writeString(s string) {
37
67
_ , ew .err = ew .w .Write ([]byte (s ))
38
68
}
39
69
40
- func (ew errWriter ) write (b []byte ) {
70
+ func (ew errWriter ) writeBytes (b []byte ) {
41
71
if ew .err != nil {
42
72
return
43
73
}
@@ -135,6 +165,35 @@ func validatorToJSONSchema(w io.Writer, v schema.FieldValidator) (err error) {
135
165
return ew .err
136
166
}
137
167
168
+ func serializeField (ew errWriter , key string , field schema.Field ) error {
169
+ fw := fieldWriter {ew , 0 }
170
+ fw .writeFormat ("%q: {" , key )
171
+ if field .Description != "" {
172
+ fw .comma ()
173
+ fw .writeFormat (`"description": %q` , field .Description )
174
+ }
175
+ if field .ReadOnly {
176
+ fw .comma ()
177
+ fw .writeFormat (`"readOnly": %t` , field .ReadOnly )
178
+ }
179
+ if field .Validator != nil {
180
+ fw .comma ()
181
+ fw .err = validatorToJSONSchema (ew , field .Validator )
182
+ }
183
+ if field .Default != nil {
184
+ b , err := json .Marshal (field .Default )
185
+ if err != nil {
186
+ return err
187
+ }
188
+ fw .comma ()
189
+ fw .writeString (`"default": ` )
190
+ fw .writeBytes (b )
191
+ }
192
+ fw .writeString ("}" )
193
+ fw .resetPropertiesCount ()
194
+ return nil
195
+ }
196
+
138
197
// SchemaToJSONSchema writes JSON Schema keys and values based on s, without the outer curly braces, to w.
139
198
func schemaToJSONSchema (w io.Writer , s * schema.Schema ) (err error ) {
140
199
if s == nil {
@@ -155,29 +214,11 @@ func schemaToJSONSchema(w io.Writer, s *schema.Schema) (err error) {
155
214
ew .writeString (", " )
156
215
}
157
216
notFirst = true
158
- ew .writeFormat ("%q: {" , key )
159
- if field .Description != "" {
160
- ew .writeFormat (`"description": %q, ` , field .Description )
161
- }
162
217
if field .Required {
163
218
required = append (required , fmt .Sprintf ("%q" , key ))
164
219
}
165
- if field .ReadOnly {
166
- ew .writeFormat (`"readOnly": %t, ` , field .ReadOnly )
167
- }
168
- if ew .err == nil {
169
- ew .err = validatorToJSONSchema (w , field .Validator )
170
- }
171
- if field .Default != nil {
172
- b , err := json .Marshal (field .Default )
173
- if err != nil {
174
- return err
175
- }
176
- ew .writeString (`, "default": ` )
177
- ew .write (b )
178
- }
179
- ew .writeString ("}" )
180
- if ew .err != nil {
220
+ err := serializeField (ew , key , field )
221
+ if err != nil || ew .err != nil {
181
222
break
182
223
}
183
224
}
0 commit comments