github.com/livermorium/go-swagger@v0.19.0/generator/templates/tupleserializer.gotmpl (about) 1 {{ define "tupleSerializer" }} 2 // UnmarshalJSON unmarshals this tuple type from a JSON array 3 func ({{.ReceiverName}} *{{ pascalize .Name }}) UnmarshalJSON(raw []byte) error { 4 // stage 1, get the array but just the array 5 var stage1 []json.RawMessage 6 buf := bytes.NewBuffer(raw) 7 dec := json.NewDecoder(buf) 8 dec.UseNumber() 9 10 if err := dec.Decode(&stage1); err != nil { 11 return err 12 } 13 14 // stage 2: hydrates struct members with tuple elements 15 {{ if .AdditionalItems }} 16 var lastIndex int 17 {{ end }} 18 {{ range $idx, $val := .Properties }}if len(stage1) > {{ $idx }} { 19 var data{{ pascalize .Name }} {{ template "dereffedSchemaType" . }} 20 buf = bytes.NewBuffer(stage1[{{ $idx }}]) 21 dec := json.NewDecoder(buf) 22 dec.UseNumber() 23 if err := dec.Decode(&data{{ pascalize .Name }}); err != nil { 24 return err 25 } 26 {{ .ReceiverName }}.{{ if .IsExported }}{{ pascalize .Name }}{{ else }}{{ camelize .Name }}{{ end }} = {{ if .IsNullable }}&{{ end }}data{{ pascalize .Name }} 27 {{ if $.AdditionalItems }} 28 lastIndex = {{ $idx }} 29 {{ end }} 30 } 31 {{ end }} 32 {{ if .AdditionalItems }} 33 // stage 3: hydrates AdditionalItems 34 if len(stage1) > lastIndex+1 { 35 for _, val := range stage1[lastIndex+1:] { 36 var toadd {{ template "schemaType" .AdditionalItems }} 37 buf = bytes.NewBuffer(val) 38 dec := json.NewDecoder(buf) 39 dec.UseNumber() 40 if err := dec.Decode({{ if not .AdditionalItems.IsNullable }}&{{ end }}toadd); err != nil { 41 return err 42 } 43 {{ with .AdditionalItems -}} 44 {{ $.ValueExpression }}.{{- if .IsExported }}{{ pascalize .Name }}{{ else }}{{ camelize .Name }}{{ end }} = append({{ $.ValueExpression }}.{{- if .IsExported }}{{ pascalize .Name }}{{ else }}{{ camelize .Name }}{{ end }}, toadd) 45 {{- end }} 46 } 47 } 48 {{ end }} 49 return nil 50 } 51 52 // MarshalJSON marshals this tuple type into a JSON array 53 func ({{.ReceiverName}} {{ pascalize .Name }}) MarshalJSON() ([]byte, error) { 54 data := []interface{}{ 55 {{ range .Properties -}} 56 {{.ReceiverName}}.{{ pascalize .Name }}, 57 {{ end }} 58 } 59 {{ with .AdditionalItems }} 60 for _, v := range {{ $.ValueExpression }}.{{ if .IsExported }}{{ pascalize .Name }}{{ else }}{{ camelize .Name }}{{ end }} { 61 data = append(data, v) 62 } 63 {{ end }} 64 return json.Marshal(data) 65 } 66 {{ end }} 67 68 {{ define "hasDiscriminatedSerializer" }} 69 // UnmarshalJSON unmarshals this object with a polymorphic type from a JSON structure 70 func ({{.ReceiverName}} *{{ pascalize .Name }}) UnmarshalJSON(raw []byte) error { 71 var data {{ template "withoutBaseTypeBody" . }} 72 buf := bytes.NewBuffer(raw) 73 dec := json.NewDecoder(buf) 74 dec.UseNumber() 75 76 if err := dec.Decode(&data); err != nil { 77 return err 78 } 79 80 {{ if or .IsBaseType .IsSubType }} 81 var base {{ template "JustBaseTypeBody" . }} 82 buf = bytes.NewBuffer(raw) 83 dec = json.NewDecoder(buf) 84 dec.UseNumber() 85 86 if err := dec.Decode(&base); err != nil { 87 return err 88 } 89 {{ end }} 90 91 {{ range .AllOf }} 92 {{ if not .IsBaseType }} 93 {{ range .Properties }} 94 {{ if or .IsBaseType (not .IsExported) }} 95 {{ if not .Required }} 96 var allOf{{ pascalize .Name }} {{ if .IsArray }}[]{{ pascalize .Items.GoType }}{{ else }}{{ pascalize .GoType }}{{ end }} 97 if string(data.{{ pascalize .Name }}) != "null" { 98 {{ camelize .Name }}, err := Unmarshal{{ if .IsArray }}{{ pascalize .Items.GoType }}Slice{{ else }}{{ pascalize .GoType }}{{ end }}(bytes.NewBuffer(data.{{ pascalize .Name }}), runtime.JSONConsumer()) 99 if err != nil && err != io.EOF { 100 return err 101 } 102 allOf{{ pascalize .Name }} = {{ camelize .Name }} 103 } 104 {{else}} 105 allOf{{ pascalize .Name }}, err := Unmarshal{{ if .IsArray }}{{ pascalize .Items.GoType }}Slice{{ else }}{{ pascalize .GoType }}{{ end }}(bytes.NewBuffer(data.{{ pascalize .Name }}), runtime.JSONConsumer()) 106 if err != nil && err != io.EOF { 107 return err 108 } 109 {{ end }} 110 {{ end }} 111 {{ end }} 112 {{ end }} 113 {{ end }} 114 {{ range .Properties }} 115 {{ if or .IsBaseType (not .IsExported) }} 116 {{ if not .Required }} 117 var prop{{ pascalize .Name }} {{ if .IsArray }}[]{{ pascalize .Items.GoType }}{{ else }}{{ pascalize .GoType }}{{ end }} 118 if string(data.{{ pascalize .Name }}) != "null" { 119 {{ camelize .Name }}, err := Unmarshal{{ if .IsArray }}{{ pascalize .Items.GoType }}Slice{{ else }}{{ pascalize .GoType }}{{ end }}(bytes.NewBuffer(data.{{ pascalize .Name }}), runtime.JSONConsumer()) 120 if err != nil && err != io.EOF { 121 return err 122 } 123 prop{{ pascalize .Name }} = {{ camelize .Name }} 124 } 125 {{else}} 126 prop{{ pascalize .Name }}, err := Unmarshal{{ if .IsArray }}{{ pascalize .Items.GoType }}Slice{{ else }}{{ pascalize .GoType }}{{ end }}(bytes.NewBuffer(data.{{ pascalize .Name }}), runtime.JSONConsumer()) 127 if err != nil && err != io.EOF { 128 return err 129 } 130 {{ end }} 131 {{ end }} 132 {{ end }} 133 134 var result {{ pascalize .Name }} 135 136 {{ range $_, $parent := .AllOf }} 137 {{ if $parent.IsAnonymous }} 138 {{ if $parent.IsBaseType }} 139 {{ range $idx, $val := $parent.Properties }} 140 {{ if ne $parent.DiscriminatorField $val.Name }} 141 {{ if $val.IsExported }} 142 result.{{ camelize $val.Name }}Field = base.{{ pascalize $val.Name }} 143 {{ else }} 144 result.{{ camelize $val.Name }}Field = allOf{{ pascalize $val.Name }} 145 {{ end }} 146 {{ else }} 147 if base.{{ pascalize $val.Name }} != result.{{ pascalize $val.Name }}() { 148 /* Not the type we're looking for. */ 149 return errors.New(422, "invalid {{$val.Name}} value: %q", base.{{ pascalize $val.Name }}) 150 } 151 {{ end }} 152 {{ end }} 153 {{ else }} 154 {{ range $idx, $val := $parent.Properties }} 155 {{ if $val.IsBaseType }} 156 result.{{ camelize $val.Name }}Field = allOf{{ pascalize $val.Name }} 157 {{ else }} 158 result.{{ pascalize $val.Name }} = data.{{ pascalize $val.Name }} 159 {{ end }} 160 {{ end }} 161 {{ end }} 162 {{ else }} 163 {{ if and $parent.IsBaseType $parent.IsExported }} 164 {{ range $idx, $val := $parent.Properties }} 165 {{ if ne $parent.DiscriminatorField $val.Name }} 166 {{ if $val.IsExported }} 167 result.{{ camelize $val.Name }}Field = base.{{ pascalize $val.Name }} 168 {{ else }} 169 result.{{ camelize $val.Name }}Field = allOf{{ pascalize $val.Name }} 170 {{ end }} 171 {{ else }} 172 if base.{{ pascalize $val.Name }} != result.{{ pascalize $val.Name }}() { 173 /* Not the type we're looking for. */ 174 return errors.New(422, "invalid {{$val.Name}} value: %q", base.{{ pascalize $val.Name }}) 175 } 176 {{ end }} 177 {{ end }} 178 {{ else }} 179 result.{{ $parent.GoType }} = data.{{ $parent.GoType }} 180 {{ end }} 181 {{ end }} 182 {{ end }} 183 {{ range .Properties }} 184 // {{ .Name }} 185 result.{{ if .IsBaseType }}{{ camelize .Name }}Field{{ else }}{{ pascalize .Name }}{{ end }} = {{ if .IsBaseType }}prop{{ pascalize .Name }}{{ else }}data.{{ pascalize .Name}}{{ end }} 186 {{ end }} 187 *{{ .ReceiverName }} = result 188 189 {{ if .IsAdditionalProperties }} 190 // Additional Properties: read raw, remove named properties, and add to map 191 rawProps := make(map[string]{{ if .AdditionalProperties }}json.RawMessage{{ else }}interface{}{{ end }}) 192 if err := json.Unmarshal(raw, &rawProps); err != nil { 193 return err 194 } 195 196 {{ range .Properties -}} 197 delete(rawProps, {{ printf "%q" .Name }}) 198 {{ end }} 199 200 {{ if .AdditionalProperties }} 201 if len(rawProps) > 0 { 202 {{ .ValueExpression }} = make(map[string]{{ template "schemaType" .AdditionalProperties }}) 203 for k, v := range rawProps { 204 var toadd {{ template "schemaType" .AdditionalProperties }} 205 if err := json.Unmarshal(v, {{if not .AdditionalProperties.IsNullable }}&{{ end }}toadd); err != nil { 206 return err 207 } 208 {{ .ValueExpression }}[k] = toadd 209 } 210 } 211 {{ else }} 212 {{ .ValueExpression }} = rawProps 213 {{ end }} 214 {{ end }} 215 216 return nil 217 } 218 219 // MarshalJSON marshals this object with a polymorphic type to a JSON structure 220 func ({{.ReceiverName}} {{ pascalize .Name }}) MarshalJSON() ([]byte, error) { {{ $receiverName := .ReceiverName }} 221 var b1, b2, b3 []byte 222 var err error 223 b1, err = json.Marshal({{ template "withoutBaseTypeBodyOrNonExported" . }}) 224 if err != nil { 225 return nil, err 226 } 227 b2, err = json.Marshal({{ template "withBaseTypeBodyAndNonExported" . }}) 228 if err != nil { 229 return nil, err 230 } 231 {{ if .IsAdditionalProperties }} 232 if len({{ .ValueExpression }}) > 0 { 233 // make JSON object for the additional properties 234 b3, err = json.Marshal({{ .ValueExpression }}) 235 if err != nil { 236 return nil, err 237 } 238 } 239 {{ end }} 240 241 return swag.ConcatJSON(b1, b2, b3), nil 242 } 243 {{ end }} 244 245 {{ define "allOfSerializer" }} 246 {{- $receiverName := .ReceiverName }} 247 // UnmarshalJSON unmarshals this object from a JSON structure 248 func ({{.ReceiverName}} *{{ pascalize .Name }}) UnmarshalJSON(raw []byte) error { 249 {{- range .AllOf }} 250 // {{ pascalize .Name }} 251 {{- if and .IsAnonymous .Properties }}{{/* unmarshalling properties in all of anonymous objects */}} 252 {{- $part := pascalize .Name }} 253 var data{{ $part }} struct { 254 {{- range .Properties }} 255 {{- if not .IsBaseType }} 256 {{- if not $.IsExported }} 257 {{ template "privstructfield" . }} 258 {{- else }} 259 {{ pascalize .Name}} {{ template "schemaType" . }} `json:"{{ .Name }}{{ if and (not .Required) .IsEmptyOmitted }},omitempty{{ end }}"` 260 {{- end }} 261 {{ else }} 262 {{ if not $.IsExported }} 263 {{ template "privstructfield" . }} 264 {{ else }} 265 {{ pascalize .Name}} json.RawMessage `json:"{{ .Name }}{{ if and (not .Required) .IsEmptyOmitted }},omitempty{{ end }}"` 266 {{ end }} 267 {{ end }} 268 {{- end }} 269 {{- if .HasAdditionalProperties }} 270 {{ pascalize .AdditionalProperties.Name }}{{ if not .IsExported }}Field{{ end }} map[string]{{ template "schemaType" .AdditionalProperties }} `json:"-"` 271 {{- end }} 272 {{- if .AdditionalItems }} 273 {{ pascalize .AdditionalItems.Name }}{{ if or (not .IsExported) .IsSubType }}Field{{ end }} []{{ template "schemaType" .AdditionalItems }} `json:"-"` 274 {{- end }} 275 } 276 if err := swag.ReadJSON(raw, &data{{ $part }}); err != nil { 277 return err 278 } 279 {{ range .Properties }} 280 {{ $receiverName }}.{{ pascalize .Name }} = data{{ $part }}.{{ pascalize .Name }} 281 {{ end }} 282 {{- else if .IsAnonymous }} 283 var {{ varname .Name }} {{ .GoType }} 284 if err := {{ if .IsBaseType}}Unmarshal{{ .GoType }}(bytes.NewBuffer(raw), &{{ varname .Name }}){{ else }} swag.ReadJSON(raw, &{{ varname .Name }}){{ end }}; err != nil { 285 return err 286 } 287 {{ .ValueExpression }} = {{ varname .Name }} 288 {{- end }} 289 {{- if not .IsAnonymous }}{{/* unmarshalling allOf named objects */}} 290 var {{ varname .Name }} {{ .GoType }} 291 if err := {{ if .IsBaseType}}Unmarshal{{ .GoType }}(bytes.NewBuffer(raw), &{{ varname .Name }}){{ else }} swag.ReadJSON(raw, &{{ varname .Name }}){{ end }}; err != nil { 292 return err 293 } 294 {{ .ReceiverName }}.{{ stripPackage .GoType "" }} = {{ varname .Name }} 295 {{ end }} 296 {{ end }} 297 {{- if .Properties }} 298 // now for regular properties 299 {{- $part := pascalize .Name }} 300 var props{{ $part }} struct { 301 {{- range .Properties }} 302 {{- if not .IsBaseType }} 303 {{- if not $.IsExported }} 304 {{ template "privstructfield" . }} 305 {{- else }} 306 {{ pascalize .Name}} {{ template "schemaType" . }} `json:"{{ .Name }}{{ if and (not .Required) .IsEmptyOmitted }},omitempty{{ end }}"` 307 {{- end }} 308 {{- else }} 309 {{- if not $.IsExported }} 310 {{ template "privstructfield" . }} 311 {{- else }} 312 {{ pascalize .Name}} json.RawMessage `json:"{{ .Name }}{{ if and (not .Required) .IsEmptyOmitted }},omitempty{{ end }}"` 313 {{- end }} 314 {{- end }} 315 {{ end }} 316 } 317 if err := swag.ReadJSON(raw, &props{{ $part }}); err != nil { 318 return err 319 } 320 {{- range .Properties }} 321 {{ $receiverName }}.{{ pascalize .Name }} = props{{ $part }}.{{ pascalize .Name }} 322 {{ end }} 323 {{- end }} 324 {{ if .HasAdditionalProperties }} 325 // TODO: AdditionalProperties 326 {{- end }} 327 {{- if .AdditionalItems }} 328 // TODO: AdditionalItems 329 {{- end }} 330 return nil 331 } 332 333 // MarshalJSON marshals this object to a JSON structure 334 func ({{.ReceiverName}} {{ pascalize .Name }}) MarshalJSON() ([]byte, error) { 335 _parts := make([][]byte, 0, {{ len .AllOf }}) 336 {{ range .AllOf }} 337 {{- if and .IsAnonymous .Properties }} 338 {{- $part := pascalize .Name }} 339 var data{{ $part }} struct { 340 {{- range .Properties }} 341 {{- if not .IsBaseType }} 342 {{ if not $.IsExported }} 343 {{ template "privstructfield" . }} 344 {{ else }} 345 {{ pascalize .Name}} {{ template "schemaType" . }} `json:"{{ .Name }}{{ if and (not .Required) .IsEmptyOmitted }},omitempty{{ end }}"` 346 {{ end }} 347 {{- else }} 348 {{ if not $.IsExported }} 349 {{ template "privstructfield" . }} 350 {{ else }} 351 {{ pascalize .Name}} json.RawMessage `json:"{{ .Name }}{{ if and (not .Required) .IsEmptyOmitted }},omitempty{{ end }}"` 352 {{ end}} 353 {{- end }} 354 {{ end }} 355 {{ if .HasAdditionalProperties }} 356 {{ pascalize .AdditionalProperties.Name }}{{ if not .IsExported }}Field{{ end }} map[string]{{ template "schemaType" .AdditionalProperties }} `json:"-"` 357 {{ end }} 358 {{ if .AdditionalItems }} 359 {{ pascalize .AdditionalItems.Name }}{{ if or (not .IsExported) .IsSubType }}Field{{ end }} []{{ template "schemaType" .AdditionalItems }} `json:"-"` 360 {{ end }} 361 } 362 363 {{ range .Properties }} 364 data{{ $part }}.{{ pascalize .Name }} = {{ $receiverName }}.{{ pascalize .Name }} 365 {{ end }} 366 367 jsonData{{ $part }}, err{{ $part }} := swag.WriteJSON(data{{ $part }}) 368 if err{{ $part }} != nil { 369 return nil, err{{ $part }} 370 } 371 _parts = append(_parts, jsonData{{ $part }}) 372 {{- else if .IsAnonymous }}{{/* unmarshalling anonymous type composition */}} 373 {{ varname .Name }}, err := swag.WriteJSON({{ .ValueExpression }}) 374 if err != nil { 375 return nil, err 376 } 377 _parts = append(_parts, {{ varname .Name }}) 378 {{- end }} 379 {{ if not .IsAnonymous }} 380 {{ varname .Name }}, err := swag.WriteJSON({{ $receiverName }}.{{ stripPackage .GoType "" }}) 381 if err != nil { 382 return nil, err 383 } 384 _parts = append(_parts, {{ varname .Name }}) 385 {{ end }} 386 {{ end }} 387 {{- if .Properties }} 388 // now for regular properties 389 {{- $part := pascalize .Name }} 390 var props{{ $part }} struct { 391 {{- range .Properties }} 392 {{- if not .IsBaseType }} 393 {{- if not $.IsExported }} 394 {{ template "privstructfield" . }} 395 {{- else }} 396 {{ pascalize .Name}} {{ template "schemaType" . }} `json:"{{ .Name }}{{ if and (not .Required) .IsEmptyOmitted }},omitempty{{ end }}"` 397 {{- end }} 398 {{- else }} 399 {{- if not $.IsExported }} 400 {{ template "privstructfield" . }} 401 {{- else }} 402 {{ pascalize .Name}} json.RawMessage `json:"{{ .Name }}{{ if and (not .Required) .IsEmptyOmitted }},omitempty{{ end }}"` 403 {{- end }} 404 {{- end }} 405 {{ end }} 406 } 407 {{- range .Properties }} 408 props{{ $part }}.{{ pascalize .Name }} = {{ $receiverName }}.{{ pascalize .Name }} 409 {{ end }} 410 jsonDataProps{{ $part }}, err{{ $part }} := swag.WriteJSON(props{{ $part }}) 411 if err{{ $part }} != nil { 412 return nil, err{{ $part }} 413 } 414 _parts = append(_parts, jsonDataProps{{ $part }}) 415 {{- end }} 416 {{- if .HasAdditionalProperties }} 417 {{- end }} 418 {{- if .HasAdditionalItems }} 419 {{- end }} 420 return swag.ConcatJSON(_parts...), nil 421 } 422 {{ end }} 423 424 {{ define "schemaSerializer" }} 425 {{- if and .IsSubType (not .HasBaseType) }} 426 {{ template "hasDiscriminatedSerializer" . }} 427 {{ else if .IsTuple }} 428 {{ template "tupleSerializer" . }} 429 {{ else if .HasBaseType -}} 430 {{ template "hasDiscriminatedSerializer" . }} 431 {{ else if .IsAdditionalProperties }} 432 {{ template "additionalPropertiesSerializer" . }} 433 {{- else if and (gt (len .AllOf) 0) (not .IsSubType ) -}} 434 {{ template "allOfSerializer" . }} 435 {{ end -}} 436 {{ end }}