github.com/boxboat/in-toto-golang@v0.0.3-0.20210303203820-2fa16ecbe6f6/in_toto/util.go (about) 1 package in_toto 2 3 import ( 4 "fmt" 5 "path/filepath" 6 ) 7 8 /* 9 Set represents a data structure for set operations. See `NewSet` for how to 10 create a Set, and available Set receivers for useful set operations. 11 12 Under the hood Set aliases map[string]struct{}, where the map keys are the set 13 elements and the map values are a memory-efficient way of storing the keys. 14 */ 15 type Set map[string]struct{} 16 17 /* 18 NewSet creates a new Set, assigns it the optionally passed variadic string 19 elements, and returns it. 20 */ 21 func NewSet(elems ...string) Set { 22 var s Set 23 s = make(map[string]struct{}) 24 for _, elem := range elems { 25 s.Add(elem) 26 } 27 return s 28 } 29 30 /* 31 Has returns True if the passed string is member of the set on which it was 32 called and False otherwise. 33 */ 34 func (s Set) Has(elem string) bool { 35 _, ok := s[elem] 36 return ok 37 } 38 39 /* 40 Add adds the passed string to the set on which it was called, if the string is 41 not a member of the set. 42 */ 43 func (s Set) Add(elem string) { 44 s[elem] = struct{}{} 45 } 46 47 /* 48 Remove removes the passed string from the set on which was is called, if the 49 string is a member of the set. 50 */ 51 func (s Set) Remove(elem string) { 52 delete(s, elem) 53 } 54 55 /* 56 Intersection creates and returns a new Set with the elements of the set on 57 which it was called that are also in the passed set. 58 */ 59 func (s Set) Intersection(s2 Set) Set { 60 res := NewSet() 61 for elem := range s { 62 if s2.Has(elem) == false { 63 continue 64 } 65 res.Add(elem) 66 } 67 return res 68 } 69 70 /* 71 Difference creates and returns a new Set with the elements of the set on 72 which it was called that are not in the passed set. 73 */ 74 func (s Set) Difference(s2 Set) Set { 75 res := NewSet() 76 for elem := range s { 77 if s2.Has(elem) { 78 continue 79 } 80 res.Add(elem) 81 } 82 return res 83 } 84 85 /* 86 Filter creates and returns a new Set with the elements of the set on which it 87 was called that match the passed pattern. A matching error is treated like a 88 non-match plus a warning is printed. 89 */ 90 func (s Set) Filter(pattern string) Set { 91 res := NewSet() 92 for elem := range s { 93 matched, err := filepath.Match(pattern, elem) 94 if err != nil { 95 fmt.Printf("WARNING: %s, pattern was '%s'\n", err, pattern) 96 continue 97 } 98 if !matched { 99 continue 100 } 101 res.Add(elem) 102 } 103 return res 104 } 105 106 /* 107 Slice creates and returns an unordered string slice with the elements of the 108 set on which it was called. 109 */ 110 func (s Set) Slice() []string { 111 var res []string 112 res = make([]string, 0, len(s)) 113 for elem := range s { 114 res = append(res, elem) 115 } 116 return res 117 } 118 119 /* 120 InterfaceKeyStrings returns string keys of passed interface{} map in an 121 unordered string slice. 122 */ 123 func InterfaceKeyStrings(m map[string]interface{}) []string { 124 res := make([]string, len(m)) 125 i := 0 126 for k := range m { 127 res[i] = k 128 i++ 129 } 130 return res 131 } 132 133 /* 134 IsSubSet checks if the parameter subset is a 135 subset of the superset s. 136 */ 137 func (s Set) IsSubSet(subset Set) bool { 138 if len(subset) > len(s) { 139 return false 140 } 141 for key := range subset { 142 if s.Has(key) { 143 continue 144 } else { 145 return false 146 } 147 } 148 return true 149 }