result.go 4.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155
  1. package result
  2. import (
  3. "fmt"
  4. "runtime"
  5. "gitp78su.ipnodns.ru/svi/kern/v4/d0/defs/def_spec_base"
  6. "gitp78su.ipnodns.ru/svi/kern/v4/d0/helpers"
  7. )
  8. // Result — обёртка вокруг результата с возможной ошибкой.
  9. //
  10. // Может быть либо только полезное значение, либо только ошибка.
  11. type Result[T any] struct {
  12. val T // Полезное значение
  13. isCheck def_spec_base.Bool // Если проверено
  14. err error // Ошибка
  15. }
  16. const (
  17. str5 = def_spec_base.Txt("NewOk(): result==nil")
  18. )
  19. // ResOk -- возвращает успешный Result с значением.
  20. func ResOk[T any](result T) *Result[T] {
  21. helpers.If(helpers.IsNil(result)).Hassert(str5)
  22. sf := &Result[T]{
  23. val: result,
  24. }
  25. runtime.SetFinalizer(sf, sf.destroy)
  26. return sf
  27. }
  28. var (
  29. str6 = def_spec_base.Txt("NewErr(): err==nil")
  30. )
  31. // ResErr -- возвращает Result с ошибкой.
  32. func ResErr[T any](err error) *Result[T] {
  33. helpers.If(err == nil).Hassert(str6)
  34. sf := &Result[T]{
  35. err: err,
  36. }
  37. runtime.SetFinalizer(sf, sf.destroy)
  38. return sf
  39. }
  40. var (
  41. str7 = def_spec_base.Txt("WrapErr(): result not have error")
  42. str8 = def_spec_base.Txt("WrapErr(): err==nil")
  43. )
  44. // WrapErr -- оборачивает существующий Result с ошибкой с новой ошибкой.
  45. func WrapErr[T any](res *Result[T], err error) *Result[T] {
  46. helpers.If(res.IsOk()).Hassert(str7)
  47. helpers.If(err == nil).Hassert(str8)
  48. err0 := res.Err() // Чтобы не было паники при финализации и обернуть ошибку
  49. err = fmt.Errorf("%v, err=\n\t%w", err0, err)
  50. sf := ResErr[T](err)
  51. return sf
  52. }
  53. var (
  54. str9 = def_spec_base.Txt("Result[T].destroy(): err not checked")
  55. )
  56. func (sf *Result[T]) destroy(res *Result[T]) {
  57. helpers.If(!res.isCheck).Hassert(str9)
  58. }
  59. // IsOk -- возвращает true, если Result содержит значение.
  60. func (sf *Result[T]) IsOk() def_spec_base.Bool {
  61. sf.isCheck = true
  62. return sf.err == nil
  63. }
  64. // IsErr -- возвращает true, если Result содержит ошибку.
  65. func (sf *Result[T]) IsErr() def_spec_base.Bool {
  66. sf.isCheck = true
  67. return sf.err != nil
  68. }
  69. // Ok -- возвращает значение, если оно есть, иначе паникует.
  70. func (sf *Result[T]) Ok() T {
  71. helpers.If(sf.err != nil).Hassert("Result[T].Ok(): err!=nil, err=\n\t%v", sf.err)
  72. sf.isCheck = true
  73. return sf.val
  74. }
  75. // OkOr -- возвращает значение, если оно есть, или значение по умолчанию.
  76. func (sf *Result[T]) OkOr(defaultValue T) T {
  77. sf.isCheck = true
  78. if sf.err != nil {
  79. sf.val = defaultValue
  80. sf.err = nil
  81. }
  82. return sf.Ok()
  83. }
  84. var (
  85. str11 = def_spec_base.Txt("Result[T].OkOrFn(): fn==nil")
  86. )
  87. // OkOrFn -- возвращает значение, если оно есть, или результат выполнения функции.
  88. func (sf *Result[T]) OkOrFn(fn func() T) T {
  89. helpers.If(fn == nil).Hassert(str11)
  90. sf.isCheck = true
  91. if sf.err != nil {
  92. sf.val = fn()
  93. sf.err = nil
  94. }
  95. return sf.Ok()
  96. }
  97. var (
  98. str12 = def_spec_base.Txt("Result[T].Err(): err==nil")
  99. )
  100. // Err -- возвращает ошибку, если она есть.
  101. func (sf *Result[T]) Err() error {
  102. helpers.If(sf.err == nil).Hassert(str12)
  103. sf.isCheck = true
  104. return sf.err
  105. }
  106. const str13 = "Result[T].Error(): err==nil"
  107. // Error -- возвращает строковое представление ошибки, если она есть.
  108. func (sf *Result[T]) Error() string {
  109. helpers.If(sf.err == nil).Hassert(str13)
  110. sf.isCheck = true
  111. return sf.err.Error()
  112. }
  113. // Hassert -- проверяет, что нет ошибки (с паникой).
  114. func (sf *Result[T]) Hassert(msgFormat def_spec_base.Txt, args ...any) T {
  115. if sf.err != nil {
  116. txtErr := fmt.Sprintf("Result[T].Hassert(): have error, err=\n\t%v", sf.err)
  117. msgErr := def_spec_base.Txt(txtErr)
  118. helpers.If(sf.err != nil).Hassert(msgErr)
  119. }
  120. sf.isCheck = true
  121. return sf.val
  122. }
  123. // Assert -- проверяет, что нет ошибки (с паникой только на локальном стенде).
  124. func (sf *Result[T]) Assert(msgFormat def_spec_base.Txt, args ...any) T {
  125. if sf.err != nil {
  126. strErr := fmt.Sprintf("Result[T].Assert(): have error, , err=\n\t%v", sf.err)
  127. txtErr := def_spec_base.Txt(strErr)
  128. helpers.If(sf.err != nil).Assert(txtErr, args...)
  129. }
  130. sf.isCheck = true
  131. return sf.val
  132. }