Ver código fonte

SVI Рабочее сохранение

SVI 4 meses atrás
pai
commit
4d27a75400

+ 2 - 1
v4/docs/index.md

@@ -114,11 +114,12 @@ kern — фреймворк для создания модульных комп
 ## Сделать
 
 - [x] разложить Hassert и Assert на условия и действие!!!
+- [ ] TUF сериализация/десериализация (собственная разработка, замена JSON);
 - +++ перейти на структурированный лог
 - ++ BaseBus и LocalBus упростить
 - перевести все базовые типы на внутренние
 - контрактные внутренние типы;
-- TUF сериализация/десериализация (собственная разработка, замена JSON);
+
 - сильное разделение на модули (WASI);
 - WASI модули (для надёжных модульных монолитов);
 - HTTP-сервер на stdlib (для PWA и WASM приложений);

+ 3 - 3
v4/lev0/core_spec/ebool.go

@@ -1,13 +1,13 @@
 package core_spec
 
-import "gitp78su.ipnodns.ru/svi/kern/v4/lev0/defs"
+import "gitp78su.ipnodns.ru/svi/kern/v4/lev0/defs/def_spec"
 
 // EBool -- расширенный бул.
 type EBool interface {
 	// IsOk -- проверяет на true.
-	IsOk() defs.Bool
+	IsOk() def_spec.Bool
 	// IsNot -- проверяет на false.
-	IsNot() defs.Bool
+	IsNot() def_spec.Bool
 }
 
 // EBoolMut -- мутабельный расширенный бул.

+ 3 - 3
v4/lev0/core_spec/estr.go

@@ -1,18 +1,18 @@
 package core_spec
 
-import "gitp78su.ipnodns.ru/svi/kern/v4/lev0/defs"
+import "gitp78su.ipnodns.ru/svi/kern/v4/lev0/defs/def_spec"
 
 // EStr -- расширенная строка.
 type EStr interface {
 	// SelfCheck -- выполняет самопроверку строки.
 	SelfCheck()
 	// Get -- возвращает строку.
-	Get() defs.ITxtFix
+	Get() def_spec.ITxtFix
 }
 
 // EStrMut -- мутабельная расширенная строка.
 type EStrMut interface {
 	EStr
 	// Set -- устанавливает строку.
-	Set(defs.ITxtFix)
+	Set(def_spec.ITxtFix)
 }

+ 1 - 2
v4/lev0/core_spec/ichan.go

@@ -1,7 +1,6 @@
 package core_spec
 
 import (
-	"gitp78su.ipnodns.ru/svi/kern/v4/lev0/defs"
 	"gitp78su.ipnodns.ru/svi/kern/v4/lev0/defs/def_spec"
 )
 
@@ -16,5 +15,5 @@ type IChan[T any] interface {
 	// Close -- закрыть канал.
 	Close()
 	// IsClosed -- проверяет закрыт ли канал.
-	IsClosed() defs.Bool
+	IsClosed() def_spec.Bool
 }

+ 4 - 4
v4/lev0/core_spec/isafe_bool.go

@@ -1,17 +1,17 @@
 package core_spec
 
-import "gitp78su.ipnodns.ru/svi/kern/v4/lev0/defs"
+import "gitp78su.ipnodns.ru/svi/kern/v4/lev0/defs/def_spec"
 
 // ISafeBool -- интерфейс к потокобезопасной переменной.
 type ISafeBool interface {
 	// Get -- возвращает хранимое значение потокобезопасной переменной
-	Get() defs.Bool
+	Get() def_spec.Bool
 	// Set -- взводит хранимое потокобезопасное значение
 	Set()
 	// Reset -- сбрасывает хранимое потокобезопасное значение
 	Reset()
 	// FromStr -- устанавливает значение из строки
-	FromStr(defs.ITxtFix) IOption[defs.IErr]
+	FromStr(def_spec.ITxtFix) IOption[def_spec.IErr]
 	// Getenv -- получает значение из окружения
-	Getenv(defs.ITxtFix) IOption[defs.IErr]
+	Getenv(def_spec.ITxtFix) IOption[def_spec.IErr]
 }

