aboutsummaryrefslogtreecommitdiff
path: root/internal/calendar/merge.go
blob: ce8fe8f15018f1d77ee98bd35ce6e404d9cbaa0a (plain) (blame)
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
package calendar

// mergeLayers folds an ordered layer stack into one raw celebration set. Later
// layers override earlier ones field-by-field; a slug with Fields["suppress"]
// == "true" is removed; variant sub-sections merge per variant.
func mergeLayers(layers []Layer) map[string]RawCelebration {
	out := map[string]RawCelebration{}
	for _, layer := range layers {
		for slug, rc := range layer.Cels {
			if rc.Fields["suppress"] == "true" {
				delete(out, slug)
				continue
			}
			cur, ok := out[slug]
			if !ok {
				cur = RawCelebration{Fields: map[string]string{}, Variants: map[string]map[string]string{}}
			} else {
				cur = cloneRaw(cur)
			}
			for k, v := range rc.Fields {
				cur.Fields[k] = v
			}
			for variant, fields := range rc.Variants {
				if cur.Variants[variant] == nil {
					cur.Variants[variant] = map[string]string{}
				}
				for k, v := range fields {
					cur.Variants[variant][k] = v
				}
			}
			cur.Fields["layer"] = layer.ID // provenance: last writer
			out[slug] = cur
		}
	}
	return out
}

func cloneRaw(rc RawCelebration) RawCelebration {
	nf := make(map[string]string, len(rc.Fields))
	for k, v := range rc.Fields {
		nf[k] = v
	}
	nv := make(map[string]map[string]string, len(rc.Variants))
	for variant, fields := range rc.Variants {
		m := make(map[string]string, len(fields))
		for k, v := range fields {
			m[k] = v
		}
		nv[variant] = m
	}
	return RawCelebration{Fields: nf, Variants: nv}
}