gitlab.com/evatix-go/core@v1.3.55/coredata/coredynamic/Dynamic.go (about) 1 package coredynamic 2 3 import ( 4 "encoding/json" 5 "fmt" 6 "reflect" 7 "strconv" 8 9 "gitlab.com/evatix-go/core/constants" 10 "gitlab.com/evatix-go/core/constants/bitsize" 11 "gitlab.com/evatix-go/core/coredata/corejson" 12 "gitlab.com/evatix-go/core/coredata/coreonce" 13 "gitlab.com/evatix-go/core/defaulterr" 14 "gitlab.com/evatix-go/core/errcore" 15 "gitlab.com/evatix-go/core/internal/messages" 16 "gitlab.com/evatix-go/core/internal/reflectinternal" 17 "gitlab.com/evatix-go/core/internal/strutilinternal" 18 "gitlab.com/evatix-go/core/issetter" 19 ) 20 21 type Dynamic struct { 22 innerData interface{} 23 isValid bool 24 reflectType reflect.Type 25 reflectVal *reflect.Value 26 innerDataString *string 27 typeName coreonce.StringOnce 28 length coreonce.IntegerOnce 29 isPointer issetter.Value 30 } 31 32 func InvalidDynamic() Dynamic { 33 return *InvalidDynamicPtr() 34 } 35 36 func InvalidDynamicPtr() *Dynamic { 37 return NewDynamicPtr( 38 nil, 39 false) 40 } 41 42 func NewDynamicValid( 43 data interface{}, 44 ) Dynamic { 45 return *NewDynamicPtr(data, true) 46 } 47 48 func NewDynamic( 49 data interface{}, 50 isValid bool, 51 ) Dynamic { 52 return *NewDynamicPtr(data, isValid) 53 } 54 55 func NewDynamicPtr( 56 data interface{}, 57 isValid bool, 58 ) *Dynamic { 59 return &Dynamic{ 60 innerData: data, 61 isValid: isValid, 62 typeName: coreonce.NewStringOnce(func() string { 63 return fmt.Sprintf(constants.SprintTypeFormat, data) 64 }), 65 length: coreonce.NewIntegerOnce(func() int { 66 if data == nil { 67 return 0 68 } 69 70 return LengthOfReflect(reflect.ValueOf(data)) 71 }), 72 } 73 } 74 75 func (it *Dynamic) Data() interface{} { 76 return it.innerData 77 } 78 79 func (it *Dynamic) Value() interface{} { 80 return it.innerData 81 } 82 83 // Length Returns length of a slice, map, array 84 // 85 // It will also reduce from pointer 86 // 87 // Reference : https://cutt.ly/PnaWAFn | https://cutt.ly/jnaEig8 | https://play.golang.org/p/UCORoShXlv1 88 func (it *Dynamic) Length() int { 89 return it.length.Value() 90 } 91 92 func (it *Dynamic) StructStringPtr() *string { 93 if it.innerDataString != nil { 94 return it.innerDataString 95 } 96 97 toString := strutilinternal.AnyToString(it.innerData) 98 it.innerDataString = &toString 99 100 return it.innerDataString 101 } 102 103 func (it *Dynamic) ReflectValue() *reflect.Value { 104 if it.reflectVal != nil { 105 return it.reflectVal 106 } 107 108 reflectValueOfAny := reflect.ValueOf(it.innerData) 109 it.reflectVal = &reflectValueOfAny 110 111 return it.reflectVal 112 } 113 114 func (it *Dynamic) MapToKeyVal() (*KeyValCollection, error) { 115 return MapAsKeyValSlice(*it.ReflectValue()) 116 } 117 118 func (it *Dynamic) ReflectKind() reflect.Kind { 119 return it.ReflectValue().Kind() 120 } 121 122 func (it *Dynamic) ReflectTypeName() string { 123 return it.typeName.Value() 124 } 125 126 func (it *Dynamic) ReflectType() reflect.Type { 127 if it.reflectType != nil { 128 return it.reflectType 129 } 130 131 reflectType := reflect.TypeOf(it.innerData) 132 it.reflectType = reflectType 133 134 return it.reflectType 135 } 136 137 func (it *Dynamic) IsReflectTypeOf( 138 typeRequest reflect.Type, 139 ) bool { 140 return it.ReflectType() == typeRequest 141 } 142 143 func (it *Dynamic) ItemReflectValueUsingIndex(index int) reflect.Value { 144 return it.ReflectValue().Index(index) 145 } 146 147 func (it *Dynamic) ItemReflectValueUsingKey(key interface{}) reflect.Value { 148 return it.ReflectValue().MapIndex(reflect.ValueOf(key)) 149 } 150 151 func (it *Dynamic) ItemUsingIndex(index int) interface{} { 152 return it.ReflectValue().Index(index).Interface() 153 } 154 155 func (it *Dynamic) ItemUsingKey(key interface{}) interface{} { 156 return it.ReflectValue().MapIndex(reflect.ValueOf(key)).Interface() 157 } 158 159 func (it *Dynamic) String() string { 160 return *it.StructStringPtr() 161 } 162 163 func (it *Dynamic) StructString() string { 164 return *it.StructStringPtr() 165 } 166 167 func (it *Dynamic) IsReflectKind(checkingKind reflect.Kind) bool { 168 return it.ReflectKind() == checkingKind 169 } 170 171 func (it *Dynamic) IsPointer() bool { 172 if it.isPointer.IsUninitialized() { 173 it.isPointer = issetter.GetBool( 174 it.IsReflectKind(reflect.Ptr)) 175 } 176 177 return it.isPointer.IsTrue() 178 } 179 180 func (it *Dynamic) IsValueType() bool { 181 return !it.IsPointer() 182 } 183 184 func (it *Dynamic) IsStructStringNullOrEmpty() bool { 185 return it.IsNull() || strutilinternal.IsNullOrEmpty( 186 it.StructStringPtr()) 187 } 188 189 func (it *Dynamic) IsStructStringNullOrEmptyOrWhitespace() bool { 190 return it.IsNull() || strutilinternal.IsNullOrEmptyOrWhitespace( 191 it.StructStringPtr()) 192 } 193 194 func (it *Dynamic) IsPrimitive() bool { 195 return reflectinternal.IsPrimitive(it.ReflectKind()) 196 } 197 198 // IsNumber true if float (any), byte, int (any), uint(any) 199 func (it *Dynamic) IsNumber() bool { 200 return reflectinternal.IsNumber(it.ReflectKind()) 201 } 202 203 func (it *Dynamic) IntDefault(defaultInt int) (val int, isSuccess bool) { 204 if it.IsNull() { 205 return defaultInt, false 206 } 207 208 stringVal := it.StructString() 209 toInt, err := strconv.Atoi(stringVal) 210 211 if err == nil { 212 return toInt, true 213 } 214 215 return defaultInt, false 216 } 217 218 func (it *Dynamic) Float64() (val float64, err error) { 219 if it.IsNull() { 220 return constants.Zero, errcore. 221 ParsingFailedType.Error( 222 messages.DynamicFailedToParseToFloat64BecauseNull, 223 it.String()) 224 } 225 226 stringVal := it.StructString() 227 valFloat, err2 := strconv.ParseFloat(stringVal, bitsize.Of64) 228 229 if err2 != nil { 230 reference := stringVal + 231 constants.NewLineUnix + 232 err2.Error() 233 234 return constants.Zero, errcore. 235 ParsingFailedType.Error( 236 errcore.FailedToConvertType.String(), 237 reference) 238 } 239 240 return valFloat, err 241 } 242 243 func (it *Dynamic) IsStruct() bool { 244 return it.ReflectKind() == reflect.Struct 245 } 246 247 func (it *Dynamic) IsFunc() bool { 248 return it.ReflectKind() == reflect.Func 249 } 250 251 func (it *Dynamic) IsSliceOrArray() bool { 252 k := it.ReflectKind() 253 254 return k == reflect.Slice || k == reflect.Array 255 } 256 257 func (it *Dynamic) IsSliceOrArrayOrMap() bool { 258 k := it.ReflectKind() 259 260 return k == reflect.Slice || 261 k == reflect.Array || 262 k == reflect.Map 263 } 264 265 func (it *Dynamic) IsMap() bool { 266 return it.ReflectKind() == reflect.Map 267 } 268 269 func (it *Dynamic) IsNull() bool { 270 return it.innerData == nil 271 } 272 273 func (it *Dynamic) IsValid() bool { 274 return it.isValid 275 } 276 277 func (it *Dynamic) IsInvalid() bool { 278 return !it.isValid 279 } 280 281 func (it *Dynamic) Loop( 282 loopProcessorFunc func(index int, item interface{}) (isBreak bool), 283 ) (isCalled bool) { 284 if it.IsInvalid() || it.IsNull() || it.Length() <= 0 { 285 return false 286 } 287 288 length := it.Length() 289 rv := *it.ReflectValue() 290 291 for i := 0; i < length; i++ { 292 isBreak := loopProcessorFunc( 293 i, 294 rv.Index(i).Interface()) 295 296 if isBreak { 297 return true 298 } 299 } 300 301 return true 302 } 303 304 func (it *Dynamic) FilterAsDynamicCollection( 305 filterFunc func(index int, itemAsDynamic Dynamic) (isTake, isBreak bool), 306 ) *DynamicCollection { 307 if it.IsInvalid() || it.IsNull() || it.Length() <= 0 { 308 return EmptyDynamicCollection() 309 } 310 311 length := it.Length() 312 rv := *it.ReflectValue() 313 dynamicCollection := NewDynamicCollection(length / 2) 314 315 for i := 0; i < length; i++ { 316 currentRv := rv.Index(i) 317 valInf := currentRv.Interface() 318 currentDynamic := NewDynamic(valInf, currentRv.IsValid()) 319 320 isTake, isBreak := filterFunc( 321 i, 322 currentDynamic) 323 324 if isTake { 325 dynamicCollection.Add(currentDynamic) 326 } 327 328 if isBreak { 329 return dynamicCollection 330 } 331 } 332 333 return dynamicCollection 334 } 335 336 func (it *Dynamic) LoopMap( 337 mapLoopProcessorFunc func(index int, key, value interface{}) (isBreak bool), 338 ) (isCalled bool) { 339 if it.IsInvalid() || it.IsNull() || it.Length() <= 0 { 340 return false 341 } 342 343 rv := *it.ReflectValue() 344 mapIterator := rv.MapRange() 345 index := 0 346 for mapIterator.Next() { 347 k := mapIterator.Key() 348 v := mapIterator.Value() 349 isBreak := mapLoopProcessorFunc(index, k.Interface(), v.Interface()) 350 351 if isBreak { 352 return true 353 } 354 355 index++ 356 } 357 358 return true 359 } 360 361 func (it *Dynamic) ConvertUsingFunc( 362 converter SimpleInOutConverter, 363 expectedType reflect.Type, 364 ) *SimpleResult { 365 return converter(it.innerData, expectedType) 366 } 367 368 func (it Dynamic) NonPtr() Dynamic { 369 return it 370 } 371 372 func (it *Dynamic) Ptr() *Dynamic { 373 return it 374 } 375 376 func (it *Dynamic) Bytes() (rawBytes []byte, isSuccess bool) { 377 if it == nil { 378 return nil, false 379 } 380 381 rawBytes, isSuccess = it.innerData.([]byte) 382 383 if isSuccess { 384 return rawBytes, isSuccess 385 } 386 387 rawBytes, err := json.Marshal(it.innerData) 388 389 return rawBytes, err != nil 390 } 391 392 func (it *Dynamic) ReflectSetTo(toPointer interface{}) error { 393 if it == nil { 394 return defaulterr.NilResult 395 } 396 397 return ReflectSetFromTo( 398 it.innerData, 399 toPointer) 400 } 401 402 func (it *Dynamic) Deserialize(jsonBytes []byte) (deserialized *Dynamic, err error) { 403 if it == nil { 404 return InvalidDynamicPtr(), defaulterr.UnmarshallingFailedDueToNilOrEmpty 405 } 406 407 err = corejson. 408 Deserialize. 409 UsingBytes(jsonBytes, it.innerData) 410 411 it.isValid = err == nil 412 413 return it, err 414 } 415 416 func (it *Dynamic) ValueMarshal() (jsonBytes []byte, err error) { 417 if it == nil { 418 return nil, defaulterr.NilResult 419 } 420 421 return corejson. 422 Serialize. 423 ToBytesErr(it.innerData) 424 } 425 426 func (it *Dynamic) JsonPayloadMust() (jsonBytes []byte) { 427 return corejson. 428 Serialize. 429 ToSafeBytesMust(it.innerData) 430 } 431 432 // JsonBytesPtr returns empty string on nil. 433 // no error on nil. 434 func (it *Dynamic) JsonBytesPtr() (jsonBytesPtr *[]byte, err error) { 435 if it.IsNull() { 436 return &[]byte{}, nil 437 } 438 439 marshalledBytes, e := json.Marshal(it.innerData) 440 441 if e != nil { 442 return &[]byte{}, e 443 } 444 445 return &marshalledBytes, nil 446 } 447 448 func (it *Dynamic) MarshalJSON() ([]byte, error) { 449 return corejson. 450 Serialize. 451 ToBytesErr(it.innerData) 452 } 453 454 func (it *Dynamic) UnmarshalJSON(data []byte) error { 455 if it == nil { 456 return defaulterr.UnmarshallingFailedDueToNilOrEmpty 457 } 458 459 err := corejson. 460 Deserialize. 461 UsingBytes(data, it.innerData) 462 463 it.isValid = err == nil 464 465 return err 466 } 467 468 func (it *Dynamic) JsonModel() interface{} { 469 return it.innerData 470 } 471 472 func (it *Dynamic) JsonModelAny() interface{} { 473 return it.JsonModel() 474 } 475 476 func (it Dynamic) Json() corejson.Result { 477 return corejson.New(it) 478 } 479 480 func (it Dynamic) JsonPtr() *corejson.Result { 481 return corejson.NewPtr(it) 482 } 483 484 //goland:noinspection GoLinterLocal 485 func (it *Dynamic) ParseInjectUsingJson( 486 jsonResult *corejson.Result, 487 ) (*Dynamic, error) { 488 err := jsonResult.Unmarshal(it) 489 490 if err != nil { 491 return nil, err 492 } 493 494 return it, nil 495 } 496 497 // ParseInjectUsingJsonMust Panic if error 498 //goland:noinspection GoLinterLocal 499 func (it *Dynamic) ParseInjectUsingJsonMust( 500 jsonResult *corejson.Result, 501 ) *Dynamic { 502 newUsingJson, err := 503 it.ParseInjectUsingJson(jsonResult) 504 505 if err != nil { 506 panic(err) 507 } 508 509 return newUsingJson 510 } 511 512 func (it *Dynamic) JsonParseSelfInject( 513 jsonResult *corejson.Result, 514 ) error { 515 _, err := it.ParseInjectUsingJson( 516 jsonResult, 517 ) 518 519 return err 520 } 521 522 func (it *Dynamic) IsStringType() bool { 523 _, isString := it.innerData.(string) 524 525 return isString 526 } 527 528 func (it *Dynamic) JsonBytes() (jsonBytesPtr []byte, err error) { 529 allBytes, err := it.JsonBytesPtr() 530 531 if err != nil { 532 return []byte{}, err 533 } 534 535 return *allBytes, err 536 } 537 538 func (it *Dynamic) JsonString() (jsonString string, err error) { 539 marshalledBytes, err := it.JsonBytes() 540 541 if err != nil { 542 return constants.EmptyString, err 543 } 544 545 return string(marshalledBytes), err 546 } 547 548 func (it *Dynamic) JsonStringMust() string { 549 marshalledBytes, err := it.JsonBytes() 550 551 if err != nil { 552 errcore. 553 MarshallingFailedType. 554 HandleUsingPanic(err.Error(), it.innerDataString) 555 } 556 557 return string(marshalledBytes) 558 } 559 560 func (it Dynamic) Clone() Dynamic { 561 return NewDynamic( 562 it.innerData, 563 it.isValid) 564 } 565 566 func (it *Dynamic) ClonePtr() *Dynamic { 567 if it == nil { 568 return nil 569 } 570 571 return NewDynamicPtr( 572 it.innerData, 573 it.isValid) 574 } 575 576 func (it *Dynamic) ValueInt() int { 577 casted, isSuccess := it.innerData.(int) 578 579 if isSuccess { 580 return casted 581 } 582 583 return constants.InvalidValue 584 } 585 586 func (it *Dynamic) ValueUInt() uint { 587 casted, isSuccess := it.innerData.(uint) 588 589 if isSuccess { 590 return casted 591 } 592 593 return constants.Zero 594 } 595 596 func (it *Dynamic) ValueStrings() []string { 597 casted, isSuccess := it.innerData.([]string) 598 599 if isSuccess { 600 return casted 601 } 602 603 return nil 604 } 605 606 func (it *Dynamic) ValueBool() bool { 607 casted, isSuccess := it.innerData.(bool) 608 609 if isSuccess { 610 return casted 611 } 612 613 return false 614 } 615 616 func (it *Dynamic) ValueInt64() int64 { 617 casted, isSuccess := it.innerData.(int64) 618 619 if isSuccess { 620 return casted 621 } 622 623 return constants.InvalidValue 624 } 625 626 func (it *Dynamic) ValueNullErr() error { 627 if it == nil { 628 return errcore. 629 CannotBeNilOrEmptyType. 630 ErrorNoRefs("Dynamic is nil or null") 631 } 632 633 if reflectinternal.IsNull(it.innerData) { 634 return errcore. 635 CannotBeNilOrEmptyType. 636 ErrorNoRefs("Dynamic internal data is nil.") 637 } 638 639 return nil 640 } 641 642 func (it *Dynamic) ValueString() string { 643 if it == nil || it.innerData == nil { 644 return constants.EmptyString 645 } 646 647 currentString, isString := it.innerData.(string) 648 649 if isString { 650 return currentString 651 } 652 653 return fmt.Sprintf( 654 constants.SprintValueFormat, 655 it.innerData, 656 ) 657 }