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 }