Ver Fonte

SVI Внедрение Result и Option; 100.0%

SVI há 1 ano atrás
pai
commit
fecbc51734

+ 1 - 1
Makefile

@@ -6,7 +6,7 @@ demo:
 mod:
 	clear
 	go get -u ./...
-	go mod tidy -compat=1.24.0
+	go mod tidy -compat=1.22.0
 	go mod vendor
 	go fmt ./...
 

+ 1 - 1
go.mod

@@ -1,6 +1,6 @@
 module gitp78su.ipnodns.ru/svi/kern
 
-go 1.24.0
+go 1.22.0
 
 require (
 	github.com/ajstarks/svgo v0.0.0-20211024235047-1546f124cd8b

+ 12 - 14
kern.go

@@ -19,8 +19,6 @@ import (
 	"gitp78su.ipnodns.ru/svi/kern/krn/kctx"
 	"gitp78su.ipnodns.ru/svi/kern/krn/kmodule"
 	"gitp78su.ipnodns.ru/svi/kern/krn/kmonolit"
-	"gitp78su.ipnodns.ru/svi/kern/krn/koption"
-	"gitp78su.ipnodns.ru/svi/kern/krn/kresult"
 	"gitp78su.ipnodns.ru/svi/kern/krn/kserv_http"
 	"gitp78su.ipnodns.ru/svi/kern/krn/kstore_kv"
 	. "gitp78su.ipnodns.ru/svi/kern/krn/ktypes"
@@ -170,22 +168,22 @@ func NewSafeString() ISafeString {
 	return str
 }
 
-// NewOk -- возвращает новый положительный результат операции
-func NewOk[T any](res T) *kresult.Result[T] {
-	return kresult.NewOk(res)
+// MakeOk -- возвращает новый положительный результат операции
+func MakeOk[T any](res T) Result[T] {
+	return NewOk(res)
 }
 
-// NewErr -- возвращает новую ошибку результат операции
-func NewErr(err error) *kresult.Result[any] {
-	return kresult.NewErr(err)
+// MakeErr -- возвращает новую ошибку результат операции
+func MakeErr[T any](err error) Result[T] {
+	return NewErr[T](err)
 }
 
-// NewSome -- возвращает новый не пустой результат операции
-func NewSome[T any](some T) *koption.Option[T] {
-	return koption.NewSome(some)
+// MakeSome -- возвращает новый не пустой результат операции
+func MakeSome[T any](some T) Option[T] {
+	return NewSome(some)
 }
 
-// NewNone -- возвращает новый пустой результат операции
-func NewNone() *koption.Option[any] {
-	return koption.NewNone()
+// MakeNone -- возвращает новый пустой результат операции
+func MakeNone[T any]() Option[T] {
+	return NewNone[T]()
 }

+ 4 - 18
kern_test.go

@@ -134,24 +134,10 @@ func (sf *tester) new() {
 		sf.t.Fatalf("new(): ISafeStr==nil")
 	}
 
-	res := NewOk("test ok")
-	if res == nil {
-		sf.t.Fatalf("new(): res==nil")
-	}
-	resErr := NewErr(fmt.Errorf("test err"))
-	if resErr == nil {
-		sf.t.Fatalf("new(): resErr==nil")
-	}
-
-	some := NewSome("test err")
-	if some == nil {
-		sf.t.Fatalf("new(): some==nil")
-	}
-
-	none := NewNone()
-	if none == nil {
-		sf.t.Fatalf("new(): none==nil")
-	}
+	_ = MakeOk("test ok")
+	_ = MakeErr[bool](fmt.Errorf("test err"))
+	_ = MakeSome("test err")
+	_ = MakeNone[int64]()
 
 	kernServHttp := GetKernelServerHttp()
 	go kernServHttp.Run()

+ 11 - 16
krn/kbus/dict_topic_serve/dict_topic_serve.go

@@ -51,37 +51,32 @@ func (sf *dictServe) Unregister(handler IBusHandlerServe) {
 }
 
 // SendRequest -- вызывает обработчик при поступлении запроса
-func (sf *dictServe) SendRequest(topic ATopic, binReq []byte) ([]byte, error) {
+func (sf *dictServe) SendRequest(topic ATopic, binReq []byte) Result[[]byte] {
 	sf.RLock()
 	defer sf.RUnlock()
 	handler, isOk := sf.dictServe[topic]
 	if !isOk {
-		return nil, fmt.Errorf("dictServe.SendRequest(): handler for topic (%v) not exists", topic)
+		err := fmt.Errorf("dictServe.SendRequest(): handler for topic (%v) not exists", topic)
+		return NewErr[[]byte](err)
 	}
 	var (
-		chErr  = make(chan error, 2)
-		binRes []byte
+		chRes = make(chan Result[[]byte], 2)
 	)
 	ctx, fnCancel := context.WithTimeout(sf.ctx.Ctx(), time.Millisecond*time.Duration(TimeoutDefault))
 	defer fnCancel()
 	fnCall := func() {
-		defer close(chErr)
-		var err error
-		binRes, err = handler.FnBack(binReq)
-		if err != nil {
-			chErr <- err
-		}
+		defer close(chRes)
+		res := handler.FnBack(binReq)
+		chRes <- res
 	}
 	go fnCall()
 	select {
 	case <-ctx.Done():
-		return nil, fmt.Errorf("dictServe.SendRequest(): in call for topic (%v), err=\n\t%w", topic, ctx.Err())
-	case err := <-chErr:
-		if err != nil {
-			return nil, fmt.Errorf("dictServe.SendRequest(): error in call for topic (%v), err=\n\t%w", topic, err)
-		}
+		err := fmt.Errorf("dictServe.SendRequest(): in call for topic (%v), err=\n\t%w", topic, ctx.Err())
+		return NewErr[[]byte](err)
+	case res := <-chRes:
+		return res
 	}
-	return binRes, nil
 }
 
 var TimeoutDefault = 15000

+ 10 - 19
krn/kbus/dict_topic_serve/dict_topic_serve_test.go

@@ -37,13 +37,10 @@ func (sf *tester) callBad3() {
 	ctx.Cancel()
 	ctx.Wg().Wait()
 	sf.dict.Register(sf.hand)
-	binMsg, err := sf.dict.SendRequest(sf.hand.Topic(), []byte("test"))
-	if err == nil {
+	res := sf.dict.SendRequest(sf.hand.Topic(), []byte("test"))
+	if res.IsOk() {
 		sf.t.Fatalf("callBad3(): err==nil")
 	}
-	if binMsg != nil {
-		sf.t.Fatalf("callBad3(): binMsg!=nil")
-	}
 }
 
 func (sf *tester) delGood2() {
@@ -71,11 +68,11 @@ func (sf *tester) delBad1() {
 func (sf *tester) sendGood1() {
 	sf.t.Log("sendGood1")
 	TimeoutDefault = 5000
-	binMsg, err := sf.dict.SendRequest(sf.hand.Topic(), []byte("test_good"))
-	if err != nil {
-		sf.t.Fatalf("sendGood1(): err=%v", err)
+	res := sf.dict.SendRequest(sf.hand.Topic(), []byte("test_good"))
+	if res.IsErr() {
+		sf.t.Fatalf("sendGood1(): err=%v", res.Error())
 	}
-	if binMsg == nil {
+	if res.Unwrap() == nil {
 		sf.t.Fatalf("sendGood1(): binMsg==nil")
 	}
 }
@@ -84,13 +81,10 @@ func (sf *tester) sendGood1() {
 func (sf *tester) sendBad2() {
 	sf.t.Log("sendBad2")
 	sf.hand.IsBad_.Set()
-	binMsg, err := sf.dict.SendRequest(sf.hand.Topic(), []byte("test"))
-	if err == nil {
+	res := sf.dict.SendRequest(sf.hand.Topic(), []byte("test"))
+	if res.IsOk() {
 		sf.t.Fatalf("sendBad2(): err==nil")
 	}
-	if binMsg != nil {
-		sf.t.Fatalf("sendBad2(): binMsg!=nil")
-	}
 	sf.hand.IsBad_.Reset()
 }
 
@@ -130,13 +124,10 @@ func (sf *tester) addBad1() {
 // Вызов несуществующего топика
 func (sf *tester) sendBad1() {
 	sf.t.Log("sendBad1")
-	binRes, err := sf.dict.SendRequest("test_bad_topic", []byte("test"))
-	if err == nil {
+	res := sf.dict.SendRequest("test_bad_topic", []byte("test"))
+	if res.IsOk() {
 		sf.t.Fatalf("sendBad1(): err==nil")
 	}
-	if binRes != nil {
-		sf.t.Fatalf("sendBad1(): binRes!=nil")
-	}
 }
 
 // Создание словаря подписчиков

+ 13 - 13
krn/kbus/kbus_base/kbus_base.go

@@ -79,32 +79,32 @@ func (sf *KBusBase) Unsubscribe(handler IBusHandlerSubscribe) {
 }
 
 // Subscribe -- подписывает обработчик на топик
-func (sf *KBusBase) Subscribe(handler IBusHandlerSubscribe) error {
+func (sf *KBusBase) Subscribe(handler IBusHandlerSubscribe) Result[bool] {
 	sf.log.Debug("KBusBase.Subscribe(): handler='%v'", handler.Name())
 	if !sf.IsWork_.Get() {
 		err := fmt.Errorf("KBusBase.Subscribe():  handler='%v', bus already closed", handler.Name())
 		sf.log.Err(err.Error())
-		return err
+		return NewErr[bool](err)
 	}
 	sf.dictSub.Subscribe(handler)
-	return nil
+	return NewOk(true)
 }
 
 // SendRequest -- отправляет запрос в шину данных
-func (sf *KBusBase) SendRequest(topic ATopic, binReq []byte) ([]byte, error) {
+func (sf *KBusBase) SendRequest(topic ATopic, binReq []byte) Result[[]byte] {
 	sf.log.Debug("KBusBase.SendRequest(): topic='%v'", topic)
 	if !sf.IsWork_.Get() {
 		err := fmt.Errorf("KBusBase.SendRequest():  topic='%v', bus already closed", topic)
 		sf.log.Err(err.Error())
-		return nil, err
+		return NewErr[[]byte](err)
 	}
-	binResp, err := sf.dictServe.SendRequest(topic, binReq)
-	if err != nil {
-		err := fmt.Errorf("KBusBase.SendRequest(): topic='%v', err=\n\t%w", topic, err)
+	res := sf.dictServe.SendRequest(topic, binReq)
+	if res.IsErr() {
+		err := fmt.Errorf("KBusBase.SendRequest(): topic='%v', err=\n\t%w", topic, res.Error())
 		sf.log.Err(err.Error())
-		return nil, err
+		return NewErr[[]byte](err)
 	}
-	return binResp, nil
+	return res
 }
 
 // RegisterServe -- регистрирует обработчики входящих запросов
@@ -115,16 +115,16 @@ func (sf *KBusBase) RegisterServe(handler IBusHandlerServe) {
 }
 
 // Publish -- публикует сообщение в шину
-func (sf *KBusBase) Publish(topic ATopic, binMsg []byte) (err error) {
+func (sf *KBusBase) Publish(topic ATopic, binMsg []byte) Result[bool] {
 	sf.log.Debug("KBusBase.Publish(): topic='%v'", topic)
 	if !sf.IsWork_.Get() {
 		err := fmt.Errorf("KBusBase.Publish(): topic='%v',bus already closed", topic)
 		sf.log.Err(err.Error())
-		return err
+		return NewErr[bool](err)
 	}
 	// Асинхронный запуск чтения
 	go sf.dictSub.Read(topic, binMsg)
-	return nil
+	return NewOk(true)
 }
 
 // IsWork -- возвращает признак работы шины

+ 18 - 21
krn/kbus/kbus_base/kbus_base_test.go

@@ -59,11 +59,11 @@ func (sf *tester) unsubBad1() {
 
 func (sf *tester) reqGood1() {
 	sf.t.Log("reqGood1")
-	binMsg, err := sf.bus.SendRequest(sf.handServ.Topic_, []byte("test_msg"))
-	if err != nil {
-		sf.t.Fatalf("reqGood1(): err=%v", err)
+	res := sf.bus.SendRequest(sf.handServ.Topic_, []byte("test_msg"))
+	if res.IsErr() {
+		sf.t.Fatalf("reqGood1(): err=%v", res.Error())
 	}
-	if binMsg == nil {
+	if res.Unwrap() == nil {
 		sf.t.Fatalf("reqGood1(): binMsg==nil")
 	}
 }
@@ -92,13 +92,10 @@ func (sf *tester) servBad1() {
 // Нет такого топика
 func (sf *tester) reqBad1() {
 	sf.t.Log("reqBad1")
-	binMsg, err := sf.bus.SendRequest("test_topic1", []byte("test_msg"))
-	if err == nil {
+	res := sf.bus.SendRequest("test_topic1", []byte("test_msg"))
+	if res.IsOk() {
 		sf.t.Fatalf("reqBad1(): err==nil")
 	}
-	if binMsg != nil {
-		sf.t.Fatalf("reqBad1(): binMsg!=nil")
-	}
 }
 
 // Нет читателей топика
@@ -109,9 +106,9 @@ func (sf *tester) pubGood10() {
 			sf.t.Fatalf("pubGood10(): panic=%v", _panic)
 		}
 	}()
-	err := sf.bus.Publish("test_topic1", []byte("test_msg"))
-	if err != nil {
-		sf.t.Fatalf("pubGood10(): err=%v", nil)
+	res := sf.bus.Publish("test_topic1", []byte("test_msg"))
+	if res.IsErr() {
+		sf.t.Fatalf("pubGood10(): err=%v", res.Error())
 	}
 }
 
@@ -122,9 +119,9 @@ func (sf *tester) subGood1() {
 			sf.t.Fatalf("subGood1(): panic=%v", _panic)
 		}
 	}()
-	err := sf.bus.Subscribe(sf.handSub)
-	if err != nil {
-		sf.t.Fatalf("subGood1(): err=%v", err)
+	res := sf.bus.Subscribe(sf.handSub)
+	if res.IsErr() {
+		sf.t.Fatalf("subGood1(): err=%v", res.Error())
 	}
 }
 
@@ -156,16 +153,16 @@ func (sf *tester) close() {
 	if sf.bus.IsWork() {
 		sf.t.Fatalf("close(): bus work")
 	}
-	err := sf.bus.Subscribe(sf.handSub)
-	if err == nil {
+	res := sf.bus.Subscribe(sf.handSub)
+	if res.IsOk() {
 		sf.t.Fatalf("close(): err==nil")
 	}
-	err = sf.bus.Publish("test_topic1", []byte("test_msg"))
-	if err == nil {
+	res = sf.bus.Publish("test_topic1", []byte("test_msg"))
+	if res.IsOk() {
 		sf.t.Fatalf("close(): err==nil")
 	}
-	_, err = sf.bus.SendRequest("test_topic", []byte("test_msg"))
-	if err == nil {
+	res1 := sf.bus.SendRequest("test_topic", []byte("test_msg"))
+	if res1.IsOk() {
 		sf.t.Fatalf("close(): err==nil")
 	}
 }

+ 13 - 17
krn/kbus/kbus_http/client_bus_http/client_bus_http.go

@@ -22,7 +22,6 @@ import (
 	"gitp78su.ipnodns.ru/svi/kern/krn/kbus/kbus_msg/msg_unsub"
 	"gitp78su.ipnodns.ru/svi/kern/krn/kctx"
 	. "gitp78su.ipnodns.ru/svi/kern/krn/ktypes"
-	"gitp78su.ipnodns.ru/svi/kern/mock/mock_hand_sub_http"
 )
 
 // ClientBusHttp -- клиент HTTP-шины
@@ -83,7 +82,7 @@ func (sf *ClientBusHttp) Unsubscribe(handler IBusHandlerSubscribe) {
 }
 
 // Subscribe -- подписывается на топик в дистанционной шине
-func (sf *ClientBusHttp) Subscribe(handler IBusHandlerSubscribe) error {
+func (sf *ClientBusHttp) Subscribe(handler IBusHandlerSubscribe) Result[bool] {
 	_uuid, err := uuid.NewV6()
 	Hassert(err == nil, "ClientBusHttp.Subscribe(): in generate UUID v6, err=\n\t%v", err)
 	req := &msg_sub.SubscribeReq{
@@ -102,7 +101,7 @@ func (sf *ClientBusHttp) Subscribe(handler IBusHandlerSubscribe) error {
 	if err != nil {
 		err := fmt.Errorf("ClientBusHttp.Subscribe(): in make request, err=\n\t%w", err)
 		sf.log.Err(err.Error())
-		return err
+		return NewErr[bool](err)
 	}
 	resp := &msg_sub.SubscribeResp{}
 	err = json.Unmarshal(binBody, resp)
@@ -110,18 +109,15 @@ func (sf *ClientBusHttp) Subscribe(handler IBusHandlerSubscribe) error {
 	if string(resp.Status_) != "ok" {
 		err := fmt.Errorf("ClientBusHttp.Subscribe(): resp!='ok', err=\n\t%v", resp.Status_)
 		sf.log.Err(err.Error())
-		return err
+		return NewErr[bool](err)
 	}
 	Hassert(resp.Uuid_ == req.Uuid_, "ClientBusHttp.Subscribe(): resp uuid(%v) bad", resp.Uuid_)
-	// FIXME: вот тут похоже дичь
-	_handler := handler.(*mock_hand_sub_http.MockHandSubHttp)
-	_handler.SetName(resp.Name_)
-	err = sf.bus.Subscribe(_handler)
-	return err
+	res := sf.bus.Subscribe(handler)
+	return res
 }
 
 // SendRequest -- отправляет в дистанционную шину запрос
-func (sf *ClientBusHttp) SendRequest(topic ATopic, binReq []byte) ([]byte, error) {
+func (sf *ClientBusHttp) SendRequest(topic ATopic, binReq []byte) Result[[]byte] {
 	_uuid, err := uuid.NewV6()
 	Hassert(err == nil, "ClientBusHttp.SendRequest(): in generate UUID v6, err=\n\t%v", err)
 	req := &msg_serve.ServeReq{
@@ -140,7 +136,7 @@ func (sf *ClientBusHttp) SendRequest(topic ATopic, binReq []byte) ([]byte, error
 	if err != nil {
 		err := fmt.Errorf("ClientBusHttp.SendRequest(): in make request, err=\n\t%w", err)
 		sf.log.Err(err.Error())
-		return nil, err
+		return NewErr[[]byte](err)
 	}
 	resp := &msg_serve.ServeResp{}
 	err = json.Unmarshal(binBody, resp)
@@ -148,10 +144,10 @@ func (sf *ClientBusHttp) SendRequest(topic ATopic, binReq []byte) ([]byte, error
 	if string(resp.Status_) != "ok" {
 		err := fmt.Errorf("ClientBusHttp.SendRequest(): resp!='ok', err=\n\t%v", resp.Status_)
 		sf.log.Err(err.Error())
-		return nil, err
+		return NewErr[[]byte](err)
 	}
 	Hassert(resp.Uuid_ == req.Uuid_, "ClientBusHttp.SendRequest(): resp uuid(%v) bad", resp.Uuid_)
-	return resp.BinResp_, nil
+	return NewOk(resp.BinResp_)
 }
 
 // RegisterServe -- регистрирует в локальной шине обработчик
@@ -161,7 +157,7 @@ func (sf *ClientBusHttp) RegisterServe(handler IBusHandlerServe) {
 }
 
 // Publish -- публикует сообщение в дистанционной шину
-func (sf *ClientBusHttp) Publish(topic ATopic, binMsg []byte) error {
+func (sf *ClientBusHttp) Publish(topic ATopic, binMsg []byte) Result[bool] {
 	_uuid, err := uuid.NewV6()
 	Hassert(err == nil, "ClientBusHttp.Publish(): in generate UUID v6, err=\n\t%v", err)
 	req := &msg_pub.PublishReq{
@@ -180,7 +176,7 @@ func (sf *ClientBusHttp) Publish(topic ATopic, binMsg []byte) error {
 	if err != nil {
 		err := fmt.Errorf("ClientBusHttp.Publish(): in make request, err=\n\t%w", err)
 		sf.log.Err(err.Error())
-		return err
+		return NewErr[bool](err)
 	}
 	resp := &msg_pub.PublishResp{}
 	err = json.Unmarshal(binBody, resp)
@@ -188,10 +184,10 @@ func (sf *ClientBusHttp) Publish(topic ATopic, binMsg []byte) error {
 	if string(resp.Status_) != "ok" {
 		err := fmt.Errorf("ClientBusHttp.Publish(): resp!='ok', err=\n\t%v", resp.Status_)
 		sf.log.Err(err.Error())
-		return err
+		return NewErr[bool](err)
 	}
 	Hassert(resp.Uuid_ == req.Uuid_, "ClientBusHttp.Publish(): resp uuid(%v) bad", resp.Uuid_)
-	return nil
+	return NewOk(true)
 }
 
 // Единый обработчик запросов

+ 29 - 44
krn/kbus/kbus_http/client_bus_http/client_bus_http_test.go

@@ -53,14 +53,14 @@ func (sf *tester) send() {
 
 func (sf *tester) sendGood1() {
 	sf.t.Log("sendGood1")
-	binResp, err := sf.cl.SendRequest("test_topic_serv", []byte("test msg 456"))
-	if err != nil {
-		sf.t.Fatalf("sendGood1(): err=%v", err)
+	res := sf.cl.SendRequest("test_topic_serv", []byte("test msg 456"))
+	if res.IsErr() {
+		sf.t.Fatalf("sendGood1(): err=%v", res.Error())
 	}
-	if binResp == nil {
+	if res.Unwrap() == nil {
 		sf.t.Fatalf("sendGood1(): binResp==nil")
 	}
-	strResp := string(binResp)
+	strResp := string(res.Unwrap())
 	if strResp != "test msg 456" {
 		sf.t.Fatalf("sendGood1(): strResp(%v)!='test msg 456'", strResp)
 	}
@@ -74,25 +74,19 @@ func (sf *tester) sendBad2() {
 	defer func() {
 		sf.cl.urlRemote = urlRemote
 	}()
-	binResp, err := sf.cl.SendRequest("test_topic_serv", []byte("test msg"))
-	if err == nil {
+	res := sf.cl.SendRequest("test_topic_serv", []byte("test msg"))
+	if res.IsOk() {
 		sf.t.Fatalf("sendBad2(): err==nil")
 	}
-	if binResp != nil {
-		sf.t.Fatalf("sendBad2(): binResp!=nil")
-	}
 }
 
 // Нет такого топика
 func (sf *tester) sendBad1() {
 	sf.t.Log("sendBad1")
-	binResp, err := sf.cl.SendRequest("test_bad_topic", []byte("test msg"))
-	if err == nil {
+	res := sf.cl.SendRequest("test_bad_topic", []byte("test msg"))
+	if res.IsOk() {
 		sf.t.Fatalf("sendBad1(): err==nil")
 	}
-	if binResp != nil {
-		sf.t.Fatalf("sendBad1(): binResp!=nil")
-	}
 }
 
 // Регистрация серверного обработчика
@@ -148,21 +142,12 @@ func (sf *tester) pubBad2() {
 		}
 	}()
 	sf.handSub.BinMsg_ = []byte{}
-	err := sf.cl.Publish("test_topic_sub", []byte("test_msg_456"))
-	if err != nil {
-		if strings.Contains(err.Error(), "topic='test_topic_sub',bus already closed") {
+	res := sf.cl.Publish("test_topic_sub", []byte("test_msg_456"))
+	if res.IsOk() {
+		if strings.Contains(res.Error().Error(), "topic='test_topic_sub',bus already closed") {
 			return
 		}
-		sf.t.Fatalf("pubBad2(): err=%v", err)
-	}
-	for {
-		SleepMs()
-		if sf.handSub.Msg() != "" {
-			break
-		}
-	}
-	if msg := sf.handSub.Msg(); msg != "test_msg_456" {
-		sf.t.Fatalf("bad msg(%v)", msg)
+		sf.t.Fatalf("pubBad2(): err=%v", res.Error())
 	}
 }
 
@@ -174,12 +159,12 @@ func (sf *tester) pubGood1() {
 		}
 	}()
 	sf.handSub.BinMsg_ = []byte{}
-	err := sf.cl.Publish("test_topic_sub", []byte("test_msg_456"))
-	if err != nil {
-		if strings.Contains(err.Error(), "topic='test_topic_sub',bus already closed") {
+	res := sf.cl.Publish("test_topic_sub", []byte("test_msg_456"))
+	if res.IsErr() {
+		if strings.Contains(res.Error().Error(), "topic='test_topic_sub',bus already closed") {
 			return
 		}
-		sf.t.Fatalf("pubGood1(): err=%v", err)
+		sf.t.Fatalf("pubGood1(): err=%v", res.Error())
 	}
 	for {
 		SleepMs()
@@ -205,8 +190,8 @@ func (sf *tester) pubBad1() {
 			sf.t.Fatalf("pubBad1(): panic=%v", _panic)
 		}
 	}()
-	err := sf.cl.Publish("test_topic", []byte("test_msg"))
-	if err == nil {
+	res := sf.cl.Publish("test_topic", []byte("test_msg"))
+	if res.IsOk() {
 		sf.t.Fatalf("pubBad1(): err==nil")
 	}
 }
@@ -231,12 +216,12 @@ func (sf *tester) subBad3() {
 			sf.t.Fatalf("subBad3(): panic=%v", _panic)
 		}
 	}()
-	err := sf.cl.Subscribe(sf.handSub)
-	if err != nil {
-		if strings.Contains(err.Error(), "bus already closed") {
+	res := sf.cl.Subscribe(sf.handSub)
+	if res.IsErr() {
+		if strings.Contains(res.Error().Error(), "bus already closed") {
 			return
 		}
-		sf.t.Fatalf("subBad3(): err=%v", err)
+		sf.t.Fatalf("subBad3(): err=%v", res.Error())
 	}
 }
 
@@ -247,12 +232,12 @@ func (sf *tester) subGood1() {
 			sf.t.Fatalf("subGood1(): panic=%v", _panic)
 		}
 	}()
-	err := sf.cl.Subscribe(sf.handSub)
-	if err != nil {
-		if strings.Contains(err.Error(), "bus already closed") {
+	res := sf.cl.Subscribe(sf.handSub)
+	if res.IsErr() {
+		if strings.Contains(res.Error().Error(), "bus already closed") {
 			return
 		}
-		sf.t.Fatalf("subGood1(): err=%v", err)
+		sf.t.Fatalf("subGood1(): err=%v", res.Error())
 	}
 }
 
@@ -269,8 +254,8 @@ func (sf *tester) subBad2() {
 			sf.t.Fatalf("subBad2(): panic=%v", _panic)
 		}
 	}()
-	err := sf.cl.Subscribe(sf.handSub)
-	if err == nil {
+	res := sf.cl.Subscribe(sf.handSub)
+	if res.IsOk() {
 		sf.t.Fatalf("subBad2(): err==nil")
 	}
 }

+ 14 - 13
krn/kbus/kbus_http/kbus_http.go

@@ -79,9 +79,9 @@ func (sf *kBusHttp) processSubscribe(req *msg_sub.SubscribeReq) *msg_sub.Subscri
 		Uuid_:   req.Uuid_,
 		Name_:   handler.Name(),
 	}
-	err := sf.Subscribe(handler)
-	if err != nil {
-		resp.Status_ = fmt.Sprintf("kernelBusHttp.processSubscribe(): err=\n\t%v", err)
+	res := sf.Subscribe(handler)
+	if res.IsErr() {
+		resp.Status_ = fmt.Sprintf("kernelBusHttp.processSubscribe(): err=\n\t%v", res.Error())
 		return resp
 	}
 	return resp
@@ -113,13 +113,14 @@ func (sf *kBusHttp) postPublish(ctx *fiber.Ctx) error {
 // Выполняет процесс публикации
 func (sf *kBusHttp) processPublish(req *msg_pub.PublishReq) *msg_pub.PublishResp {
 	req.SelfCheck()
-	err := sf.Publish(req.Topic_, req.BinMsg_)
+	res := sf.Publish(req.Topic_, req.BinMsg_)
 	resp := &msg_pub.PublishResp{
 		Status_: "ok",
 		Uuid_:   req.Uuid_,
 	}
-	if err != nil {
-		resp.Status_ = fmt.Sprintf("kernelBusHttp.processPublish(): err=\n\t%v", err)
+	if res.IsErr() {
+		resp.Status_ = fmt.Sprintf("kernelBusHttp.processPublish(): err=\n\t%v", res.Error())
+		return resp
 	}
 	return resp
 }
@@ -150,16 +151,16 @@ func (sf *kBusHttp) postSendRequest(ctx *fiber.Ctx) error {
 // Обрабатывает входящий запрос
 func (sf *kBusHttp) processSendRequest(req *msg_serve.ServeReq) *msg_serve.ServeResp {
 	req.SelfCheck()
-	binResp, err := sf.SendRequest(req.Topic_, req.BinReq_)
+	res := sf.SendRequest(req.Topic_, req.BinReq_)
 	resp := &msg_serve.ServeResp{
-		Status_:  "ok",
-		Uuid_:    req.Uuid_,
-		BinResp_: binResp,
+		Status_: "ok",
+		Uuid_:   req.Uuid_,
 	}
-	if err != nil {
-		resp.Status_ = fmt.Sprintf("kernelBusHttp.processSendRequest(): err=\n\t%v", err)
+	if res.IsErr() {
+		resp.Status_ = fmt.Sprintf("kernelBusHttp.processSendRequest(): err=\n\t%v", res.Error())
+		return resp
 	}
-
+	resp.BinResp_ = res.Unwrap()
 	return resp
 }
 

+ 9 - 9
krn/kbus/kbus_http/kbus_http_test.go

@@ -53,9 +53,9 @@ func (sf *tester) unsub() {
 
 func (sf *tester) unsubGood2() {
 	sf.t.Log("unsubGood2")
-	err := bus.Subscribe(sf.handSub)
-	if err != nil {
-		sf.t.Fatalf("unsubGood1(): err=%v", err)
+	res := bus.Subscribe(sf.handSub)
+	if res.IsErr() {
+		sf.t.Fatalf("unsubGood1(): err=%v", res.Error())
 	}
 	req := &msg_unsub.UnsubReq{
 		Name_: sf.handSub.Name_,
@@ -112,9 +112,9 @@ func (sf *tester) unsubBad3() {
 
 func (sf *tester) unsubGood1() {
 	sf.t.Log("unsubGood1")
-	err := bus.Subscribe(sf.handSub)
-	if err != nil {
-		sf.t.Fatalf("unsubGood1(): err=%v", err)
+	res := bus.Subscribe(sf.handSub)
+	if res.IsErr() {
+		sf.t.Fatalf("unsubGood1(): err=%v", res.Error())
 	}
 	count := 0
 	for count < 100 {
@@ -247,9 +247,9 @@ func (sf *tester) pubBad2() {
 // Все поля на месте
 func (sf *tester) pubGood1() {
 	sf.t.Log("pubGood1")
-	err := bus.Subscribe(sf.handSub)
-	if err != nil {
-		sf.t.Fatalf("pubGood1(): err=%v", err)
+	res := bus.Subscribe(sf.handSub)
+	if res.IsErr() {
+		sf.t.Fatalf("pubGood1(): err=%v", res.Error())
 	}
 	req := &msg_pub.PublishReq{
 		Topic_:  "topic_sub",

+ 3 - 3
krn/kbus/kbus_local/client_bus_local/client_bus_local_test.go

@@ -25,8 +25,8 @@ func (sf *tester) new() {
 	if sf.cl == nil {
 		sf.t.Fatalf("new(): client==nil")
 	}
-	err := sf.cl.Publish("local_topic", []byte("test_msg"))
-	if err != nil {
-		sf.t.Fatalf("new(): err=%v", err)
+	res := sf.cl.Publish("local_topic", []byte("test_msg"))
+	if res.IsErr() {
+		sf.t.Fatalf("new(): err=%v", res.Error())
 	}
 }

+ 6 - 6
krn/kmodule/kmodule.go

@@ -85,25 +85,25 @@ func (sf *kModule) sigLive() {
 	var (
 		topic  = sf.name + "_live"
 		iPhase = 0
-		err    error
+		res    Result[bool]
 	)
 	fnPhase := func() {
 		switch iPhase {
 		case 0:
 			sf.strLive.Set("|")
-			err = sf.bus.Publish(ATopic(topic), sf.strLive.Byte())
+			res = sf.bus.Publish(ATopic(topic), sf.strLive.Byte())
 		case 1:
 			sf.strLive.Set("/")
-			err = sf.bus.Publish(ATopic(topic), sf.strLive.Byte())
+			res = sf.bus.Publish(ATopic(topic), sf.strLive.Byte())
 		case 2:
 			sf.strLive.Set("-")
-			err = sf.bus.Publish(ATopic(topic), sf.strLive.Byte())
+			res = sf.bus.Publish(ATopic(topic), sf.strLive.Byte())
 		case 3:
 			sf.strLive.Set("\\")
-			err = sf.bus.Publish(ATopic(topic), sf.strLive.Byte())
+			res = sf.bus.Publish(ATopic(topic), sf.strLive.Byte())
 			iPhase = -1
 		}
-		sf.recErr(err)
+		sf.recErr(res.Error())
 		iPhase++
 		sf.stat.Add(1)
 		time.Sleep(time.Millisecond * time.Duration(sf.timePhase.Get()))

+ 5 - 5
krn/ktypes/ikernel_bus.go

@@ -23,7 +23,7 @@ type IBusHandlerSubscribe interface {
 type IBusHandlerServe interface {
 	IBusBaseHandler
 	// FnBack -- функция обратного вызова
-	FnBack(binReq []byte) (binResp []byte, err error)
+	FnBack(binReq []byte) Result[[]byte]
 }
 
 // IDictSubHook -- словарь обработчиков по единственному топик
@@ -56,7 +56,7 @@ type IDictTopicServe interface {
 	// Register -- регистрирует единственный обработчик на единственный топик
 	Register(IBusHandlerServe)
 	// SendRequest -- выполняет запрос по указанному топику
-	SendRequest(topic ATopic, binReq []byte) (binResp []byte, errResp error)
+	SendRequest(topic ATopic, binReq []byte) Result[[]byte]
 	// Unregister -- удаляет единственный обработчик с единственного топика
 	Unregister(IBusHandlerServe)
 }
@@ -67,12 +67,12 @@ type IDictTopicServe interface {
 //	Подписка и обслуживание входящих запросов требует _обработчиков_.
 type IKernelBus interface {
 	// Publish -- публикует сообщение в шину
-	Publish(topic ATopic, binMsg []byte) error
+	Publish(topic ATopic, binMsg []byte) Result[bool]
 	// SendRequest -- выполняет запрос по указанному топику
-	SendRequest(topic ATopic, binReq []byte) (binResp []byte, errResp error)
+	SendRequest(topic ATopic, binReq []byte) Result[[]byte]
 
 	// Subscribe -- подписывает обработчик на топик
-	Subscribe(IBusHandlerSubscribe) error
+	Subscribe(IBusHandlerSubscribe) Result[bool]
 	// Unsubscribe -- отписывается от топика
 	Unsubscribe(IBusHandlerSubscribe)
 	// RegisterServe -- Регистрирует обработчик на обслуживание входящих запросов

+ 8 - 6
krn/koption/koption.go → krn/ktypes/koption.go

@@ -1,4 +1,4 @@
-package koption
+package ktypes
 
 import (
 	"reflect"
@@ -12,20 +12,22 @@ type Option[T any] struct {
 }
 
 // NewSome - полезный результат
-func NewSome[T any](value T) *Option[T] {
+func NewSome[T any](value T) Option[T] {
 	// Для некоторых типов нужна дополнительная проверка через reflect
 	v := reflect.ValueOf(value)
 	switch v.Kind() {
 	case reflect.Ptr, reflect.Slice, reflect.Map, reflect.Chan, reflect.Func, reflect.Interface:
 		Hassert(!v.IsNil(), "NewSome[T any](): value==nil")
 	}
-	sf := &Option[T]{val: &value}
+	sf := Option[T]{val: &value}
 	return sf
 }
 
 // NewNone - нет результата в ответе
-func NewNone() *Option[any] {
-	return &Option[any]{nil}
+func NewNone[T any]() Option[T] {
+	return Option[T]{
+		val: nil,
+	}
 }
 
 // IsSome - проверяет, есть ли значение
@@ -40,7 +42,7 @@ func (sf *Option[T]) IsNone() bool {
 
 // Unwrap - извлекает значение (паника, если None)
 func (sf *Option[T]) Unwrap() T {
-	Hassert(sf.val != nil, "Option[T].Unwrap(): Called Unwrap on None!")
+	Hassert(sf.val != nil, "Option[T].Unwrap(): val==nil!")
 	return *sf.val
 }
 

+ 16 - 25
krn/koption/kresult_test.go → krn/ktypes/koption_test.go

@@ -1,22 +1,22 @@
-package koption
+package ktypes
 
 import (
 	"testing"
 )
 
-type tester struct {
+type testerOption struct {
 	t *testing.T
 }
 
-func TestResult(t *testing.T) {
-	sf := &tester{
+func TestOption(t *testing.T) {
+	sf := &testerOption{
 		t: t,
 	}
 	sf.create()
 }
 
 // Создаёт новый Result
-func (sf *tester) create() {
+func (sf *testerOption) create() {
 	sf.t.Log("create")
 	sf.createSomeBad1()
 	sf.createSomeGood1()
@@ -24,17 +24,14 @@ func (sf *tester) create() {
 	sf.createNoneGood1()
 }
 
-func (sf *tester) createNoneGood1() {
+func (sf *testerOption) createNoneGood1() {
 	sf.t.Log("createNoneGood1")
 	defer func() {
 		if _panic := recover(); _panic != nil {
 			sf.t.Fatalf("createNoneGood1(): panic=%v", _panic)
 		}
 	}()
-	res := NewNone()
-	if res == nil {
-		sf.t.Fatalf("createNoneGood1(): res==nil")
-	}
+	res := NewNone[string]()
 	if res.IsSome() {
 		sf.t.Fatalf("createNoneGood1(): is ok")
 	}
@@ -55,7 +52,7 @@ func (sf *tester) createNoneGood1() {
 	sf.assert(res)
 }
 
-func (sf *tester) assert(res *Option[any]) {
+func (sf *testerOption) assert(res Option[string]) {
 	sf.t.Log("assert")
 	defer func() {
 		if _panic := recover(); _panic == nil {
@@ -65,7 +62,7 @@ func (sf *tester) assert(res *Option[any]) {
 	res.Hassert("test assert")
 }
 
-func (sf *tester) hassert(res *Option[any]) {
+func (sf *testerOption) hassert(res Option[string]) {
 	sf.t.Log("hassert")
 	defer func() {
 		if _panic := recover(); _panic == nil {
@@ -75,7 +72,7 @@ func (sf *tester) hassert(res *Option[any]) {
 	res.Hassert("test hassert")
 }
 
-func (sf *tester) unwrapErr(res *Option[any]) {
+func (sf *testerOption) unwrapErr(res Option[string]) {
 	sf.t.Log("unwrapErr")
 	defer func() {
 		if _panic := recover(); _panic == nil {
@@ -85,7 +82,7 @@ func (sf *tester) unwrapErr(res *Option[any]) {
 	_ = res.Unwrap()
 }
 
-func (sf *tester) createSomeGood2() {
+func (sf *testerOption) createSomeGood2() {
 	sf.t.Log("createSomeGood2")
 	defer func() {
 		if _panic := recover(); _panic != nil {
@@ -94,9 +91,6 @@ func (sf *tester) createSomeGood2() {
 	}()
 	str := "test val"
 	res := NewSome(str)
-	if res == nil {
-		sf.t.Fatalf("createSomeGood1(): res==nil")
-	}
 	if !res.IsSome() {
 		sf.t.Fatalf("createSomeGood1(): not ok")
 	}
@@ -120,16 +114,16 @@ func (sf *tester) createSomeGood2() {
 }
 
 // Функция высшего порядка для замещения ошибки
-func (sf *tester) fnWrap2() any {
+func (sf *testerOption) fnWrap2() string {
 	return "test5"
 }
 
 // Функция высшего порядка для замещения ошибки
-func (sf *tester) fnWrap() string {
+func (sf *testerOption) fnWrap() string {
 	return "test1"
 }
 
-func (sf *tester) createSomeGood1() {
+func (sf *testerOption) createSomeGood1() {
 	sf.t.Log("createSomeGood1")
 	defer func() {
 		if _panic := recover(); _panic != nil {
@@ -137,14 +131,11 @@ func (sf *tester) createSomeGood1() {
 		}
 	}()
 	str := "test val"
-	res := NewSome(&str)
-	if res == nil {
-		sf.t.Fatalf("createSomeGood1(): res==nil")
-	}
+	_ = NewSome(&str)
 }
 
 // Нет результата
-func (sf *tester) createSomeBad1() {
+func (sf *testerOption) createSomeBad1() {
 	sf.t.Log("createSomeBad1")
 	defer func() {
 		if _panic := recover(); _panic == nil {

+ 6 - 6
krn/kresult/kresult.go → krn/ktypes/kresult.go

@@ -1,4 +1,4 @@
-package kresult
+package ktypes
 
 import (
 	"reflect"
@@ -6,7 +6,7 @@ import (
 	. "gitp78su.ipnodns.ru/svi/kern/kc/helpers"
 )
 
-// Result — аналог Result<T, E> из Rust
+// Result — обёртка вокруг результата с возможной ошибкой
 //
 // Может быть либо только полезное значение, либо только ошибка
 type Result[T any] struct {
@@ -15,23 +15,23 @@ type Result[T any] struct {
 }
 
 // NewOk -- возвращает успешный Result с значением
-func NewOk[T any](result T) *Result[T] {
+func NewOk[T any](result T) Result[T] {
 	// Для некоторых типов нужна дополнительная проверка через reflect
 	v := reflect.ValueOf(result)
 	switch v.Kind() {
 	case reflect.Ptr, reflect.Slice, reflect.Map, reflect.Chan, reflect.Func, reflect.Interface:
 		Hassert(!v.IsNil(), "NewOk(): result==nil")
 	}
-	sf := &Result[T]{
+	sf := Result[T]{
 		val: result,
 	}
 	return sf
 }
 
 // NewErr -- возвращает Result с ошибкой
-func NewErr(err error) *Result[any] {
+func NewErr[T any](err error) Result[T] {
 	Hassert(err != nil, "NewError(): err==nil")
-	return &Result[any]{
+	return Result[T]{
 		err: err,
 	}
 }

+ 17 - 26
krn/kresult/kresult_test.go → krn/ktypes/kresult_test.go

@@ -1,23 +1,23 @@
-package kresult
+package ktypes
 
 import (
 	"fmt"
 	"testing"
 )
 
-type tester struct {
+type testerResult struct {
 	t *testing.T
 }
 
 func TestResult(t *testing.T) {
-	sf := &tester{
+	sf := &testerResult{
 		t: t,
 	}
 	sf.create()
 }
 
 // Создаёт новый Result
-func (sf *tester) create() {
+func (sf *testerResult) create() {
 	sf.t.Log("create")
 	sf.createOkBad1()
 	sf.createOkGood1()
@@ -26,7 +26,7 @@ func (sf *tester) create() {
 	sf.createErrGood1()
 }
 
-func (sf *tester) createErrGood1() {
+func (sf *testerResult) createErrGood1() {
 	sf.t.Log("createErrGood1")
 	defer func() {
 		if _panic := recover(); _panic != nil {
@@ -34,10 +34,7 @@ func (sf *tester) createErrGood1() {
 		}
 	}()
 	err := fmt.Errorf("test err")
-	res := NewErr(err)
-	if res == nil {
-		sf.t.Fatalf("createErrGood1(): res==nil")
-	}
+	res := NewErr[string](err)
 	if res.IsOk() {
 		sf.t.Fatalf("createErrGood1(): is ok")
 	}
@@ -61,7 +58,7 @@ func (sf *tester) createErrGood1() {
 	sf.assert(res)
 }
 
-func (sf *tester) assert(res *Result[any]) {
+func (sf *testerResult) assert(res Result[string]) {
 	sf.t.Log("assert")
 	defer func() {
 		if _panic := recover(); _panic == nil {
@@ -71,7 +68,7 @@ func (sf *tester) assert(res *Result[any]) {
 	res.Hassert("test assert")
 }
 
-func (sf *tester) hassert(res *Result[any]) {
+func (sf *testerResult) hassert(res Result[string]) {
 	sf.t.Log("hassert")
 	defer func() {
 		if _panic := recover(); _panic == nil {
@@ -81,7 +78,7 @@ func (sf *tester) hassert(res *Result[any]) {
 	res.Hassert("test hassert")
 }
 
-func (sf *tester) unwrapErr(res *Result[any]) {
+func (sf *testerResult) unwrapErr(res Result[string]) {
 	sf.t.Log("unwrapErr")
 	defer func() {
 		if _panic := recover(); _panic == nil {
@@ -92,7 +89,7 @@ func (sf *tester) unwrapErr(res *Result[any]) {
 }
 
 // Нет ошибки
-func (sf *tester) createErrBad1() {
+func (sf *testerResult) createErrBad1() {
 	sf.t.Log("createErrBad1")
 	defer func() {
 		if _panic := recover(); _panic == nil {
@@ -100,10 +97,10 @@ func (sf *tester) createErrBad1() {
 		}
 	}()
 	var err error
-	_ = NewErr(err)
+	_ = NewErr[bool](err)
 }
 
-func (sf *tester) createOkGood2() {
+func (sf *testerResult) createOkGood2() {
 	sf.t.Log("createOkGood2")
 	defer func() {
 		if _panic := recover(); _panic != nil {
@@ -112,9 +109,6 @@ func (sf *tester) createOkGood2() {
 	}()
 	str := "test val"
 	res := NewOk(str)
-	if res == nil {
-		sf.t.Fatalf("createOkGood1(): res==nil")
-	}
 	if !res.IsOk() {
 		sf.t.Fatalf("createOkGood1(): not ok")
 	}
@@ -141,16 +135,16 @@ func (sf *tester) createOkGood2() {
 }
 
 // Функция высшего порядка для замещения ошибки
-func (sf *tester) fnWrap2() any {
+func (sf *testerResult) fnWrap2() string {
 	return "test5"
 }
 
 // Функция высшего порядка для замещения ошибки
-func (sf *tester) fnWrap() string {
+func (sf *testerResult) fnWrap() string {
 	return "test1"
 }
 
-func (sf *tester) createOkGood1() {
+func (sf *testerResult) createOkGood1() {
 	sf.t.Log("createOkGood1")
 	defer func() {
 		if _panic := recover(); _panic != nil {
@@ -158,14 +152,11 @@ func (sf *tester) createOkGood1() {
 		}
 	}()
 	str := "test val"
-	res := NewOk(&str)
-	if res == nil {
-		sf.t.Fatalf("createOkGood1(): res==nil")
-	}
+	_ = NewOk(&str)
 }
 
 // Нет результата
-func (sf *tester) createOkBad1() {
+func (sf *testerResult) createOkBad1() {
 	sf.t.Log("createOkBad1")
 	defer func() {
 		if _panic := recover(); _panic == nil {

+ 4 - 3
mock/mock_hand_serve/mock_hand_serve.go

@@ -34,14 +34,15 @@ func NewMockHandlerServe(topic ATopic, name string) *MockHandlerServe {
 }
 
 // Функция обратного вызова подписки
-func (sf *MockHandlerServe) FnBack(binMsg []byte) ([]byte, error) {
+func (sf *MockHandlerServe) FnBack(binMsg []byte) Result[[]byte] {
 	sf.block.Lock()
 	defer sf.block.Unlock()
 	if sf.IsBad_.Get() {
-		return nil, fmt.Errorf("FnBack(): isBad==true")
+		err := fmt.Errorf("FnBack(): isBad==true")
+		return NewErr[[]byte](err)
 	}
 	sf.Msg_ = binMsg
-	return sf.Msg_, nil
+	return NewOk(binMsg)
 }
 
 // Возвращает уникальное имя обработчика подписки

+ 7 - 10
mock/mock_hand_serve/mock_hand_serve_test.go

@@ -26,12 +26,12 @@ func (sf *tester) back() {
 
 func (sf *tester) backGood1() {
 	sf.t.Log("backGood1")
-	binMsg, err := sf.hand.FnBack([]byte("test_msg"))
-	if err != nil {
-		sf.t.Fatalf("backGood1(): err=%v", err)
+	res := sf.hand.FnBack([]byte("test_msg"))
+	if res.IsErr() {
+		sf.t.Fatalf("backGood1(): err=%v", res.Error())
 	}
-	if string(binMsg) != "test_msg" {
-		sf.t.Fatalf("backGood1(): binMsg(%v)!='test_msg'", string(binMsg))
+	if string(res.Unwrap()) != "test_msg" {
+		sf.t.Fatalf("backGood1(): binMsg(%v)!='test_msg'", string(res.Unwrap()))
 	}
 }
 
@@ -39,13 +39,10 @@ func (sf *tester) backGood1() {
 func (sf *tester) backBad1() {
 	sf.t.Log("backBad1")
 	sf.hand.IsBad_.Set()
-	binMsg, err := sf.hand.FnBack([]byte("test_msg"))
-	if err == nil {
+	res := sf.hand.FnBack([]byte("test_msg"))
+	if res.IsOk() {
 		sf.t.Fatalf("backBad1(): err==nil")
 	}
-	if binMsg != nil {
-		sf.t.Fatalf("backBad1(): binMsg!=nil")
-	}
 	sf.hand.IsBad_.Reset()
 }