github.com/diptanu/nomad@v0.5.7-0.20170516172507-d72e86cbe3d9/helper/funcs.go (about) 1 package helper 2 3 import ( 4 "crypto/sha512" 5 "fmt" 6 "regexp" 7 "time" 8 ) 9 10 // validUUID is used to check if a given string looks like a UUID 11 var validUUID = regexp.MustCompile(`(?i)^[\da-f]{8}-[\da-f]{4}-[\da-f]{4}-[\da-f]{4}-[\da-f]{12}$`) 12 13 // IsUUID returns true if the given string is a valid UUID. 14 func IsUUID(str string) bool { 15 const uuidLen = 36 16 if len(str) != uuidLen { 17 return false 18 } 19 20 return validUUID.MatchString(str) 21 } 22 23 // HashUUID takes an input UUID and returns a hashed version of the UUID to 24 // ensure it is well distributed. 25 func HashUUID(input string) (output string, hashed bool) { 26 if !IsUUID(input) { 27 return "", false 28 } 29 30 // Hash the input 31 buf := sha512.Sum512([]byte(input)) 32 output = fmt.Sprintf("%08x-%04x-%04x-%04x-%12x", 33 buf[0:4], 34 buf[4:6], 35 buf[6:8], 36 buf[8:10], 37 buf[10:16]) 38 39 return output, true 40 } 41 42 // boolToPtr returns the pointer to a boolean 43 func BoolToPtr(b bool) *bool { 44 return &b 45 } 46 47 // IntToPtr returns the pointer to an int 48 func IntToPtr(i int) *int { 49 return &i 50 } 51 52 // UintToPtr returns the pointer to an uint 53 func Uint64ToPtr(u uint64) *uint64 { 54 return &u 55 } 56 57 // StringToPtr returns the pointer to a string 58 func StringToPtr(str string) *string { 59 return &str 60 } 61 62 // TimeToPtr returns the pointer to a time stamp 63 func TimeToPtr(t time.Duration) *time.Duration { 64 return &t 65 } 66 67 // MapStringStringSliceValueSet returns the set of values in a map[string][]string 68 func MapStringStringSliceValueSet(m map[string][]string) []string { 69 set := make(map[string]struct{}) 70 for _, slice := range m { 71 for _, v := range slice { 72 set[v] = struct{}{} 73 } 74 } 75 76 flat := make([]string, 0, len(set)) 77 for k := range set { 78 flat = append(flat, k) 79 } 80 return flat 81 } 82 83 func SliceStringToSet(s []string) map[string]struct{} { 84 m := make(map[string]struct{}, (len(s)+1)/2) 85 for _, k := range s { 86 m[k] = struct{}{} 87 } 88 return m 89 } 90 91 // SliceStringIsSubset returns whether the smaller set of strings is a subset of 92 // the larger. If the smaller slice is not a subset, the offending elements are 93 // returned. 94 func SliceStringIsSubset(larger, smaller []string) (bool, []string) { 95 largerSet := make(map[string]struct{}, len(larger)) 96 for _, l := range larger { 97 largerSet[l] = struct{}{} 98 } 99 100 subset := true 101 var offending []string 102 for _, s := range smaller { 103 if _, ok := largerSet[s]; !ok { 104 subset = false 105 offending = append(offending, s) 106 } 107 } 108 109 return subset, offending 110 } 111 112 func SliceSetDisjoint(first, second []string) (bool, []string) { 113 contained := make(map[string]struct{}, len(first)) 114 for _, k := range first { 115 contained[k] = struct{}{} 116 } 117 118 offending := make(map[string]struct{}) 119 for _, k := range second { 120 if _, ok := contained[k]; ok { 121 offending[k] = struct{}{} 122 } 123 } 124 125 if len(offending) == 0 { 126 return true, nil 127 } 128 129 flattened := make([]string, 0, len(offending)) 130 for k := range offending { 131 flattened = append(flattened, k) 132 } 133 return false, flattened 134 } 135 136 // Helpers for copying generic structures. 137 func CopyMapStringString(m map[string]string) map[string]string { 138 l := len(m) 139 if l == 0 { 140 return nil 141 } 142 143 c := make(map[string]string, l) 144 for k, v := range m { 145 c[k] = v 146 } 147 return c 148 } 149 150 func CopyMapStringInt(m map[string]int) map[string]int { 151 l := len(m) 152 if l == 0 { 153 return nil 154 } 155 156 c := make(map[string]int, l) 157 for k, v := range m { 158 c[k] = v 159 } 160 return c 161 } 162 163 func CopyMapStringFloat64(m map[string]float64) map[string]float64 { 164 l := len(m) 165 if l == 0 { 166 return nil 167 } 168 169 c := make(map[string]float64, l) 170 for k, v := range m { 171 c[k] = v 172 } 173 return c 174 } 175 176 func CopySliceString(s []string) []string { 177 l := len(s) 178 if l == 0 { 179 return nil 180 } 181 182 c := make([]string, l) 183 for i, v := range s { 184 c[i] = v 185 } 186 return c 187 } 188 189 func CopySliceInt(s []int) []int { 190 l := len(s) 191 if l == 0 { 192 return nil 193 } 194 195 c := make([]int, l) 196 for i, v := range s { 197 c[i] = v 198 } 199 return c 200 } 201 202 // CleanEnvVar replaces all occurrences of illegal characters in an environment 203 // variable with the specified byte. 204 func CleanEnvVar(s string, r byte) string { 205 b := []byte(s) 206 for i, c := range b { 207 switch { 208 case c == '_': 209 case c >= 'a' && c <= 'z': 210 case c >= 'A' && c <= 'Z': 211 case i > 0 && c >= '0' && c <= '9': 212 default: 213 // Replace! 214 b[i] = r 215 } 216 } 217 return string(b) 218 }