gitlab.com/evatix-go/core@v1.3.55/coreimpl/enumimpl/numberEnumBase.go (about)

     1  package enumimpl
     2  
     3  import (
     4  	"errors"
     5  	"fmt"
     6  	"sort"
     7  
     8  	"gitlab.com/evatix-go/core/constants"
     9  	"gitlab.com/evatix-go/core/coredata/coreonce"
    10  	"gitlab.com/evatix-go/core/errcore"
    11  	"gitlab.com/evatix-go/core/internal/csvinternal"
    12  	"gitlab.com/evatix-go/core/internal/strutilinternal"
    13  )
    14  
    15  type numberEnumBase struct {
    16  	actualValueRanges      interface{}
    17  	stringRanges           []string
    18  	rangesCsvString        coreonce.StringOnce
    19  	rangesInvalidMessage   coreonce.StringOnce
    20  	invalidError           coreonce.ErrorOnce
    21  	integerEnumRangesOnce  coreonce.IntegersOnce
    22  	typeName               string
    23  	minAny, maxAny         interface{}
    24  	minStr, maxStr         string
    25  	keyAnyValues           []KeyAnyVal
    26  	rangesDynamicMap       map[string]interface{}
    27  	rangesIntegerStringMap map[int]string
    28  }
    29  
    30  // newNumberEnumBase
    31  //
    32  //  @actualRangesAnyType : []Byte, []int, []int8... not pointer
    33  //
    34  //  Lengths must match stringRanges and actualRangesAnyType
    35  func newNumberEnumBase(
    36  	typeName string,
    37  	actualRangesAnyType interface{},
    38  	nameRanges []string,
    39  	min, max interface{},
    40  ) numberEnumBase {
    41  	if nameRanges == nil {
    42  		errcore.MeaningfulErrorHandle(
    43  			errcore.CannotBeNilType,
    44  			"newNumberEnumBase",
    45  			errors.New("StringRanges cannot be nil"))
    46  	}
    47  
    48  	integerEnumRangesOnce := coreonce.NewIntegersOnce(func() []int {
    49  		return IntegersRangesOfAnyVal(actualRangesAnyType)
    50  	})
    51  
    52  	_, isString := actualRangesAnyType.([]string)
    53  
    54  	rangesToCsvOnce := coreonce.NewStringOnce(func() string {
    55  		if isString {
    56  			clonedList := strutilinternal.Clone(nameRanges)
    57  			sort.Strings(clonedList)
    58  
    59  			return csvinternal.StringsToStringDefaultNoQuotations(
    60  				clonedList...)
    61  		}
    62  
    63  		allKeyValues := KeyAnyValues(
    64  			nameRanges,
    65  			actualRangesAnyType)
    66  		length := len(allKeyValues)
    67  		newMap := make(map[int]string, length)
    68  		integersSlice := make([]int, length)
    69  
    70  		for i, keyAnyVal := range allKeyValues {
    71  			valueInt := keyAnyVal.ValInt()
    72  			newMap[valueInt] = keyAnyVal.String()
    73  			integersSlice[i] = valueInt
    74  		}
    75  
    76  		sort.Ints(integersSlice)
    77  
    78  		newSortedSlice := make([]string, length)
    79  
    80  		for i, valueInt := range integersSlice {
    81  			nameValue := newMap[valueInt]
    82  			newSortedSlice[i] = nameValue
    83  		}
    84  
    85  		return csvinternal.StringsToStringDefaultNoQuotations(
    86  			newSortedSlice...)
    87  	})
    88  
    89  	invalidMessageOnce := coreonce.NewStringOnce(func() string {
    90  		msg := errcore.EnumRangeNotMeet(
    91  			min,
    92  			max,
    93  			rangesToCsvOnce.Value())
    94  
    95  		return msg
    96  	})
    97  
    98  	return numberEnumBase{
    99  		actualValueRanges:    actualRangesAnyType,
   100  		stringRanges:         nameRanges,
   101  		rangesCsvString:      rangesToCsvOnce,
   102  		rangesInvalidMessage: invalidMessageOnce,
   103  		invalidError: coreonce.NewErrorOnce(func() error {
   104  			return errors.New(invalidMessageOnce.Value())
   105  		}),
   106  		integerEnumRangesOnce: integerEnumRangesOnce,
   107  		typeName:              typeName,
   108  		minAny:                min,
   109  		maxAny:                max,
   110  	}
   111  }
   112  
   113  func (it numberEnumBase) MinMaxAny() (min, max interface{}) {
   114  	return it.minAny, it.maxAny
   115  }
   116  
   117  func (it *numberEnumBase) MinValueString() string {
   118  	if it.minStr != "" {
   119  		return it.minStr
   120  	}
   121  
   122  	it.minStr = convAnyValToString(it.minAny)
   123  
   124  	return it.minStr
   125  }
   126  
   127  func (it numberEnumBase) MinInt() int {
   128  	return ConvEnumAnyValToInteger(it.minAny)
   129  }
   130  
   131  func (it numberEnumBase) MaxInt() int {
   132  	return ConvEnumAnyValToInteger(it.maxAny)
   133  }
   134  
   135  func (it numberEnumBase) AllNameValues() []string {
   136  	return AllNameValues(
   137  		it.StringRanges(),
   138  		it.actualValueRanges)
   139  }
   140  
   141  func (it numberEnumBase) RangesMap() map[int]string {
   142  	return it.DynamicMap().ConvMapIntegerString()
   143  }
   144  
   145  func (it numberEnumBase) OnlySupportedErr(supportedNames ...string) error {
   146  	return OnlySupportedErr(
   147  		it.StringRanges(),
   148  		supportedNames...)
   149  }
   150  
   151  func (it numberEnumBase) OnlySupportedMsgErr(errMessage string, supportedNames ...string) error {
   152  	return errcore.ConcatMessageWithErr(
   153  		errMessage,
   154  		it.OnlySupportedErr(supportedNames...))
   155  }
   156  
   157  func (it *numberEnumBase) MaxValueString() string {
   158  	if it.maxStr != "" {
   159  		return it.maxStr
   160  	}
   161  
   162  	it.maxStr = convAnyValToString(it.maxAny)
   163  
   164  	return it.maxStr
   165  }
   166  
   167  func (it *numberEnumBase) IntegerEnumRanges() []int {
   168  	return it.integerEnumRangesOnce.Values()
   169  }
   170  
   171  func (it numberEnumBase) Length() int {
   172  	return len(it.StringRanges())
   173  }
   174  
   175  func (it numberEnumBase) Count() int {
   176  	return len(it.StringRanges())
   177  }
   178  
   179  func (it *numberEnumBase) RangesDynamicMap() map[string]interface{} {
   180  	if it.rangesDynamicMap != nil {
   181  		return it.rangesDynamicMap
   182  	}
   183  
   184  	newMap := make(
   185  		map[string]interface{},
   186  		len(it.stringRanges)+1)
   187  
   188  	for _, keyAnyVal := range it.KeyAnyValues() {
   189  		newMap[keyAnyVal.Key] = keyAnyVal.AnyValue
   190  	}
   191  
   192  	it.rangesDynamicMap = newMap
   193  
   194  	return newMap
   195  }
   196  
   197  func (it *numberEnumBase) DynamicMap() DynamicMap {
   198  	return it.RangesDynamicMap()
   199  }
   200  
   201  func (it *numberEnumBase) notFoundJsonBytesError(
   202  	currentValueInf interface{},
   203  ) error {
   204  	compiledMessage := fmt.Sprintf(
   205  		currentValueNotFoundInJsonMapFormat,
   206  		currentValueInf,
   207  		it.RangesInvalidMessage())
   208  
   209  	return errors.New(compiledMessage)
   210  }
   211  
   212  func (it *numberEnumBase) RangesIntegerStringMap() map[int]string {
   213  	if it.rangesDynamicMap != nil {
   214  		return it.rangesIntegerStringMap
   215  	}
   216  
   217  	newMap := make(
   218  		map[int]string,
   219  		len(it.stringRanges)+1)
   220  
   221  	for _, keyAnyVal := range it.KeyAnyValues() {
   222  		newMap[keyAnyVal.ValInt()] = keyAnyVal.Key
   223  	}
   224  
   225  	it.rangesIntegerStringMap = newMap
   226  
   227  	return newMap
   228  }
   229  
   230  func (it *numberEnumBase) KeyAnyValues() []KeyAnyVal {
   231  	if it.keyAnyValues != nil {
   232  		return it.keyAnyValues
   233  	}
   234  
   235  	it.keyAnyValues = KeyAnyValues(
   236  		it.StringRanges(),
   237  		it.actualValueRanges)
   238  
   239  	return it.keyAnyValues
   240  }
   241  
   242  func (it numberEnumBase) KeyValIntegers() []KeyValInteger {
   243  	slice := make([]KeyValInteger, it.Length())
   244  
   245  	it.LoopInteger(func(index int, name string, valInteger int) (isBreak bool) {
   246  		slice[index] = KeyValInteger{
   247  			Key:          name,
   248  			ValueInteger: valInteger,
   249  		}
   250  
   251  		return false
   252  	})
   253  
   254  	return slice
   255  }
   256  
   257  func (it numberEnumBase) Loop(looperFunc LooperFunc) {
   258  	for i, keyAnyVal := range it.KeyAnyValues() {
   259  		isBreak := looperFunc(i, keyAnyVal.Key, keyAnyVal.AnyValue)
   260  
   261  		if isBreak {
   262  			return
   263  		}
   264  	}
   265  }
   266  
   267  func (it numberEnumBase) LoopInteger(looperFunc LooperIntegerFunc) {
   268  	for i, keyAnyVal := range it.KeyAnyValues() {
   269  		isBreak := looperFunc(
   270  			i,
   271  			keyAnyVal.Key,
   272  			keyAnyVal.ValInt())
   273  
   274  		if isBreak {
   275  			return
   276  		}
   277  	}
   278  }
   279  
   280  func (it numberEnumBase) TypeName() string {
   281  	return it.typeName
   282  }
   283  
   284  // NameWithValueOption
   285  //
   286  // Warning :
   287  //
   288  // Make sure non ptr is called +
   289  // String should also be attached with non ptr.
   290  func (it numberEnumBase) NameWithValueOption(
   291  	value interface{},
   292  	isIncludeQuotation bool,
   293  ) string {
   294  	if isIncludeQuotation {
   295  		return fmt.Sprintf(
   296  			constants.EnumDoubleQuoteNameValueFormat,
   297  			value,
   298  			value)
   299  	}
   300  
   301  	return NameWithValue(value)
   302  }
   303  
   304  // NameWithValue
   305  //
   306  // Warning :
   307  //
   308  // Make sure non ptr is called +
   309  // String should also be attached with non ptr.
   310  func (it numberEnumBase) NameWithValue(
   311  	value interface{},
   312  ) string {
   313  	return NameWithValue(value)
   314  }
   315  
   316  func (it numberEnumBase) ValueString(
   317  	value interface{},
   318  ) string {
   319  	return fmt.Sprintf(
   320  		constants.SprintNumberFormat,
   321  		value,
   322  	)
   323  }
   324  
   325  // Format
   326  //
   327  //  Outputs name and
   328  //  value by given format.
   329  //
   330  // sample-format :
   331  //  - "Enum of {type-name} - {name} - {value}"
   332  //
   333  // sample-format-output :
   334  //  - "Enum of EnumFullName - Invalid - 0"
   335  //
   336  // Key-Meaning :
   337  //  - {type-name} : represents type-name string
   338  //  - {name}      : represents name string
   339  //  - {value}     : represents value string
   340  func (it numberEnumBase) Format(
   341  	format string,
   342  	value interface{},
   343  ) string {
   344  	return Format(
   345  		it.TypeName(),
   346  		it.ToName(value),
   347  		it.ValueString(value),
   348  		format,
   349  	)
   350  }
   351  
   352  func (it *numberEnumBase) RangeNamesCsv() string {
   353  	return it.rangesCsvString.Value()
   354  }
   355  
   356  func (it *numberEnumBase) RangesInvalidMessage() string {
   357  	return it.rangesInvalidMessage.Value()
   358  }
   359  
   360  func (it *numberEnumBase) RangesInvalidErr() error {
   361  	return it.invalidError.Value()
   362  }
   363  
   364  func (it numberEnumBase) StringRangesPtr() *[]string {
   365  	return &it.stringRanges
   366  }
   367  
   368  func (it numberEnumBase) StringRanges() []string {
   369  	return it.stringRanges
   370  }
   371  
   372  func (it numberEnumBase) NamesHashset() map[string]bool {
   373  	if it.Length() == 0 {
   374  		return map[string]bool{}
   375  	}
   376  
   377  	return toHashset(it.StringRanges()...)
   378  }
   379  
   380  func (it numberEnumBase) JsonString(input interface{}) string {
   381  	return it.ToEnumString(input)
   382  }
   383  
   384  func (it numberEnumBase) ToEnumString(
   385  	input interface{},
   386  ) string {
   387  	return fmt.Sprintf(
   388  		constants.SprintValueFormat,
   389  		input)
   390  }
   391  
   392  func (it numberEnumBase) ToName(
   393  	input interface{},
   394  ) string {
   395  	return fmt.Sprintf(
   396  		constants.SprintValueFormat,
   397  		input)
   398  }