7a04f298d2
- update to latest telegram layer - remove some references to fields in tg.Entities that don't exist in the schema - originally added here: https://github.com/beeper/td/commit/820929062a2ba0104397bc01235ab58a9cff780e - referenced here - https://github.com/mautrix/telegramgo/commit/124f0967ed195b5a380c9bd02e170ada9710dde3 - https://github.com/mautrix/telegramgo/commit/4205047aab2e0639217148b5d125bfaab668bd8e
131 lines
2.7 KiB
Go
131 lines
2.7 KiB
Go
package main
|
|
|
|
import (
|
|
"encoding/json"
|
|
"fmt"
|
|
"io"
|
|
|
|
"github.com/go-faster/errors"
|
|
"github.com/k0kubun/pp/v3"
|
|
|
|
"go.mau.fi/mautrix-telegram/pkg/gotd/bin"
|
|
"go.mau.fi/mautrix-telegram/pkg/gotd/mt"
|
|
"go.mau.fi/mautrix-telegram/pkg/gotd/proto/codec"
|
|
"go.mau.fi/mautrix-telegram/pkg/gotd/tdp"
|
|
"go.mau.fi/mautrix-telegram/pkg/gotd/tg"
|
|
"go.mau.fi/mautrix-telegram/pkg/gotd/tmap"
|
|
"go.mau.fi/mautrix-telegram/pkg/gotd/transport"
|
|
)
|
|
|
|
// Object is abstraction for TL schema object.
|
|
type Object interface {
|
|
bin.Object
|
|
tdp.Object
|
|
}
|
|
|
|
// Formatter formats given bin.Object and prints it to io.Writer.
|
|
type Formatter interface {
|
|
Format(w io.Writer, i Object) error
|
|
}
|
|
|
|
// FormatterFunc is functional adapter for Formatter.
|
|
type FormatterFunc func(w io.Writer, i Object) error
|
|
|
|
// Format implements Formatter.
|
|
func (f FormatterFunc) Format(w io.Writer, i Object) error {
|
|
return f(w, i)
|
|
}
|
|
|
|
func formats(name string) Formatter {
|
|
switch name {
|
|
case "json":
|
|
return FormatterFunc(func(w io.Writer, i Object) error {
|
|
e := json.NewEncoder(w)
|
|
e.SetIndent("", "\t")
|
|
return e.Encode(i)
|
|
})
|
|
case "pp":
|
|
return FormatterFunc(func(w io.Writer, i Object) error {
|
|
_, err := pp.Fprintln(w, i)
|
|
return err
|
|
})
|
|
case "tdp":
|
|
return FormatterFunc(func(w io.Writer, i Object) error {
|
|
_, err := io.WriteString(w, tdp.Format(i))
|
|
return err
|
|
})
|
|
default: // "go" format
|
|
return FormatterFunc(func(w io.Writer, i Object) error {
|
|
_, err := fmt.Fprintln(w, i)
|
|
return err
|
|
})
|
|
}
|
|
}
|
|
|
|
// Printer decodes messages from given reader and prints is using Formatter.
|
|
type Printer struct {
|
|
src io.Reader
|
|
codec transport.Codec
|
|
format Formatter
|
|
}
|
|
|
|
// NewPrinter creates new Printer.
|
|
// If format is nil, "go" format will be used.
|
|
// If c is nil, codec.Intermediate will be use.
|
|
func NewPrinter(src io.Reader, format Formatter, c transport.Codec) Printer {
|
|
if c == nil {
|
|
c = codec.Intermediate{}
|
|
}
|
|
if format == nil {
|
|
format = formats("go")
|
|
}
|
|
return Printer{
|
|
src: src,
|
|
codec: c,
|
|
format: format,
|
|
}
|
|
}
|
|
|
|
// Print prints decoded messages to output.
|
|
func (p Printer) Print(output io.Writer) error {
|
|
b := &bin.Buffer{}
|
|
|
|
m := tmap.NewConstructor(
|
|
tg.TypesConstructorMap(),
|
|
mt.TypesConstructorMap(),
|
|
)
|
|
for {
|
|
b.Reset()
|
|
if err := p.codec.Read(p.src, b); err != nil {
|
|
if errors.Is(err, io.EOF) {
|
|
return nil
|
|
}
|
|
|
|
return err
|
|
}
|
|
|
|
id, err := b.PeekID()
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
obj := m.New(id)
|
|
if obj == nil {
|
|
return errors.Errorf("find type %#x", id)
|
|
}
|
|
|
|
v, ok := obj.(Object)
|
|
if !ok {
|
|
return errors.Errorf("unexpected type %T", obj)
|
|
}
|
|
|
|
if err := v.Decode(b); err != nil {
|
|
return err
|
|
}
|
|
|
|
if err := p.format.Format(output, v); err != nil {
|
|
return err
|
|
}
|
|
}
|
|
}
|