File: simpleunion

package info (click to toggle)
golang-github-digitalocean-go-qemu 0.0~git20250212.ee9b066-1
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid, trixie
  • size: 860 kB
  • sloc: sh: 34; makefile: 3
file content (68 lines) | stat: -rw-r--r-- 2,057 bytes parent folder | download | duplicates (2)
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
{{/*

It's important to note that union implementations are always a basic
type or a struct, never another union. This means that we can safely
decode union implementations with json.Unmarshal, so we don't have to
handle recursively calling decodeFoo functions to unmarshal unions.

Also, there is one simple union type whose name clashes with the
underlying struct type: ImageInfoSpecificVmdk. The struct type is not
used anywhere outside the simple union, so we just skip the
redefinition, but still tack on all the marshaling logic.

*/}}

{{ $basename := .Name.Go }}

// {{ .Name }} -> {{ $basename }} (simple union)

// {{ $basename }} implements the "{{ .Name }}" QMP API type.
//
// Can be one of:
{{- range $suffix, $type := .Options }}
//   - {{ $basename }}{{ $suffix.Go }}
{{- end }}
type {{ $basename }} interface {
     is{{ $basename }}()
}

{{- range $suffix, $type := .Options }}
{{ $subname := printf "%s%s" $basename $suffix.Go }}
{{- if ne $subname $type.Go }}
// {{ $subname }} is an implementation of {{ $basename }}.
type {{ $subname }} {{ $type.Go }}
{{- end }}

func ({{ $subname }}) is{{ $basename }}() {}

// MarshalJSON implements json.Marshaler.
func (s {{ $subname }}) MarshalJSON() ([]byte, error) {
     v := map[string]interface{}{
          "type": "{{ $suffix }}",
          "data": {{ $type.Go }} (s),
     }
     return json.Marshal(v)
}
{{- end }}

func decode{{ $basename }}(bs json.RawMessage) ({{ $basename }}, error) {
     v := struct{
          T string `json:"type"`
          V json.RawMessage `json:"data"`
     }{}
     if err := json.Unmarshal([]byte(bs), &v); err != nil {
          return nil, err
     }
     switch v.T {
     {{- range $suffix, $type := .Options }}
     case "{{ $suffix }}":
          var ret {{ $basename }}{{ $suffix.Go }}
          if err := json.Unmarshal([]byte(v.V), &ret); err != nil {
               return nil, err
          }
          return ret, nil
     {{- end }}
     default:
          return nil, fmt.Errorf("unknown subtype %q for union {{ $basename }}", v.T)
     }
}