-
Notifications
You must be signed in to change notification settings - Fork 7
/
Copy pathuser_diff.go
93 lines (82 loc) · 2.18 KB
/
user_diff.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
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
package yext
import "reflect"
// Diff calculates the differences betwee a base User (a) and a proposed set of
// changes represented by a second User (b). The diffing logic will ignore fields in
// (b) location that aren't set (nil). This characteristic makes the function ideal
// for calculating the minimal PUT required to up date an object via the API.
func (a *User) Diff(b *User) (d *User, diff bool) {
diff, d = false, &User{Id: String(a.GetId())}
var (
aValue, bValue = reflect.ValueOf(a).Elem(), reflect.ValueOf(b).Elem()
aType = reflect.TypeOf(*a)
numA = aValue.NumField()
)
for i := 0; i < numA; i++ {
var (
nameA = aType.Field(i).Name
valA = aValue.Field(i)
valB = bValue.Field(i)
)
if valB.IsNil() || nameA == "Id" {
continue
}
if nameA == "ACLs" {
if len(a.ACLs) != len(b.ACLs) {
diff = true
d.ACLs = b.ACLs
} else {
aACLHash, bACLHash := make(map[string]bool), make(map[string]bool)
for j := 0; j < len(a.ACLs); j++ {
aACLHash[a.ACLs[j].Hash()] = true
bACLHash[b.ACLs[j].Hash()] = true
}
for bHash, _ := range bACLHash {
if _, ok := aACLHash[bHash]; !ok {
diff = true
d.ACLs = b.ACLs
break
}
}
for aHash, _ := range aACLHash {
if _, ok := bACLHash[aHash]; !ok {
diff = true
d.ACLs = b.ACLs
break
}
}
}
} else if !reflect.DeepEqual(valA.Interface(), valB.Interface()) {
diff = true
reflect.ValueOf(d).Elem().FieldByName(nameA).Set(valB)
}
}
if !diff {
// ensure that d remains nil if nothing has changed
d = nil
}
return d, diff
}
func (u *User) Copy() (n *User) {
n = &User{
Id: String(u.GetId()),
FirstName: String(u.GetFirstName()),
LastName: String(u.GetLastName()),
PhoneNumber: String(u.GetPhoneNumber()),
EmailAddress: String(u.GetEmailAddress()),
UserName: String(u.GetUserName()),
Password: String(u.GetPassword()),
ACLs: make([]ACL, len(u.ACLs)),
}
for i := 0; i < len(u.ACLs); i++ {
uACL := u.ACLs[i]
n.ACLs[i] = ACL{
Role: Role{
Id: uACL.Id,
Name: String(uACL.GetName()),
},
On: uACL.On,
AccessOn: uACL.AccessOn,
}
}
return n
}