gui v1 (test1)
This commit is contained in:
parent
60ef1deb90
commit
56707d420b
|
@ -0,0 +1,394 @@
|
|||
// Code generated by go.wit.com/apps/autogenpb DO NOT EDIT.
|
||||
// This file was autogenerated with autogenpb v0.0.79 2025-09-01_01:52:08_UTC
|
||||
// go install go.wit.com/apps/autogenpb@latest
|
||||
//
|
||||
// define which structs (messages) you want to use in the .proto file
|
||||
// Then sort.pb.go and marshal.pb.go files are autogenerated
|
||||
//
|
||||
// autogenpb uses it and has an example .proto file with instructions
|
||||
//
|
||||
|
||||
package chatpb
|
||||
|
||||
import (
|
||||
"time"
|
||||
|
||||
"github.com/google/uuid"
|
||||
"go.wit.com/gui"
|
||||
"go.wit.com/lib/protobuf/guipb"
|
||||
"go.wit.com/log"
|
||||
timestamppb "google.golang.org/protobuf/types/known/timestamppb"
|
||||
)
|
||||
|
||||
// START GUI
|
||||
|
||||
func (x *Books) NewTable(title string) *BooksTable {
|
||||
t := new(BooksTable)
|
||||
t.x = x
|
||||
pb := new(guipb.Table)
|
||||
pb.Title = title
|
||||
t.pb = pb
|
||||
return t
|
||||
}
|
||||
|
||||
func (t *BooksTable) AddStringFunc(title string, f func(*Book) string) *BookStringFunc {
|
||||
t.pb.Order = append(t.pb.Order, title)
|
||||
|
||||
sf := new(BookStringFunc)
|
||||
sf.title = title
|
||||
sf.f = f
|
||||
sf.order = t.order
|
||||
t.order += 1
|
||||
t.stringFuncs = append(t.stringFuncs, sf)
|
||||
return sf
|
||||
}
|
||||
|
||||
func (t *BooksTable) AddButtonFunc(title string, f func(*Book) string) *BookButtonFunc {
|
||||
t.pb.Order = append(t.pb.Order, title)
|
||||
|
||||
sf := new(BookButtonFunc)
|
||||
sf.title = title
|
||||
sf.f = f
|
||||
sf.order = t.order
|
||||
t.order += 1
|
||||
t.buttonFuncs = append(t.buttonFuncs, sf)
|
||||
return sf
|
||||
}
|
||||
|
||||
func (t *BooksTable) AddIntFunc(title string, f func(*Book) int) *BookIntFunc {
|
||||
t.pb.Order = append(t.pb.Order, title)
|
||||
|
||||
sf := new(BookIntFunc)
|
||||
sf.title = title
|
||||
sf.f = f
|
||||
sf.order = t.order
|
||||
t.order += 1
|
||||
t.intFuncs = append(t.intFuncs, sf)
|
||||
return sf
|
||||
}
|
||||
|
||||
func (t *BooksTable) AddTimeFunc(title string, f func(*Book) time.Time) *BookTimeFunc {
|
||||
t.pb.Order = append(t.pb.Order, title)
|
||||
|
||||
sf := new(BookTimeFunc)
|
||||
sf.title = title
|
||||
sf.f = f
|
||||
sf.order = t.order
|
||||
t.order += 1
|
||||
t.timeFuncs = append(t.timeFuncs, sf)
|
||||
return sf
|
||||
}
|
||||
|
||||
func (sf *BookStringFunc) SetTitle(title string) {
|
||||
sf.title = title
|
||||
}
|
||||
func (sf *BookIntFunc) SetTitle(title string) {
|
||||
sf.title = title
|
||||
}
|
||||
func (sf *BookTimeFunc) SetTitle(title string) {
|
||||
sf.title = title
|
||||
}
|
||||
|
||||
func (mt *BooksTable) SetParent(p *gui.Node) {
|
||||
mt.parent = p
|
||||
}
|
||||
|
||||
func (mt *BooksTable) ShowTable() {
|
||||
// log.Info("ShowTable() SENDING TO GUI")
|
||||
mt.MakeTable()
|
||||
mt.parent.ShowTable(mt.pb)
|
||||
}
|
||||
|
||||
type BookStringFunc struct {
|
||||
title string
|
||||
f func(*Book) string
|
||||
Custom func(*Book)
|
||||
order int
|
||||
}
|
||||
|
||||
type BookButtonFunc struct {
|
||||
title string
|
||||
f func(*Book) string
|
||||
Custom func(*Book)
|
||||
order int
|
||||
}
|
||||
|
||||
type BookIntFunc struct {
|
||||
title string
|
||||
f func(*Book) int
|
||||
Custom func(*Book)
|
||||
order int
|
||||
}
|
||||
|
||||
type BookTimeFunc struct {
|
||||
title string
|
||||
f func(*Book) time.Time
|
||||
Custom func(*Book)
|
||||
order int
|
||||
}
|
||||
|
||||
type BooksTable struct {
|
||||
pb *guipb.Table
|
||||
parent *gui.Node
|
||||
x *Books
|
||||
hostnames []string
|
||||
stringFuncs []*BookStringFunc
|
||||
intFuncs []*BookIntFunc
|
||||
timeFuncs []*BookTimeFunc
|
||||
buttonFuncs []*BookButtonFunc
|
||||
CustomFunc func(*Book)
|
||||
order int
|
||||
}
|
||||
|
||||
func (mt *BooksTable) doStringFunc(name string) bool {
|
||||
for _, sf := range mt.stringFuncs {
|
||||
if sf.title != name {
|
||||
continue
|
||||
}
|
||||
// log.Info("chatpb: found stringfunc name:", name)
|
||||
r := new(guipb.StringRow)
|
||||
r.Header = new(guipb.Widget)
|
||||
r.Header.Name = name
|
||||
for m := range mt.x.IterAll() {
|
||||
r.Vals = append(r.Vals, sf.f(m))
|
||||
// log.Info("chatpb: adding", name, r.Vals)
|
||||
}
|
||||
mt.pb.StringRows = append(mt.pb.StringRows, r)
|
||||
return true
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
func (mt *BooksTable) doButtonFunc(name string) bool {
|
||||
for _, sf := range mt.buttonFuncs {
|
||||
if sf.title != name {
|
||||
continue
|
||||
}
|
||||
// log.Info("chatpb: found stringfunc name:", name)
|
||||
r := new(guipb.ButtonRow)
|
||||
r.Header = new(guipb.Widget)
|
||||
r.Header.Name = name
|
||||
for m := range mt.x.IterAll() {
|
||||
r.Vals = append(r.Vals, sf.f(m))
|
||||
// log.Info("chatpb: adding", name, r.Vals)
|
||||
}
|
||||
mt.pb.ButtonRows = append(mt.pb.ButtonRows, r)
|
||||
return true
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
func (mt *BooksTable) doIntFunc(name string) bool {
|
||||
for _, sf := range mt.intFuncs {
|
||||
if sf.title != name {
|
||||
continue
|
||||
}
|
||||
// log.Info("chatpb: found intfunc name:", name)
|
||||
r := new(guipb.IntRow)
|
||||
r.Header = new(guipb.Widget)
|
||||
r.Header.Name = name
|
||||
for m := range mt.x.IterAll() {
|
||||
r.Vals = append(r.Vals, int64(sf.f(m)))
|
||||
// log.Info("chatpb: adding", name, r.Vals)
|
||||
}
|
||||
mt.pb.IntRows = append(mt.pb.IntRows, r)
|
||||
return true
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
func (mt *BooksTable) doTimeFunc(name string) bool {
|
||||
for _, sf := range mt.timeFuncs {
|
||||
if sf.title != name {
|
||||
continue
|
||||
}
|
||||
// log.Info("chatpb: found timefunc name:", name)
|
||||
r := new(guipb.TimeRow)
|
||||
r.Header = new(guipb.Widget)
|
||||
r.Header.Name = name
|
||||
for m := range mt.x.IterAll() {
|
||||
t := sf.f(m)
|
||||
r.Vals = append(r.Vals, timestamppb.New(t)) // convert to protobuf time
|
||||
// log.Info("chatpb: adding", name, r.Vals)
|
||||
}
|
||||
mt.pb.TimeRows = append(mt.pb.TimeRows, r)
|
||||
return true
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
func (mt *BooksTable) MakeTable() {
|
||||
for _, name := range mt.pb.Order {
|
||||
// log.Info("chatpb: looking for row name()", name)
|
||||
if mt.doStringFunc(name) {
|
||||
continue
|
||||
}
|
||||
if mt.doIntFunc(name) {
|
||||
continue
|
||||
}
|
||||
if mt.doTimeFunc(name) {
|
||||
continue
|
||||
}
|
||||
if mt.doButtonFunc(name) {
|
||||
continue
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func (t *BooksTable) AddUuid() *BookStringFunc {
|
||||
sf := t.AddStringFunc("Uuid", func(m *Book) string {
|
||||
return m.Uuid
|
||||
})
|
||||
return sf
|
||||
}
|
||||
|
||||
func (t *BooksTable) AddTitle() *BookStringFunc {
|
||||
sf := t.AddStringFunc("Title", func(m *Book) string {
|
||||
return m.Title
|
||||
})
|
||||
return sf
|
||||
}
|
||||
|
||||
func (t *BooksTable) AddContent() *BookStringFunc {
|
||||
sf := t.AddStringFunc("Content", func(m *Book) string {
|
||||
return m.Content
|
||||
})
|
||||
return sf
|
||||
}
|
||||
func (mt *BooksTable) NewUuid() {
|
||||
mt.pb.Uuid = uuid.New().String()
|
||||
}
|
||||
|
||||
// START TABLE UPDATE
|
||||
func (mt *BooksTable) todoUpdate() {
|
||||
for _, name := range mt.pb.Order {
|
||||
// log.Info("Bookpb: trying to update row()", name)
|
||||
if mt.updateStringFunc(name) {
|
||||
continue
|
||||
}
|
||||
if mt.updateTimeFunc(name) {
|
||||
continue
|
||||
}
|
||||
/*
|
||||
if mt.updateIntFunc(name) {
|
||||
continue
|
||||
}
|
||||
*/
|
||||
}
|
||||
// mt.dumpStringFunc("Hostname")
|
||||
mt.parent.UpdateTable(mt.pb)
|
||||
}
|
||||
|
||||
func (mt *BooksTable) dumpStringFunc(name string) {
|
||||
for i, r := range mt.pb.StringRows {
|
||||
// log.Info("could use", i, r.Header.Name, "for name =", name)
|
||||
if r.Header.Name == name {
|
||||
log.Info("dump Strings row", i, r.Header.Name, r.Vals)
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func (mt *BooksTable) updateStringFunc(name string) bool {
|
||||
// log.Info("LOOKING FOR STRING row", name)
|
||||
var found *guipb.StringRow
|
||||
for _, r := range mt.pb.StringRows {
|
||||
// log.Info("could use", i, r.Header.Name, "for name =", name)
|
||||
if r.Header.Name == name {
|
||||
// log.Info("found row", i, r.Header.Name)
|
||||
found = r
|
||||
break
|
||||
}
|
||||
}
|
||||
if found == nil {
|
||||
log.Info("did not find string row", name)
|
||||
return false
|
||||
}
|
||||
for _, sf := range mt.stringFuncs {
|
||||
if sf.title != name {
|
||||
continue
|
||||
}
|
||||
// log.Info("Bookpb: starting", name, found.Vals)
|
||||
for i, _ := range found.Vals {
|
||||
tmp := sf.f(mt.x.Books[i])
|
||||
if tmp == "www.wit.com" {
|
||||
log.Info("virtpb: FOUND WWW", i)
|
||||
tmp = "new.www"
|
||||
}
|
||||
found.Vals[i] = tmp
|
||||
}
|
||||
// log.Info("Bookpb: ending", name, found.Vals)
|
||||
return true
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
func (mt *BooksTable) updateTimeFunc(name string) bool {
|
||||
log.Info("LOOKING FOR TIME row", name)
|
||||
var found *guipb.TimeRow
|
||||
for i, r := range mt.pb.TimeRows {
|
||||
// log.Info("could use", i, r.Header.Name, "for name =", name)
|
||||
if r.Header.Name == name {
|
||||
log.Info("found row", i, r.Header.Name)
|
||||
found = r
|
||||
break
|
||||
}
|
||||
}
|
||||
if found == nil {
|
||||
log.Info("did not find time row", name)
|
||||
return false
|
||||
}
|
||||
for _, sf := range mt.timeFuncs {
|
||||
if sf.title != name {
|
||||
continue
|
||||
}
|
||||
// log.Info("updateTimeFunc() has row len =", len(mt.x.Books))
|
||||
// log.Info("virtpb: starting", name, found.Vals)
|
||||
for i, _ := range found.Vals {
|
||||
newt := sf.f(mt.x.Books[i])
|
||||
found.Vals[i] = timestamppb.New(newt) // convert to protobuf time
|
||||
}
|
||||
// log.Info("virtpb: ending", name, found.Vals)
|
||||
return true
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
func (mt *BooksTable) Delete() {
|
||||
if mt == nil {
|
||||
log.Info("mt == nil table already deleted")
|
||||
return
|
||||
}
|
||||
// log.Info("table Delete here")
|
||||
mt.parent.DeleteTable(mt.pb)
|
||||
}
|
||||
|
||||
func (mt *BooksTable) booksCustom(w *guipb.Widget) {
|
||||
row := mt.x.Books[w.Location.Y-1]
|
||||
// log.Info("got to booksCustom() with", w.Location.X, w.Location.Y-1)
|
||||
|
||||
for _, sf := range mt.buttonFuncs {
|
||||
if sf.order == int(w.Location.X) {
|
||||
// log.Info("found order", sf.order)
|
||||
if sf.Custom != nil {
|
||||
log.Info("doing Custom() func for button")
|
||||
sf.Custom(row)
|
||||
return
|
||||
}
|
||||
}
|
||||
}
|
||||
mt.CustomFunc(row)
|
||||
}
|
||||
|
||||
func (mt *BooksTable) Custom(f func(*Book)) {
|
||||
mt.pb.RegisterCustom(mt.booksCustom)
|
||||
mt.CustomFunc = f
|
||||
}
|
||||
|
||||
func (mt *BooksTable) GetUuid() string {
|
||||
return mt.pb.Uuid
|
||||
}
|
||||
|
||||
// END TABLE UPDATE
|
||||
|
||||
// END GUI
|
|
@ -0,0 +1,56 @@
|
|||
// Code generated by go.wit.com/apps/autogenpb DO NOT EDIT.
|
||||
// This file was autogenerated with autogenpb v0.0.79 2025-09-01_01:52:08_UTC
|
||||
// go install go.wit.com/apps/autogenpb@latest
|
||||
//
|
||||
// define which structs (messages) you want to use in the .proto file
|
||||
// Then sort.pb.go and marshal.pb.go files are autogenerated
|
||||
//
|
||||
// autogenpb uses it and has an example .proto file with instructions
|
||||
//
|
||||
|
||||
package chatpb
|
||||
|
||||
import (
|
||||
"google.golang.org/protobuf/encoding/protojson"
|
||||
"google.golang.org/protobuf/encoding/prototext"
|
||||
"google.golang.org/protobuf/proto"
|
||||
)
|
||||
|
||||
// human readable JSON
|
||||
func (v *Books) FormatJSON() string {
|
||||
return protojson.Format(v)
|
||||
}
|
||||
|
||||
// marshal json
|
||||
func (v *Books) MarshalJSON() ([]byte, error) {
|
||||
return protojson.Marshal(v)
|
||||
}
|
||||
|
||||
// unmarshal json
|
||||
func (v *Books) UnmarshalJSON(data []byte) error {
|
||||
return protojson.Unmarshal(data, v)
|
||||
}
|
||||
|
||||
// apparently this isn't stable, but it's awesomely better
|
||||
// https://protobuf.dev/reference/go/faq/#unstable-text
|
||||
// it's brilliant for config files!
|
||||
func (v *Books) FormatTEXT() string {
|
||||
v.fixUuid()
|
||||
return prototext.Format(v)
|
||||
}
|
||||
|
||||
// unmarshalTEXT. This reads the .text config file back in after the user edits it
|
||||
func (v *Books) UnmarshalTEXT(data []byte) error {
|
||||
return prototext.Unmarshal(data, v)
|
||||
}
|
||||
|
||||
// marshal to wire. This is called winning.
|
||||
func (v *Books) Marshal() ([]byte, error) {
|
||||
v.fixUuid()
|
||||
return proto.Marshal(v)
|
||||
}
|
||||
|
||||
// unmarshal from wire. You have won.
|
||||
func (v *Books) Unmarshal(data []byte) error {
|
||||
return proto.Unmarshal(data, v)
|
||||
}
|
|
@ -0,0 +1,355 @@
|
|||
// Code modified by go.wit.com/apps/autogenpb DO NOT EDIT.
|
||||
//
|
||||
// user defined Mutex locks were auto added
|
||||
//
|
||||
// autogenpb version & build time: v0.0.79 2025-09-01_01:52:08_UTC
|
||||
// autogenpb auto generates Sort(), Unique() and Marshal() functions
|
||||
// go install go.wit.com/apps/autogenpb@latest
|
||||
|
||||
// Code generated by protoc-gen-go. DO NOT EDIT.
|
||||
// versions:
|
||||
// protoc-gen-go v1.33.0
|
||||
// protoc v3.21.12
|
||||
// source: book.proto
|
||||
|
||||
package chatpb // autogenpb changed the package name
|
||||
|
||||
import (
|
||||
reflect "reflect"
|
||||
sync "sync"
|
||||
|
||||
protoreflect "google.golang.org/protobuf/reflect/protoreflect"
|
||||
protoimpl "google.golang.org/protobuf/runtime/protoimpl"
|
||||
_ "google.golang.org/protobuf/types/known/structpb"
|
||||
timestamppb "google.golang.org/protobuf/types/known/timestamppb"
|
||||
)
|
||||
|
||||
const (
|
||||
// Verify that this generated code is sufficiently up-to-date.
|
||||
_ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion)
|
||||
// Verify that runtime/protoimpl is sufficiently up-to-date.
|
||||
_ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20)
|
||||
)
|
||||
|
||||
type Book struct {
|
||||
sync.RWMutex // auto-added by go.wit.com/apps/autogenpb
|
||||
|
||||
state protoimpl.MessageState
|
||||
sizeCache protoimpl.SizeCache
|
||||
unknownFields protoimpl.UnknownFields
|
||||
|
||||
Uuid string `protobuf:"bytes,1,opt,name=uuid,proto3" json:"uuid,omitempty"` // `autogenpb:unique` `autogenpb:sort`
|
||||
Ctime *timestamppb.Timestamp `protobuf:"bytes,2,opt,name=ctime,proto3" json:"ctime,omitempty"`
|
||||
Title string `protobuf:"bytes,3,opt,name=Title,proto3" json:"Title,omitempty"`
|
||||
Version int32 `protobuf:"varint,4,opt,name=version,proto3" json:"version,omitempty"`
|
||||
From Who `protobuf:"varint,5,opt,name=from,proto3,enum=chatpb.Who" json:"from,omitempty"`
|
||||
Content string `protobuf:"bytes,6,opt,name=content,proto3" json:"content,omitempty"`
|
||||
Table *Table `protobuf:"bytes,7,opt,name=table,proto3" json:"table,omitempty"`
|
||||
GeminiRequest *GeminiRequest `protobuf:"bytes,8,opt,name=GeminiRequest,proto3" json:"GeminiRequest,omitempty"`
|
||||
}
|
||||
|
||||
func (x *Book) Reset() {
|
||||
*x = Book{}
|
||||
if protoimpl.UnsafeEnabled {
|
||||
mi := &file_book_proto_msgTypes[0]
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
}
|
||||
|
||||
func (x *Book) String() string {
|
||||
return protoimpl.X.MessageStringOf(x)
|
||||
}
|
||||
|
||||
func (*Book) ProtoMessage() {}
|
||||
|
||||
func (x *Book) ProtoReflect() protoreflect.Message {
|
||||
mi := &file_book_proto_msgTypes[0]
|
||||
if protoimpl.UnsafeEnabled && x != nil {
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
if ms.LoadMessageInfo() == nil {
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
return ms
|
||||
}
|
||||
return mi.MessageOf(x)
|
||||
}
|
||||
|
||||
// Deprecated: Use Book.ProtoReflect.Descriptor instead.
|
||||
func (*Book) Descriptor() ([]byte, []int) {
|
||||
return file_book_proto_rawDescGZIP(), []int{0}
|
||||
}
|
||||
|
||||
func (x *Book) GetUuid() string {
|
||||
if x != nil {
|
||||
return x.Uuid
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
func (x *Book) GetCtime() *timestamppb.Timestamp {
|
||||
if x != nil {
|
||||
return x.Ctime
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (x *Book) GetTitle() string {
|
||||
if x != nil {
|
||||
return x.Title
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
func (x *Book) GetVersion() int32 {
|
||||
if x != nil {
|
||||
return x.Version
|
||||
}
|
||||
return 0
|
||||
}
|
||||
|
||||
func (x *Book) GetFrom() Who {
|
||||
if x != nil {
|
||||
return x.From
|
||||
}
|
||||
return Who_NOONE
|
||||
}
|
||||
|
||||
func (x *Book) GetContent() string {
|
||||
if x != nil {
|
||||
return x.Content
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
func (x *Book) GetTable() *Table {
|
||||
if x != nil {
|
||||
return x.Table
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (x *Book) GetGeminiRequest() *GeminiRequest {
|
||||
if x != nil {
|
||||
return x.GeminiRequest
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
type Books struct {
|
||||
sync.RWMutex // auto-added by go.wit.com/apps/autogenpb
|
||||
|
||||
state protoimpl.MessageState
|
||||
sizeCache protoimpl.SizeCache
|
||||
unknownFields protoimpl.UnknownFields
|
||||
|
||||
Uuid string `protobuf:"bytes,1,opt,name=uuid,proto3" json:"uuid,omitempty"` // `autogenpb:uuid:8b6409ad-4498-43a6-b09a-7835c00dcb9a`
|
||||
Version string `protobuf:"bytes,2,opt,name=version,proto3" json:"version,omitempty"` // `autogenpb:version:v0.0.1`
|
||||
Books []*Book `protobuf:"bytes,3,rep,name=Books,proto3" json:"Books,omitempty"` // THIS MUST BE Chat and then Chats
|
||||
Ctime *timestamppb.Timestamp `protobuf:"bytes,4,opt,name=ctime,proto3" json:"ctime,omitempty"`
|
||||
Title string `protobuf:"bytes,5,opt,name=Title,proto3" json:"Title,omitempty"`
|
||||
TitleUuid string `protobuf:"bytes,6,opt,name=TitleUuid,proto3" json:"TitleUuid,omitempty"`
|
||||
}
|
||||
|
||||
func (x *Books) Reset() {
|
||||
*x = Books{}
|
||||
if protoimpl.UnsafeEnabled {
|
||||
mi := &file_book_proto_msgTypes[1]
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
}
|
||||
|
||||
func (x *Books) String() string {
|
||||
return protoimpl.X.MessageStringOf(x)
|
||||
}
|
||||
|
||||
func (*Books) ProtoMessage() {}
|
||||
|
||||
func (x *Books) ProtoReflect() protoreflect.Message {
|
||||
mi := &file_book_proto_msgTypes[1]
|
||||
if protoimpl.UnsafeEnabled && x != nil {
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
if ms.LoadMessageInfo() == nil {
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
return ms
|
||||
}
|
||||
return mi.MessageOf(x)
|
||||
}
|
||||
|
||||
// Deprecated: Use Books.ProtoReflect.Descriptor instead.
|
||||
func (*Books) Descriptor() ([]byte, []int) {
|
||||
return file_book_proto_rawDescGZIP(), []int{1}
|
||||
}
|
||||
|
||||
func (x *Books) GetUuid() string {
|
||||
if x != nil {
|
||||
return x.Uuid
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
func (x *Books) GetVersion() string {
|
||||
if x != nil {
|
||||
return x.Version
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
func (x *Books) GetBooks() []*Book {
|
||||
if x != nil {
|
||||
return x.Books
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (x *Books) GetCtime() *timestamppb.Timestamp {
|
||||
if x != nil {
|
||||
return x.Ctime
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (x *Books) GetTitle() string {
|
||||
if x != nil {
|
||||
return x.Title
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
func (x *Books) GetTitleUuid() string {
|
||||
if x != nil {
|
||||
return x.TitleUuid
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
var File_book_proto protoreflect.FileDescriptor
|
||||
|
||||
var file_book_proto_rawDesc = []byte{
|
||||
0x0a, 0x0a, 0x62, 0x6f, 0x6f, 0x6b, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x12, 0x06, 0x63, 0x68,
|
||||
0x61, 0x74, 0x70, 0x62, 0x1a, 0x1f, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2f, 0x70, 0x72, 0x6f,
|
||||
0x74, 0x6f, 0x62, 0x75, 0x66, 0x2f, 0x74, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x2e,
|
||||
0x70, 0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x1c, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2f, 0x70, 0x72,
|
||||
0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2f, 0x73, 0x74, 0x72, 0x75, 0x63, 0x74, 0x2e, 0x70, 0x72,
|
||||
0x6f, 0x74, 0x6f, 0x1a, 0x0a, 0x63, 0x68, 0x61, 0x74, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x22,
|
||||
0x99, 0x02, 0x0a, 0x04, 0x42, 0x6f, 0x6f, 0x6b, 0x12, 0x12, 0x0a, 0x04, 0x75, 0x75, 0x69, 0x64,
|
||||
0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x75, 0x75, 0x69, 0x64, 0x12, 0x30, 0x0a, 0x05,
|
||||
0x63, 0x74, 0x69, 0x6d, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x67, 0x6f,
|
||||
0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x54, 0x69,
|
||||
0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x52, 0x05, 0x63, 0x74, 0x69, 0x6d, 0x65, 0x12, 0x14,
|
||||
0x0a, 0x05, 0x54, 0x69, 0x74, 0x6c, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x54,
|
||||
0x69, 0x74, 0x6c, 0x65, 0x12, 0x18, 0x0a, 0x07, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x18,
|
||||
0x04, 0x20, 0x01, 0x28, 0x05, 0x52, 0x07, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x12, 0x1f,
|
||||
0x0a, 0x04, 0x66, 0x72, 0x6f, 0x6d, 0x18, 0x05, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x0b, 0x2e, 0x63,
|
||||
0x68, 0x61, 0x74, 0x70, 0x62, 0x2e, 0x57, 0x68, 0x6f, 0x52, 0x04, 0x66, 0x72, 0x6f, 0x6d, 0x12,
|
||||
0x18, 0x0a, 0x07, 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x18, 0x06, 0x20, 0x01, 0x28, 0x09,
|
||||
0x52, 0x07, 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x12, 0x23, 0x0a, 0x05, 0x74, 0x61, 0x62,
|
||||
0x6c, 0x65, 0x18, 0x07, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0d, 0x2e, 0x63, 0x68, 0x61, 0x74, 0x70,
|
||||
0x62, 0x2e, 0x54, 0x61, 0x62, 0x6c, 0x65, 0x52, 0x05, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x12, 0x3b,
|
||||
0x0a, 0x0d, 0x47, 0x65, 0x6d, 0x69, 0x6e, 0x69, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x18,
|
||||
0x08, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x15, 0x2e, 0x63, 0x68, 0x61, 0x74, 0x70, 0x62, 0x2e, 0x47,
|
||||
0x65, 0x6d, 0x69, 0x6e, 0x69, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x52, 0x0d, 0x47, 0x65,
|
||||
0x6d, 0x69, 0x6e, 0x69, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x22, 0xbf, 0x01, 0x0a, 0x05,
|
||||
0x42, 0x6f, 0x6f, 0x6b, 0x73, 0x12, 0x12, 0x0a, 0x04, 0x75, 0x75, 0x69, 0x64, 0x18, 0x01, 0x20,
|
||||
0x01, 0x28, 0x09, 0x52, 0x04, 0x75, 0x75, 0x69, 0x64, 0x12, 0x18, 0x0a, 0x07, 0x76, 0x65, 0x72,
|
||||
0x73, 0x69, 0x6f, 0x6e, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x76, 0x65, 0x72, 0x73,
|
||||
0x69, 0x6f, 0x6e, 0x12, 0x22, 0x0a, 0x05, 0x42, 0x6f, 0x6f, 0x6b, 0x73, 0x18, 0x03, 0x20, 0x03,
|
||||
0x28, 0x0b, 0x32, 0x0c, 0x2e, 0x63, 0x68, 0x61, 0x74, 0x70, 0x62, 0x2e, 0x42, 0x6f, 0x6f, 0x6b,
|
||||
0x52, 0x05, 0x42, 0x6f, 0x6f, 0x6b, 0x73, 0x12, 0x30, 0x0a, 0x05, 0x63, 0x74, 0x69, 0x6d, 0x65,
|
||||
0x18, 0x04, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e,
|
||||
0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61,
|
||||
0x6d, 0x70, 0x52, 0x05, 0x63, 0x74, 0x69, 0x6d, 0x65, 0x12, 0x14, 0x0a, 0x05, 0x54, 0x69, 0x74,
|
||||
0x6c, 0x65, 0x18, 0x05, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x54, 0x69, 0x74, 0x6c, 0x65, 0x12,
|
||||
0x1c, 0x0a, 0x09, 0x54, 0x69, 0x74, 0x6c, 0x65, 0x55, 0x75, 0x69, 0x64, 0x18, 0x06, 0x20, 0x01,
|
||||
0x28, 0x09, 0x52, 0x09, 0x54, 0x69, 0x74, 0x6c, 0x65, 0x55, 0x75, 0x69, 0x64, 0x62, 0x06, 0x70,
|
||||
0x72, 0x6f, 0x74, 0x6f, 0x33,
|
||||
}
|
||||
|
||||
var (
|
||||
file_book_proto_rawDescOnce sync.Once
|
||||
file_book_proto_rawDescData = file_book_proto_rawDesc
|
||||
)
|
||||
|
||||
func file_book_proto_rawDescGZIP() []byte {
|
||||
file_book_proto_rawDescOnce.Do(func() {
|
||||
file_book_proto_rawDescData = protoimpl.X.CompressGZIP(file_book_proto_rawDescData)
|
||||
})
|
||||
return file_book_proto_rawDescData
|
||||
}
|
||||
|
||||
var file_book_proto_msgTypes = make([]protoimpl.MessageInfo, 2)
|
||||
var file_book_proto_goTypes = []interface{}{
|
||||
(*Book)(nil), // 0: chatpb.Book
|
||||
(*Books)(nil), // 1: chatpb.Books
|
||||
(*timestamppb.Timestamp)(nil), // 2: google.protobuf.Timestamp
|
||||
(Who)(0), // 3: chatpb.Who
|
||||
(*Table)(nil), // 4: chatpb.Table
|
||||
(*GeminiRequest)(nil), // 5: chatpb.GeminiRequest
|
||||
}
|
||||
var file_book_proto_depIdxs = []int32{
|
||||
2, // 0: chatpb.Book.ctime:type_name -> google.protobuf.Timestamp
|
||||
3, // 1: chatpb.Book.from:type_name -> chatpb.Who
|
||||
4, // 2: chatpb.Book.table:type_name -> chatpb.Table
|
||||
5, // 3: chatpb.Book.GeminiRequest:type_name -> chatpb.GeminiRequest
|
||||
0, // 4: chatpb.Books.Books:type_name -> chatpb.Book
|
||||
2, // 5: chatpb.Books.ctime:type_name -> google.protobuf.Timestamp
|
||||
6, // [6:6] is the sub-list for method output_type
|
||||
6, // [6:6] is the sub-list for method input_type
|
||||
6, // [6:6] is the sub-list for extension type_name
|
||||
6, // [6:6] is the sub-list for extension extendee
|
||||
0, // [0:6] is the sub-list for field type_name
|
||||
}
|
||||
|
||||
func init() { file_book_proto_init() }
|
||||
func file_book_proto_init() {
|
||||
if File_book_proto != nil {
|
||||
return
|
||||
}
|
||||
file_chat_proto_init()
|
||||
if !protoimpl.UnsafeEnabled {
|
||||
file_book_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} {
|
||||
switch v := v.(*Book); i {
|
||||
case 0:
|
||||
return &v.state
|
||||
case 1:
|
||||
return &v.sizeCache
|
||||
case 2:
|
||||
return &v.unknownFields
|
||||
default:
|
||||
return nil
|
||||
}
|
||||
}
|
||||
file_book_proto_msgTypes[1].Exporter = func(v interface{}, i int) interface{} {
|
||||
switch v := v.(*Books); i {
|
||||
case 0:
|
||||
return &v.state
|
||||
case 1:
|
||||
return &v.sizeCache
|
||||
case 2:
|
||||
return &v.unknownFields
|
||||
default:
|
||||
return nil
|
||||
}
|
||||
}
|
||||
}
|
||||
type x struct{}
|
||||
out := protoimpl.TypeBuilder{
|
||||
File: protoimpl.DescBuilder{
|
||||
GoPackagePath: reflect.TypeOf(x{}).PkgPath(),
|
||||
RawDescriptor: file_book_proto_rawDesc,
|
||||
NumEnums: 0,
|
||||
NumMessages: 2,
|
||||
NumExtensions: 0,
|
||||
NumServices: 0,
|
||||
},
|
||||
GoTypes: file_book_proto_goTypes,
|
||||
DependencyIndexes: file_book_proto_depIdxs,
|
||||
MessageInfos: file_book_proto_msgTypes,
|
||||
}.Build()
|
||||
File_book_proto = out.File
|
||||
file_book_proto_rawDesc = nil
|
||||
file_book_proto_goTypes = nil
|
||||
file_book_proto_depIdxs = nil
|
||||
}
|
|
@ -0,0 +1,283 @@
|
|||
// Code generated by go.wit.com/apps/autogenpb DO NOT EDIT.
|
||||
// This file was autogenerated with autogenpb v0.0.79 2025-09-01_01:52:08_UTC
|
||||
// go install go.wit.com/apps/autogenpb@latest
|
||||
//
|
||||
// define which structs (messages) you want to use in the .proto file
|
||||
// Then sort.pb.go and marshal.pb.go files are autogenerated
|
||||
//
|
||||
// autogenpb uses it and has an example .proto file with instructions
|
||||
//
|
||||
|
||||
package chatpb
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"iter"
|
||||
"sort"
|
||||
"sync"
|
||||
|
||||
"google.golang.org/protobuf/proto"
|
||||
)
|
||||
|
||||
// a simple global lock
|
||||
var bookMu sync.RWMutex
|
||||
|
||||
func (x *Books) fixUuid() {
|
||||
if x == nil {
|
||||
return
|
||||
}
|
||||
if x.Uuid == "8b6409ad-4498-43a6-b09a-7835c00dcb9a" {
|
||||
return
|
||||
}
|
||||
x.Uuid = "8b6409ad-4498-43a6-b09a-7835c00dcb9a"
|
||||
x.Version = "v0.0.1 go.wit.com/lib/protobuf/chatpb"
|
||||
}
|
||||
|
||||
func NewBooks() *Books {
|
||||
x := new(Books)
|
||||
x.Uuid = "8b6409ad-4498-43a6-b09a-7835c00dcb9a"
|
||||
x.Version = "v0.0.1 go.wit.com/lib/protobuf/chatpb"
|
||||
return x
|
||||
}
|
||||
|
||||
// START SORT
|
||||
|
||||
// DEFINE THE Books SCANNER.
|
||||
// itializes a new scanner.
|
||||
func newBooksScanner(things []*Books) *BooksScanner {
|
||||
return &BooksScanner{things: things}
|
||||
}
|
||||
|
||||
type BooksScanner struct {
|
||||
sync.Mutex
|
||||
|
||||
things []*Books
|
||||
index int
|
||||
}
|
||||
|
||||
func (it *BooksScanner) Scan() bool {
|
||||
if it.index >= len(it.things) {
|
||||
return false
|
||||
}
|
||||
it.Lock()
|
||||
it.index++
|
||||
it.Unlock()
|
||||
return true
|
||||
}
|
||||
|
||||
// Next() returns the next thing in the array
|
||||
func (it *BooksScanner) Next() *Books {
|
||||
if it.things[it.index-1] == nil {
|
||||
fmt.Println("Next() error in BooksScanner", it.index)
|
||||
}
|
||||
return it.things[it.index-1]
|
||||
}
|
||||
|
||||
// END DEFINE THE SCANNER
|
||||
|
||||
// DEFINE THE Book SCANNER.
|
||||
// itializes a new scanner.
|
||||
func newBookScanner(things []*Book) *BookScanner {
|
||||
return &BookScanner{things: things}
|
||||
}
|
||||
|
||||
type BookScanner struct {
|
||||
sync.Mutex
|
||||
|
||||
things []*Book
|
||||
index int
|
||||
}
|
||||
|
||||
func (it *BookScanner) Scan() bool {
|
||||
if it.index >= len(it.things) {
|
||||
return false
|
||||
}
|
||||
it.Lock()
|
||||
it.index++
|
||||
it.Unlock()
|
||||
return true
|
||||
}
|
||||
|
||||
// Next() returns the next thing in the array
|
||||
func (it *BookScanner) Next() *Book {
|
||||
if it.things[it.index-1] == nil {
|
||||
fmt.Println("Next() error in BookScanner", it.index)
|
||||
}
|
||||
return it.things[it.index-1]
|
||||
}
|
||||
|
||||
// END DEFINE THE SCANNER
|
||||
|
||||
// sort struct by Uuid
|
||||
type sortBookUuid []*Book
|
||||
|
||||
func (a sortBookUuid) Len() int { return len(a) }
|
||||
func (a sortBookUuid) Less(i, j int) bool { return a[i].Uuid < a[j].Uuid }
|
||||
func (a sortBookUuid) Swap(i, j int) { a[i], a[j] = a[j], a[i] }
|
||||
|
||||
// safely returns a slice of pointers to the FRUIT protobufs
|
||||
func (x *Books) allBooks() []*Book {
|
||||
x.RLock()
|
||||
defer x.RUnlock()
|
||||
|
||||
// Create a new slice to hold pointers to each FRUIT
|
||||
var tmp []*Book
|
||||
tmp = make([]*Book, len(x.Books))
|
||||
for i, p := range x.Books {
|
||||
tmp[i] = p // Copy pointers for safe iteration
|
||||
}
|
||||
|
||||
return tmp
|
||||
}
|
||||
|
||||
// safely returns a slice of pointers to the Book protobufs
|
||||
func (x *Books) selectAllBooks() []*Book {
|
||||
x.RLock()
|
||||
defer x.RUnlock()
|
||||
|
||||
// Create a new slice to hold pointers to each Book
|
||||
var tmp []*Book
|
||||
tmp = make([]*Book, len(x.Books))
|
||||
for i, p := range x.Books {
|
||||
tmp[i] = p // Copy pointers for safe iteration
|
||||
}
|
||||
|
||||
return tmp
|
||||
}
|
||||
func (x *Books) SortByUuid() *BookScanner {
|
||||
// copy the pointers as fast as possible.
|
||||
things := x.selectAllBooks()
|
||||
|
||||
// todo: try slices.SortFunc() instead to see what happens
|
||||
sort.Sort(sortBookUuid(things))
|
||||
// slices.SortFunc(things, func(a, b *Books) bool {
|
||||
// return a.Uuid < b.Uuid // Sort by ??. let the compiler work it out??
|
||||
// })
|
||||
return newBookScanner(things)
|
||||
}
|
||||
|
||||
// 'for x := range' syntax using the awesome golang 1.24 'iter'
|
||||
func (x *Books) IterByUuid() iter.Seq[*Book] {
|
||||
items := x.selectAllBooks()
|
||||
sort.Sort(sortBookUuid(items))
|
||||
// log.Println("Made Iter.Seq[] with length", len(items))
|
||||
return func(yield func(*Book) bool) {
|
||||
for _, v := range items {
|
||||
if !yield(v) {
|
||||
return
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// END SORT
|
||||
|
||||
func (x *Books) Len() int {
|
||||
x.RLock()
|
||||
defer x.RUnlock()
|
||||
|
||||
return len(x.Books)
|
||||
}
|
||||
|
||||
// a Append() shortcut (that does Clone() with a mutex) notsure if it really works
|
||||
func (x *Books) Append(y *Book) {
|
||||
x.Lock()
|
||||
defer x.Unlock()
|
||||
|
||||
x.Books = append(x.Books, proto.Clone(y).(*Book))
|
||||
}
|
||||
|
||||
func (x *Books) All() *BookScanner {
|
||||
BookPointers := x.selectAllBooks()
|
||||
|
||||
scanner := newBookScanner(BookPointers)
|
||||
return scanner
|
||||
}
|
||||
|
||||
// Iterate 'for x := range' syntax using the awesome golang 1.24 'iter'
|
||||
func (x *Books) IterAll() iter.Seq[*Book] {
|
||||
items := x.selectAllBooks()
|
||||
// log.Println("Made All() Iter.Seq[] with length", len(items))
|
||||
return func(yield func(*Book) bool) {
|
||||
for _, v := range items {
|
||||
if !yield(v) {
|
||||
return
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
func (x *Books) Delete(y *Book) bool {
|
||||
x.Lock()
|
||||
defer x.Unlock()
|
||||
|
||||
for i, _ := range x.Books {
|
||||
if x.Books[i] == y {
|
||||
x.Books[i] = x.Books[len(x.Books)-1]
|
||||
x.Books = x.Books[:len(x.Books)-1]
|
||||
return true
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
// lookup a Books by the Uuid
|
||||
func (x *Books) FindByUuid(s string) *Book {
|
||||
if x == nil {
|
||||
return nil
|
||||
}
|
||||
|
||||
x.RLock()
|
||||
defer x.RUnlock()
|
||||
|
||||
for i, _ := range x.Books {
|
||||
if x.Books[i].Uuid == s {
|
||||
return x.Books[i]
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// returns a Book if Uuid matches, otherwise create
|
||||
func (x *Books) InsertByUuid(y string) *Book {
|
||||
x.Lock()
|
||||
defer x.Unlock()
|
||||
|
||||
for _, z := range x.Books {
|
||||
if z.Uuid == y {
|
||||
return z
|
||||
}
|
||||
}
|
||||
|
||||
z := new(Book)
|
||||
z.Uuid = y
|
||||
x.Books = append(x.Books, z)
|
||||
return z
|
||||
}
|
||||
|
||||
func (x *Books) DeleteByUuid(s string) bool {
|
||||
x.Lock()
|
||||
defer x.Unlock()
|
||||
|
||||
for i, _ := range x.Books {
|
||||
if x.Books[i].Uuid == s {
|
||||
x.Books[i] = x.Books[len(x.Books)-1]
|
||||
x.Books = x.Books[:len(x.Books)-1]
|
||||
return true
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
func (x *Books) AppendByUuid(y *Book) bool {
|
||||
x.Lock()
|
||||
defer x.Unlock()
|
||||
|
||||
for _, p := range x.Books {
|
||||
if p.Uuid == y.Uuid {
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
||||
x.Books = append(x.Books, proto.Clone(y).(*Book))
|
||||
return true
|
||||
}
|
|
@ -0,0 +1,387 @@
|
|||
// Code generated by go.wit.com/apps/autogenpb DO NOT EDIT.
|
||||
// This file was autogenerated with autogenpb v0.0.79 2025-09-01_01:52:08_UTC
|
||||
// go install go.wit.com/apps/autogenpb@latest
|
||||
//
|
||||
// define which structs (messages) you want to use in the .proto file
|
||||
// Then sort.pb.go and marshal.pb.go files are autogenerated
|
||||
//
|
||||
// autogenpb uses it and has an example .proto file with instructions
|
||||
//
|
||||
|
||||
package chatpb
|
||||
|
||||
import (
|
||||
"time"
|
||||
|
||||
"github.com/google/uuid"
|
||||
"go.wit.com/gui"
|
||||
"go.wit.com/lib/protobuf/guipb"
|
||||
"go.wit.com/log"
|
||||
timestamppb "google.golang.org/protobuf/types/known/timestamppb"
|
||||
)
|
||||
|
||||
// START GUI
|
||||
|
||||
func (x *Chats) NewTable(title string) *ChatsTable {
|
||||
t := new(ChatsTable)
|
||||
t.x = x
|
||||
pb := new(guipb.Table)
|
||||
pb.Title = title
|
||||
t.pb = pb
|
||||
return t
|
||||
}
|
||||
|
||||
func (t *ChatsTable) AddStringFunc(title string, f func(*Chat) string) *ChatStringFunc {
|
||||
t.pb.Order = append(t.pb.Order, title)
|
||||
|
||||
sf := new(ChatStringFunc)
|
||||
sf.title = title
|
||||
sf.f = f
|
||||
sf.order = t.order
|
||||
t.order += 1
|
||||
t.stringFuncs = append(t.stringFuncs, sf)
|
||||
return sf
|
||||
}
|
||||
|
||||
func (t *ChatsTable) AddButtonFunc(title string, f func(*Chat) string) *ChatButtonFunc {
|
||||
t.pb.Order = append(t.pb.Order, title)
|
||||
|
||||
sf := new(ChatButtonFunc)
|
||||
sf.title = title
|
||||
sf.f = f
|
||||
sf.order = t.order
|
||||
t.order += 1
|
||||
t.buttonFuncs = append(t.buttonFuncs, sf)
|
||||
return sf
|
||||
}
|
||||
|
||||
func (t *ChatsTable) AddIntFunc(title string, f func(*Chat) int) *ChatIntFunc {
|
||||
t.pb.Order = append(t.pb.Order, title)
|
||||
|
||||
sf := new(ChatIntFunc)
|
||||
sf.title = title
|
||||
sf.f = f
|
||||
sf.order = t.order
|
||||
t.order += 1
|
||||
t.intFuncs = append(t.intFuncs, sf)
|
||||
return sf
|
||||
}
|
||||
|
||||
func (t *ChatsTable) AddTimeFunc(title string, f func(*Chat) time.Time) *ChatTimeFunc {
|
||||
t.pb.Order = append(t.pb.Order, title)
|
||||
|
||||
sf := new(ChatTimeFunc)
|
||||
sf.title = title
|
||||
sf.f = f
|
||||
sf.order = t.order
|
||||
t.order += 1
|
||||
t.timeFuncs = append(t.timeFuncs, sf)
|
||||
return sf
|
||||
}
|
||||
|
||||
func (sf *ChatStringFunc) SetTitle(title string) {
|
||||
sf.title = title
|
||||
}
|
||||
func (sf *ChatIntFunc) SetTitle(title string) {
|
||||
sf.title = title
|
||||
}
|
||||
func (sf *ChatTimeFunc) SetTitle(title string) {
|
||||
sf.title = title
|
||||
}
|
||||
|
||||
func (mt *ChatsTable) SetParent(p *gui.Node) {
|
||||
mt.parent = p
|
||||
}
|
||||
|
||||
func (mt *ChatsTable) ShowTable() {
|
||||
// log.Info("ShowTable() SENDING TO GUI")
|
||||
mt.MakeTable()
|
||||
mt.parent.ShowTable(mt.pb)
|
||||
}
|
||||
|
||||
type ChatStringFunc struct {
|
||||
title string
|
||||
f func(*Chat) string
|
||||
Custom func(*Chat)
|
||||
order int
|
||||
}
|
||||
|
||||
type ChatButtonFunc struct {
|
||||
title string
|
||||
f func(*Chat) string
|
||||
Custom func(*Chat)
|
||||
order int
|
||||
}
|
||||
|
||||
type ChatIntFunc struct {
|
||||
title string
|
||||
f func(*Chat) int
|
||||
Custom func(*Chat)
|
||||
order int
|
||||
}
|
||||
|
||||
type ChatTimeFunc struct {
|
||||
title string
|
||||
f func(*Chat) time.Time
|
||||
Custom func(*Chat)
|
||||
order int
|
||||
}
|
||||
|
||||
type ChatsTable struct {
|
||||
pb *guipb.Table
|
||||
parent *gui.Node
|
||||
x *Chats
|
||||
hostnames []string
|
||||
stringFuncs []*ChatStringFunc
|
||||
intFuncs []*ChatIntFunc
|
||||
timeFuncs []*ChatTimeFunc
|
||||
buttonFuncs []*ChatButtonFunc
|
||||
CustomFunc func(*Chat)
|
||||
order int
|
||||
}
|
||||
|
||||
func (mt *ChatsTable) doStringFunc(name string) bool {
|
||||
for _, sf := range mt.stringFuncs {
|
||||
if sf.title != name {
|
||||
continue
|
||||
}
|
||||
// log.Info("chatpb: found stringfunc name:", name)
|
||||
r := new(guipb.StringRow)
|
||||
r.Header = new(guipb.Widget)
|
||||
r.Header.Name = name
|
||||
for m := range mt.x.IterAll() {
|
||||
r.Vals = append(r.Vals, sf.f(m))
|
||||
// log.Info("chatpb: adding", name, r.Vals)
|
||||
}
|
||||
mt.pb.StringRows = append(mt.pb.StringRows, r)
|
||||
return true
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
func (mt *ChatsTable) doButtonFunc(name string) bool {
|
||||
for _, sf := range mt.buttonFuncs {
|
||||
if sf.title != name {
|
||||
continue
|
||||
}
|
||||
// log.Info("chatpb: found stringfunc name:", name)
|
||||
r := new(guipb.ButtonRow)
|
||||
r.Header = new(guipb.Widget)
|
||||
r.Header.Name = name
|
||||
for m := range mt.x.IterAll() {
|
||||
r.Vals = append(r.Vals, sf.f(m))
|
||||
// log.Info("chatpb: adding", name, r.Vals)
|
||||
}
|
||||
mt.pb.ButtonRows = append(mt.pb.ButtonRows, r)
|
||||
return true
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
func (mt *ChatsTable) doIntFunc(name string) bool {
|
||||
for _, sf := range mt.intFuncs {
|
||||
if sf.title != name {
|
||||
continue
|
||||
}
|
||||
// log.Info("chatpb: found intfunc name:", name)
|
||||
r := new(guipb.IntRow)
|
||||
r.Header = new(guipb.Widget)
|
||||
r.Header.Name = name
|
||||
for m := range mt.x.IterAll() {
|
||||
r.Vals = append(r.Vals, int64(sf.f(m)))
|
||||
// log.Info("chatpb: adding", name, r.Vals)
|
||||
}
|
||||
mt.pb.IntRows = append(mt.pb.IntRows, r)
|
||||
return true
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
func (mt *ChatsTable) doTimeFunc(name string) bool {
|
||||
for _, sf := range mt.timeFuncs {
|
||||
if sf.title != name {
|
||||
continue
|
||||
}
|
||||
// log.Info("chatpb: found timefunc name:", name)
|
||||
r := new(guipb.TimeRow)
|
||||
r.Header = new(guipb.Widget)
|
||||
r.Header.Name = name
|
||||
for m := range mt.x.IterAll() {
|
||||
t := sf.f(m)
|
||||
r.Vals = append(r.Vals, timestamppb.New(t)) // convert to protobuf time
|
||||
// log.Info("chatpb: adding", name, r.Vals)
|
||||
}
|
||||
mt.pb.TimeRows = append(mt.pb.TimeRows, r)
|
||||
return true
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
func (mt *ChatsTable) MakeTable() {
|
||||
for _, name := range mt.pb.Order {
|
||||
// log.Info("chatpb: looking for row name()", name)
|
||||
if mt.doStringFunc(name) {
|
||||
continue
|
||||
}
|
||||
if mt.doIntFunc(name) {
|
||||
continue
|
||||
}
|
||||
if mt.doTimeFunc(name) {
|
||||
continue
|
||||
}
|
||||
if mt.doButtonFunc(name) {
|
||||
continue
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func (t *ChatsTable) AddUuid() *ChatStringFunc {
|
||||
sf := t.AddStringFunc("Uuid", func(m *Chat) string {
|
||||
return m.Uuid
|
||||
})
|
||||
return sf
|
||||
}
|
||||
|
||||
func (t *ChatsTable) AddChatName() *ChatStringFunc {
|
||||
sf := t.AddStringFunc("ChatName", func(m *Chat) string {
|
||||
return m.ChatName
|
||||
})
|
||||
return sf
|
||||
}
|
||||
func (mt *ChatsTable) NewUuid() {
|
||||
mt.pb.Uuid = uuid.New().String()
|
||||
}
|
||||
|
||||
// START TABLE UPDATE
|
||||
func (mt *ChatsTable) todoUpdate() {
|
||||
for _, name := range mt.pb.Order {
|
||||
// log.Info("Chatpb: trying to update row()", name)
|
||||
if mt.updateStringFunc(name) {
|
||||
continue
|
||||
}
|
||||
if mt.updateTimeFunc(name) {
|
||||
continue
|
||||
}
|
||||
/*
|
||||
if mt.updateIntFunc(name) {
|
||||
continue
|
||||
}
|
||||
*/
|
||||
}
|
||||
// mt.dumpStringFunc("Hostname")
|
||||
mt.parent.UpdateTable(mt.pb)
|
||||
}
|
||||
|
||||
func (mt *ChatsTable) dumpStringFunc(name string) {
|
||||
for i, r := range mt.pb.StringRows {
|
||||
// log.Info("could use", i, r.Header.Name, "for name =", name)
|
||||
if r.Header.Name == name {
|
||||
log.Info("dump Strings row", i, r.Header.Name, r.Vals)
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func (mt *ChatsTable) updateStringFunc(name string) bool {
|
||||
// log.Info("LOOKING FOR STRING row", name)
|
||||
var found *guipb.StringRow
|
||||
for _, r := range mt.pb.StringRows {
|
||||
// log.Info("could use", i, r.Header.Name, "for name =", name)
|
||||
if r.Header.Name == name {
|
||||
// log.Info("found row", i, r.Header.Name)
|
||||
found = r
|
||||
break
|
||||
}
|
||||
}
|
||||
if found == nil {
|
||||
log.Info("did not find string row", name)
|
||||
return false
|
||||
}
|
||||
for _, sf := range mt.stringFuncs {
|
||||
if sf.title != name {
|
||||
continue
|
||||
}
|
||||
// log.Info("Chatpb: starting", name, found.Vals)
|
||||
for i, _ := range found.Vals {
|
||||
tmp := sf.f(mt.x.Chats[i])
|
||||
if tmp == "www.wit.com" {
|
||||
log.Info("virtpb: FOUND WWW", i)
|
||||
tmp = "new.www"
|
||||
}
|
||||
found.Vals[i] = tmp
|
||||
}
|
||||
// log.Info("Chatpb: ending", name, found.Vals)
|
||||
return true
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
func (mt *ChatsTable) updateTimeFunc(name string) bool {
|
||||
log.Info("LOOKING FOR TIME row", name)
|
||||
var found *guipb.TimeRow
|
||||
for i, r := range mt.pb.TimeRows {
|
||||
// log.Info("could use", i, r.Header.Name, "for name =", name)
|
||||
if r.Header.Name == name {
|
||||
log.Info("found row", i, r.Header.Name)
|
||||
found = r
|
||||
break
|
||||
}
|
||||
}
|
||||
if found == nil {
|
||||
log.Info("did not find time row", name)
|
||||
return false
|
||||
}
|
||||
for _, sf := range mt.timeFuncs {
|
||||
if sf.title != name {
|
||||
continue
|
||||
}
|
||||
// log.Info("updateTimeFunc() has row len =", len(mt.x.Chats))
|
||||
// log.Info("virtpb: starting", name, found.Vals)
|
||||
for i, _ := range found.Vals {
|
||||
newt := sf.f(mt.x.Chats[i])
|
||||
found.Vals[i] = timestamppb.New(newt) // convert to protobuf time
|
||||
}
|
||||
// log.Info("virtpb: ending", name, found.Vals)
|
||||
return true
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
func (mt *ChatsTable) Delete() {
|
||||
if mt == nil {
|
||||
log.Info("mt == nil table already deleted")
|
||||
return
|
||||
}
|
||||
// log.Info("table Delete here")
|
||||
mt.parent.DeleteTable(mt.pb)
|
||||
}
|
||||
|
||||
func (mt *ChatsTable) chatsCustom(w *guipb.Widget) {
|
||||
row := mt.x.Chats[w.Location.Y-1]
|
||||
// log.Info("got to chatsCustom() with", w.Location.X, w.Location.Y-1)
|
||||
|
||||
for _, sf := range mt.buttonFuncs {
|
||||
if sf.order == int(w.Location.X) {
|
||||
// log.Info("found order", sf.order)
|
||||
if sf.Custom != nil {
|
||||
log.Info("doing Custom() func for button")
|
||||
sf.Custom(row)
|
||||
return
|
||||
}
|
||||
}
|
||||
}
|
||||
mt.CustomFunc(row)
|
||||
}
|
||||
|
||||
func (mt *ChatsTable) Custom(f func(*Chat)) {
|
||||
mt.pb.RegisterCustom(mt.chatsCustom)
|
||||
mt.CustomFunc = f
|
||||
}
|
||||
|
||||
func (mt *ChatsTable) GetUuid() string {
|
||||
return mt.pb.Uuid
|
||||
}
|
||||
|
||||
// END TABLE UPDATE
|
||||
|
||||
// END GUI
|
|
@ -0,0 +1,130 @@
|
|||
// Code generated by go.wit.com/apps/autogenpb DO NOT EDIT.
|
||||
// This file was autogenerated with autogenpb v0.0.79 2025-09-01_01:52:08_UTC
|
||||
// go install go.wit.com/apps/autogenpb@latest
|
||||
//
|
||||
// define which structs (messages) you want to use in the .proto file
|
||||
// Then sort.pb.go and marshal.pb.go files are autogenerated
|
||||
//
|
||||
// autogenpb uses it and has an example .proto file with instructions
|
||||
//
|
||||
|
||||
package chatpb
|
||||
|
||||
import (
|
||||
"google.golang.org/protobuf/encoding/protojson"
|
||||
"google.golang.org/protobuf/encoding/prototext"
|
||||
"google.golang.org/protobuf/proto"
|
||||
)
|
||||
|
||||
// human readable JSON
|
||||
func (v *Chats) FormatJSON() string {
|
||||
return protojson.Format(v)
|
||||
}
|
||||
|
||||
// marshal json
|
||||
func (v *Chats) MarshalJSON() ([]byte, error) {
|
||||
return protojson.Marshal(v)
|
||||
}
|
||||
|
||||
// unmarshal json
|
||||
func (v *Chats) UnmarshalJSON(data []byte) error {
|
||||
return protojson.Unmarshal(data, v)
|
||||
}
|
||||
|
||||
// apparently this isn't stable, but it's awesomely better
|
||||
// https://protobuf.dev/reference/go/faq/#unstable-text
|
||||
// it's brilliant for config files!
|
||||
func (v *Chats) FormatTEXT() string {
|
||||
v.fixUuid()
|
||||
return prototext.Format(v)
|
||||
}
|
||||
|
||||
// unmarshalTEXT. This reads the .text config file back in after the user edits it
|
||||
func (v *Chats) UnmarshalTEXT(data []byte) error {
|
||||
return prototext.Unmarshal(data, v)
|
||||
}
|
||||
|
||||
// marshal to wire. This is called winning.
|
||||
func (v *Chats) Marshal() ([]byte, error) {
|
||||
v.fixUuid()
|
||||
return proto.Marshal(v)
|
||||
}
|
||||
|
||||
// unmarshal from wire. You have won.
|
||||
func (v *Chats) Unmarshal(data []byte) error {
|
||||
return proto.Unmarshal(data, v)
|
||||
}
|
||||
|
||||
// human readable JSON
|
||||
func (v *GeminiRequest) FormatJSON() string {
|
||||
return protojson.Format(v)
|
||||
}
|
||||
|
||||
// marshal json
|
||||
func (v *GeminiRequest) MarshalJSON() ([]byte, error) {
|
||||
return protojson.Marshal(v)
|
||||
}
|
||||
|
||||
// unmarshal json
|
||||
func (v *GeminiRequest) UnmarshalJSON(data []byte) error {
|
||||
return protojson.Unmarshal(data, v)
|
||||
}
|
||||
|
||||
// apparently this isn't stable, but it's awesomely better
|
||||
// https://protobuf.dev/reference/go/faq/#unstable-text
|
||||
// it's brilliant for config files!
|
||||
func (v *GeminiRequest) FormatTEXT() string {
|
||||
return prototext.Format(v)
|
||||
}
|
||||
|
||||
// unmarshalTEXT. This reads the .text config file back in after the user edits it
|
||||
func (v *GeminiRequest) UnmarshalTEXT(data []byte) error {
|
||||
return prototext.Unmarshal(data, v)
|
||||
}
|
||||
|
||||
// marshal to wire. This is called winning.
|
||||
func (v *GeminiRequest) Marshal() ([]byte, error) {
|
||||
return proto.Marshal(v)
|
||||
}
|
||||
|
||||
// unmarshal from wire. You have won.
|
||||
func (v *GeminiRequest) Unmarshal(data []byte) error {
|
||||
return proto.Unmarshal(data, v)
|
||||
}
|
||||
|
||||
// human readable JSON
|
||||
func (v *ChatEntry) FormatJSON() string {
|
||||
return protojson.Format(v)
|
||||
}
|
||||
|
||||
// marshal json
|
||||
func (v *ChatEntry) MarshalJSON() ([]byte, error) {
|
||||
return protojson.Marshal(v)
|
||||
}
|
||||
|
||||
// unmarshal json
|
||||
func (v *ChatEntry) UnmarshalJSON(data []byte) error {
|
||||
return protojson.Unmarshal(data, v)
|
||||
}
|
||||
|
||||
// apparently this isn't stable, but it's awesomely better
|
||||
// https://protobuf.dev/reference/go/faq/#unstable-text
|
||||
// it's brilliant for config files!
|
||||
func (v *ChatEntry) FormatTEXT() string {
|
||||
return prototext.Format(v)
|
||||
}
|
||||
|
||||
// unmarshalTEXT. This reads the .text config file back in after the user edits it
|
||||
func (v *ChatEntry) UnmarshalTEXT(data []byte) error {
|
||||
return prototext.Unmarshal(data, v)
|
||||
}
|
||||
|
||||
// marshal to wire. This is called winning.
|
||||
func (v *ChatEntry) Marshal() ([]byte, error) {
|
||||
return proto.Marshal(v)
|
||||
}
|
||||
|
||||
// unmarshal from wire. You have won.
|
||||
func (v *ChatEntry) Unmarshal(data []byte) error {
|
||||
return proto.Unmarshal(data, v)
|
||||
}
|
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,22 @@
|
|||
module go.wit.com/lib/protobuf/chatpb
|
||||
|
||||
go 1.24.1
|
||||
|
||||
require (
|
||||
github.com/google/uuid v1.6.0
|
||||
go.wit.com/gui v0.25.1
|
||||
go.wit.com/lib/cobol v0.0.4
|
||||
go.wit.com/lib/gui/shell v0.22.32
|
||||
go.wit.com/lib/protobuf/bugpb v0.0.5
|
||||
go.wit.com/lib/protobuf/guipb v0.0.13
|
||||
go.wit.com/log v0.22.18
|
||||
google.golang.org/protobuf v1.36.9
|
||||
)
|
||||
|
||||
require (
|
||||
github.com/go-cmd/cmd v1.4.3 // indirect
|
||||
go.wit.com/widget v1.1.30 // indirect
|
||||
golang.org/x/sys v0.35.0 // indirect
|
||||
golang.org/x/term v0.34.0 // indirect
|
||||
golang.org/x/text v0.26.0 // indirect
|
||||
)
|
|
@ -0,0 +1,32 @@
|
|||
github.com/go-cmd/cmd v1.4.3 h1:6y3G+3UqPerXvPcXvj+5QNPHT02BUw7p6PsqRxLNA7Y=
|
||||
github.com/go-cmd/cmd v1.4.3/go.mod h1:u3hxg/ry+D5kwh8WvUkHLAMe2zQCaXd00t35WfQaOFk=
|
||||
github.com/go-test/deep v1.1.0 h1:WOcxcdHcvdgThNXjw0t76K42FXTU7HpNQWHpA2HHNlg=
|
||||
github.com/go-test/deep v1.1.0/go.mod h1:5C2ZWiW0ErCdrYzpqxLbTX7MG14M9iiw8DgHncVwcsE=
|
||||
github.com/google/go-cmp v0.5.5 h1:Khx7svrCpmxxtHBq5j2mp/xVjsi8hQMfNLvJFAlrGgU=
|
||||
github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
|
||||
github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0=
|
||||
github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
|
||||
go.wit.com/gui v0.25.1 h1:zwPXkHgITaFXkWey/BZh2jY+/6A+lttZq4K/uBK3X3g=
|
||||
go.wit.com/gui v0.25.1/go.mod h1:LHbRB8G4IFxcDWK3K6aklVWcgRg2OUG/Vyxrpw4/+w4=
|
||||
go.wit.com/lib/cobol v0.0.4 h1:iLNXtmMEs9v6aShWGDQBNlcrKJNYGBFeWMhRWlEnWUk=
|
||||
go.wit.com/lib/cobol v0.0.4/go.mod h1:defmzUYkoI/YF7Gbr+kn1vcwIzvnphKN7OXJLaRx8dc=
|
||||
go.wit.com/lib/gui/shell v0.22.32 h1:TXyB6INM3XdAW2DbXsdEAjWWqiKwM+LwOh9oWxKv7NE=
|
||||
go.wit.com/lib/gui/shell v0.22.32/go.mod h1:psAaUebukAkyG2HQb9GITc18CZ8WME/ShPi5JuaUuaY=
|
||||
go.wit.com/lib/protobuf/bugpb v0.0.5 h1:o09DPLf4GwbU99vy8oVPdv2BNyEdRsy0wnFUnXiO8L0=
|
||||
go.wit.com/lib/protobuf/bugpb v0.0.5/go.mod h1:FkkeImmqh67mOnz8MHM6Ohs6km9T8Vr4mdgztCypsSk=
|
||||
go.wit.com/lib/protobuf/guipb v0.0.13 h1:OWTVXU5IIUMVieM9j2Uojyv8cV4ePRrvGmV8CbVSRtE=
|
||||
go.wit.com/lib/protobuf/guipb v0.0.13/go.mod h1:RXKFw3HD9t/qBlXFslrwzUgoqQCJ9ryPTAvSVHvDdjI=
|
||||
go.wit.com/log v0.22.18 h1:wlpNjxrFBCcHrZxVURR6QE/9vrVOVDEWgoupS76YQns=
|
||||
go.wit.com/log v0.22.18/go.mod h1:XE4lTfAibWgwBJksIk7u3IEJ8xcBvNhnlewYAQGj2Ew=
|
||||
go.wit.com/widget v1.1.30 h1:O/dIG7QtDrZkR5P6f8JAMyevBiMXSun9vL6F0KFAWV8=
|
||||
go.wit.com/widget v1.1.30/go.mod h1:wj7TpAr2gk7Poa+v8XQkH1aidnTdgAa/a8GxrMtcztw=
|
||||
golang.org/x/sys v0.35.0 h1:vz1N37gP5bs89s7He8XuIYXpyY0+QlsKmzipCbUtyxI=
|
||||
golang.org/x/sys v0.35.0/go.mod h1:BJP2sWEmIv4KK5OTEluFJCKSidICx8ciO85XgH3Ak8k=
|
||||
golang.org/x/term v0.34.0 h1:O/2T7POpk0ZZ7MAzMeWFSg6S5IpWd/RXDlM9hgM3DR4=
|
||||
golang.org/x/term v0.34.0/go.mod h1:5jC53AEywhIVebHgPVeg0mj8OD3VO9OzclacVrqpaAw=
|
||||
golang.org/x/text v0.26.0 h1:P42AVeLghgTYr4+xUnTRKDMqpar+PtX7KWuNQL21L8M=
|
||||
golang.org/x/text v0.26.0/go.mod h1:QK15LZJUUQVJxhz7wXgxSy/CJaTFjd0G+YLonydOVQA=
|
||||
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543 h1:E7g+9GITq07hpfrRu66IVDexMakfv52eLZ2CXBWiKr4=
|
||||
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||
google.golang.org/protobuf v1.36.9 h1:w2gp2mA27hUeUzj9Ex9FBjsBm40zfaDtEWow293U7Iw=
|
||||
google.golang.org/protobuf v1.36.9/go.mod h1:fuxRtAxBytpl4zzqUh6/eyUujkJdNiuEkXntxiD/uRU=
|
Loading…
Reference in New Issue