+ 3 - 3
v4/lev0/core_spec/isafe_bool_react.go

@@ -1,14 +1,14 @@
 package core_spec
 
 import (
-	"gitp78su.ipnodns.ru/svi/kern/v4/lev0/defs"
+	"gitp78su.ipnodns.ru/svi/kern/v4/lev0/defs/def_spec"
 )
 
 // ISafeBoolReact -- реактивный потокобезопасный булевый признак.
 type ISafeBoolReact interface {
 	ISafeBool
 	// Add -- добавляет функцию обратного вызова
-	Add(key defs.ITxtFix, fn func(EBoolMut)) IResult[bool]
+	Add(key def_spec.ITxtFix, fn func(EBoolMut)) IResult[bool]
 	// Delete -- удаляет функцию обратного вызова по ключу
-	Delete(key defs.ITxtFix)
+	Delete(key def_spec.ITxtFix)
 }

+ 1 - 2
v4/lev0/core_spec/isafe_string.go

@@ -1,7 +1,6 @@
 package core_spec
 
 import (
-	"gitp78su.ipnodns.ru/svi/kern/v4/lev0/defs"
 	"gitp78su.ipnodns.ru/svi/kern/v4/lev0/defs/def_spec"
 )
 
@@ -16,5 +15,5 @@ type ISafeString interface {
 	// Byte -- возвращает байтовое представление строки
 	Byte() []byte
 	// Getenv -- устанавливает строку из переменной окружения
-	Getenv(defs.ITxtFix) IResult[def_spec.ITxtFix]
+	Getenv(def_spec.ITxtFix) IResult[def_spec.ITxtFix]
 }

+ 9 - 8
v4/lev0/core_spec/itime.go

@@ -1,24 +1,25 @@
 package core_spec
 
 import (
-	"gitp78su.ipnodns.ru/svi/kern/v4/lev0/defs"
+	"gitp78su.ipnodns.ru/svi/kern/v4/lev0/defs/def_spec"
 )
 
+// ITimeFix -- метка времени.
+// Вывод: "2006-01-02 15:04:05.000 -07 MST".
+type ITimeFix def_spec.ITxtFix
+
 // ITime -- интерфейс времени.
 // Вывод: "2006-01-02 15:04:05.000 -07 MST".
 type ITime interface {
-	defs.IString
+	def_spec.IString
+	def_spec.ITuf
 	// Time -- получить время.
-	Time() defs.ITimeFix
-	// MarshalJSON -- сериализация в JSON себя
-	MarshalJSON() ([]byte, error)
-	// UnmarshalJSON -- десериализация из JSON себя
-	UnmarshalJSON([]byte) error
+	Time() ITimeFix
 }
 
 // ITimeMut -- интерфейс времени с мутацией.
 type ITimeMut interface {
 	ITime
 	// Set -- установить время.
-	Set(val defs.ITimeFix)
+	Set(val ITimeFix)
 }

+ 9 - 0
v4/lev0/defs/def_spec/def_tuf.go

@@ -0,0 +1,9 @@
+package def_spec
+
+// ITuf -- интерфейс сериализатора.
+type ITuf interface {
+	// ToTuf -- сериализация
+	ToTuf() ATxt
+	// FromTuf -- десериализация
+	FromTuf(data ATxt) IOption[IErr]
+}

+ 19 - 9
v4/lev0/defs/defs.go

@@ -5,6 +5,7 @@ import (
 	"gitp78su.ipnodns.ru/svi/kern/v4/lev0/defs/def_err"
 	"gitp78su.ipnodns.ru/svi/kern/v4/lev0/defs/def_spec"
 	"gitp78su.ipnodns.ru/svi/kern/v4/lev0/defs/def_txt"
+	"gitp78su.ipnodns.ru/svi/kern/v4/lev0/option"
 )
 
 // Bool -- внутренне представление логического значения.
