gitee.com/sy_183/go-common@v1.0.5-0.20231205030221-958cfe129b47/config/handler.go (about) 1 package config 2 3 import ( 4 "encoding" 5 "encoding/json" 6 "gitee.com/sy_183/go-common/assert" 7 "gitee.com/sy_183/go-common/errors" 8 "gitee.com/sy_183/go-common/strings/unsafe" 9 "gopkg.in/yaml.v3" 10 "reflect" 11 "strconv" 12 "time" 13 ) 14 15 type handler interface { 16 canHandle(c any) bool 17 handle(c any) (nc any, modified bool, err error) 18 handleAfterChildren(c any) (nc any, modified bool, err error) 19 } 20 21 type PreModifyConfig interface { 22 PreModify() (nc any, modified bool) 23 } 24 25 type PreHandlerConfig interface { 26 PreHandle() 27 } 28 29 type PreModifyAfterChildrenConfig interface { 30 PreModifyAfterChildren() (nc any, modified bool) 31 } 32 33 type PreHandleAfterChildrenConfig interface { 34 PreHandleAfterChildren() 35 } 36 37 type PostModifyConfig interface { 38 PostModify() (nc any, modified bool, err error) 39 } 40 41 type PostHandlerConfig interface { 42 PostHandle() error 43 } 44 45 type PostModifyAfterChildrenConfig interface { 46 PostModifyAfterChildren() (nc any, modified bool, err error) 47 } 48 49 type PostHandleAfterChildrenConfig interface { 50 PostHandleAfterChildren() error 51 } 52 53 type preHandler struct{} 54 55 func (preHandler) canHandle(c any) bool { 56 if _, ok := c.(PreModifyConfig); ok { 57 return true 58 } 59 if _, ok := c.(PreHandlerConfig); ok { 60 return true 61 } 62 return false 63 } 64 65 func (p preHandler) handle(c any) (nc any, modified bool, err error) { 66 nc = c 67 if pmc, ok := nc.(PreModifyConfig); ok { 68 if nc, modified = pmc.PreModify(); !modified { 69 nc = c 70 } 71 } 72 if phc, ok := nc.(PreHandlerConfig); ok { 73 phc.PreHandle() 74 } 75 return 76 } 77 78 func (p preHandler) handleAfterChildren(c any) (nc any, modified bool, err error) { 79 nc = c 80 if pmc, ok := nc.(PreModifyAfterChildrenConfig); ok { 81 if nc, modified = pmc.PreModifyAfterChildren(); !modified { 82 nc = c 83 } 84 } 85 if phc, ok := nc.(PreHandleAfterChildrenConfig); ok { 86 phc.PreHandleAfterChildren() 87 } 88 return 89 } 90 91 type postHandler struct{} 92 93 func (postHandler) canHandle(c any) bool { 94 if _, ok := c.(PostModifyConfig); ok { 95 return true 96 } 97 if _, ok := c.(PostHandlerConfig); ok { 98 return true 99 } 100 return false 101 } 102 103 func (postHandler) handle(c any) (nc any, modified bool, err error) { 104 nc = c 105 if pmc, ok := nc.(PostModifyConfig); ok { 106 if nc, modified, err = pmc.PostModify(); err != nil { 107 return 108 } else if !modified { 109 nc = c 110 } else { 111 ct := reflect.TypeOf(c) 112 nct := reflect.TypeOf(nc) 113 if ct.Kind() == reflect.Ptr && ct.Elem() == nct { 114 nec := reflect.New(nct) 115 nec.Elem().Set(reflect.ValueOf(nc)) 116 nc = nec.Interface() 117 } 118 } 119 } 120 if phc, ok := nc.(PostHandlerConfig); ok { 121 err = phc.PostHandle() 122 } 123 return 124 } 125 126 func (postHandler) handleAfterChildren(c any) (nc any, modified bool, err error) { 127 nc = c 128 if pmc, ok := nc.(PostModifyAfterChildrenConfig); ok { 129 if nc, modified, err = pmc.PostModifyAfterChildren(); err != nil { 130 return 131 } else if !modified { 132 nc = c 133 } else { 134 ct := reflect.TypeOf(c) 135 nct := reflect.TypeOf(nc) 136 if ct.Kind() == reflect.Ptr && ct.Elem() == nct { 137 ncp := reflect.New(nct) 138 ncp.Elem().Set(reflect.ValueOf(nc)) 139 nc = ncp.Interface() 140 } 141 } 142 } 143 144 if phc, ok := nc.(PostHandleAfterChildrenConfig); ok { 145 err = phc.PostHandleAfterChildren() 146 } 147 return 148 } 149 150 func handleDefault(v reflect.Value, zerop, timeLayerp, def *string, cs map[any]struct{}) error { 151 vt := v.Type() 152 if def != nil { 153 var vp, nv reflect.Value 154 if vt.Kind() != reflect.Ptr { 155 if v.CanAddr() { 156 vp = v.Addr() 157 } else { 158 vp = reflect.New(vt) 159 nv = vp.Elem() 160 nv.Set(v) 161 } 162 } else if v.IsNil() { 163 if v.CanSet() { 164 nv = reflect.New(vt.Elem()) 165 vp = nv 166 } 167 } else { 168 vp = v 169 } 170 if vp != (reflect.Value{}) { 171 if vp.CanInterface() { 172 vpi := vp.Interface() 173 if tp, is := vpi.(*time.Time); is { 174 t, err := time.Parse(*timeLayerp, *def) 175 if err != nil { 176 return err 177 } 178 *tp = t 179 return nil 180 } 181 if m, is := vpi.(encoding.TextUnmarshaler); is { 182 if err := m.UnmarshalText(unsafe.Bytes(*def)); err != nil { 183 return err 184 } 185 if nv != (reflect.Value{}) { 186 v.Set(nv) 187 } 188 return nil 189 } 190 } 191 } 192 } 193 switch vt.Kind() { 194 case reflect.String: 195 if v.CanSet() && def != nil { 196 if v.IsZero() { 197 v.SetString(*def) 198 } 199 } 200 case reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64, reflect.Int: 201 if v.CanSet() && def != nil { 202 if vt == reflect.TypeOf(time.Duration(0)) { 203 du, err := time.ParseDuration(*def) 204 if err != nil { 205 return err 206 } 207 if v.IsZero() { 208 v.SetInt(int64(du)) 209 } 210 } else { 211 parsed, err := strconv.ParseInt(*def, 0, int(vt.Size())*8) 212 if err != nil { 213 return err 214 } 215 if v.IsZero() { 216 v.SetInt(parsed) 217 } 218 } 219 } 220 case reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uint: 221 if v.CanSet() && def != nil { 222 parsed, err := strconv.ParseUint(*def, 0, int(vt.Size())*8) 223 if err != nil { 224 return err 225 } 226 if v.IsZero() { 227 v.SetUint(parsed) 228 } 229 } 230 case reflect.Float32, reflect.Float64: 231 if v.CanSet() && def != nil { 232 parsed, err := strconv.ParseFloat(*def, int(vt.Size())*8) 233 if err != nil { 234 return err 235 } 236 if v.IsZero() { 237 v.SetFloat(parsed) 238 } 239 } 240 case reflect.Complex64, reflect.Complex128: 241 if v.CanSet() && def != nil { 242 parsed, err := strconv.ParseComplex(*def, int(vt.Size())*8) 243 if err != nil { 244 return err 245 } 246 if v.IsZero() { 247 v.SetComplex(parsed) 248 } 249 } 250 case reflect.Bool: 251 if v.CanSet() && def != nil { 252 var zero bool 253 parsed, err := strconv.ParseBool(*def) 254 if err != nil { 255 return err 256 } 257 if v.Bool() == zero { 258 v.SetBool(parsed) 259 } 260 } 261 case reflect.Array, reflect.Struct: 262 if def != nil && v.IsZero() { 263 if vt == reflect.TypeOf(time.Time{}) { 264 if v.CanSet() { 265 parsed, err := time.Parse(time.RFC3339Nano, *def) 266 if err != nil { 267 return err 268 } 269 v.Set(reflect.ValueOf(parsed)) 270 } 271 } else if *def != "" { 272 // noCopy flag represents the pointer using the current array or struct 273 var noCopy bool 274 var pv reflect.Value 275 var pvi any 276 if v.CanAddr() { 277 // pointer using the current array or struct 278 pv = v.Addr() 279 noCopy = true 280 if pv.CanInterface() { 281 pvi = pv.Interface() 282 } 283 } else if v.CanSet() { 284 // new array pointer 285 pv = reflect.New(vt) 286 pvi = pv.Interface() 287 } 288 if pvi != nil { 289 // parse array use yaml or json 290 err := yaml.Unmarshal(unsafe.Bytes(*def), pvi) 291 if err != nil { 292 err2 := json.Unmarshal(unsafe.Bytes(*def), pvi) 293 if err2 != nil { 294 return errors.Append(err, err2) 295 } 296 } 297 if !noCopy { 298 // use the pointer of the current array, and do not 299 // need to set 300 v.Set(pv.Elem()) 301 } 302 } 303 } 304 } 305 switch vt.Kind() { 306 case reflect.Array: 307 // handle array element 308 l := v.Len() 309 for i := 0; i < l; i++ { 310 if err := handleDefault(v.Index(i), nil, nil, nil, cs); err != nil { 311 return err 312 } 313 } 314 case reflect.Struct: 315 nf := v.NumField() 316 for i := 0; i < nf; i++ { 317 fv := v.Field(i) 318 if !vt.Field(i).IsExported() { 319 continue 320 } 321 tag := vt.Field(i).Tag 322 if fdef, has := tag.Lookup("default"); has { 323 var fzerop *string 324 if fzero, has := tag.Lookup("zero"); has { 325 fzerop = &fzero 326 } 327 var ftimeLayerp *string 328 if ftimeLayer, has := tag.Lookup("timeLayer"); has { 329 ftimeLayerp = &ftimeLayer 330 } 331 if err := handleDefault(fv, fzerop, ftimeLayerp, &fdef, cs); err != nil { 332 return err 333 } 334 } else if err := handleDefault(fv, nil, nil, nil, cs); err != nil { 335 return err 336 } 337 } 338 } 339 case reflect.Slice, reflect.Map: 340 kind := vt.Kind() 341 if def != nil && v.CanSet() { 342 if *def != "" && v.Len() == 0 { 343 var pv reflect.Value 344 var pvi any 345 if v.CanAddr() { 346 if pv = v.Addr(); pv.CanInterface() { 347 // use current pointer of slice or map 348 if !v.IsNil() { 349 // map or slice is nil, make it first 350 switch kind { 351 case reflect.Slice: 352 v.Set(reflect.MakeSlice(vt, 0, 0)) 353 case reflect.Map: 354 v.Set(reflect.MakeMap(vt)) 355 } 356 } 357 pvi = pv.Interface() 358 } 359 } 360 if pvi == nil { 361 // new pointer of slice or map 362 pv = reflect.New(vt) 363 switch kind { 364 case reflect.Slice: 365 pv.Elem().Set(reflect.MakeSlice(vt, 0, 0)) 366 case reflect.Map: 367 pv.Elem().Set(reflect.MakeMap(vt)) 368 } 369 pvi = pv.Interface() 370 } 371 // parse slice or map use yaml or json 372 err := yaml.Unmarshal(unsafe.Bytes(*def), pvi) 373 if err != nil { 374 err2 := json.Unmarshal(unsafe.Bytes(*def), pvi) 375 if err2 != nil { 376 return errors.Append(err, err2) 377 } 378 } 379 v.Set(pv.Elem()) 380 } 381 } 382 switch kind { 383 case reflect.Slice: 384 // handle slice element 385 l := v.Len() 386 for i := 0; i < l; i++ { 387 if err := handleDefault(v.Index(i), nil, nil, nil, cs); err != nil { 388 return err 389 } 390 } 391 case reflect.Map: 392 // handle map value 393 for iter := v.MapRange(); iter.Next(); { 394 if err := handleDefault(iter.Value(), nil, nil, nil, cs); err != nil { 395 return err 396 } 397 } 398 } 399 case reflect.Ptr: 400 if def != nil && v.CanSet() { 401 nv := reflect.New(vt.Elem()) 402 if err := handleDefault(nv.Elem(), zerop, timeLayerp, def, cs); err != nil { 403 return err 404 } 405 if v.CanInterface() { 406 // update recursive call set 407 if !v.IsNil() { 408 delete(cs, v.Interface()) 409 } 410 v.Set(nv) 411 cs[v.Interface()] = struct{}{} 412 } 413 } else if v.IsNil() { 414 return nil 415 } else { 416 if v.CanInterface() { 417 // check and update recursive call set 418 if _, repeat := cs[v.Interface()]; repeat { 419 return nil 420 } 421 cs[v.Interface()] = struct{}{} 422 } 423 if err := handleDefault(v.Elem(), zerop, timeLayerp, def, cs); err != nil { 424 return err 425 } 426 } 427 } 428 return nil 429 } 430 431 func HandleDefault(c any) error { 432 return handleDefault(reflect.ValueOf(c), nil, nil, nil, make(map[interface{}]struct{})) 433 } 434 435 func doHandlerPtr(pi any, pv reflect.Value, setFn func(v reflect.Value), handleFn func(c any) (nc any, modified bool, err error), cs map[any]struct{}) (err error, repeat bool) { 436 pvt := pv.Type() 437 nc, mod, err := handleFn(pi) 438 if err != nil { 439 return err, false 440 } 441 if mod { 442 nct := reflect.TypeOf(nc) 443 ncv := reflect.ValueOf(nc) 444 if nct == pvt && ncv != pv { 445 if pv.CanSet() { 446 pv.Set(ncv) 447 } else if setFn != nil { 448 setFn(ncv) 449 } 450 delete(cs, pi) 451 if _, repeat := cs[nc]; repeat { 452 return nil, true 453 } 454 cs[nc] = struct{}{} 455 } else if nct == pvt.Elem() { 456 if ve := pv.Elem(); ve.CanSet() { 457 ve.Set(ncv) 458 } 459 } 460 } 461 return nil, false 462 } 463 464 func doHandle(v, pv reflect.Value, copied bool, setFn func(v reflect.Value), handleFn func(c any) (nc any, modified bool, err error)) error { 465 if pv.CanInterface() { 466 nc, mod, err := handleFn(pv.Interface()) 467 if err != nil { 468 return err 469 } 470 if mod { 471 nct := reflect.TypeOf(nc) 472 ncv := reflect.ValueOf(nc) 473 if v.CanSet() { 474 if nct == v.Type() { 475 v.Set(ncv) 476 } else if nct == pv.Type() && (copied || ncv != pv) { 477 v.Set(ncv.Elem()) 478 } 479 } else if setFn != nil { 480 if nct == v.Type() { 481 setFn(ncv) 482 } else if nct == pv.Type() && (copied || ncv != pv) { 483 setFn(ncv.Elem()) 484 } 485 } 486 } 487 } 488 return nil 489 } 490 491 func handleChildren(v reflect.Value, handler handler, cs map[any]struct{}) error { 492 vt := v.Type() 493 switch v.Kind() { 494 case reflect.Slice, reflect.Array: 495 ll := v.Len() 496 for i := 0; i < ll; i++ { 497 if err := handle(v.Index(i), nil, handler, cs); err != nil { 498 return err 499 } 500 } 501 case reflect.Map: 502 for iter := v.MapRange(); iter.Next(); { 503 if err := handle(iter.Value(), func(mv reflect.Value) { 504 v.SetMapIndex(iter.Key(), mv) 505 }, handler, cs); err != nil { 506 return err 507 } 508 } 509 case reflect.Struct: 510 nf := v.NumField() 511 for i := 0; i < nf; i++ { 512 fv := v.Field(i) 513 if !vt.Field(i).IsExported() { 514 continue 515 } 516 if err := handle(fv, nil, handler, cs); err != nil { 517 return err 518 } 519 } 520 case reflect.Ptr: 521 if err := handle(v, nil, handler, cs); err != nil { 522 return err 523 } 524 } 525 return nil 526 } 527 528 func handle(v reflect.Value, setFn func(v reflect.Value), handler handler, cs map[any]struct{}) error { 529 vt := v.Type() 530 if v.Kind() == reflect.Ptr { 531 if v.IsNil() { 532 return nil 533 } 534 if v.CanInterface() { 535 c := v.Interface() 536 if _, repeat := cs[c]; repeat { 537 return nil 538 } 539 cs[c] = struct{}{} 540 if err, repeat := doHandlerPtr(c, v, setFn, handler.handle, cs); err != nil { 541 return err 542 } else if repeat { 543 return nil 544 } 545 } 546 if err := handleChildren(v.Elem(), handler, cs); err != nil { 547 return err 548 } 549 if v.CanInterface() { 550 c := v.Interface() 551 if err, repeat := doHandlerPtr(c, v, setFn, handler.handleAfterChildren, cs); err != nil { 552 return err 553 } else if repeat { 554 return nil 555 } 556 } 557 } else if handler.canHandle(reflect.NewAt(vt, nil).Interface()) { 558 var pv reflect.Value 559 var copied bool 560 if v.CanAddr() { 561 pv = v.Addr() 562 } else { 563 pv = reflect.New(vt) 564 pv.Elem().Set(v) 565 copied = true 566 } 567 if pv.CanInterface() { 568 if err := doHandle(v, pv, copied, setFn, handler.handle); err != nil { 569 return err 570 } 571 } 572 if err := handleChildren(v, handler, cs); err != nil { 573 return err 574 } 575 if pv.CanInterface() { 576 if err := doHandle(v, pv, copied, setFn, handler.handleAfterChildren); err != nil { 577 return err 578 } 579 } 580 } else if err := handleChildren(v, handler, cs); err != nil { 581 return err 582 } 583 584 return nil 585 } 586 587 func PreHandle(c any) error { 588 return handle(reflect.ValueOf(c), nil, preHandler{}, make(map[interface{}]struct{})) 589 } 590 591 func PostHandle(c any) error { 592 return handle(reflect.ValueOf(c), nil, postHandler{}, make(map[interface{}]struct{})) 593 } 594 595 //func handle3(handler handler, c any, cs map[any]struct{}) (nc any, modified bool, err error) { 596 // var mod bool 597 // nc = c 598 // // ct: config type 599 // ct := reflect.TypeOf(c) 600 // // cv: config value 601 // cv := reflect.ValueOf(nc) 602 // v := cv 603 // 604 // switch ct.Kind() { 605 // case reflect.Ptr: 606 // if cv.IsNil() { 607 // return c, false, nil 608 // } 609 // v = v.Elem() 610 // if _, repeat := cs[nc]; repeat { 611 // return 612 // } 613 // } 614 // 615 // old := nc 616 // if nc, mod, err = handler.handle(nc); err != nil { 617 // return 618 // } 619 // modified = modified || mod 620 // 621 // if ct.Kind() == reflect.Ptr && mod { 622 // // handler modify config 623 // delete(cs, old) 624 // cs[nc] = struct{}{} 625 // } 626 // 627 // switch v.Kind() { 628 // case reflect.Struct: 629 // nf := v.NumField() 630 // // walk fields and handle filed 631 // for i := 0; i < nf; i++ { 632 // fv := v.Field(i) 633 // if fv.Kind() == reflect.Ptr { 634 // if fv.CanInterface() { 635 // fi := fv.Interface() 636 // if nfi, mod, err := handle3(handler, fi, cs); err != nil { 637 // return nc, modified, err 638 // } else if mod { 639 // fv.Set(reflect.ValueOf(nfi)) 640 // } 641 // } 642 // continue 643 // } 644 // // field not pointer and field has address 645 // if fv.CanAddr() { 646 // // field has address 647 // // fpv: field pointer value 648 // fpv := fv.Addr() 649 // if fpv.CanInterface() { 650 // // fpi: field pointer interface 651 // fpi := fpv.Interface() 652 // // nfpi: new field pointer interface 653 // if nfpi, mod, err := handle3(handler, fpi, cs); err != nil { 654 // return nc, modified, err 655 // } else if mod { 656 // fpv.Set(reflect.ValueOf(nfpi)) 657 // } 658 // } 659 // continue 660 // } 661 // // field not have address 662 // if fv.CanInterface() { 663 // fpv := reflect.New(fv.Type()) 664 // fpv.Elem().Set(fv) 665 // if fpv.CanInterface() { 666 // // mpi: map pointer interface 667 // fpi := fpv.Interface() 668 // // npmi: new map pointer interface 669 // if nfpi, mod, err := handle3(handler, fpi, cs); err != nil { 670 // return nc, modified, err 671 // } else if mod { 672 // fpv = reflect.ValueOf(nfpi) 673 // } 674 // fv.Set(fpv.Elem()) 675 // } 676 // } 677 // } 678 // 679 // case reflect.Map: 680 // for iter := v.MapRange(); iter.Next(); { 681 // // mv: map value 682 // mv := iter.Value() 683 // if mv.Kind() == reflect.Ptr { 684 // if mv.CanInterface() { 685 // // mvi: map value interface 686 // mvi := mv.Interface() 687 // // nmvi: new map value interface 688 // // mod: map value modified 689 // if nmvi, mod, err := handle3(handler, mvi, cs); err != nil { 690 // return nc, modified, err 691 // } else if mod { 692 // v.SetMapIndex(iter.Key(), reflect.ValueOf(nmvi)) 693 // } 694 // } 695 // continue 696 // } 697 // if mv.CanAddr() { 698 // // mpv: map pointer value 699 // mpv := mv.Addr() 700 // if mpv.CanInterface() { 701 // // mpi: map pointer interface 702 // mpi := mpv.Interface() 703 // // npmi: new map pointer interface 704 // if nmpi, mod, err := handle3(handler, mpi, cs); err != nil { 705 // return nc, modified, err 706 // } else if mod { 707 // mpv.Set(reflect.ValueOf(nmpi)) 708 // } 709 // } 710 // continue 711 // } 712 // if mv.CanInterface() { 713 // // mvi: map value interface 714 // mpv := reflect.New(mv.Type()) 715 // mpv.Elem().Set(mv) 716 // if mpv.CanInterface() { 717 // // mpi: map pointer interface 718 // mpi := mpv.Interface() 719 // // npmi: new map pointer interface 720 // if nmpi, mod, err := handle3(handler, mpi, cs); err != nil { 721 // return nc, modified, err 722 // } else if mod { 723 // mpv = reflect.ValueOf(nmpi) 724 // } 725 // v.SetMapIndex(iter.Key(), mpv.Elem()) 726 // } 727 // } 728 // } 729 // 730 // case reflect.Slice, reflect.Array: 731 // ll := v.Len() 732 // for i := 0; i < ll; i++ { 733 // lv := v.Index(i) 734 // if lv.Kind() == reflect.Ptr { 735 // if lv.CanInterface() { 736 // // lvi: list value interface 737 // lvi := lv.Interface() 738 // // nlvi: new list value interface 739 // // mod: list value modified 740 // if nlvi, mod, err := handle3(handler, lvi, cs); err != nil { 741 // return nc, modified, err 742 // } else if mod { 743 // lv.Set(reflect.ValueOf(nlvi)) 744 // } 745 // } 746 // continue 747 // } 748 // if lv.CanAddr() { 749 // // lpv: list pointer value 750 // lpv := lv.Addr() 751 // if lpv.CanInterface() { 752 // // lpi: list pointer interface 753 // lpi := lpv.Interface() 754 // // nlmi: new list pointer interface 755 // if nlpi, mod, err := handle3(handler, lpi, cs); err != nil { 756 // return nc, modified, err 757 // } else if mod { 758 // lpv.Set(reflect.ValueOf(nlpi)) 759 // } 760 // } 761 // continue 762 // } 763 // if lv.CanInterface() { 764 // lpv := reflect.New(lv.Type()) 765 // lpv.Elem().Set(lv) 766 // if lpv.CanInterface() { 767 // // mpi: map pointer interface 768 // lpi := lpv.Interface() 769 // // npmi: new map pointer interface 770 // if nlpi, mod, err := handle3(handler, lpi, cs); err != nil { 771 // return nc, modified, err 772 // } else if mod { 773 // lpv = reflect.ValueOf(nlpi) 774 // } 775 // lv.Set(lpv.Elem()) 776 // } 777 // } 778 // } 779 // } 780 // 781 // old = nc 782 // if nc, mod, err = handler.handleAfterChildren(nc); err != nil { 783 // return 784 // } 785 // modified = modified || mod 786 // 787 // if ct.Kind() == reflect.Ptr && mod { 788 // // handler modify config 789 // delete(cs, old) 790 // cs[nc] = struct{}{} 791 // } 792 // 793 // return 794 //} 795 796 func Handle(c any) error { 797 if err := HandleDefault(c); err != nil { 798 return err 799 } 800 if err := PreHandle(c); err != nil { 801 return err 802 } 803 if err := PostHandle(c); err != nil { 804 return err 805 } 806 return nil 807 } 808 809 func HandleWith[C any](c C) (C, error) { 810 if err := Handle(c); err != nil { 811 return c, err 812 } 813 return c, nil 814 } 815 816 func MustHandleWith[C any](c C) C { 817 return assert.Must(HandleWith(c)) 818 }