From 84b2be31693e22a381e6ab24df59c5ff2a9ee59d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mike=20Schw=C3=B6rer?= Date: Wed, 9 Aug 2023 14:40:16 +0200 Subject: [PATCH] v0.0.235 added .Enum(..) to exerr --- bfcodegen/enum-generate.go | 42 ++++++---------------------- enums/enum.go | 24 ++++++++++++++++ exerr/builder.go | 5 ++++ exerr/meta.go | 28 +++++++++++++++++++ exerr/typeWrapper.go | 56 ++++++++++++++++++++++++++++++++++++++ goextVersion.go | 4 +-- 6 files changed, 123 insertions(+), 36 deletions(-) create mode 100644 enums/enum.go diff --git a/bfcodegen/enum-generate.go b/bfcodegen/enum-generate.go index 4d781f8..e9b658a 100644 --- a/bfcodegen/enum-generate.go +++ b/bfcodegen/enum-generate.go @@ -209,36 +209,10 @@ func fmtOutput(cs string, enums []EnumDef, pkgname string) string { str += "\n" str += "import \"gogs.mikescher.com/BlackForestBytes/goext/langext\"" + "\n" + str += "import \"gogs.mikescher.com/BlackForestBytes/goext/enums\"" + "\n" str += "\n" - str += "const ChecksumGenerator = \"" + cs + "\"" + "\n" - str += "\n" - - str += "type Enum interface {" + "\n" - str += " Valid() bool" + "\n" - str += " ValuesAny() []any" + "\n" - str += " ValuesMeta() []EnumMetaValue" + "\n" - str += " VarName() string" + "\n" - str += "}" + "\n" - str += "" + "\n" - - str += "type StringEnum interface {" + "\n" - str += " Enum" + "\n" - str += " String() string" + "\n" - str += "}" + "\n" - str += "" + "\n" - - str += "type DescriptionEnum interface {" + "\n" - str += " Enum" + "\n" - str += " Description() string" + "\n" - str += "}" + "\n" - str += "\n" - - str += "type EnumMetaValue struct {" + "\n" - str += " VarName string `json:\"varName\"`" + "\n" - str += " Value any `json:\"value\"`" + "\n" - str += " Description *string `json:\"description\"`" + "\n" - str += "}" + "\n" + str += "const ChecksumGenerator = \"" + cs + "\" // GoExtVersion: " + goext.GoextVersion + "\n" str += "\n" for _, enumdef := range enums { @@ -292,7 +266,7 @@ func fmtOutput(cs string, enums []EnumDef, pkgname string) string { str += "}" + "\n" str += "" + "\n" - str += "func (e " + enumdef.EnumTypeName + ") ValuesMeta() []EnumMetaValue {" + "\n" + str += "func (e " + enumdef.EnumTypeName + ") ValuesMeta() []enums.EnumMetaValue {" + "\n" str += " return " + enumdef.EnumTypeName + "ValuesMeta()" str += "}" + "\n" str += "" + "\n" @@ -322,11 +296,11 @@ func fmtOutput(cs string, enums []EnumDef, pkgname string) string { str += "}" + "\n" str += "" + "\n" - str += "func (e " + enumdef.EnumTypeName + ") Meta() EnumMetaValue {" + "\n" + str += "func (e " + enumdef.EnumTypeName + ") Meta() enums.EnumMetaValue {" + "\n" if hasDescr { - str += " return EnumMetaValue{VarName: e.VarName(), Value: e, Description: langext.Ptr(e.Description())}" + str += " return enums.EnumMetaValue{VarName: e.VarName(), Value: e, Description: langext.Ptr(e.Description())}" } else { - str += " return EnumMetaValue{VarName: e.VarName(), Value: e, Description: nil}" + str += " return enums.EnumMetaValue{VarName: e.VarName(), Value: e, Description: nil}" } str += "}" + "\n" str += "" + "\n" @@ -346,8 +320,8 @@ func fmtOutput(cs string, enums []EnumDef, pkgname string) string { str += "}" + "\n" str += "" + "\n" - str += "func " + enumdef.EnumTypeName + "ValuesMeta() []EnumMetaValue {" + "\n" - str += " return []EnumMetaValue{" + "\n" + str += "func " + enumdef.EnumTypeName + "ValuesMeta() []enums.EnumMetaValue {" + "\n" + str += " return []enums.EnumMetaValue{" + "\n" for _, v := range enumdef.Values { str += " " + v.VarName + ".Meta(),\n" } diff --git a/enums/enum.go b/enums/enum.go new file mode 100644 index 0000000..0a44196 --- /dev/null +++ b/enums/enum.go @@ -0,0 +1,24 @@ +package enums + +type Enum interface { + Valid() bool + ValuesAny() []any + ValuesMeta() []EnumMetaValue + VarName() string +} + +type StringEnum interface { + Enum + String() string +} + +type DescriptionEnum interface { + Enum + Description() string +} + +type EnumMetaValue struct { + VarName string `json:"varName"` + Value any `json:"value"` + Description *string `json:"description"` +} diff --git a/exerr/builder.go b/exerr/builder.go index 3681229..774169b 100644 --- a/exerr/builder.go +++ b/exerr/builder.go @@ -9,6 +9,7 @@ import ( "github.com/rs/zerolog" "go.mongodb.org/mongo-driver/bson/primitive" "gogs.mikescher.com/BlackForestBytes/goext/dataext" + "gogs.mikescher.com/BlackForestBytes/goext/enums" "gogs.mikescher.com/BlackForestBytes/goext/langext" "net/http" "os" @@ -281,6 +282,10 @@ func (b *Builder) Stringer(key string, val fmt.Stringer) *Builder { } } +func (b *Builder) Enum(key string, val enums.Enum) *Builder { + return b.addMeta(key, MDTEnum, newEnumWrap(val)) +} + func (b *Builder) Stack() *Builder { return b.addMeta("@Stack", MDTString, string(debug.Stack())) } diff --git a/exerr/meta.go b/exerr/meta.go index 102d0da..c243e0c 100644 --- a/exerr/meta.go +++ b/exerr/meta.go @@ -43,6 +43,7 @@ const ( MDTID metaDataType = "ID" MDTAny metaDataType = "Interface" MDTNil metaDataType = "Nil" + MDTEnum metaDataType = "Enum" ) type MetaValue struct { @@ -131,6 +132,8 @@ func (v MetaValue) SerializeValue() (string, error) { return string(r), nil case MDTNil: return "", nil + case MDTEnum: + return v.Value.(EnumWrap).Serialize(), nil } return "", errors.New("Unknown type: " + string(v.DataType)) } @@ -208,6 +211,8 @@ func (v MetaValue) ShortString(lim int) string { return langext.StrLimit(string(r), lim, "...") case MDTNil: return "<>" + case MDTEnum: + return v.Value.(EnumWrap).String() } return "(err)" } @@ -270,6 +275,14 @@ func (v MetaValue) Apply(key string, evt *zerolog.Event) *zerolog.Event { return evt.Ints32(key, v.Value.([]int32)) case MDTNil: return evt.Str(key, "<>") + case MDTEnum: + if v.Value.(EnumWrap).IsNil { + return evt.Any(key, nil) + } else if v.Value.(EnumWrap).ValueRaw != nil { + return evt.Any(key, v.Value.(EnumWrap).ValueRaw) + } else { + return evt.Str(key, v.Value.(EnumWrap).ValueString) + } } return evt.Str(key, "(err)") } @@ -511,6 +524,10 @@ func (v *MetaValue) Deserialize(value string, datatype metaDataType) error { v.Value = nil v.DataType = datatype return nil + case MDTEnum: + v.Value = deserializeEnumWrap(value) + v.DataType = datatype + return nil } return errors.New("Unknown type: " + string(datatype)) } @@ -581,6 +598,8 @@ func (v MetaValue) ValueString() string { return string(r) case MDTNil: return "<>" + case MDTEnum: + return v.Value.(EnumWrap).String() } return "(err)" } @@ -616,6 +635,15 @@ func (v MetaValue) rawValueForJson() any { if v.DataType == MDTNil { return nil } + if v.DataType == MDTEnum { + if v.Value.(EnumWrap).IsNil { + return nil + } + if v.Value.(EnumWrap).ValueRaw != nil { + return v.Value.(EnumWrap).ValueRaw + } + return v.Value.(EnumWrap).ValueString + } return v.Value } diff --git a/exerr/typeWrapper.go b/exerr/typeWrapper.go index 0880fef..b1eff3c 100644 --- a/exerr/typeWrapper.go +++ b/exerr/typeWrapper.go @@ -4,6 +4,7 @@ import ( "encoding/json" "fmt" "github.com/rs/zerolog/log" + "gogs.mikescher.com/BlackForestBytes/goext/enums" "gogs.mikescher.com/BlackForestBytes/goext/langext" "strings" ) @@ -131,3 +132,58 @@ func deserializeAnyWrap(v string) AnyWrap { } } } + +type EnumWrap struct { + Type string + ValueString string + ValueRaw enums.Enum // `ValueRaw` is lost during serialization roundtrip + IsNil bool +} + +func newEnumWrap(val enums.Enum) EnumWrap { + t := fmt.Sprintf("%T", val) + arr := strings.Split(t, ".") + if len(arr) > 0 { + t = arr[len(arr)-1] + } + + if langext.IsNil(val) { + return EnumWrap{Type: t, ValueString: "", ValueRaw: val, IsNil: true} + } + + if enumstr, ok := val.(enums.StringEnum); ok { + return EnumWrap{Type: t, ValueString: enumstr.String(), ValueRaw: val, IsNil: false} + } + + return EnumWrap{Type: t, ValueString: fmt.Sprintf("%v", val), ValueRaw: val, IsNil: false} +} + +func (w EnumWrap) Serialize() string { + if w.IsNil { + return "!nil" + ":" + w.Type + } + return w.Type + ":" + w.ValueString +} + +func (w EnumWrap) String() string { + if w.IsNil { + return w.Type + "<>" + } + return "[" + w.Type + "] " + w.ValueString +} + +func deserializeEnumWrap(v string) EnumWrap { + r := strings.SplitN(v, ":", 2) + + if len(r) == 2 && r[0] == "!nil" { + return EnumWrap{Type: r[1], ValueString: v, ValueRaw: nil, IsNil: true} + } + + if len(r) == 0 { + return EnumWrap{} + } else if len(r) == 1 { + return EnumWrap{Type: "", ValueString: v, ValueRaw: nil, IsNil: false} + } else { + return EnumWrap{Type: r[0], ValueString: r[1], ValueRaw: nil, IsNil: false} + } +} diff --git a/goextVersion.go b/goextVersion.go index 7fc7da9..a2c1988 100644 --- a/goextVersion.go +++ b/goextVersion.go @@ -1,5 +1,5 @@ package goext -const GoextVersion = "0.0.234" +const GoextVersion = "0.0.235" -const GoextVersionTimestamp = "2023-08-09T10:39:14+0200" +const GoextVersionTimestamp = "2023-08-09T14:40:16+0200"