forked from devfile/api
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathnormalize.go
64 lines (56 loc) · 1.72 KB
/
normalize.go
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
package unions
import (
"reflect"
dw "github.com/devfile/api/v2/pkg/apis/workspaces/v1alpha2"
"github.com/mitchellh/reflectwalk"
)
type normalizer struct {
}
func (n *normalizer) Struct(s reflect.Value) error {
if s.CanAddr() {
addr := s.Addr()
if addr.CanInterface() {
i := addr.Interface()
if u, ok := i.(dw.Union); ok {
_ = u.Normalize()
}
}
}
return nil
}
func (n *normalizer) StructField(reflect.StructField, reflect.Value) error {
return nil
}
type simplifier struct {
}
func (n *simplifier) Struct(s reflect.Value) error {
if s.CanAddr() {
addr := s.Addr()
if addr.CanInterface() {
i := addr.Interface()
if u, ok := i.(dw.Union); ok {
u.Simplify()
}
}
}
return nil
}
func (n *simplifier) StructField(reflect.StructField, reflect.Value) error {
return nil
}
// Normalize allows normalizing all the unions
// encountered while walking through the whole struct tree.
// Union normalizing works according to the following rules:
// - When only one field of the union is set and no discriminator is set, set the discriminator according to the union value.
// - When several fields are set and a discriminator is set, remove (== reset to zero value) all the values that do not match the discriminator.
// - When only one union value is set and it matches discriminator, just do nothing.
// - In other case, something is inconsistent or ambiguous: an error is thrown.
func Normalize(tree interface{}) error {
return reflectwalk.Walk(tree, &normalizer{})
}
// Simplify allows removing the discriminator of all unions
// encountered while walking through the whole struct tree,
// but after normalizing them if necessary.
func Simplify(tree interface{}) error {
return reflectwalk.Walk(tree, &simplifier{})
}