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