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  }