forge config

This commit is contained in:
Jeff Carr 2025-09-12 16:10:00 -05:00
parent 60ef1deb90
commit c94db3c331
10 changed files with 6027 additions and 0 deletions

394
book.gui.pb.go Normal file
View File

@ -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

56
book.marshal.pb.go Normal file
View File

@ -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)
}

355
book.pb.go Normal file
View File

@ -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
}

283
book.sort.pb.go Normal file
View File

@ -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
}

387
chat.gui.pb.go Normal file
View File

@ -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

130
chat.marshal.pb.go Normal file
View File

@ -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)
}

2927
chat.pb.go Normal file

File diff suppressed because it is too large Load Diff

1441
chat.sort.pb.go Normal file

File diff suppressed because it is too large Load Diff

22
go.mod Normal file
View File

@ -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.2
go.wit.com/lib/cobol v0.0.6
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.14
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
)

32
go.sum Normal file
View File

@ -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.2 h1:Efs6sduON1a7I2MmV3QiPNGclHqOOCisNqbnbjQ/OpY=
go.wit.com/gui v0.25.2/go.mod h1:jjAQ/g3QRZjZVQMrdvNYSbFGXdXmWJ1zKaMDoj/MZBI=
go.wit.com/lib/cobol v0.0.6 h1:gx3mWLlQ4pFe5LvuUdH+X65+pFRx8CoOi5lDSenQ1wk=
go.wit.com/lib/cobol v0.0.6/go.mod h1:Ixiq/nzGWx1xbDy9Lmg3nhwC1+Pia+61TosyVIgyOnU=
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.14 h1:K/SrSG6oCgem2UMrn3YeOGv2EPPZxKlk9wMNniFkGyQ=
go.wit.com/lib/protobuf/guipb v0.0.14/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=