@@ -45,17 +46,26 @@ func Err(msg ATxt, arg ...any) IErr {
 	return def_err.Err(msg, arg...)
 }
 
-// ITimeFix -- метка времени.
-// Вывод: "2006-01-02 15:04:05.000 -07 MST".
-type ITimeFix ITxtFix
+
 
 // BucketName -- имя сущности.
 type BucketName ITxtFix
 
-// StreamName -- имя потока для ожидания.
-// type StreamName = stream_name.AStreamName
+// ITuf -- интерфейс к сериализатору TUF.
+type ITuf = def_spec.ITuf
+
+// IResult -- результат выполнения.
+type IResult[T any] = def_spec.IResult[T]
+
+// IOption -- опциональный результат.
+type IOption[T any] = def_spec.IOption[T]
+
+// NewSome -- создать новый опциональный результат.
+func NewSome[T any](val T) IOption[T] {
+	return option.NewSome(val)
+}
 
-// NewStreamName -- создать новое имя потока.
-// func NewStreamName(val Str) *stream_name.AStreamName {
-// 	return stream_name.NewAStreamName(val)
-// }
+// NewNone -- создать новый опциональный результат.
+func NewNone[T any]() IOption[T] {
+	return option.NewNone[T]()
+}

+ 1 - 2
v4/lev0/option/option.go

@@ -4,7 +4,6 @@ import (
 	"reflect"
 
 	mKs "gitp78su.ipnodns.ru/svi/kern/v4/lev0/core_spec"
-	"gitp78su.ipnodns.ru/svi/kern/v4/lev0/defs"
 	"gitp78su.ipnodns.ru/svi/kern/v4/lev0/defs/def_spec"
 	mH "gitp78su.ipnodns.ru/svi/kern/v4/lev0/helpers"
 )
