|
@@ -3,6 +3,7 @@ package ktypes
|
|
|
import (
|
|
import (
|
|
|
"fmt"
|
|
"fmt"
|
|
|
"reflect"
|
|
"reflect"
|
|
|
|
|
+ "runtime"
|
|
|
|
|
|
|
|
. "gitp78su.ipnodns.ru/svi/kern/v2/kc/helpers"
|
|
. "gitp78su.ipnodns.ru/svi/kern/v2/kc/helpers"
|
|
|
)
|
|
)
|
|
@@ -11,9 +12,10 @@ import (
|
|
|
//
|
|
//
|
|
|
// Может быть либо только полезное значение, либо только ошибка
|
|
// Может быть либо только полезное значение, либо только ошибка
|
|
|
type Result[T any] struct {
|
|
type Result[T any] struct {
|
|
|
- val T // Полезное значение
|
|
|
|
|
- isErr bool
|
|
|
|
|
- err error // Ошибка
|
|
|
|
|
|
|
+ val T // Полезное значение
|
|
|
|
|
+ isErr bool // Если содержит ошибку
|
|
|
|
|
+ isCheck bool // Если проверено
|
|
|
|
|
+ err error // Ошибка
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
// NewOk -- возвращает успешный Result с значением
|
|
// NewOk -- возвращает успешный Result с значением
|
|
@@ -27,16 +29,19 @@ func NewOk[T any](result T) Result[T] {
|
|
|
sf := Result[T]{
|
|
sf := Result[T]{
|
|
|
val: result,
|
|
val: result,
|
|
|
}
|
|
}
|
|
|
|
|
+ runtime.SetFinalizer(&sf, sf.destroy)
|
|
|
return sf
|
|
return sf
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
// NewErr -- возвращает Result с ошибкой
|
|
// NewErr -- возвращает Result с ошибкой
|
|
|
func NewErr[T any](err error) Result[T] {
|
|
func NewErr[T any](err error) Result[T] {
|
|
|
Hassert(err != nil, "NewError(): err==nil")
|
|
Hassert(err != nil, "NewError(): err==nil")
|
|
|
- return Result[T]{
|
|
|
|
|
|
|
+ sf := Result[T]{
|
|
|
err: err,
|
|
err: err,
|
|
|
isErr: true,
|
|
isErr: true,
|
|
|
}
|
|
}
|
|
|
|
|
+ runtime.SetFinalizer(&sf, sf.destroy)
|
|
|
|
|
+ return sf
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
// WrapErr -- оборачивает существующий Result с ошибкой с новой ошибкой
|
|
// WrapErr -- оборачивает существующий Result с ошибкой с новой ошибкой
|
|
@@ -45,17 +50,26 @@ func WrapErr[T any](res Result[T], err error) Result[T] {
|
|
|
Hassert(err != nil, "WrapErr(): err==nil")
|
|
Hassert(err != nil, "WrapErr(): err==nil")
|
|
|
err0 := res.Err()
|
|
err0 := res.Err()
|
|
|
err = fmt.Errorf("%v, err=\n\t%w", err0, err)
|
|
err = fmt.Errorf("%v, err=\n\t%w", err0, err)
|
|
|
- res0 := NewErr[T](err)
|
|
|
|
|
- return res0
|
|
|
|
|
|
|
+ sf := NewErr[T](err)
|
|
|
|
|
+ runtime.SetFinalizer(&sf, sf.destroy)
|
|
|
|
|
+ return sf
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+func (sf *Result[T]) destroy(res *Result[T]) {
|
|
|
|
|
+ if !res.isCheck {
|
|
|
|
|
+ Hassert(false, "Result[T].destroy(): err not checked")
|
|
|
|
|
+ }
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
// IsOk -- возвращает true, если Result содержит значение
|
|
// IsOk -- возвращает true, если Result содержит значение
|
|
|
func (sf *Result[T]) IsOk() bool {
|
|
func (sf *Result[T]) IsOk() bool {
|
|
|
|
|
+ sf.isCheck = true
|
|
|
return !sf.isErr
|
|
return !sf.isErr
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
// IsErr -- возвращает true, если Result содержит ошибку
|
|
// IsErr -- возвращает true, если Result содержит ошибку
|
|
|
func (sf *Result[T]) IsErr() bool {
|
|
func (sf *Result[T]) IsErr() bool {
|
|
|
|
|
+ sf.isCheck = true
|
|
|
return sf.isErr
|
|
return sf.isErr
|
|
|
}
|
|
}
|
|
|
|
|
|
|
@@ -67,6 +81,7 @@ func (sf *Result[T]) Val() T {
|
|
|
|
|
|
|
|
// ValOr -- возвращает значение, если оно есть, или значение по умолчанию
|
|
// ValOr -- возвращает значение, если оно есть, или значение по умолчанию
|
|
|
func (sf *Result[T]) ValOr(defaultValue T) T {
|
|
func (sf *Result[T]) ValOr(defaultValue T) T {
|
|
|
|
|
+ sf.isCheck = true
|
|
|
if sf.isErr {
|
|
if sf.isErr {
|
|
|
return defaultValue
|
|
return defaultValue
|
|
|
}
|
|
}
|
|
@@ -76,6 +91,7 @@ func (sf *Result[T]) ValOr(defaultValue T) T {
|
|
|
// ValOrFn -- возвращает значение, если оно есть, или результат выполнения функции
|
|
// ValOrFn -- возвращает значение, если оно есть, или результат выполнения функции
|
|
|
func (sf *Result[T]) ValOrFn(fn func() T) T {
|
|
func (sf *Result[T]) ValOrFn(fn func() T) T {
|
|
|
Hassert(fn != nil, "Result[T].ValOrFn(): fn==nil")
|
|
Hassert(fn != nil, "Result[T].ValOrFn(): fn==nil")
|
|
|
|
|
+ sf.isCheck = true
|
|
|
if sf.isErr {
|
|
if sf.isErr {
|
|
|
return fn()
|
|
return fn()
|
|
|
}
|
|
}
|
|
@@ -85,12 +101,14 @@ func (sf *Result[T]) ValOrFn(fn func() T) T {
|
|
|
// Err -- возвращает ошибку, если она есть
|
|
// Err -- возвращает ошибку, если она есть
|
|
|
func (sf *Result[T]) Err() error {
|
|
func (sf *Result[T]) Err() error {
|
|
|
Hassert(sf.isErr, "Result[T].Err(): err==nil")
|
|
Hassert(sf.isErr, "Result[T].Err(): err==nil")
|
|
|
|
|
+ sf.isCheck = true
|
|
|
return sf.err
|
|
return sf.err
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
// Error -- возвращает строковое представление ошибки, если она есть
|
|
// Error -- возвращает строковое представление ошибки, если она есть
|
|
|
func (sf *Result[T]) Error() string {
|
|
func (sf *Result[T]) Error() string {
|
|
|
Hassert(sf.isErr, "Result[T].Error(): err==nil")
|
|
Hassert(sf.isErr, "Result[T].Error(): err==nil")
|
|
|
|
|
+ sf.isCheck = true
|
|
|
return sf.err.Error()
|
|
return sf.err.Error()
|
|
|
}
|
|
}
|
|
|
|
|
|
|
@@ -102,6 +120,7 @@ func (sf *Result[T]) Hassert(msgFormat string, args ...any) {
|
|
|
}
|
|
}
|
|
|
msg := fmt.Sprintf(msgFormat+strErr, args...)
|
|
msg := fmt.Sprintf(msgFormat+strErr, args...)
|
|
|
Hassert(!sf.isErr, msg)
|
|
Hassert(!sf.isErr, msg)
|
|
|
|
|
+ sf.isCheck = true
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
// Assert -- проверяет, что нет ошибки (с паникой только на локальном стенде)
|
|
// Assert -- проверяет, что нет ошибки (с паникой только на локальном стенде)
|
|
@@ -112,4 +131,5 @@ func (sf *Result[T]) Assert(msgFormat string, args ...any) {
|
|
|
}
|
|
}
|
|
|
msg := fmt.Sprintf(msgFormat+strErr, args...)
|
|
msg := fmt.Sprintf(msgFormat+strErr, args...)
|
|
|
Assert(!sf.isErr, msg)
|
|
Assert(!sf.isErr, msg)
|
|
|
|
|
+ sf.isCheck = true
|
|
|
}
|
|
}
|