File: dict.go

package info (click to toggle)
golang-github-dave-jennifer 1.4.1-2
  • links: PTS, VCS
  • area: main
  • in suites: bookworm, forky, sid, trixie
  • size: 372 kB
  • sloc: makefile: 4
file content (81 lines) | stat: -rw-r--r-- 1,578 bytes parent folder | download
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
package jen

import (
	"bytes"
	"io"
	"sort"
)

// Dict renders as key/value pairs. Use with Values for map or composite
// literals.
type Dict map[Code]Code

// DictFunc executes a func(Dict) to generate the value. Use with Values for
// map or composite literals.
func DictFunc(f func(Dict)) Dict {
	d := Dict{}
	f(d)
	return d
}

func (d Dict) render(f *File, w io.Writer, s *Statement) error {
	first := true
	// must order keys to ensure repeatable source
	type kv struct {
		k Code
		v Code
	}
	lookup := map[string]kv{}
	keys := []string{}
	for k, v := range d {
		if k.isNull(f) || v.isNull(f) {
			continue
		}
		buf := &bytes.Buffer{}
		if err := k.render(f, buf, nil); err != nil {
			return err
		}
		keys = append(keys, buf.String())
		lookup[buf.String()] = kv{k: k, v: v}
	}
	sort.Strings(keys)
	for _, key := range keys {
		k := lookup[key].k
		v := lookup[key].v
		if first && len(keys) > 1 {
			if _, err := w.Write([]byte("\n")); err != nil {
				return err
			}
			first = false
		}
		if err := k.render(f, w, nil); err != nil {
			return err
		}
		if _, err := w.Write([]byte(":")); err != nil {
			return err
		}
		if err := v.render(f, w, nil); err != nil {
			return err
		}
		if len(keys) > 1 {
			if _, err := w.Write([]byte(",\n")); err != nil {
				return err
			}
		}
	}
	return nil
}

func (d Dict) isNull(f *File) bool {
	if d == nil || len(d) == 0 {
		return true
	}
	for k, v := range d {
		if !k.isNull(f) && !v.isNull(f) {
			// if any of the key/value pairs are both not null, the Dict is not
			// null
			return false
		}
	}
	return true
}