@@ -21,7 +20,7 @@ func NewSome[T any](value T) mKs.IOption[T] {
 	switch v.Kind() {
 	case reflect.Pointer, reflect.Slice, reflect.Map, reflect.Chan,
 		reflect.Func, reflect.Interface:
-		isNil := defs.Bool(v.IsNil())
+		isNil := def_spec.Bool(v.IsNil())
 		mH.If(isNil).Hassert("NewSome[T any](): value==nil")
 	}
 	sf := &Option[T]{some: &value}

+ 80 - 0
v4/lev0/tuf/tuf.go

@@ -0,0 +1,80 @@
+// package tuf -- Text Universal Format
+package tuf
+
+import (
+	"fmt"
+	"strings"
+
+	"gitp78su.ipnodns.ru/svi/kern/v4/lev0/defs/def_err"
+	"gitp78su.ipnodns.ru/svi/kern/v4/lev0/defs/def_spec"
+	"gitp78su.ipnodns.ru/svi/kern/v4/lev0/helpers"
+	"gitp78su.ipnodns.ru/svi/kern/v4/lev0/result"
+)
+
+// StrToTuf -- конвертация строки в ITuf.
+func StrToTuf(key, val def_spec.ATxt) def_spec.ATxt {
+	keyCheck(key)
+
+	txtRes := "ATxt;" + string(key) + ";" + replace(val) + "\n"
+	return def_spec.ATxt(txtRes)
+}
+
+// BoolToTuf -- конвертация bool в ITuf.
+func BoolToTuf(key def_spec.ATxt, val def_spec.Bool) def_spec.ATxt {
+	keyCheck(key)
+	txtRes := "Bool;" + string(key) + ";" + fmt.Sprint(val) + "\n"
+	return def_spec.ATxt(txtRes)
+}
+
+// RecToTuf -- конвертация записи в TUF.
+func RecToTuf(type_, val def_spec.ATxt) def_spec.ATxt {
+	keyCheck(type_)
+	strRes := "Rec;" + string(type_) + ";" + replace(val) + "\n"
+	return def_spec.ATxt(strRes)
+}
+
+// RecFromTuf -- конвертация записи из TUF.
+func RecFromTuf(type_, val def_spec.ATxt) def_spec.IResult[def_spec.ATxt] {
+	keyCheck(type_)
+	lstField := strings.Split(string(val), ";")
+	if len(lstField) != 3 {
+		return result.NewErr[def_spec.ATxt](
+			def_err.Err("tuf.RecFromTuf(): valTuf len(%v)!=3", len(lstField)))
+	}
+	if lstField[0] != "Rec" {
+		return result.NewErr[def_spec.ATxt](
+			def_err.Err("tuf.RecFromTuf(): valTuf(%v) not record", lstField[0]))
+	}
+	if lstField[1] != string(type_) {
+		return result.NewErr[def_spec.ATxt](
+			def_err.Err("tuf.RecFromTuf(): valTuf(%v) not valid type(%v)", lstField[1], type_))
+	}
+	txtRes := restore(lstField[2])
+	return result.NewOk(txtRes)
+}
+
+// Проверяет ключ на допустимое значение.
+func keyCheck(key def_spec.ATxt) {
+	helpers.If(def_spec.Bool(strings.Contains(string(key), ";"))).Hassert("tuf.keyCheck(): key contains ';'")
+	helpers.If(def_spec.Bool(strings.Contains(string(key), "\n"))).Hassert("tuf.keyCheck(): key contains '\\n'")
+	helpers.If(def_spec.Bool(strings.Contains(string(key), "="))).Hassert("tuf.keyCheck(): key contains '='")
+}
+
+// Заменяет все запрещённые комбинации.
+func replace(val def_spec.ATxt) string {
+	strVal := strings.ReplaceAll(string(val), "\r", "")
+	strVal = strings.ReplaceAll(strVal, "\n", "`NL")
+	strVal = strings.ReplaceAll(strVal, "`", "`TL")
+	strVal = strings.ReplaceAll(strVal, "=", "`EQ")
+	strVal = strings.ReplaceAll(strVal, ";", "`CS")
+	return strVal
+}
+
+// Восстанавливает строку.
+func restore(val string) def_spec.ATxt {
+	strVal := strings.ReplaceAll(val, "`TL", "`")
+	strVal = strings.ReplaceAll(strVal, "`CS", ";")
+	strVal = strings.ReplaceAll(strVal, "`EQ", "=")
+	strVal = strings.ReplaceAll(strVal, "`NL", "\n")
+	return def_spec.ATxt(strVal)
+}

+ 23 - 24
v4/lev0/voc/etime/etime.go

@@ -1,24 +1,23 @@
 package etime
 
 import (
-	"encoding/json"
-	"fmt"
 	"time"
 
-	mKs "gitp78su.ipnodns.ru/svi/kern/v4/lev0/core_spec"
+	"gitp78su.ipnodns.ru/svi/kern/v4/lev0/core_spec"
 	"gitp78su.ipnodns.ru/svi/kern/v4/lev0/defs"
 	"gitp78su.ipnodns.ru/svi/kern/v4/lev0/helpers"
+	"gitp78su.ipnodns.ru/svi/kern/v4/lev0/tuf"
 )
 
 // ETime -- метка времени.
 // Вывод: "2006-01-02 15:04:05.000 -07 MST".
 type ETime struct {
-	defs.ITimeFix
-	isFill bool // Признак заполнения
+	core_spec.ITimeFix
+	isFill defs.Bool // Признак заполнения
 }
 
 // NewETime -- создает новый экземпляр ETime.
-func NewETime(val defs.ITimeFix) mKs.ITime {
+func NewETime(val core_spec.ITimeFix) core_spec.ITime {
 	helpers.If(val.Get() == "").Hassert("NewETime(): val is empty")
 	sf := &ETime{
 		ITimeFix: val,
@@ -28,17 +27,17 @@ func NewETime(val defs.ITimeFix) mKs.ITime {
 }
 
 // NewETimeAuto -- создаёт фиксированную авто-метку времени.
-func NewETimeAuto() mKs.ITime {
+func NewETimeAuto() core_spec.ITime {
 	sf := &ETime{
 		isFill: true,
 	}
 	val := defs.TxtFix(time.Now().Local().Format("2006-01-02 15:04:05.000 -07 MST"))
-	sf.Set(defs.ITimeFix(val))
+	sf.Set(core_spec.ITimeFix(val))
 	return sf
 }
 
 // NewETimeAutoMut -- создаёт изменяемую авто-метку времени.
-func NewETimeAutoMut() mKs.ITimeMut {
+func NewETimeAutoMut() core_spec.ITimeMut {
 	sf := &ETime{
 		isFill: true,
 	}
@@ -54,31 +53,31 @@ func (sf *ETime) String() string {
 }
 
 // Time -- возвращает типизированную строку.
-func (sf *ETime) Time() defs.ITimeFix {
+func (sf *ETime) Time() core_spec.ITimeFix {
 	helpers.If(sf.Get() == "").Hassert("ETime.Time(): значение не инициализировано")
 	return sf.ITimeFix
 }
 
 // Set -- устанавливает типизированное значение.
-func (sf *ETime) Set(val defs.ITimeFix) {
+func (sf *ETime) Set(val core_spec.ITimeFix) {
 	helpers.If(val.Get() == "").Hassert("ETime.Set(): val is empty")
 	sf.ITimeFix = val
 }
 
-// MarshalJSON -- сериализует себя в строку.
-func (sf *ETime) MarshalJSON() ([]byte, error) {
-	binMsg, err := json.Marshal(sf)
-	if err != nil {
-		err = fmt.Errorf("ETime.MarshalJSON(): in self marshall, err=\n\t%w", err)
-		return nil, err
-	}
-	return binMsg, err
+// ToTuf -- сериализует себя в строку.
+func (sf *ETime) ToTuf() defs.ATxt {
+	txtRes := tuf.StrToTuf("val", sf.Get())
+	txtRes += tuf.BoolToTuf("isFill", sf.isFill)
+	txtRes = tuf.RecToTuf("ETime", txtRes)
+	return txtRes
 }
 
-// UnmarshalJSON -- десериализует из строки.
-func (sf *ETime) UnmarshalJSON(binMsg []byte) error {
-	if err := json.Unmarshal(binMsg, sf); err != nil {
-		return fmt.Errorf("ETime.UnmarshalJSON(): in self unmarshall, err=\n\t%w", err)
+// FromTuf -- десериализует из defs.ATxt в строки.
+func (sf *ETime) FromTuf(txtMsg defs.ATxt) defs.IOption[defs.IErr] {
+	resRec := tuf.RecFromTuf("ETime", txtMsg) // Получить текст записи
+	if resRec.IsErr() {
+		err := defs.Err("ETime.FromTuf(): in extract record from TUF, err=\n\t%v", resRec.Error())
+		return defs.NewSome(err)
 	}
-	return nil
+	return defs.NewNone[defs.IErr]()
 }

+ 4 - 5
v4/lev0/voc/voc.go

@@ -2,28 +2,27 @@
 package voc
 
 import (
-	mKs "gitp78su.ipnodns.ru/svi/kern/v4/lev0/core_spec"
-	"gitp78su.ipnodns.ru/svi/kern/v4/lev0/defs"
+	"gitp78su.ipnodns.ru/svi/kern/v4/lev0/core_spec"
 	"gitp78su.ipnodns.ru/svi/kern/v4/lev0/voc/etime"
 )
 
 // NewETime -- создать новую метку времени.
 //
 
-func NewETime(val defs.ITimeFix) mKs.ITime {
+func NewETime(val core_spec.ITimeFix) core_spec.ITime {
 	return etime.NewETime(val)
 }
 
 // NewETimeAuto -- создать новую фиксированную авто-метку
 //
 
-func NewETimeAuto() mKs.ITime {
+func NewETimeAuto() core_spec.ITime {
 	return etime.NewETimeAuto()
 }
 
 // NewETimeAutoMut -- создать новую фиксированную авто-метку
 //
 
-func NewETimeAutoMut() mKs.ITimeMut {
+func NewETimeAutoMut() core_spec.ITimeMut {
 	return etime.NewETimeAutoMut()
 }

+ 1 - 1
v4/lev1/log_buf/log_msg/log_msg.go

@@ -33,7 +33,7 @@ const (
 type logMsg struct {
 	level     defs.ITxtMut
 	createdAt core_spec.ITime
-	msg       defs.ITimeFix
+	msg       core_spec.ITimeFix
 }
 
 // NewLogMsg -- возвращает новое сообщение логгера.

+ 2 - 1
v4/lev2/kmodule/mod_stat/mod_stat_sec/mod_stat_sec.go

@@ -10,6 +10,7 @@ import (
 	"time"
 
 	svg "github.com/ajstarks/svgo"
+	"gitp78su.ipnodns.ru/svi/kern/v4/lev0/core_spec"
 	"gitp78su.ipnodns.ru/svi/kern/v4/lev0/defs"
 )
 
@@ -73,7 +74,7 @@ func (sf *ModStatSec) Add(val defs.Int) {
 // )
 
 // Svg -- возвращает сгенерированный SVG по минутному срезу.
-func (sf *ModStatSec) Svg() defs.ITimeFix {
+func (sf *ModStatSec) Svg() core_spec.ITimeFix {
 	sf.Lock()
 	defer sf.Unlock()
 	sf.bufSvg.Reset()

+ 5 - 5
v4/lev2/kserv_http/kserv_http.go

@@ -16,7 +16,7 @@ import (
 	"github.com/gofiber/fiber/v3/middleware/compress"
 	"github.com/gofiber/fiber/v3/middleware/static"
 
-	mKs "gitp78su.ipnodns.ru/svi/kern/v4/lev0/core_spec"
+	"gitp78su.ipnodns.ru/svi/kern/v4/lev0/core_spec"
 	"gitp78su.ipnodns.ru/svi/kern/v4/lev0/defs"
 	"gitp78su.ipnodns.ru/svi/kern/v4/lev0/etypes/ebool"
 	"gitp78su.ipnodns.ru/svi/kern/v4/lev0/helpers"
@@ -40,8 +40,8 @@ type kServHttp struct {
 	log      comp_spec.ILogBuf
 	strUrl   defs.ITxtFix // URL, на котором слушает HTTP-сервер
 	fiberApp *fiber.App
-	isWork   mKs.ISafeBool
-	isEnd    mKs.ISafeBool
+	isWork   core_spec.ISafeBool
+	isEnd    core_spec.ISafeBool
 }
 
 //go:embed static/*
@@ -78,7 +78,7 @@ func GetKernelServHttp() kspec.IKernelServerHttp {
 
 	optMonolit := kCtx.Get(defs.TxtFix("monolitName"))
 	optMonolit.Hassert("GetKernelServHttp(): not have monolit name from kCtx")
-	strMonolit := optMonolit.Some().Val().(defs.ITimeFix)
+	strMonolit := optMonolit.Some().Val().(core_spec.ITimeFix)
 	confFiber := fiber.Config{
 		ServerHeader: strMonolit.String(),
 		UnescapePath: true,
@@ -117,7 +117,7 @@ func GetKernelServHttp() kspec.IKernelServerHttp {
 }
 
 // IsWork -- возвращает признак работы.
-func (sf *kServHttp) IsWork() mKs.EBool {
+func (sf *kServHttp) IsWork() core_spec.EBool {
 	res := sf.isWork.Get()
 	return ebool.NewEBool(res)
 }