gitlab.com/evatix-go/core@v1.3.55/converters/stringsTo.go (about) 1 package converters 2 3 import ( 4 "errors" 5 "strconv" 6 "strings" 7 8 "gitlab.com/evatix-go/core/constants" 9 "gitlab.com/evatix-go/core/constants/bitsize" 10 "gitlab.com/evatix-go/core/converters/coreconverted" 11 "gitlab.com/evatix-go/core/defaulterr" 12 "gitlab.com/evatix-go/core/errcore" 13 "gitlab.com/evatix-go/core/internal/strutilinternal" 14 "gitlab.com/evatix-go/core/simplewrap" 15 ) 16 17 type stringsTo struct{} 18 19 func (it stringsTo) Hashset( 20 lines []string, 21 ) map[string]bool { 22 length := len(lines) 23 hashset := make(map[string]bool, length) 24 25 for _, s := range lines { 26 hashset[s] = true 27 } 28 29 return hashset 30 } 31 32 func (it stringsTo) HashmapTrimColon( 33 lines ...string, 34 ) map[string]string { 35 return strutilinternal. 36 SliceToMapConverter(lines). 37 LineSplitMapOptions( 38 true, 39 constants.Colon) 40 } 41 42 func (it stringsTo) HashmapTrimHyphen( 43 lines ...string, 44 ) map[string]string { 45 return strutilinternal. 46 SliceToMapConverter(lines). 47 LineSplitMapOptions( 48 true, 49 constants.Hyphen) 50 } 51 52 func (it stringsTo) HashmapOptions( 53 isTrim bool, 54 splitter string, 55 lines ...string, 56 ) map[string]string { 57 return strutilinternal. 58 SliceToMapConverter(lines). 59 LineSplitMapOptions( 60 isTrim, 61 splitter) 62 } 63 64 func (it stringsTo) HashmapTrim( 65 splitter string, 66 lines []string, 67 ) map[string]string { 68 return strutilinternal. 69 SliceToMapConverter(lines). 70 LineSplitMapTrim(splitter) 71 } 72 73 // HashmapUsingFuncOptions 74 // 75 // Skips if empty after trim 76 func (it stringsTo) HashmapUsingFuncOptions( 77 isTrimBefore bool, 78 processorFunc func(line string) (key, val string), 79 lines ...string, 80 ) map[string]string { 81 return strutilinternal. 82 SliceToMapConverter(lines). 83 LineProcessorMapOptions( 84 isTrimBefore, 85 processorFunc) 86 } 87 88 // HashmapUsingFuncTrim 89 // 90 // Skips if empty after trim 91 func (it stringsTo) HashmapUsingFuncTrim( 92 processorFunc func(line string) (key, val string), 93 lines ...string, 94 ) map[string]string { 95 return strutilinternal. 96 SliceToMapConverter(lines). 97 LineProcessorMapOptions( 98 true, 99 processorFunc) 100 } 101 102 // MapStringIntegerUsingFunc 103 // 104 // Skips if empty after trim 105 func (it stringsTo) MapStringIntegerUsingFunc( 106 isTrimBefore bool, 107 processorFunc func(line string) (key string, val int), 108 lines ...string, 109 ) map[string]int { 110 return strutilinternal. 111 SliceToMapConverter(lines). 112 LineProcessorMapStringIntegerOptions( 113 isTrimBefore, 114 processorFunc) 115 } 116 117 // MapStringAnyUsingFunc 118 // 119 // Skips if empty after trim 120 func (it stringsTo) MapStringAnyUsingFunc( 121 isTrimBefore bool, 122 processorFunc func(line string) (key string, val interface{}), 123 lines ...string, 124 ) map[string]interface{} { 125 return strutilinternal. 126 SliceToMapConverter(lines). 127 LineProcessorMapStringAnyOptions( 128 isTrimBefore, 129 processorFunc) 130 } 131 132 func (it stringsTo) MapConverter( 133 lines ...string, 134 ) StringsToMapConverter { 135 return lines 136 } 137 138 // PointerStrings 139 // 140 // Will give empty or converted results array (not nil) 141 // It doesn't copy but points to same string address in the array 142 // 143 // Example code : https://play.golang.org/p/_OkY82E2kO9 144 func (it stringsTo) PointerStrings(pointerToStrings *[]string) *[]*string { 145 if pointerToStrings == nil || *pointerToStrings == nil { 146 var emptyResult []*string 147 148 return &emptyResult 149 } 150 151 newArray := make([]*string, len(*pointerToStrings)) 152 153 for i := range *pointerToStrings { 154 // direct access important here. 155 newArray[i] = &(*pointerToStrings)[i] 156 } 157 158 return &newArray 159 } 160 161 // PointerStringsCopy 162 // 163 // will give empty or converted results array (not nil) 164 // Copy each item to the new array 165 func (it stringsTo) PointerStringsCopy(pointerToStrings *[]string) *[]*string { 166 if pointerToStrings == nil || *pointerToStrings == nil { 167 var emptyResult []*string 168 169 return &emptyResult 170 } 171 172 newArray := make([]*string, len(*pointerToStrings)) 173 174 for i, value := range *pointerToStrings { 175 // here copy is important 176 valueCopy := value 177 newArray[i] = &valueCopy 178 } 179 180 return &newArray 181 } 182 183 // IntegersConditional handle converts from processor func 184 func (it stringsTo) IntegersConditional( 185 processor func(in string) (out int, isTake, isBreak bool), 186 lines ...string, 187 ) []int { 188 results := make([]int, 0, len(lines)) 189 190 for _, v := range lines { 191 out, isTake, isBreak := processor(v) 192 193 if isTake { 194 results = append(results, out) 195 } 196 197 if isBreak { 198 break 199 } 200 } 201 202 return results 203 } 204 205 // IntegersWithDefaults On fail use the default int 206 func (it stringsTo) IntegersWithDefaults( 207 defaultInt int, 208 lines ...string, 209 ) *coreconverted.Integers { 210 results := make([]int, 0, len(lines)) 211 var errMessages []string 212 213 for i, v := range lines { 214 vInt, err := strconv.Atoi(v) 215 216 if err != nil { 217 results[i] = defaultInt 218 errMessage := constants.IndexColonSpace + 219 strconv.Itoa(i) + 220 err.Error() 221 errMessages = append( 222 errMessages, 223 errMessage) 224 225 continue 226 } 227 228 results[i] = vInt 229 } 230 231 var combinedError error 232 if len(errMessages) > 0 { 233 errCompiledMessage := strings.Join(errMessages, constants.NewLineUnix) 234 combinedError = errors.New(errCompiledMessage) 235 } 236 237 return &coreconverted.Integers{ 238 Values: results, 239 CombinedError: combinedError, 240 } 241 } 242 243 // IntegersOptionPanic 244 // 245 // panic if not a number 246 func (it stringsTo) IntegersOptionPanic( 247 isPanic bool, 248 lines ...string, 249 ) []int { 250 results := make([]int, len(lines)) 251 252 for i, v := range lines { 253 vInt, err := strconv.Atoi(v) 254 255 if isPanic && err != nil { 256 panic(err) 257 } else if err != nil { 258 continue 259 } 260 261 results[i] = vInt 262 } 263 264 return results 265 } 266 267 // IntegersSkipErrors 268 // 269 // no errors captured. 270 func (it stringsTo) IntegersSkipErrors( 271 lines ...string, 272 ) []int { 273 return it.IntegersOptionPanic( 274 false, 275 lines...) 276 } 277 278 // BytesConditional only take if isTake returns true, breaks and exits if isBreak to true 279 func (it stringsTo) BytesConditional( 280 processor func(in string) (out byte, isTake, isBreak bool), 281 stringsSlice []string, 282 ) []byte { 283 results := make([]byte, 0, len(stringsSlice)) 284 285 for _, v := range stringsSlice { 286 out, isTake, isBreak := processor(v) 287 288 if isTake { 289 results = append(results, out) 290 } 291 292 if isBreak { 293 break 294 } 295 } 296 297 return results 298 } 299 300 // BytesWithDefaults 301 // 302 // panic if not a number or more than 255 303 func (it stringsTo) BytesWithDefaults( 304 defaultByte byte, 305 stringsSlice ...string, 306 ) *coreconverted.Bytes { 307 results := make([]byte, len(stringsSlice)) 308 var sliceErr []string 309 310 for i, v := range stringsSlice { 311 vInt, err := strconv.Atoi(v) 312 313 if err != nil { 314 msg := err.Error() + 315 constants.CommaRawValueColonSpace + 316 v + 317 constants.CommaIndexColonSpace + 318 strconv.Itoa(i) 319 sliceErr = append( 320 sliceErr, 321 msg) 322 323 results[i] = defaultByte 324 325 continue 326 } 327 328 if vInt > constants.MaxUnit8AsInt { 329 msg := defaulterr.CannotConvertStringToByte.Error() + 330 constants.CommaRawValueColonSpace + 331 v + 332 constants.CommaIndexColonSpace + 333 strconv.Itoa(i) 334 sliceErr = append( 335 sliceErr, 336 msg) 337 338 results[i] = defaultByte 339 340 continue 341 } 342 343 results[i] = byte(vInt) 344 } 345 346 return &coreconverted.Bytes{ 347 Values: results, 348 CombinedError: errcore.SliceToError(sliceErr), 349 } 350 } 351 352 func (it stringsTo) Csv(isSkipQuoteOnlyOnExistence bool, stringsSlice ...string) string { 353 csvLines := simplewrap.DoubleQuoteWrapElements( 354 isSkipQuoteOnlyOnExistence, 355 stringsSlice...) 356 357 return strings.Join(csvLines, constants.Comma) 358 } 359 360 func (it stringsTo) CsvUsingPtrStrings(isSkipQuoteOnlyOnExistence bool, stringsSlice *[]string) string { 361 if stringsSlice == nil { 362 return "" 363 } 364 365 csvLines := simplewrap.DoubleQuoteWrapElements( 366 isSkipQuoteOnlyOnExistence, 367 *stringsSlice..., 368 ) 369 370 return strings.Join(csvLines, constants.Comma) 371 } 372 373 func (it stringsTo) CsvWithIndexes(lines []string) string { 374 csvLines := simplewrap.DoubleQuoteWrapElementsWithIndexes( 375 lines..., 376 ) 377 378 return strings.Join(csvLines, constants.Comma) 379 } 380 381 // BytesMust 382 // 383 // panic if not a number or more than 255 or less than 0 384 func (it stringsTo) BytesMust(lines ...string) []byte { 385 results := make([]byte, len(lines)) 386 387 for i, v := range lines { 388 vInt, err := StringToByte(v) 389 390 if err != nil { 391 panic(err) 392 } 393 394 results[i] = vInt 395 } 396 397 return results 398 } 399 400 // Float64sMust 401 // 402 // panic if not a number 403 func (it stringsTo) Float64sMust(lines ...string) []float64 { 404 results := make([]float64, len(lines)) 405 406 for i, v := range lines { 407 vFloat, err := strconv.ParseFloat(v, bitsize.Of64) 408 409 if err != nil { 410 panic(err) 411 } 412 413 results[i] = vFloat 414 } 415 416 return results 417 } 418 419 // Float64sConditional 420 // 421 // handle convert from processor function either throw or ignore 422 func (it stringsTo) Float64sConditional( 423 processor func(in string) (out float64, isTake, isBreak bool), 424 lines []string, 425 ) []float64 { 426 results := make([]float64, 0, len(lines)) 427 428 for _, v := range lines { 429 out, isTake, isBreak := processor(v) 430 431 if isTake { 432 results = append(results, out) 433 } 434 435 if isBreak { 436 break 437 } 438 } 439 440 return results 441 }