File: marshal.go

package info (click to toggle)
golang-github-relex-aini 1.6.0-1~exp1
  • links: PTS, VCS
  • area: main
  • in suites: experimental
  • size: 204 kB
  • sloc: makefile: 15
file content (74 lines) | stat: -rw-r--r-- 2,536 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
package aini

import (
	"encoding/json"

	"github.com/samber/lo"
	"golang.org/x/exp/maps"
)

type alwaysNil interface{} // to hold place for Group and Host references; must be nil in serialized form

func (group *Group) MarshalJSON() ([]byte, error) {
	type groupWithoutCustomMarshal Group

	return json.Marshal(&struct {
		groupWithoutCustomMarshal
		Hosts         map[string]alwaysNil
		Children      map[string]alwaysNil
		Parents       map[string]alwaysNil
		DirectParents map[string]alwaysNil
	}{
		groupWithoutCustomMarshal: groupWithoutCustomMarshal(*group),
		Hosts:                     makeNilValueMap(group.Hosts),
		Children:                  makeNilValueMap(group.Children),
		Parents:                   makeNilValueMap(group.Parents),
		DirectParents:             makeNilValueMap(group.DirectParents),
	})
}

func (host *Host) MarshalJSON() ([]byte, error) {
	type hostWithoutCustomMarshal Host

	return json.Marshal(&struct {
		hostWithoutCustomMarshal
		Groups       map[string]alwaysNil
		DirectGroups map[string]alwaysNil
	}{
		hostWithoutCustomMarshal: hostWithoutCustomMarshal(*host),
		Groups:                   makeNilValueMap(host.Groups),
		DirectGroups:             makeNilValueMap(host.DirectGroups),
	})
}

func makeNilValueMap[K comparable, V any](m map[K]*V) map[K]alwaysNil {
	return lo.MapValues(m, func(_ *V, _ K) alwaysNil { return nil })
}

func (inventory *InventoryData) UnmarshalJSON(data []byte) error {
	type inventoryWithoutCustomUnmarshal InventoryData
	var rawInventory inventoryWithoutCustomUnmarshal
	if err := json.Unmarshal(data, &rawInventory); err != nil {
		return err
	}
	// rawInventory's Groups and Hosts should now contain all properties,
	// except child group maps and host maps are filled with original keys and null values

	// reassign child groups and hosts to reference rawInventory.Hosts and .Groups

	for _, group := range rawInventory.Groups {
		group.Hosts = lo.PickByKeys(rawInventory.Hosts, maps.Keys(group.Hosts))
		group.Children = lo.PickByKeys(rawInventory.Groups, maps.Keys(group.Children))
		group.Parents = lo.PickByKeys(rawInventory.Groups, maps.Keys(group.Parents))
		group.DirectParents = lo.PickByKeys(rawInventory.Groups, maps.Keys(group.DirectParents))
	}

	for _, host := range rawInventory.Hosts {
		host.Groups = lo.PickByKeys(rawInventory.Groups, maps.Keys(host.Groups))
		host.DirectGroups = lo.PickByKeys(rawInventory.Groups, maps.Keys(host.DirectGroups))
	}

	inventory.Groups = rawInventory.Groups
	inventory.Hosts = rawInventory.Hosts
	return nil
}