kresult.go 3.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107
  1. package ktypes
  2. import (
  3. "fmt"
  4. "reflect"
  5. . "gitp78su.ipnodns.ru/svi/kern/v2/kc/helpers"
  6. )
  7. // Result — обёртка вокруг результата с возможной ошибкой
  8. //
  9. // Может быть либо только полезное значение, либо только ошибка
  10. type Result[T any] struct {
  11. val T // Полезное значение
  12. isErr bool
  13. err error // Ошибка
  14. }
  15. // NewOk -- возвращает успешный Result с значением
  16. func NewOk[T any](result T) Result[T] {
  17. // Для некоторых типов нужна дополнительная проверка через reflect
  18. v := reflect.ValueOf(result)
  19. switch v.Kind() {
  20. case reflect.Ptr, reflect.Slice, reflect.Map, reflect.Chan, reflect.Func, reflect.Interface:
  21. Hassert(!v.IsNil(), "NewOk(): result==nil")
  22. }
  23. sf := Result[T]{
  24. val: result,
  25. }
  26. return sf
  27. }
  28. // NewErr -- возвращает Result с ошибкой
  29. func NewErr[T any](err error) Result[T] {
  30. Hassert(err != nil, "NewError(): err==nil")
  31. return Result[T]{
  32. err: err,
  33. isErr: true,
  34. }
  35. }
  36. // WrapErr -- оборачивает существующий Result с ошибкой с новой ошибкой
  37. func WrapErr[T any](res Result[T], err error) Result[T] {
  38. Hassert(res.IsErr(), "WrapErr(): result not have error")
  39. Hassert(err != nil, "WrapErr(): err==nil")
  40. err0 := res.Err()
  41. err = fmt.Errorf("%v, err=\n\t%w", err0, err)
  42. res0 := NewErr[T](err)
  43. return res0
  44. }
  45. // IsOk -- возвращает true, если Result содержит значение
  46. func (sf *Result[T]) IsOk() bool {
  47. return !sf.isErr
  48. }
  49. // IsErr -- возвращает true, если Result содержит ошибку
  50. func (sf *Result[T]) IsErr() bool {
  51. return sf.isErr
  52. }
  53. // Val -- возвращает значение, если оно есть, иначе паникует
  54. func (sf *Result[T]) Val() T {
  55. Hassert(!sf.isErr, "Result[T].Val(): err(%v)!=nil", sf.err)
  56. return sf.val
  57. }
  58. // ValOr -- возвращает значение, если оно есть, или значение по умолчанию
  59. func (sf *Result[T]) ValOr(defaultValue T) T {
  60. if sf.isErr {
  61. return defaultValue
  62. }
  63. return sf.val
  64. }
  65. // ValOrFn -- возвращает значение, если оно есть, или результат выполнения функции
  66. func (sf *Result[T]) ValOrFn(fn func() T) T {
  67. Hassert(fn != nil, "Result[T].ValOrFn(): fn==nil")
  68. if sf.isErr {
  69. return fn()
  70. }
  71. return sf.val
  72. }
  73. // Err -- возвращает ошибку, если она есть
  74. func (sf *Result[T]) Err() error {
  75. Hassert(sf.isErr, "Result[T].Err(): err==nil")
  76. return sf.err
  77. }
  78. // Error -- возвращает строковое представление ошибки, если она есть
  79. func (sf *Result[T]) Error() string {
  80. Hassert(sf.isErr, "Result[T].Error(): err==nil")
  81. return sf.err.Error()
  82. }
  83. // Hassert -- проверяет, что нет ошибки (с паникой)
  84. func (sf *Result[T]) Hassert(msgFormat string, args ...any) {
  85. msg := fmt.Sprintf(msgFormat, args...)
  86. Hassert(!sf.isErr, msg+", err=\n\t%v\n", sf.err)
  87. }
  88. // Assert -- проверяет, что нет ошибки (с паникой только на локальном стенде)
  89. func (sf *Result[T]) Assert(msgFormat string, args ...any) {
  90. msg := fmt.Sprintf(msgFormat, args...)
  91. Assert(!sf.isErr, msg+", err=\n\t%v\n", sf.err)
  92. }