summaryrefslogtreecommitdiffstats
path: root/vendor/maunium.net/go/mautrix/util/marshal.go
blob: 180adef2e2cafae9a8461629f12e4a646a5a257f (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
package util

import (
	"encoding/json"
	"fmt"

	"github.com/tidwall/gjson"
	"github.com/tidwall/sjson"
)

// MarshalAndDeleteEmpty marshals a JSON object, then uses gjson to delete empty objects at the given gjson paths.
//
// This can be used as a convenient way to create a marshaler that omits empty non-pointer structs.
// See mautrix.RespSync for example.
func MarshalAndDeleteEmpty(marshalable interface{}, paths []string) ([]byte, error) {
	data, err := json.Marshal(marshalable)
	if err != nil {
		return nil, err
	}
	for _, path := range paths {
		res := gjson.GetBytes(data, path)
		if res.IsObject() && len(res.Raw) == 2 {
			data, err = sjson.DeleteBytes(data, path)
			if err != nil {
				return nil, fmt.Errorf("failed to delete empty %s: %w", path, err)
			}
		}
	}
	return data, nil
}