chore: add protobuf
This commit is contained in:
310
twt-pb/helper.go
Normal file
310
twt-pb/helper.go
Normal file
@@ -0,0 +1,310 @@
|
||||
package twt_pb
|
||||
|
||||
import (
|
||||
"io"
|
||||
"iter"
|
||||
"slices"
|
||||
"time"
|
||||
|
||||
"go.yarn.social/lextwt"
|
||||
"go.yarn.social/types"
|
||||
"google.golang.org/protobuf/proto"
|
||||
)
|
||||
|
||||
type twtRegistry interface {
|
||||
Twters() []*types.Twter
|
||||
Preamble() lextwt.Comments
|
||||
Twts() types.Twts
|
||||
WriteTo(w io.Writer) (int64, error)
|
||||
}
|
||||
|
||||
func EncodeRegistry(r twtRegistry) ([]byte, error) {
|
||||
o := &TwtRegistry{}
|
||||
o.FromLextwt(r)
|
||||
|
||||
return proto.Marshal(o)
|
||||
}
|
||||
func DecodeRegistry(b []byte) (twtRegistry, error) {
|
||||
o := &TwtRegistry{}
|
||||
err := proto.Unmarshal(b, o)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return o.ToLextwt(), nil
|
||||
}
|
||||
|
||||
func (r *TwtRegistry) FromLextwt(twt twtRegistry) error {
|
||||
twters := twt.Twters()
|
||||
r.Twters = apply(
|
||||
slices.All(twters),
|
||||
make([]*Twter, len(twters)),
|
||||
fromTwter)
|
||||
|
||||
preamble := twt.Preamble()
|
||||
r.Preamble = apply(
|
||||
slices.All(preamble),
|
||||
make([]*Comment, len(preamble)),
|
||||
fromComment)
|
||||
|
||||
twts := twt.Twts()
|
||||
r.Twts = apply(
|
||||
slices.All(twts),
|
||||
make([]*Twt, len(twts)),
|
||||
fromTwt)
|
||||
|
||||
return nil
|
||||
}
|
||||
func (r *TwtRegistry) ToLextwt() twtRegistry {
|
||||
return lextwt.NewTwtRegistry(
|
||||
apply(slices.All(r.Twters), make([]*types.Twter, len(r.Twters)), func(c *Twter) *types.Twter {
|
||||
return c.ToLextwt()
|
||||
}),
|
||||
apply(slices.All(r.Preamble), make(lextwt.Comments, len(r.Preamble)), func(c *Comment) *lextwt.Comment {
|
||||
return c.ToLextwt()
|
||||
}),
|
||||
apply(slices.All(r.Twts), make(types.Twts, len(r.Twts)), func(c *Twt) types.Twt {
|
||||
return c.ToLextwt()
|
||||
}),
|
||||
)
|
||||
}
|
||||
|
||||
func apply[U, V any](u iter.Seq2[int, U], v []V, fn func(U) V) []V {
|
||||
for i, u := range u {
|
||||
v[i] = fn(u)
|
||||
}
|
||||
return v
|
||||
|
||||
}
|
||||
|
||||
func (e *Twter) FromLextwt(twt *types.Twter) {
|
||||
e.Nick = twt.Nick
|
||||
e.Uri = twt.URI
|
||||
}
|
||||
func fromTwter(twt *types.Twter) *Twter {
|
||||
return &Twter{
|
||||
Nick: twt.Nick,
|
||||
Uri: twt.URI,
|
||||
}
|
||||
}
|
||||
func (e *Twter) ToLextwt() *types.Twter {
|
||||
return &types.Twter{
|
||||
Nick: e.Nick,
|
||||
URI: e.Uri,
|
||||
}
|
||||
}
|
||||
|
||||
func (e *Twt) FromLextwt(twt *lextwt.Twt) {
|
||||
twter := twt.Twter()
|
||||
|
||||
e.Twter.FromLextwt(&twter)
|
||||
e.Created = fromDateTime(twt.Created())
|
||||
e.Msg = apply(
|
||||
slices.All(twt.Elems()),
|
||||
make([]*Elem, len(twt.Elems())),
|
||||
fromElem,
|
||||
)
|
||||
}
|
||||
func fromTwt(twt types.Twt) *Twt {
|
||||
twter := twt.Twter()
|
||||
lx, ok := twt.(*lextwt.Twt)
|
||||
if !ok {
|
||||
return &Twt{}
|
||||
}
|
||||
|
||||
msg := lx.Elems()
|
||||
return &Twt{
|
||||
Twter: fromTwter(&twter),
|
||||
Created: fromDateTime(twt.Created()),
|
||||
Msg: apply(
|
||||
slices.All(msg),
|
||||
make([]*Elem, len(msg)),
|
||||
fromElem,
|
||||
),
|
||||
}
|
||||
}
|
||||
func (e *Twt) ToLextwt() *lextwt.Twt {
|
||||
return lextwt.NewTwt(
|
||||
*e.Twter.ToLextwt(),
|
||||
e.Created.ToLextwt(),
|
||||
apply(
|
||||
slices.All(e.Msg),
|
||||
make([]lextwt.Elem, len(e.Msg)),
|
||||
func(e *Elem) lextwt.Elem {
|
||||
return e.ToLextwt()
|
||||
},
|
||||
)...,
|
||||
)
|
||||
}
|
||||
|
||||
func fromDateTime(t time.Time) *DateTime {
|
||||
zone, offset := t.Zone()
|
||||
return &DateTime{
|
||||
Timestamp: t.UnixMicro(),
|
||||
Offset: int32(offset),
|
||||
Zone: zone,
|
||||
}
|
||||
}
|
||||
func (c *DateTime) ToLextwt() *lextwt.DateTime {
|
||||
dt := time.UnixMicro(c.Timestamp)
|
||||
dt = dt.In(time.FixedZone(c.Zone, int(c.Offset)))
|
||||
return lextwt.NewDateTime(dt, dt.Format(time.RFC3339))
|
||||
}
|
||||
|
||||
func fromElem(e lextwt.Elem) *Elem {
|
||||
if e == lextwt.LineSeparator {
|
||||
return &Elem{Elem: &Elem_Lineseparator{fromLineSeparator()}}
|
||||
}
|
||||
|
||||
switch e := e.(type) {
|
||||
case *lextwt.BangMention:
|
||||
return &Elem{Elem: &Elem_Bangmention{fromBangMention(e)}}
|
||||
|
||||
case *lextwt.Code:
|
||||
return &Elem{Elem: &Elem_Code{fromCode(e)}}
|
||||
|
||||
case *lextwt.Comment:
|
||||
return &Elem{Elem: &Elem_Comment{fromComment(e)}}
|
||||
|
||||
case *lextwt.Mention:
|
||||
return &Elem{Elem: &Elem_Mention{fromMention(e)}}
|
||||
|
||||
case *lextwt.Subject:
|
||||
return &Elem{Elem: &Elem_Subject{fromSubject(e)}}
|
||||
|
||||
case *lextwt.Tag:
|
||||
return &Elem{Elem: &Elem_Tag{fromTag(e)}}
|
||||
|
||||
case *lextwt.Link:
|
||||
return &Elem{Elem: &Elem_Link{fromLink(e)}}
|
||||
|
||||
case *lextwt.Text:
|
||||
return &Elem{Elem: &Elem_Text{fromText(e)}}
|
||||
}
|
||||
|
||||
return &Elem{}
|
||||
}
|
||||
func (c *Elem) ToLextwt() lextwt.Elem {
|
||||
switch e := c.Elem.(type) {
|
||||
case *Elem_Bangmention:
|
||||
return e.Bangmention.ToLextwt()
|
||||
case *Elem_Code:
|
||||
return e.Code.ToLextwt()
|
||||
case *Elem_Comment:
|
||||
return e.Comment.ToLextwt()
|
||||
case *Elem_Lineseparator:
|
||||
return e.Lineseparator.ToLextwt()
|
||||
case *Elem_Link:
|
||||
return e.Link.ToLextwt()
|
||||
case *Elem_Mention:
|
||||
return e.Mention.ToLextwt()
|
||||
case *Elem_Subject:
|
||||
return e.Subject.ToLextwt()
|
||||
case *Elem_Tag:
|
||||
return e.Tag.ToLextwt()
|
||||
case *Elem_Text:
|
||||
return e.Text.ToLextwt()
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func fromCode(c *lextwt.Code) *Code {
|
||||
return &Code{
|
||||
Type: Code_Type(c.CodeType()),
|
||||
Code: c.Text(),
|
||||
}
|
||||
}
|
||||
func (c *Code) ToLextwt() *lextwt.Code {
|
||||
return lextwt.NewCode(c.Code, lextwt.CodeType(c.Type))
|
||||
}
|
||||
|
||||
func fromComment(c *lextwt.Comment) *Comment {
|
||||
return &Comment{
|
||||
Comment: c.Text(),
|
||||
Key: c.Key(),
|
||||
Value: c.Value(),
|
||||
}
|
||||
}
|
||||
func (c *Comment) ToLextwt() *lextwt.Comment {
|
||||
if c.Key != "" {
|
||||
return lextwt.NewCommentValue(c.Comment, c.Key, c.Value)
|
||||
}
|
||||
return lextwt.NewComment(c.Comment)
|
||||
}
|
||||
|
||||
func fromBangMention(c *lextwt.BangMention) *BangMention {
|
||||
return &BangMention{
|
||||
Name: c.Name(),
|
||||
Target: c.Target(),
|
||||
}
|
||||
}
|
||||
func (c *BangMention) ToLextwt() *lextwt.BangMention {
|
||||
return lextwt.NewBangMention(c.Name, c.Target)
|
||||
}
|
||||
|
||||
func fromMention(c *lextwt.Mention) *Mention {
|
||||
return &Mention{
|
||||
Name: c.Name(),
|
||||
Target: c.Target(),
|
||||
}
|
||||
}
|
||||
func (c *Mention) ToLextwt() *lextwt.Mention {
|
||||
return lextwt.NewMention(c.Name, c.Target)
|
||||
}
|
||||
|
||||
func fromTag(c *lextwt.Tag) *Tag {
|
||||
return &Tag{
|
||||
Tag: c.Text(),
|
||||
Target: c.Target(),
|
||||
}
|
||||
}
|
||||
func (c *Tag) ToLextwt() *lextwt.Tag {
|
||||
return lextwt.NewTag(c.Tag, c.Target)
|
||||
}
|
||||
|
||||
func fromLineSeparator() *LineSeparator {
|
||||
return &LineSeparator{}
|
||||
}
|
||||
func (c *LineSeparator) ToLextwt() lextwt.Elem {
|
||||
return lextwt.LineSeparator
|
||||
}
|
||||
|
||||
func fromLink(c *lextwt.Link) *Link {
|
||||
return &Link{
|
||||
Type: Link_Type(c.LinkType()),
|
||||
Alt: c.Text(),
|
||||
Target: c.Target(),
|
||||
Title: c.Title(),
|
||||
}
|
||||
}
|
||||
func (c *Link) ToLextwt() *lextwt.Link {
|
||||
if c.Type == Link_Type(lextwt.LinkMedia) {
|
||||
return lextwt.NewMedia(c.Alt, c.Target, c.Title)
|
||||
}
|
||||
return lextwt.NewLink(c.Alt, c.Target, lextwt.LinkType(c.Type))
|
||||
}
|
||||
|
||||
func fromSubject(c *lextwt.Subject) *Subject {
|
||||
if tag, ok := c.Tag().(*lextwt.Tag); ok {
|
||||
return &Subject{
|
||||
Tag: fromTag(tag),
|
||||
}
|
||||
}
|
||||
return &Subject{
|
||||
Subject: c.Text(),
|
||||
}
|
||||
}
|
||||
func (c *Subject) ToLextwt() *lextwt.Subject {
|
||||
if c.Tag != nil {
|
||||
return lextwt.NewSubjectTag(c.Tag.Tag, c.Tag.Target)
|
||||
}
|
||||
return lextwt.NewSubject(c.Subject)
|
||||
}
|
||||
|
||||
func fromText(c *lextwt.Text) *Text {
|
||||
return &Text{
|
||||
Text: c.Literal(),
|
||||
}
|
||||
}
|
||||
func (c *Text) ToLextwt() *lextwt.Text {
|
||||
return lextwt.NewText(c.Text)
|
||||
}
|
||||
2
twt-pb/helper_test.go
Normal file
2
twt-pb/helper_test.go
Normal file
@@ -0,0 +1,2 @@
|
||||
package twt_pb_test
|
||||
|
||||
1252
twt-pb/lextwt.pb.go
Normal file
1252
twt-pb/lextwt.pb.go
Normal file
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user