1package sprig 2 3import ( 4 "encoding/base32" 5 "encoding/base64" 6 "fmt" 7 "reflect" 8 "strconv" 9 "strings" 10 11 util "github.com/Masterminds/goutils" 12) 13 14func base64encode(v string) string { 15 return base64.StdEncoding.EncodeToString([]byte(v)) 16} 17 18func base64decode(v string) string { 19 data, err := base64.StdEncoding.DecodeString(v) 20 if err != nil { 21 return err.Error() 22 } 23 return string(data) 24} 25 26func base32encode(v string) string { 27 return base32.StdEncoding.EncodeToString([]byte(v)) 28} 29 30func base32decode(v string) string { 31 data, err := base32.StdEncoding.DecodeString(v) 32 if err != nil { 33 return err.Error() 34 } 35 return string(data) 36} 37 38func abbrev(width int, s string) string { 39 if width < 4 { 40 return s 41 } 42 r, _ := util.Abbreviate(s, width) 43 return r 44} 45 46func abbrevboth(left, right int, s string) string { 47 if right < 4 || left > 0 && right < 7 { 48 return s 49 } 50 r, _ := util.AbbreviateFull(s, left, right) 51 return r 52} 53func initials(s string) string { 54 // Wrap this just to eliminate the var args, which templates don't do well. 55 return util.Initials(s) 56} 57 58func randAlphaNumeric(count int) string { 59 // It is not possible, it appears, to actually generate an error here. 60 r, _ := util.CryptoRandomAlphaNumeric(count) 61 return r 62} 63 64func randAlpha(count int) string { 65 r, _ := util.CryptoRandomAlphabetic(count) 66 return r 67} 68 69func randAscii(count int) string { 70 r, _ := util.CryptoRandomAscii(count) 71 return r 72} 73 74func randNumeric(count int) string { 75 r, _ := util.CryptoRandomNumeric(count) 76 return r 77} 78 79func untitle(str string) string { 80 return util.Uncapitalize(str) 81} 82 83func quote(str ...interface{}) string { 84 out := make([]string, 0, len(str)) 85 for _, s := range str { 86 if s != nil { 87 out = append(out, fmt.Sprintf("%q", strval(s))) 88 } 89 } 90 return strings.Join(out, " ") 91} 92 93func squote(str ...interface{}) string { 94 out := make([]string, 0, len(str)) 95 for _, s := range str { 96 if s != nil { 97 out = append(out, fmt.Sprintf("'%v'", s)) 98 } 99 } 100 return strings.Join(out, " ") 101} 102 103func cat(v ...interface{}) string { 104 v = removeNilElements(v) 105 r := strings.TrimSpace(strings.Repeat("%v ", len(v))) 106 return fmt.Sprintf(r, v...) 107} 108 109func indent(spaces int, v string) string { 110 pad := strings.Repeat(" ", spaces) 111 return pad + strings.Replace(v, "\n", "\n"+pad, -1) 112} 113 114func nindent(spaces int, v string) string { 115 return "\n" + indent(spaces, v) 116} 117 118func replace(old, new, src string) string { 119 return strings.Replace(src, old, new, -1) 120} 121 122func plural(one, many string, count int) string { 123 if count == 1 { 124 return one 125 } 126 return many 127} 128 129func strslice(v interface{}) []string { 130 switch v := v.(type) { 131 case []string: 132 return v 133 case []interface{}: 134 b := make([]string, 0, len(v)) 135 for _, s := range v { 136 if s != nil { 137 b = append(b, strval(s)) 138 } 139 } 140 return b 141 default: 142 val := reflect.ValueOf(v) 143 switch val.Kind() { 144 case reflect.Array, reflect.Slice: 145 l := val.Len() 146 b := make([]string, 0, l) 147 for i := 0; i < l; i++ { 148 value := val.Index(i).Interface() 149 if value != nil { 150 b = append(b, strval(value)) 151 } 152 } 153 return b 154 default: 155 if v == nil { 156 return []string{} 157 } 158 159 return []string{strval(v)} 160 } 161 } 162} 163 164func removeNilElements(v []interface{}) []interface{} { 165 newSlice := make([]interface{}, 0, len(v)) 166 for _, i := range v { 167 if i != nil { 168 newSlice = append(newSlice, i) 169 } 170 } 171 return newSlice 172} 173 174func strval(v interface{}) string { 175 switch v := v.(type) { 176 case string: 177 return v 178 case []byte: 179 return string(v) 180 case error: 181 return v.Error() 182 case fmt.Stringer: 183 return v.String() 184 default: 185 return fmt.Sprintf("%v", v) 186 } 187} 188 189func trunc(c int, s string) string { 190 if c < 0 && len(s)+c > 0 { 191 return s[len(s)+c:] 192 } 193 if c >= 0 && len(s) > c { 194 return s[:c] 195 } 196 return s 197} 198 199func join(sep string, v interface{}) string { 200 return strings.Join(strslice(v), sep) 201} 202 203func split(sep, orig string) map[string]string { 204 parts := strings.Split(orig, sep) 205 res := make(map[string]string, len(parts)) 206 for i, v := range parts { 207 res["_"+strconv.Itoa(i)] = v 208 } 209 return res 210} 211 212func splitn(sep string, n int, orig string) map[string]string { 213 parts := strings.SplitN(orig, sep, n) 214 res := make(map[string]string, len(parts)) 215 for i, v := range parts { 216 res["_"+strconv.Itoa(i)] = v 217 } 218 return res 219} 220 221// substring creates a substring of the given string. 222// 223// If start is < 0, this calls string[:end]. 224// 225// If start is >= 0 and end < 0 or end bigger than s length, this calls string[start:] 226// 227// Otherwise, this calls string[start, end]. 228func substring(start, end int, s string) string { 229 if start < 0 { 230 return s[:end] 231 } 232 if end < 0 || end > len(s) { 233 return s[start:] 234 } 235 return s[start:end] 236} 237