File size: 1,258 Bytes
6380833
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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
package slicesx

import "github.com/samber/lo"

type Diff[T comparable, S ~[]T] struct {
	additionsMap map[T]struct{}
	additions    S

	removalsMap map[T]struct{}
	removals    S
}

func (d Diff[T, S]) Has(item T) bool {
	return d.InAdditions(item) || d.InRemovals(item)
}

func (d Diff[T, S]) InAdditions(item T) bool {
	if _, ok := d.additionsMap[item]; ok {
		return true
	}

	return false
}

func (d Diff[T, S]) InRemovals(item T) bool {
	if _, ok := d.removalsMap[item]; ok {
		return true
	}

	return false
}

func (d Diff[T, S]) Additions() S {
	return d.additions
}

func (d Diff[T, S]) Removals() S {
	return d.removals
}

func (d Diff[T, S]) HasChanged() bool {
	return len(d.additions) > 0 || len(d.removals) > 0
}

func (d Diff[T, S]) Changed() S {
	return append(d.additions, d.removals...)
}

func NewDiff[T comparable, S ~[]T](base, new S) *Diff[T, S] {
	additions, removals := lo.Difference(base, new)

	additionsMap := lo.SliceToMap(additions, func(item T) (T, struct{}) {
		return item, struct{}{}
	})

	removalsMap := lo.SliceToMap(removals, func(item T) (T, struct{}) {
		return item, struct{}{}
	})

	return &Diff[T, S]{
		additionsMap: additionsMap,
		additions:    additions,
		removalsMap:  removalsMap,
		removals:     removals,
	}
}