autocomplete
This commit is contained in:
parent
60ef1deb90
commit
eeff97eaf3
|
@ -0,0 +1,257 @@
|
||||||
|
// Code generated by go.wit.com/apps/autogenpb DO NOT EDIT.
|
||||||
|
// This file was autogenerated with autogenpb v0.5.3-12-g0ccf2c0 2025-09-18_03:38:50_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"
|
||||||
|
"google.golang.org/protobuf/proto"
|
||||||
|
anypb "google.golang.org/protobuf/types/known/anypb"
|
||||||
|
timestamppb "google.golang.org/protobuf/types/known/timestamppb"
|
||||||
|
"google.golang.org/protobuf/types/known/wrapperspb"
|
||||||
|
)
|
||||||
|
|
||||||
|
// 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
|
||||||
|
}
|
||||||
|
|
||||||
|
// force the application to choose the type of data. this allows the GUI plugin to be smarter
|
||||||
|
func (t *BooksTable) AddStringFunc(title string, f func(*Book) string) *BookAnyFunc {
|
||||||
|
t.pb.Order = append(t.pb.Order, title)
|
||||||
|
|
||||||
|
sf := new(BookAnyFunc)
|
||||||
|
sf.title = title
|
||||||
|
sf.f = func(x *Book) any {
|
||||||
|
return f(x)
|
||||||
|
}
|
||||||
|
sf.attr = new(guipb.ColAttr)
|
||||||
|
sf.attr.Width = int32(sf.Width)
|
||||||
|
sf.attr.Type = guipb.ColAttr_STRING
|
||||||
|
|
||||||
|
t.anyFuncs = append(t.anyFuncs, sf)
|
||||||
|
return sf
|
||||||
|
}
|
||||||
|
|
||||||
|
// force the application to choose the type of data. this allows the GUI plugin to be smarter
|
||||||
|
func (t *BooksTable) AddButtonFunc(title string, f func(*Book) string) *BookAnyFunc {
|
||||||
|
t.pb.Order = append(t.pb.Order, title)
|
||||||
|
|
||||||
|
sf := new(BookAnyFunc)
|
||||||
|
sf.title = title
|
||||||
|
sf.f = func(x *Book) any {
|
||||||
|
return f(x)
|
||||||
|
}
|
||||||
|
sf.attr = new(guipb.ColAttr)
|
||||||
|
sf.attr.Width = int32(sf.Width)
|
||||||
|
sf.attr.Type = guipb.ColAttr_STRING
|
||||||
|
sf.attr.Click = true
|
||||||
|
|
||||||
|
t.anyFuncs = append(t.anyFuncs, sf)
|
||||||
|
return sf
|
||||||
|
}
|
||||||
|
|
||||||
|
// force the application to choose the type of data. this allows the GUI plugin to be smarter
|
||||||
|
func (t *BooksTable) AddIntFunc(title string, f func(*Book) int) *BookAnyFunc {
|
||||||
|
t.pb.Order = append(t.pb.Order, title)
|
||||||
|
|
||||||
|
sf := new(BookAnyFunc)
|
||||||
|
sf.title = title
|
||||||
|
sf.f = func(x *Book) any {
|
||||||
|
return f(x)
|
||||||
|
}
|
||||||
|
sf.attr = new(guipb.ColAttr)
|
||||||
|
sf.attr.Width = int32(sf.Width)
|
||||||
|
sf.attr.Type = guipb.ColAttr_INT
|
||||||
|
|
||||||
|
t.anyFuncs = append(t.anyFuncs, sf)
|
||||||
|
return sf
|
||||||
|
}
|
||||||
|
|
||||||
|
// force the application to choose the type of data. this allows the GUI plugin to be smarter
|
||||||
|
func (t *BooksTable) AddTimeFunc(title string, f func(*Book) time.Time) *BookAnyFunc {
|
||||||
|
t.pb.Order = append(t.pb.Order, title)
|
||||||
|
|
||||||
|
sf := new(BookAnyFunc)
|
||||||
|
sf.title = title
|
||||||
|
sf.f = func(x *Book) any {
|
||||||
|
return f(x)
|
||||||
|
}
|
||||||
|
sf.attr = new(guipb.ColAttr)
|
||||||
|
sf.attr.Width = int32(sf.Width)
|
||||||
|
sf.attr.Type = guipb.ColAttr_TIME
|
||||||
|
|
||||||
|
// t.timeFuncs = append(t.timeFuncs, sf)
|
||||||
|
t.anyFuncs = append(t.anyFuncs, sf)
|
||||||
|
return sf
|
||||||
|
}
|
||||||
|
|
||||||
|
func (sf *BookAnyFunc) 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 BookAnyFunc struct {
|
||||||
|
title string
|
||||||
|
f func(*Book) any
|
||||||
|
Custom func(*Book)
|
||||||
|
Width int
|
||||||
|
attr *guipb.ColAttr
|
||||||
|
}
|
||||||
|
|
||||||
|
type BooksTable struct {
|
||||||
|
pb *guipb.Table
|
||||||
|
parent *gui.Node
|
||||||
|
x *Books
|
||||||
|
hostnames []string
|
||||||
|
anyFuncs []*BookAnyFunc
|
||||||
|
CustomFunc func(*Book)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (mt *BooksTable) doAnyFuncNew(sf *BookAnyFunc) bool {
|
||||||
|
r := new(guipb.AnyCol)
|
||||||
|
r.Header = new(guipb.Widget)
|
||||||
|
r.Header.Name = sf.title
|
||||||
|
r.Attr = proto.Clone(sf.attr).(*guipb.ColAttr)
|
||||||
|
|
||||||
|
for m := range mt.x.IterAll() {
|
||||||
|
t := sf.f(m)
|
||||||
|
switch r.Attr.Type {
|
||||||
|
case guipb.ColAttr_STRING:
|
||||||
|
// anyProto, err := anypb.New(tsProto)
|
||||||
|
stringValue := wrapperspb.String(t.(string))
|
||||||
|
anyProto, err := anypb.New(stringValue)
|
||||||
|
_ = err // do something with err someday (?)
|
||||||
|
r.Vals = append(r.Vals, anyProto)
|
||||||
|
// return col.Vals[row] true
|
||||||
|
case guipb.ColAttr_INT:
|
||||||
|
var finalInt int
|
||||||
|
finalInt = t.(int)
|
||||||
|
intVal := wrapperspb.Int32(int32(finalInt))
|
||||||
|
anyProto, _ := anypb.New(intVal)
|
||||||
|
r.Vals = append(r.Vals, anyProto)
|
||||||
|
case guipb.ColAttr_DURATION:
|
||||||
|
case guipb.ColAttr_TIME:
|
||||||
|
var goTime time.Time
|
||||||
|
goTime = t.(time.Time)
|
||||||
|
tsProto := timestamppb.New(goTime)
|
||||||
|
anyProto, err := anypb.New(tsProto)
|
||||||
|
_ = err // do something with err someday (?)
|
||||||
|
r.Vals = append(r.Vals, anyProto)
|
||||||
|
default:
|
||||||
|
log.Info("cell unhandled type", r.Attr.Type)
|
||||||
|
}
|
||||||
|
// cellTime := r.Vals[row]
|
||||||
|
// s := shell.FormatDuration(time.Since(cellTime.AsTime()))
|
||||||
|
}
|
||||||
|
|
||||||
|
mt.pb.AnyCols = append(mt.pb.AnyCols, r)
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
|
func (mt *BooksTable) MakeTable() {
|
||||||
|
for _, sf := range mt.anyFuncs {
|
||||||
|
mt.doAnyFuncNew(sf)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (t *BooksTable) AddUuid() *BookAnyFunc {
|
||||||
|
sf := t.AddStringFunc("Uuid", func(m *Book) string {
|
||||||
|
return m.Uuid
|
||||||
|
})
|
||||||
|
return sf
|
||||||
|
}
|
||||||
|
|
||||||
|
func (t *BooksTable) AddTitle() *BookAnyFunc {
|
||||||
|
sf := t.AddStringFunc("Title", func(m *Book) string {
|
||||||
|
return m.Title
|
||||||
|
})
|
||||||
|
return sf
|
||||||
|
}
|
||||||
|
|
||||||
|
func (t *BooksTable) AddContent() *BookAnyFunc {
|
||||||
|
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 (doesn't work yet)
|
||||||
|
|
||||||
|
func (mt *BooksTable) dumpStringFunc(name string) {
|
||||||
|
for i, r := range mt.pb.StringCols {
|
||||||
|
// 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) 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 i, sf := range mt.anyFuncs {
|
||||||
|
if i == int(w.Location.X) {
|
||||||
|
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.5.3-12-g0ccf2c0 2025-09-18_03:38:50_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.5.3-12-g0ccf2c0 2025-09-18_03:38:50_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,286 @@
|
||||||
|
// Code generated by go.wit.com/apps/autogenpb DO NOT EDIT.
|
||||||
|
// This file was autogenerated with autogenpb v0.5.3-12-g0ccf2c0 2025-09-18_03:38:50_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) *Book {
|
||||||
|
x.Lock()
|
||||||
|
defer x.Unlock()
|
||||||
|
|
||||||
|
z := proto.Clone(y).(*Book)
|
||||||
|
x.Books = append(x.Books, z)
|
||||||
|
|
||||||
|
return z
|
||||||
|
}
|
||||||
|
|
||||||
|
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,250 @@
|
||||||
|
// Code generated by go.wit.com/apps/autogenpb DO NOT EDIT.
|
||||||
|
// This file was autogenerated with autogenpb v0.5.3-12-g0ccf2c0 2025-09-18_03:38:50_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"
|
||||||
|
"google.golang.org/protobuf/proto"
|
||||||
|
anypb "google.golang.org/protobuf/types/known/anypb"
|
||||||
|
timestamppb "google.golang.org/protobuf/types/known/timestamppb"
|
||||||
|
"google.golang.org/protobuf/types/known/wrapperspb"
|
||||||
|
)
|
||||||
|
|
||||||
|
// 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
|
||||||
|
}
|
||||||
|
|
||||||
|
// force the application to choose the type of data. this allows the GUI plugin to be smarter
|
||||||
|
func (t *ChatsTable) AddStringFunc(title string, f func(*Chat) string) *ChatAnyFunc {
|
||||||
|
t.pb.Order = append(t.pb.Order, title)
|
||||||
|
|
||||||
|
sf := new(ChatAnyFunc)
|
||||||
|
sf.title = title
|
||||||
|
sf.f = func(x *Chat) any {
|
||||||
|
return f(x)
|
||||||
|
}
|
||||||
|
sf.attr = new(guipb.ColAttr)
|
||||||
|
sf.attr.Width = int32(sf.Width)
|
||||||
|
sf.attr.Type = guipb.ColAttr_STRING
|
||||||
|
|
||||||
|
t.anyFuncs = append(t.anyFuncs, sf)
|
||||||
|
return sf
|
||||||
|
}
|
||||||
|
|
||||||
|
// force the application to choose the type of data. this allows the GUI plugin to be smarter
|
||||||
|
func (t *ChatsTable) AddButtonFunc(title string, f func(*Chat) string) *ChatAnyFunc {
|
||||||
|
t.pb.Order = append(t.pb.Order, title)
|
||||||
|
|
||||||
|
sf := new(ChatAnyFunc)
|
||||||
|
sf.title = title
|
||||||
|
sf.f = func(x *Chat) any {
|
||||||
|
return f(x)
|
||||||
|
}
|
||||||
|
sf.attr = new(guipb.ColAttr)
|
||||||
|
sf.attr.Width = int32(sf.Width)
|
||||||
|
sf.attr.Type = guipb.ColAttr_STRING
|
||||||
|
sf.attr.Click = true
|
||||||
|
|
||||||
|
t.anyFuncs = append(t.anyFuncs, sf)
|
||||||
|
return sf
|
||||||
|
}
|
||||||
|
|
||||||
|
// force the application to choose the type of data. this allows the GUI plugin to be smarter
|
||||||
|
func (t *ChatsTable) AddIntFunc(title string, f func(*Chat) int) *ChatAnyFunc {
|
||||||
|
t.pb.Order = append(t.pb.Order, title)
|
||||||
|
|
||||||
|
sf := new(ChatAnyFunc)
|
||||||
|
sf.title = title
|
||||||
|
sf.f = func(x *Chat) any {
|
||||||
|
return f(x)
|
||||||
|
}
|
||||||
|
sf.attr = new(guipb.ColAttr)
|
||||||
|
sf.attr.Width = int32(sf.Width)
|
||||||
|
sf.attr.Type = guipb.ColAttr_INT
|
||||||
|
|
||||||
|
t.anyFuncs = append(t.anyFuncs, sf)
|
||||||
|
return sf
|
||||||
|
}
|
||||||
|
|
||||||
|
// force the application to choose the type of data. this allows the GUI plugin to be smarter
|
||||||
|
func (t *ChatsTable) AddTimeFunc(title string, f func(*Chat) time.Time) *ChatAnyFunc {
|
||||||
|
t.pb.Order = append(t.pb.Order, title)
|
||||||
|
|
||||||
|
sf := new(ChatAnyFunc)
|
||||||
|
sf.title = title
|
||||||
|
sf.f = func(x *Chat) any {
|
||||||
|
return f(x)
|
||||||
|
}
|
||||||
|
sf.attr = new(guipb.ColAttr)
|
||||||
|
sf.attr.Width = int32(sf.Width)
|
||||||
|
sf.attr.Type = guipb.ColAttr_TIME
|
||||||
|
|
||||||
|
// t.timeFuncs = append(t.timeFuncs, sf)
|
||||||
|
t.anyFuncs = append(t.anyFuncs, sf)
|
||||||
|
return sf
|
||||||
|
}
|
||||||
|
|
||||||
|
func (sf *ChatAnyFunc) 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 ChatAnyFunc struct {
|
||||||
|
title string
|
||||||
|
f func(*Chat) any
|
||||||
|
Custom func(*Chat)
|
||||||
|
Width int
|
||||||
|
attr *guipb.ColAttr
|
||||||
|
}
|
||||||
|
|
||||||
|
type ChatsTable struct {
|
||||||
|
pb *guipb.Table
|
||||||
|
parent *gui.Node
|
||||||
|
x *Chats
|
||||||
|
hostnames []string
|
||||||
|
anyFuncs []*ChatAnyFunc
|
||||||
|
CustomFunc func(*Chat)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (mt *ChatsTable) doAnyFuncNew(sf *ChatAnyFunc) bool {
|
||||||
|
r := new(guipb.AnyCol)
|
||||||
|
r.Header = new(guipb.Widget)
|
||||||
|
r.Header.Name = sf.title
|
||||||
|
r.Attr = proto.Clone(sf.attr).(*guipb.ColAttr)
|
||||||
|
|
||||||
|
for m := range mt.x.IterAll() {
|
||||||
|
t := sf.f(m)
|
||||||
|
switch r.Attr.Type {
|
||||||
|
case guipb.ColAttr_STRING:
|
||||||
|
// anyProto, err := anypb.New(tsProto)
|
||||||
|
stringValue := wrapperspb.String(t.(string))
|
||||||
|
anyProto, err := anypb.New(stringValue)
|
||||||
|
_ = err // do something with err someday (?)
|
||||||
|
r.Vals = append(r.Vals, anyProto)
|
||||||
|
// return col.Vals[row] true
|
||||||
|
case guipb.ColAttr_INT:
|
||||||
|
var finalInt int
|
||||||
|
finalInt = t.(int)
|
||||||
|
intVal := wrapperspb.Int32(int32(finalInt))
|
||||||
|
anyProto, _ := anypb.New(intVal)
|
||||||
|
r.Vals = append(r.Vals, anyProto)
|
||||||
|
case guipb.ColAttr_DURATION:
|
||||||
|
case guipb.ColAttr_TIME:
|
||||||
|
var goTime time.Time
|
||||||
|
goTime = t.(time.Time)
|
||||||
|
tsProto := timestamppb.New(goTime)
|
||||||
|
anyProto, err := anypb.New(tsProto)
|
||||||
|
_ = err // do something with err someday (?)
|
||||||
|
r.Vals = append(r.Vals, anyProto)
|
||||||
|
default:
|
||||||
|
log.Info("cell unhandled type", r.Attr.Type)
|
||||||
|
}
|
||||||
|
// cellTime := r.Vals[row]
|
||||||
|
// s := shell.FormatDuration(time.Since(cellTime.AsTime()))
|
||||||
|
}
|
||||||
|
|
||||||
|
mt.pb.AnyCols = append(mt.pb.AnyCols, r)
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
|
func (mt *ChatsTable) MakeTable() {
|
||||||
|
for _, sf := range mt.anyFuncs {
|
||||||
|
mt.doAnyFuncNew(sf)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (t *ChatsTable) AddUuid() *ChatAnyFunc {
|
||||||
|
sf := t.AddStringFunc("Uuid", func(m *Chat) string {
|
||||||
|
return m.Uuid
|
||||||
|
})
|
||||||
|
return sf
|
||||||
|
}
|
||||||
|
|
||||||
|
func (t *ChatsTable) AddChatName() *ChatAnyFunc {
|
||||||
|
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 (doesn't work yet)
|
||||||
|
|
||||||
|
func (mt *ChatsTable) dumpStringFunc(name string) {
|
||||||
|
for i, r := range mt.pb.StringCols {
|
||||||
|
// 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) 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 i, sf := range mt.anyFuncs {
|
||||||
|
if i == int(w.Location.X) {
|
||||||
|
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.5.3-12-g0ccf2c0 2025-09-18_03:38:50_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.3
|
||||||
|
go.wit.com/lib/cobol v0.0.7
|
||||||
|
go.wit.com/lib/gui/shell v0.22.33
|
||||||
|
go.wit.com/lib/protobuf/bugpb v0.0.6
|
||||||
|
go.wit.com/lib/protobuf/guipb v0.0.15
|
||||||
|
go.wit.com/log v0.25.1
|
||||||
|
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.36.0 // indirect
|
||||||
|
golang.org/x/term v0.35.0 // indirect
|
||||||
|
golang.org/x/text v0.29.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.3 h1:kDUzh/z52ghRlp/urVFCrDEIlkrfsKRmObN3LjbwsBU=
|
||||||
|
go.wit.com/gui v0.25.3/go.mod h1:H02phAerHwzSZMAb9mhL8rr7/zCbjASU8Cmg97tNvxY=
|
||||||
|
go.wit.com/lib/cobol v0.0.7 h1:VCU6cq0gBskkJop7IUhu9DddlCV5tYgRELp44vF+osw=
|
||||||
|
go.wit.com/lib/cobol v0.0.7/go.mod h1:F0bGWpoHVTOPUIq3bshRq/2/ViRGMnWDP3iwQIgeu/o=
|
||||||
|
go.wit.com/lib/gui/shell v0.22.33 h1:3MvWBQU4rOHK4Ac5MkQ62ndW7WhCBpu9F3AVeUF7YgQ=
|
||||||
|
go.wit.com/lib/gui/shell v0.22.33/go.mod h1:aRDwKXKXkZaO4y/0KPe1lhKQCXpyi8hXgUEOrHhzpAI=
|
||||||
|
go.wit.com/lib/protobuf/bugpb v0.0.6 h1:IJNEPHphShQujSl7fP7sh5rQyCLxB5Uk/uoGzMx+/Z8=
|
||||||
|
go.wit.com/lib/protobuf/bugpb v0.0.6/go.mod h1:CIMtL7AS0Gx8K9ChgL80Omk25WWIFTG2stt1BzclySw=
|
||||||
|
go.wit.com/lib/protobuf/guipb v0.0.15 h1:0MJ9FNFuUuNS8AsK+UcgGGnb3Xlw+ve7AbWLnHyIJ08=
|
||||||
|
go.wit.com/lib/protobuf/guipb v0.0.15/go.mod h1:9AzFoNKnE0161IOTfdul6SX5+GPAFNW7RPKWohenmcQ=
|
||||||
|
go.wit.com/log v0.25.1 h1:74WVf9NSN6z5jc2oSbA1ehxdZ7V/NBXTk5t0jIoaTMg=
|
||||||
|
go.wit.com/log v0.25.1/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.36.0 h1:KVRy2GtZBrk1cBYA7MKu5bEZFxQk4NIDV6RLVcC8o0k=
|
||||||
|
golang.org/x/sys v0.36.0/go.mod h1:OgkHotnGiDImocRcuBABYBEXf8A9a87e/uXjp9XT3ks=
|
||||||
|
golang.org/x/term v0.35.0 h1:bZBVKBudEyhRcajGcNc3jIfWPqV4y/Kt2XcoigOWtDQ=
|
||||||
|
golang.org/x/term v0.35.0/go.mod h1:TPGtkTLesOwf2DE8CgVYiZinHAOuy5AYUYT1lENIZnA=
|
||||||
|
golang.org/x/text v0.29.0 h1:1neNs90w9YzJ9BocxfsQNHKuAT4pkghyXc4nhZ6sJvk=
|
||||||
|
golang.org/x/text v0.29.0/go.mod h1:7MhJOA9CD2qZyOKYazxdYMF85OwPdEr9jTtBpO7ydH4=
|
||||||
|
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