gitlab.com/evatix-go/core@v1.3.55/keymk/Key.go (about)

     1  package keymk
     2  
     3  import (
     4  	"encoding/json"
     5  	"fmt"
     6  	"strconv"
     7  	"strings"
     8  
     9  	"gitlab.com/evatix-go/core/constants"
    10  	"gitlab.com/evatix-go/core/coredata/corejson"
    11  	"gitlab.com/evatix-go/core/coredata/stringslice"
    12  	"gitlab.com/evatix-go/core/defaultcapacity"
    13  	"gitlab.com/evatix-go/core/errcore"
    14  )
    15  
    16  type Key struct {
    17  	option        *Option
    18  	mainName      string
    19  	keyChains     []string
    20  	compiledChain *string
    21  }
    22  
    23  func (it *Key) CompiledChain() string {
    24  	if it.IsComplete() {
    25  		return *it.compiledChain
    26  	}
    27  
    28  	return constants.EmptyString
    29  }
    30  
    31  func (it *Key) MainName() string {
    32  	return it.mainName
    33  }
    34  
    35  func (it *Key) IsEmpty() bool {
    36  	return it.Length() == 0 && it.MainName() == ""
    37  }
    38  
    39  func (it *Key) Length() int {
    40  	if it == nil {
    41  		return 0
    42  	}
    43  
    44  	return len(it.keyChains)
    45  }
    46  
    47  func (it *Key) AppendChain(items ...interface{}) *Key {
    48  	if it.IsComplete() {
    49  		// panic
    50  		errcore.CannotModifyCompleteResourceType.HandleUsingPanic(
    51  			cannotModifyErrorMessage,
    52  			items)
    53  	}
    54  
    55  	it.keyChains = appendAnyItemsWithBaseStrings(
    56  		it.option.IsSkipEmptyEntry,
    57  		it.keyChains,
    58  		items)
    59  
    60  	return it
    61  }
    62  
    63  func (it *Key) AppendChainKeys(
    64  	keys ...*Key,
    65  ) *Key {
    66  	if len(keys) == 0 {
    67  		return it
    68  	}
    69  
    70  	for _, key := range keys {
    71  		if key == nil {
    72  			continue
    73  		}
    74  
    75  		it.AppendChainStrings(key.MainName())
    76  		it.AppendChainStrings(key.keyChains...)
    77  	}
    78  
    79  	return it
    80  }
    81  
    82  func (it *Key) CompileKeys(
    83  	keys ...*Key,
    84  ) string {
    85  	if len(keys) == 0 {
    86  		return it.Compile()
    87  	}
    88  
    89  	newSlice := make(
    90  		[]interface{},
    91  		0,
    92  		it.Length()+
    93  			defaultcapacity.PredictiveDefaultSmall(len(keys)))
    94  
    95  	for _, key := range keys {
    96  		if key == nil {
    97  			continue
    98  		}
    99  
   100  		newSlice = append(
   101  			newSlice,
   102  			key.MainName())
   103  
   104  		newSlice = appendStringsWithBaseAnyItems(
   105  			it.option.IsSkipEmptyEntry,
   106  			newSlice,
   107  			key.keyChains)
   108  	}
   109  
   110  	return it.Compile(newSlice...)
   111  }
   112  
   113  func (it *Key) AppendChainStrings(
   114  	items ...string,
   115  ) *Key {
   116  	if it.IsComplete() {
   117  		// panic
   118  		errcore.CannotModifyCompleteResourceType.HandleUsingPanic(
   119  			cannotModifyErrorMessage,
   120  			items)
   121  	}
   122  
   123  	isSkipOnEmpty := it.option.IsSkipEmptyEntry
   124  
   125  	for _, item := range items {
   126  		if isSkipOnEmpty && item == "" {
   127  			continue
   128  		}
   129  
   130  		it.keyChains = append(
   131  			it.keyChains,
   132  			item)
   133  	}
   134  
   135  	return it
   136  }
   137  
   138  func (it *Key) KeyChains() []string {
   139  	if it == nil {
   140  		return nil
   141  	}
   142  
   143  	return it.keyChains
   144  }
   145  
   146  // AllRawItems
   147  //
   148  // Returns main + whole chain (raw elements)
   149  func (it *Key) AllRawItems() []string {
   150  	if it == nil {
   151  		return nil
   152  	}
   153  
   154  	return stringslice.PrependLineNew(
   155  		it.MainName(),
   156  		it.KeyChains())
   157  }
   158  
   159  func (it *Key) HasInChains(
   160  	chainItem string,
   161  ) bool {
   162  	if it == nil {
   163  		return false
   164  	}
   165  
   166  	for _, chain := range it.keyChains {
   167  		if chain == chainItem {
   168  			return true
   169  		}
   170  	}
   171  
   172  	return false
   173  }
   174  
   175  func (it *Key) IsComplete() bool {
   176  	return it.compiledChain != nil
   177  }
   178  
   179  func (it *Key) Finalized(
   180  	items ...interface{},
   181  ) *Key {
   182  	it.AppendChain(items...)
   183  	compiled := it.rootCompile(it.option.Joiner)
   184  	it.compiledChain = &compiled
   185  
   186  	return it
   187  }
   188  
   189  func (it *Key) rootCompile(
   190  	joiner string,
   191  	items ...interface{},
   192  ) string {
   193  	if it.IsComplete() {
   194  		return it.onCompleteCompileInternal(joiner, items)
   195  	}
   196  
   197  	finalSlice := make([]string, 0, it.Length()+len(items)+constants.Capacity2)
   198  	finalSlice = append(finalSlice, it.MainName())
   199  	finalSlice = append(finalSlice, it.keyChains...)
   200  	finalSlice = appendAnyItemsWithBaseStrings(
   201  		it.option.IsSkipEmptyEntry,
   202  		finalSlice,
   203  		items)
   204  
   205  	return it.compileFinalStrings(joiner, finalSlice)
   206  }
   207  
   208  func (it *Key) rootCompileUsingStrings(
   209  	joiner string,
   210  	items ...string,
   211  ) string {
   212  	if it.IsComplete() {
   213  		return it.onCompleteCompileInternalStrings(joiner, items)
   214  	}
   215  
   216  	finalSlice := make([]string, 0, it.Length()+len(items)+constants.Capacity2)
   217  	finalSlice = append(finalSlice, it.MainName())
   218  	finalSlice = append(finalSlice, it.keyChains...)
   219  	finalSlice = stringslice.AppendStringsWithMainSlice(
   220  		it.option.IsSkipEmptyEntry,
   221  		finalSlice,
   222  		items...)
   223  
   224  	return it.compileFinalStrings(joiner, finalSlice)
   225  }
   226  
   227  func (it *Key) onCompleteCompileInternal(
   228  	joiner string,
   229  	items []interface{},
   230  ) string {
   231  	if len(items) == 0 {
   232  		return *it.compiledChain
   233  	}
   234  
   235  	additionalCompiled := it.compileCompleteAdditional(
   236  		joiner,
   237  		items...)
   238  
   239  	if additionalCompiled == constants.EmptyString {
   240  		return *it.compiledChain
   241  	}
   242  
   243  	compiledTerms := []string{
   244  		*it.compiledChain,
   245  		additionalCompiled,
   246  	}
   247  
   248  	return strings.Join(compiledTerms, joiner)
   249  }
   250  
   251  func (it *Key) onCompleteCompileInternalStrings(
   252  	joiner string,
   253  	items []string,
   254  ) string {
   255  	if len(items) == 0 {
   256  		return *it.compiledChain
   257  	}
   258  
   259  	additionalCompiled := it.compileCompleteAdditionalStrings(
   260  		joiner,
   261  		items...)
   262  
   263  	if additionalCompiled == constants.EmptyString {
   264  		return *it.compiledChain
   265  	}
   266  
   267  	compiledTerms := []string{
   268  		*it.compiledChain,
   269  		additionalCompiled,
   270  	}
   271  
   272  	return strings.Join(compiledTerms, joiner)
   273  }
   274  
   275  func (it *Key) compileSingleItem(
   276  	item string,
   277  ) string {
   278  	if it.option.IsUseBrackets {
   279  		return it.option.StartBracket + item + it.option.EndBracket
   280  	}
   281  
   282  	return item
   283  }
   284  
   285  // CompileReplaceCurlyKeyMap
   286  //
   287  // Keys will be converted to {Key} then replaced
   288  func (it *Key) CompileReplaceCurlyKeyMap(
   289  	mapToReplace map[string]string,
   290  ) string {
   291  	return it.CompileReplaceMapUsingItemsOption(
   292  		true,
   293  		mapToReplace,
   294  	)
   295  }
   296  
   297  // CompileReplaceCurlyKeyMapUsingItems
   298  //
   299  // Keys will be converted to {Key} then replaced
   300  func (it *Key) CompileReplaceCurlyKeyMapUsingItems(
   301  	mapToReplace map[string]string,
   302  	additionalItems ...interface{},
   303  ) string {
   304  	return it.CompileReplaceMapUsingItemsOption(
   305  		true,
   306  		mapToReplace,
   307  		additionalItems...)
   308  }
   309  
   310  func (it *Key) CompileReplaceMapUsingItemsOption(
   311  	isConvKeysToCurlyBraceKeys bool, // conv key to {key} before replace
   312  	mapToReplace map[string]string,
   313  	additionalItems ...interface{},
   314  ) string {
   315  	format := it.Compile(additionalItems...)
   316  
   317  	if len(mapToReplace) == 0 {
   318  		return format
   319  	}
   320  
   321  	if isConvKeysToCurlyBraceKeys {
   322  		for key, valueToReplace := range mapToReplace {
   323  			keyCurly := fmt.Sprintf(
   324  				constants.CurlyWrapFormat,
   325  				key)
   326  
   327  			format = strings.ReplaceAll(
   328  				format,
   329  				keyCurly,
   330  				valueToReplace)
   331  		}
   332  
   333  		return format
   334  	}
   335  
   336  	for key, valueToReplace := range mapToReplace {
   337  		format = strings.ReplaceAll(
   338  			format,
   339  			key,
   340  			valueToReplace)
   341  	}
   342  
   343  	return format
   344  }
   345  
   346  func (it *Key) compileFinalStrings(
   347  	joiner string, items []string,
   348  ) string {
   349  	if it.option.IsUseBrackets {
   350  		items = it.addBracketsStrings(items)
   351  	}
   352  
   353  	return strings.Join(items, joiner)
   354  }
   355  
   356  func (it *Key) addBracketsStrings(
   357  	items []string,
   358  ) []string {
   359  	for i, item := range items {
   360  		items[i] = it.option.StartBracket + item + it.option.EndBracket
   361  	}
   362  
   363  	return items
   364  }
   365  
   366  func (it *Key) ConcatNewUsingKeys(
   367  	keys ...*Key,
   368  ) *Key {
   369  	cloned := it.ClonePtr()
   370  
   371  	return cloned.AppendChainKeys(keys...)
   372  }
   373  
   374  func (it *Key) ClonePtr(
   375  	newAppendingChains ...interface{},
   376  ) *Key {
   377  	if it == nil {
   378  		return nil
   379  	}
   380  
   381  	key := NewKey.All(
   382  		it.option.ClonePtr(),
   383  		it.mainName,
   384  	)
   385  
   386  	key.AppendChainStrings(
   387  		it.keyChains...)
   388  
   389  	return key.AppendChain(
   390  		newAppendingChains...)
   391  }
   392  
   393  func (it *Key) IntRange(
   394  	startIncluding, endIncluding int,
   395  ) []string {
   396  	keyOuts := make(
   397  		[]string,
   398  		0,
   399  		endIncluding-startIncluding+1)
   400  
   401  	for i := startIncluding; i <= endIncluding; i++ {
   402  		keyOuts = append(
   403  			keyOuts,
   404  			it.CompileStrings(strconv.Itoa(i)))
   405  	}
   406  
   407  	return keyOuts
   408  }
   409  
   410  func (it *Key) IntRangeEnding(
   411  	endIncluding int,
   412  ) []string {
   413  	return it.IntRange(
   414  		constants.Zero,
   415  		endIncluding)
   416  }
   417  
   418  func (it *Key) CompileDefault() string {
   419  	return it.rootCompile(
   420  		it.option.Joiner,
   421  	)
   422  }
   423  
   424  func (it *Key) Compile(
   425  	items ...interface{},
   426  ) string {
   427  	return it.rootCompile(
   428  		it.option.Joiner,
   429  		items...)
   430  }
   431  
   432  func (it *Key) CompileStrings(
   433  	items ...string,
   434  ) string {
   435  	return it.rootCompileUsingStrings(
   436  		it.option.Joiner,
   437  		items...)
   438  }
   439  
   440  func (it *Key) JoinUsingJoiner(
   441  	joiner string,
   442  	items ...interface{},
   443  ) string {
   444  	return it.rootCompile(joiner, items...)
   445  }
   446  
   447  func (it *Key) JoinUsingOption(
   448  	tempOption *Option,
   449  	items ...interface{},
   450  ) string {
   451  	temp2 := it.option
   452  	it.option = tempOption
   453  	compiled := it.Compile(items...)
   454  	it.option = temp2
   455  
   456  	return compiled
   457  }
   458  
   459  func (it *Key) String() string {
   460  	return it.Compile()
   461  }
   462  
   463  func (it *Key) Strings() []string {
   464  	return it.AllRawItems()
   465  }
   466  
   467  func (it *Key) Name() string {
   468  	return it.Compile()
   469  }
   470  
   471  func (it *Key) KeyCompiled() string {
   472  	return it.Compile()
   473  }
   474  
   475  func (it *Key) compileCompleteAdditional(joiner string, items ...interface{}) string {
   476  	if len(items) == 0 {
   477  		return constants.EmptyString
   478  	}
   479  
   480  	finalSlice := make([]string, 0, len(items))
   481  	finalSlice = appendAnyItemsWithBaseStrings(
   482  		it.option.IsSkipEmptyEntry,
   483  		finalSlice,
   484  		items)
   485  
   486  	return it.compileFinalStrings(joiner, finalSlice)
   487  }
   488  
   489  func (it *Key) compileCompleteAdditionalStrings(joiner string, items ...string) string {
   490  	if len(items) == 0 {
   491  		return constants.EmptyString
   492  	}
   493  
   494  	finalSlice := make([]string, 0, len(items))
   495  	finalSlice = stringslice.AppendStringsWithMainSlice(
   496  		it.option.IsSkipEmptyEntry,
   497  		finalSlice,
   498  		items...)
   499  
   500  	return it.compileFinalStrings(joiner, finalSlice)
   501  }
   502  
   503  func (it *Key) TemplateReplacer() templateReplacer {
   504  	return templateReplacer{
   505  		it,
   506  	}
   507  }
   508  
   509  func (it *Key) JsonModel() keyModel {
   510  	return keyModel{
   511  		Option:        it.option,
   512  		MainName:      it.mainName,
   513  		KeyChains:     it.keyChains,
   514  		CompiledChain: it.compiledChain,
   515  	}
   516  }
   517  
   518  func (it *Key) JsonModelAny() interface{} {
   519  	return it.JsonModel()
   520  }
   521  
   522  func (it Key) Serialize() ([]byte, error) {
   523  	return corejson.Serialize.Raw(it)
   524  }
   525  
   526  func (it *Key) MarshalJSON() ([]byte, error) {
   527  	return json.Marshal(it.JsonModel())
   528  }
   529  
   530  func (it *Key) UnmarshalJSON(data []byte) error {
   531  	var deserializedModel keyModel
   532  	err := json.Unmarshal(data, &deserializedModel)
   533  
   534  	if err == nil {
   535  		it.option = deserializedModel.Option
   536  		it.mainName = deserializedModel.MainName
   537  		it.keyChains = deserializedModel.KeyChains
   538  		it.compiledChain = deserializedModel.CompiledChain
   539  	}
   540  
   541  	return err
   542  }
   543  
   544  func (it Key) Json() corejson.Result {
   545  	return corejson.New(it)
   546  }
   547  
   548  func (it Key) JsonPtr() *corejson.Result {
   549  	return corejson.NewPtr(it)
   550  }
   551  
   552  func (it Key) JsonString() string {
   553  	return corejson.NewPtr(it).JsonString()
   554  }
   555  
   556  // ParseInjectUsingJson It will not update the self but creates a new one.
   557  func (it *Key) ParseInjectUsingJson(
   558  	jsonResult *corejson.Result,
   559  ) (*Key, error) {
   560  	err := jsonResult.Unmarshal(it)
   561  
   562  	if err != nil {
   563  		return nil, err
   564  	}
   565  
   566  	return it, nil
   567  }
   568  
   569  // ParseInjectUsingJsonMust Panic if error
   570  func (it *Key) ParseInjectUsingJsonMust(
   571  	jsonResult *corejson.Result,
   572  ) *Key {
   573  	deserialized, err := it.ParseInjectUsingJson(jsonResult)
   574  
   575  	if err != nil {
   576  		panic(err)
   577  	}
   578  
   579  	return deserialized
   580  }
   581  
   582  func (it *Key) AsJsonContractsBinder() corejson.JsonContractsBinder {
   583  	return it
   584  }
   585  
   586  func (it *Key) AsJsoner() corejson.Jsoner {
   587  	return it
   588  }
   589  
   590  func (it *Key) JsonParseSelfInject(
   591  	jsonResult *corejson.Result,
   592  ) error {
   593  	_, err := it.ParseInjectUsingJson(
   594  		jsonResult,
   595  	)
   596  
   597  	return err
   598  }
   599  
   600  func (it Key) AsJsonParseSelfInjector() corejson.JsonParseSelfInjector {
   601  	return &it
   602  }
   603  
   604  func (it Key) AsJsonMarshaller() corejson.JsonMarshaller {
   605  	return &it
   606  }