move gotd fork into repo. (#111)
- 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
This commit is contained in:
@@ -0,0 +1,198 @@
|
||||
package tdjson
|
||||
|
||||
import (
|
||||
"encoding/base64"
|
||||
"encoding/hex"
|
||||
|
||||
"github.com/go-faster/errors"
|
||||
"github.com/go-faster/jx"
|
||||
|
||||
"go.mau.fi/mautrix-telegram/pkg/gotd/bin"
|
||||
)
|
||||
|
||||
// Decoder is a simple wrapper around jx.Decoder to conform TL type system.
|
||||
type Decoder struct {
|
||||
*jx.Decoder
|
||||
}
|
||||
|
||||
// Obj calls f for every key in object, using byte slice as key.
|
||||
//
|
||||
// The key value is valid only until f is not returned.
|
||||
func (b Decoder) Obj(cb func(d Decoder, key []byte) error) error {
|
||||
return b.Decoder.ObjBytes(func(d *jx.Decoder, key []byte) error {
|
||||
return cb(Decoder{Decoder: d}, key)
|
||||
})
|
||||
}
|
||||
|
||||
// Arr decodes array and invokes callback on each array element.
|
||||
func (b Decoder) Arr(cb func(d Decoder) error) error {
|
||||
return b.Decoder.Arr(func(d *jx.Decoder) error {
|
||||
return cb(Decoder{Decoder: d})
|
||||
})
|
||||
}
|
||||
|
||||
// ID deserializes given typeID.
|
||||
func (b Decoder) ID() (string, error) {
|
||||
return b.Decoder.Str()
|
||||
}
|
||||
|
||||
// FindTypeID tries to find @type field or returns error.
|
||||
func (b Decoder) FindTypeID() (string, error) {
|
||||
var (
|
||||
found bool
|
||||
typ string
|
||||
)
|
||||
if err := b.Decoder.Capture(func(d *jx.Decoder) error {
|
||||
return d.ObjBytes(func(d *jx.Decoder, key []byte) error {
|
||||
if found || string(key) != TypeField {
|
||||
return d.Skip()
|
||||
}
|
||||
|
||||
t, err := d.Str()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
typ = t
|
||||
found = true
|
||||
return nil
|
||||
})
|
||||
}); err != nil {
|
||||
return "", err
|
||||
}
|
||||
if !found {
|
||||
return "", ErrTypeIDNotFound
|
||||
}
|
||||
return typ, nil
|
||||
}
|
||||
|
||||
// ConsumeID deserializes given typeID.
|
||||
func (b Decoder) ConsumeID(id string) error {
|
||||
v, err := b.Decoder.Str()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if v != id {
|
||||
return NewUnexpectedID(id)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// Int deserializes signed 32-bit integer.
|
||||
func (b Decoder) Int() (int, error) {
|
||||
return b.Decoder.Int()
|
||||
}
|
||||
|
||||
// Bool deserializes boolean.
|
||||
func (b Decoder) Bool() (bool, error) {
|
||||
return b.Decoder.Bool()
|
||||
}
|
||||
|
||||
// Uint16 deserializes unsigned 16-bit integer.
|
||||
func (b Decoder) Uint16() (uint16, error) {
|
||||
v, err := b.Decoder.UInt32()
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
return uint16(v), nil
|
||||
}
|
||||
|
||||
// Int32 deserializes signed 32-bit integer.
|
||||
func (b Decoder) Int32() (int32, error) {
|
||||
return b.Decoder.Int32()
|
||||
}
|
||||
|
||||
// Uint32 deserializes unsigned 32-bit integer.
|
||||
func (b Decoder) Uint32() (uint32, error) {
|
||||
return b.Decoder.UInt32()
|
||||
}
|
||||
|
||||
// Int53 deserializes int53.
|
||||
func (b Decoder) Int53() (int64, error) {
|
||||
return b.Decoder.Int64()
|
||||
}
|
||||
|
||||
// Long deserializes int64.
|
||||
func (b Decoder) Long() (int64, error) {
|
||||
n, err := b.Decoder.Num()
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
return n.Int64()
|
||||
}
|
||||
|
||||
// Uint64 deserializes unsigned 64-bit integer.
|
||||
func (b Decoder) Uint64() (uint64, error) {
|
||||
return b.Decoder.UInt64()
|
||||
}
|
||||
|
||||
// Double deserializes 64-bit floating point.
|
||||
func (b Decoder) Double() (float64, error) {
|
||||
return b.Decoder.Float64()
|
||||
}
|
||||
|
||||
// Int128 deserializes 128-bit signed integer.
|
||||
func (b Decoder) Int128() (bin.Int128, error) {
|
||||
// FIXME(tdakkota): neither TDLib API not Telegram API has no Int128/Int256 fields
|
||||
// so this encoding may incorrect.
|
||||
v, err := b.Decoder.Str()
|
||||
if err != nil {
|
||||
return bin.Int128{}, err
|
||||
}
|
||||
|
||||
var result bin.Int128
|
||||
if l := hex.DecodedLen(len(v)); l != len(result) {
|
||||
return bin.Int128{}, errors.Wrapf(err, "invalid length %d", l)
|
||||
}
|
||||
|
||||
if _, err := hex.Decode(result[:], []byte(v)); err != nil {
|
||||
return bin.Int128{}, err
|
||||
}
|
||||
|
||||
return result, nil
|
||||
}
|
||||
|
||||
// Int256 deserializes 256-bit signed integer.
|
||||
func (b Decoder) Int256() (bin.Int256, error) {
|
||||
// FIXME(tdakkota): neither TDLib API not Telegram API has no Int128/Int256 fields
|
||||
// so this encoding may incorrect.
|
||||
v, err := b.Decoder.StrBytes()
|
||||
if err != nil {
|
||||
return bin.Int256{}, err
|
||||
}
|
||||
|
||||
var result bin.Int256
|
||||
if l := hex.DecodedLen(len(v)); l != len(result) {
|
||||
return bin.Int256{}, errors.Wrapf(err, "invalid length %d", l)
|
||||
}
|
||||
|
||||
if _, err := hex.Decode(result[:], v); err != nil {
|
||||
return bin.Int256{}, err
|
||||
}
|
||||
|
||||
return result, nil
|
||||
}
|
||||
|
||||
// String deserializes bare string.
|
||||
func (b Decoder) String() (string, error) {
|
||||
return b.Decoder.Str()
|
||||
}
|
||||
|
||||
// Bytes deserializes bare byte string.
|
||||
func (b Decoder) Bytes() ([]byte, error) {
|
||||
// See https://core.telegram.org/tdlib/docs/td__json__client_8h.html
|
||||
//
|
||||
// ... fields of bytes type are base64 encoded and then stored as String ...
|
||||
enc := base64.RawStdEncoding
|
||||
|
||||
v, err := b.Decoder.StrBytes()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
result := make([]byte, enc.DecodedLen(len(v)))
|
||||
if _, err := enc.Decode(result, v); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return result, nil
|
||||
}
|
||||
Reference in New Issue
Block a user