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,96 @@
|
||||
{{- /*gotype: go.mau.fi/mautrix-telegram/pkg/gotd/gen.interfaceConfig*/ -}}
|
||||
{{ define "box" }}{{ $f := .Interface }}
|
||||
// Decode{{ $f.Func }} implements binary de-serialization for {{ $f.Name }}.
|
||||
func Decode{{ $f.Func }} (buf *bin.Buffer) ({{ $f.Name }}, error) {
|
||||
id, err := buf.PeekID()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
switch id {
|
||||
{{- range $c := $f.Constructors }}
|
||||
case {{ $c.Name }}TypeID:
|
||||
// Decoding {{ $c.RawType }}.
|
||||
v := {{ $c.Name }}{}
|
||||
if err := v.Decode(buf); err != nil {
|
||||
return nil, fmt.Errorf("unable to decode {{ $f.Name }}: %w", err)
|
||||
}
|
||||
return &v, nil
|
||||
{{- end }}
|
||||
default:
|
||||
return nil, fmt.Errorf("unable to decode {{ $f.Name }}: %w", bin.NewUnexpectedID(id))
|
||||
}
|
||||
}
|
||||
|
||||
{{- if $.Config.Flags.TDLibJSON }}
|
||||
// DecodeTDLibJSON{{ $f.Func }} implements binary de-serialization for {{ $f.Name }}.
|
||||
func DecodeTDLibJSON{{ $f.Func }} (buf tdjson.Decoder) ({{ $f.Name }}, error) {
|
||||
id, err := buf.FindTypeID()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
switch id {
|
||||
{{- range $c := $f.Constructors }}
|
||||
case "{{ $c.RawName }}":
|
||||
// Decoding {{ $c.RawType }}.
|
||||
v := {{ $c.Name }}{}
|
||||
if err := v.DecodeTDLibJSON(buf); err != nil {
|
||||
return nil, fmt.Errorf("unable to decode {{ $f.Name }}: %w", err)
|
||||
}
|
||||
return &v, nil
|
||||
{{- end }}
|
||||
default:
|
||||
return nil, fmt.Errorf("unable to decode {{ $f.Name }}: %w", tdjson.NewUnexpectedID(id))
|
||||
}
|
||||
}
|
||||
{{- end }}
|
||||
|
||||
// {{ $f.Func }} boxes the {{ $f.Name }} providing a helper.
|
||||
type {{ $f.Func }}Box struct {
|
||||
{{ $f.BaseName }} {{ $f.Name }}
|
||||
}
|
||||
|
||||
// Decode implements bin.Decoder for {{ $f.Func }}Box.
|
||||
func (b *{{ $f.Func }}Box) Decode(buf *bin.Buffer) error {
|
||||
if b == nil {
|
||||
return fmt.Errorf("unable to decode {{ $f.Func }}Box to nil")
|
||||
}
|
||||
v, err := Decode{{ $f.Func }}(buf)
|
||||
if err != nil {
|
||||
return fmt.Errorf("unable to decode boxed value: %w", err)
|
||||
}
|
||||
b.{{ $f.BaseName }} = v
|
||||
return nil
|
||||
}
|
||||
|
||||
// Encode implements bin.Encode for {{ $f.Func }}Box.
|
||||
func (b *{{ $f.Func }}Box) Encode(buf *bin.Buffer) error {
|
||||
if b == nil || b.{{ $f.BaseName }} == nil {
|
||||
return fmt.Errorf("unable to encode {{ $f.Name }} as nil")
|
||||
}
|
||||
return b.{{ $f.BaseName }}.Encode(buf)
|
||||
}
|
||||
|
||||
{{- if $.Config.Flags.TDLibJSON }}
|
||||
// DecodeTDLibJSON implements bin.Decoder for {{ $f.Func }}Box.
|
||||
func (b *{{ $f.Func }}Box) DecodeTDLibJSON(buf tdjson.Decoder) error {
|
||||
if b == nil {
|
||||
return fmt.Errorf("unable to decode {{ $f.Func }}Box to nil")
|
||||
}
|
||||
v, err := DecodeTDLibJSON{{ $f.Func }}(buf)
|
||||
if err != nil {
|
||||
return fmt.Errorf("unable to decode boxed value: %w", err)
|
||||
}
|
||||
b.{{ $f.BaseName }} = v
|
||||
return nil
|
||||
}
|
||||
|
||||
// EncodeTDLibJSON implements bin.Encode for {{ $f.Func }}Box.
|
||||
func (b *{{ $f.Func }}Box) EncodeTDLibJSON(buf tdjson.Encoder) error {
|
||||
if b == nil || b.{{ $f.BaseName }} == nil {
|
||||
return fmt.Errorf("unable to encode {{ $f.Name }} as nil")
|
||||
}
|
||||
return b.{{ $f.BaseName }}.EncodeTDLibJSON(buf)
|
||||
}
|
||||
{{- end }}
|
||||
|
||||
{{ end }}
|
||||
@@ -0,0 +1,27 @@
|
||||
{{ define "client" }}
|
||||
{{ $pkg := $.Package }}
|
||||
{{ template "header" $ }}
|
||||
|
||||
// Invoker can invoke raw MTProto rpc calls.
|
||||
type Invoker interface {
|
||||
Invoke(ctx context.Context, input bin.Encoder, output bin.Decoder) error
|
||||
}
|
||||
|
||||
// Client implement methods for calling functions from TL schema via Invoker.
|
||||
type Client struct {
|
||||
rpc Invoker
|
||||
}
|
||||
|
||||
// Invoker returns Invoker used by this client.
|
||||
func (c *Client) Invoker() Invoker {
|
||||
return c.rpc
|
||||
}
|
||||
|
||||
// NewClient creates new Client.
|
||||
func NewClient(invoker Invoker) *Client {
|
||||
return &Client{
|
||||
rpc: invoker,
|
||||
}
|
||||
}
|
||||
|
||||
{{ end }}
|
||||
@@ -0,0 +1,101 @@
|
||||
{{- /*gotype: go.mau.fi/mautrix-telegram/pkg/gotd/gen.structDef*/ -}}
|
||||
{{ define "decode" }}{{ $s := . }}
|
||||
// Decode implements bin.Decoder.
|
||||
func ({{ $s.Receiver }} *{{ $s.Name }}) Decode({{ $s.BufArg }} *bin.Buffer) error {
|
||||
if {{ $s.Receiver }} == nil {
|
||||
return fmt.Errorf("can't decode {{ $s.RawType }} to nil")
|
||||
}
|
||||
{{ if not $s.Vector -}}
|
||||
if err := {{ $s.BufArg }}.ConsumeID({{ $s.Name }}TypeID); err != nil {
|
||||
return fmt.Errorf("unable to decode {{ $s.RawType }}: %w", err)
|
||||
}
|
||||
{{- end }}
|
||||
return {{ $s.Receiver }}.DecodeBare({{ $s.BufArg }})
|
||||
}
|
||||
|
||||
// DecodeBare implements bin.BareDecoder.
|
||||
func ({{ $s.Receiver }} *{{ $s.Name }}) DecodeBare({{ $s.BufArg }} *bin.Buffer) error {
|
||||
if {{ $s.Receiver }} == nil {
|
||||
return fmt.Errorf("can't decode {{ $s.RawType }} to nil")
|
||||
}
|
||||
{{- range $f := $s.Fields }}
|
||||
{{- if $f.ConditionalBool }}
|
||||
{{ $s.Receiver }}.{{ $f.Name }} = {{ $s.Receiver }}.{{ $f.ConditionalField }}.Has({{ $f.ConditionalIndex }})
|
||||
{{- else }}
|
||||
{{- if $f.Conditional}}
|
||||
if {{ $s.Receiver }}.{{ $f.ConditionalField }}.Has({{ $f.ConditionalIndex }}) {
|
||||
{{- else}}
|
||||
{
|
||||
{{- end }}
|
||||
{{- if $f.Vector }}
|
||||
headerLen, err := {{ if $f.BareVector }}{{ $s.BufArg }}.Int(){{ else }}{{ $s.BufArg }}.VectorHeader(){{ end }}
|
||||
if err != nil {
|
||||
return fmt.Errorf("unable to decode {{ $s.RawType }}: field {{ $f.RawName }}: %w", err)
|
||||
}
|
||||
|
||||
if headerLen > 0 {
|
||||
{{ $s.Receiver }}.{{ $f.Name }} = make({{ template "print_type" $f }}, 0, headerLen % bin.PreallocateLimit)
|
||||
}
|
||||
for idx := 0; idx < headerLen; idx++ {
|
||||
|
||||
{{- if $f.DoubleVector }}
|
||||
innerLen, err := {{ $s.BufArg }}.VectorHeader()
|
||||
if err != nil {
|
||||
return fmt.Errorf("unable to decode {{ $s.RawType }}: field {{ $f.RawName }}: %w", err)
|
||||
}
|
||||
|
||||
var row []{{ $f.Type }}
|
||||
if innerLen > 0 {
|
||||
row = make([]{{ $f.Type }}, 0, innerLen % bin.PreallocateLimit)
|
||||
}
|
||||
for innerIndex := 0; innerIndex < innerLen; innerLen++ {
|
||||
{{- end }}
|
||||
{{- if $f.Interface }}
|
||||
value, err := Decode{{ $f.InterfaceFunc }}({{ $s.BufArg }})
|
||||
if err != nil {
|
||||
return fmt.Errorf("unable to decode {{ $s.RawType }}: field {{ $f.RawName }}: %w", err)
|
||||
}
|
||||
{{- else if $f.Encoder }}
|
||||
var value {{ $f.Type }}
|
||||
if err := value.Decode{{ if and $f.BareEncoder $f.BareVector }}Bare{{ end }}({{ $s.BufArg }}); err != nil {
|
||||
return fmt.Errorf("unable to decode{{ if and $f.BareEncoder $f.BareVector }} bare{{ end }} {{ $s.RawType }}: field {{ $f.RawName }}: %w", err)
|
||||
}
|
||||
{{- else}}
|
||||
value, err := {{ $s.BufArg }}.{{ $f.Func }}()
|
||||
if err != nil {
|
||||
return fmt.Errorf("unable to decode {{ $s.RawType }}: field {{ $f.RawName }}: %w", err)
|
||||
}
|
||||
{{- end }}
|
||||
{{- if $f.DoubleVector }}
|
||||
row = append(row, value)
|
||||
}
|
||||
{{ $s.Receiver }}.{{ $f.Name }} = append({{ $s.Receiver }}.{{ $f.Name }}, row)
|
||||
{{- else }}
|
||||
{{ $s.Receiver }}.{{ $f.Name }} = append({{ $s.Receiver }}.{{ $f.Name }}, value)
|
||||
{{- end }}
|
||||
}
|
||||
{{- else }}
|
||||
{{- if $f.Interface }}
|
||||
value, err := Decode{{ $f.InterfaceFunc }}({{ $s.BufArg }})
|
||||
if err != nil {
|
||||
return fmt.Errorf("unable to decode {{ $s.RawType }}: field {{ $f.RawName }}: %w", err)
|
||||
}
|
||||
{{ $s.Receiver }}.{{ $f.Name }} = value
|
||||
{{- else if $f.Encoder }}
|
||||
if err := {{ $s.Receiver }}.{{ $f.Name }}.Decode({{ $s.BufArg }}); err != nil {
|
||||
return fmt.Errorf("unable to decode {{ $s.RawType }}: field {{ $f.RawName }}: %w", err)
|
||||
}
|
||||
{{- else }}
|
||||
value, err := {{ $s.BufArg }}.{{ $f.Func }}()
|
||||
if err != nil {
|
||||
return fmt.Errorf("unable to decode {{ $s.RawType }}: field {{ $f.RawName }}: %w", err)
|
||||
}
|
||||
{{ $s.Receiver }}.{{ $f.Name }} = value
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
}
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
return nil
|
||||
}
|
||||
{{ end }}
|
||||
@@ -0,0 +1,85 @@
|
||||
{{- /*gotype: go.mau.fi/mautrix-telegram/pkg/gotd/gen.structDef*/ -}}
|
||||
{{ define "decode_tdlib_json" }}{{ $s := . }}
|
||||
// DecodeTDLibJSON implements tdjson.TDLibDecoder.
|
||||
func ({{ $s.Receiver }} *{{ $s.Name }}) DecodeTDLibJSON({{ $s.BufArg }} tdjson.Decoder) error {
|
||||
if {{ $s.Receiver }} == nil {
|
||||
return fmt.Errorf("can't decode {{ $s.RawType }} to nil")
|
||||
}
|
||||
|
||||
return {{ $s.BufArg }}.Obj(func({{ $s.BufArg }} tdjson.Decoder, key []byte) error {
|
||||
switch string(key) {
|
||||
case tdjson.TypeField:
|
||||
if err := {{ $s.BufArg }}.ConsumeID("{{ $s.RawName }}"); err != nil {
|
||||
return fmt.Errorf("unable to decode {{ $s.RawType }}: %w", err)
|
||||
}
|
||||
{{- range $f := $s.Fields }}
|
||||
case "{{ $f.RawName }}":
|
||||
{{- if or $f.ConditionalBool $f.Conditional }}
|
||||
{{ $s.Receiver }}.{{ $f.ConditionalField }}.Set({{ $f.ConditionalIndex }})
|
||||
{{- end }}
|
||||
{{- if $f.Vector }}
|
||||
if err := {{ $s.BufArg }}.Arr(func({{ $s.BufArg }} tdjson.Decoder) error {
|
||||
|
||||
{{- if $f.DoubleVector }}
|
||||
var row []{{ $f.Type }}
|
||||
if err := {{ $s.BufArg }}.Arr(func({{ $s.BufArg }} tdjson.Decoder) error {
|
||||
{{- end }}
|
||||
{{- if $f.Interface }}
|
||||
value, err := DecodeTDLibJSON{{ $f.InterfaceFunc }}({{ $s.BufArg }})
|
||||
if err != nil {
|
||||
return fmt.Errorf("unable to decode {{ $s.RawType }}: field {{ $f.RawName }}: %w", err)
|
||||
}
|
||||
{{- else if $f.Encoder }}
|
||||
var value {{ $f.Type }}
|
||||
if err := value.DecodeTDLibJSON({{ $s.BufArg }}); err != nil {
|
||||
return fmt.Errorf("unable to decode {{ $s.RawType }}: field {{ $f.RawName }}: %w", err)
|
||||
}
|
||||
{{- else}}
|
||||
value, err := {{ $s.BufArg }}.{{ $f.Func }}()
|
||||
if err != nil {
|
||||
return fmt.Errorf("unable to decode {{ $s.RawType }}: field {{ $f.RawName }}: %w", err)
|
||||
}
|
||||
{{- end }}
|
||||
{{- if $f.DoubleVector }}
|
||||
row = append(row, value)
|
||||
return nil
|
||||
}); err != nil {
|
||||
return fmt.Errorf("unable to decode {{ $s.RawType }}: field {{ $f.RawName }}: %w", err)
|
||||
}
|
||||
{{ $s.Receiver }}.{{ $f.Name }} = append({{ $s.Receiver }}.{{ $f.Name }}, row)
|
||||
{{- else }}
|
||||
{{ $s.Receiver }}.{{ $f.Name }} = append({{ $s.Receiver }}.{{ $f.Name }}, value)
|
||||
{{- end }}
|
||||
return nil
|
||||
}); err != nil {
|
||||
return fmt.Errorf("unable to decode {{ $s.RawType }}: field {{ $f.RawName }}: %w", err)
|
||||
}
|
||||
{{- else }}
|
||||
{{- if $f.Interface }}
|
||||
value, err := DecodeTDLibJSON{{ $f.InterfaceFunc }}({{ $s.BufArg }})
|
||||
if err != nil {
|
||||
return fmt.Errorf("unable to decode {{ $s.RawType }}: field {{ $f.RawName }}: %w", err)
|
||||
}
|
||||
{{ $s.Receiver }}.{{ $f.Name }} = value
|
||||
{{- else if $f.Encoder }}
|
||||
{{- if not (eq $f.Type "bin.Fields") }}
|
||||
if err := {{ $s.Receiver }}.{{ $f.Name }}.DecodeTDLibJSON({{ $s.BufArg }}); err != nil {
|
||||
return fmt.Errorf("unable to decode {{ $s.RawType }}: field {{ $f.RawName }}: %w", err)
|
||||
}
|
||||
{{- end }}
|
||||
{{- else }}
|
||||
value, err := {{ $s.BufArg }}.{{ $f.Func }}()
|
||||
if err != nil {
|
||||
return fmt.Errorf("unable to decode {{ $s.RawType }}: field {{ $f.RawName }}: %w", err)
|
||||
}
|
||||
{{ $s.Receiver }}.{{ $f.Name }} = value
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
default:
|
||||
return {{ $s.BufArg }}.Skip()
|
||||
}
|
||||
return nil
|
||||
})
|
||||
}
|
||||
{{ end }}
|
||||
@@ -0,0 +1,71 @@
|
||||
{{- /*gotype: go.mau.fi/mautrix-telegram/pkg/gotd/gen.structDef*/ -}}
|
||||
{{ define "encode" }}{{ $s := . }}
|
||||
// Encode implements bin.Encoder.
|
||||
func ({{ $s.Receiver }} *{{ $s.Name }}) Encode({{ $s.BufArg }} *bin.Buffer) error {
|
||||
if {{ $s.Receiver }} == nil {
|
||||
return fmt.Errorf("can't encode {{ $s.RawType }} as nil")
|
||||
}
|
||||
{{ if not $s.Vector -}}
|
||||
{{ $s.BufArg }}.PutID({{ $s.Name }}TypeID)
|
||||
{{- end }}
|
||||
return {{ $s.Receiver }}.EncodeBare({{ $s.BufArg }})
|
||||
}
|
||||
|
||||
// EncodeBare implements bin.BareEncoder.
|
||||
func ({{ $s.Receiver }} *{{ $s.Name }}) EncodeBare({{ $s.BufArg }} *bin.Buffer) error {
|
||||
if {{ $s.Receiver }} == nil {
|
||||
return fmt.Errorf("can't encode {{ $s.RawType }} as nil")
|
||||
}
|
||||
{{- if hasFlags $s }}
|
||||
{{ $s.Receiver }}.SetFlags()
|
||||
{{- end }}
|
||||
{{- range $f := $s.Fields }}
|
||||
{{- if not $f.ConditionalBool }}
|
||||
{{- if $f.Conditional }}
|
||||
if {{ $s.Receiver }}.{{ $f.ConditionalField }}.Has({{ $f.ConditionalIndex }}) {
|
||||
{{- end }}
|
||||
{{- if $f.Vector }}
|
||||
{{ if not $f.BareVector }}{{ $s.BufArg }}.PutVectorHeader(len({{ $s.Receiver }}.{{ $f.Name }})){{ else }}{{ $s.BufArg }}.PutInt(len({{ $s.Receiver }}.{{ $f.Name }})){{- end }}
|
||||
for {{ if $f.Encoder }}idx{{ else }}_{{ end }}, {{- if $f.DoubleVector }}row{{else}}v{{end}} := range {{ $s.Receiver }}.{{ $f.Name }} {
|
||||
{{- if $f.DoubleVector }}
|
||||
{{ $s.BufArg }}.PutVectorHeader(len(row))
|
||||
for _, v := range row {
|
||||
{{- end }}
|
||||
{{- if $f.Encoder }}
|
||||
{{- if $f.Interface }}
|
||||
if v == nil {
|
||||
return fmt.Errorf("unable to encode {{ $s.RawType }}: field {{ $f.RawName }} element with index %d is nil", idx)
|
||||
}
|
||||
{{- end}}
|
||||
if err := v.Encode{{ if and $f.BareEncoder $f.BareVector }}Bare{{ end }}({{ $s.BufArg }}); err != nil {
|
||||
return fmt.Errorf("unable to encode{{ if and $f.BareEncoder $f.BareVector }} bare{{ end }} {{ $s.RawType }}: field {{ $f.RawName }} element with index %d: %w", idx, err)
|
||||
}
|
||||
{{- else }}
|
||||
{{ $s.BufArg }}.Put{{ $f.Func }}(v)
|
||||
{{- end }}
|
||||
{{- if $f.DoubleVector }}
|
||||
}
|
||||
{{- end }}
|
||||
}
|
||||
{{- else }}
|
||||
{{- if $f.Encoder }}
|
||||
{{- if $f.Interface }}
|
||||
if {{ $s.Receiver }}.{{ $f.Name }} == nil {
|
||||
return fmt.Errorf("unable to encode {{ $s.RawType }}: field {{ $f.RawName }} is nil")
|
||||
}
|
||||
{{- end}}
|
||||
if err := {{ $s.Receiver }}.{{ $f.Name }}.Encode({{ $s.BufArg }}); err != nil {
|
||||
return fmt.Errorf("unable to encode {{ $s.RawType }}: field {{ $f.RawName }}: %w", err)
|
||||
}
|
||||
{{- else }}
|
||||
{{ $s.BufArg }}.Put{{ $f.Func }}({{ $s.Receiver }}.{{ $f.Name }})
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
{{- if $f.Conditional }}
|
||||
}
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
return nil
|
||||
}
|
||||
{{ end }}
|
||||
@@ -0,0 +1,75 @@
|
||||
{{- /*gotype: go.mau.fi/mautrix-telegram/pkg/gotd/gen.structDef*/ -}}
|
||||
{{ define "encode_tdlib_json" }}{{ $s := . }}
|
||||
// EncodeTDLibJSON implements tdjson.TDLibEncoder.
|
||||
func ({{ $s.Receiver }} *{{ $s.Name }}) EncodeTDLibJSON({{ $s.BufArg }} tdjson.Encoder) error {
|
||||
if {{ $s.Receiver }} == nil {
|
||||
return fmt.Errorf("can't encode {{ $s.RawType }} as nil")
|
||||
}
|
||||
{{ $s.BufArg }}.ObjStart()
|
||||
{{ $s.BufArg }}.PutID("{{ $s.RawName }}")
|
||||
{{ $s.BufArg }}.Comma()
|
||||
{{- if hasFlags $s }}
|
||||
{{ $s.Receiver }}.SetFlags()
|
||||
{{- end }}
|
||||
{{- range $i, $f := $s.Fields }}
|
||||
{{- if not $f.ConditionalBool }}
|
||||
{{- if $f.Conditional }}
|
||||
if {{ $s.Receiver }}.{{ $f.ConditionalField }}.Has({{ $f.ConditionalIndex }}) {
|
||||
{{- end }}
|
||||
{{ $s.BufArg }}.FieldStart("{{ $f.RawName }}")
|
||||
{{- if $f.Vector }}
|
||||
{{ $s.BufArg }}.ArrStart()
|
||||
for {{ if $f.Encoder }}idx{{ else }}_{{ end }}, {{- if $f.DoubleVector }}row{{else}}v{{end}} := range {{ $s.Receiver }}.{{ $f.Name }} {
|
||||
{{- if $f.DoubleVector }}
|
||||
{{ $s.BufArg }}.ArrStart()
|
||||
for _, v := range row {
|
||||
{{- end }}
|
||||
{{- if $f.Encoder }}
|
||||
{{- if $f.Interface }}
|
||||
if v == nil {
|
||||
return fmt.Errorf("unable to encode {{ $s.RawType }}: field {{ $f.RawName }} element with index %d is nil", idx)
|
||||
}
|
||||
{{- end }}
|
||||
if err := v.EncodeTDLibJSON({{ $s.BufArg }}); err != nil {
|
||||
return fmt.Errorf("unable to encode {{ $s.RawType }}: field {{ $f.RawName }} element with index %d: %w", idx, err)
|
||||
}
|
||||
{{- else }}
|
||||
{{ $s.BufArg }}.Put{{ $f.Func }}(v)
|
||||
{{- end }}
|
||||
{{ $s.BufArg }}.Comma()
|
||||
{{- if $f.DoubleVector }}
|
||||
}
|
||||
{{ $s.BufArg }}.StripComma()
|
||||
{{ $s.BufArg }}.ArrEnd()
|
||||
{{ $s.BufArg }}.Comma()
|
||||
{{- end }}
|
||||
}
|
||||
{{ $s.BufArg }}.StripComma()
|
||||
{{ $s.BufArg }}.ArrEnd()
|
||||
{{- else }}
|
||||
{{- if $f.Encoder }}
|
||||
{{- if $f.Interface }}
|
||||
if {{ $s.Receiver }}.{{ $f.Name }} == nil {
|
||||
return fmt.Errorf("unable to encode {{ $s.RawType }}: field {{ $f.RawName }} is nil")
|
||||
}
|
||||
{{- end }}
|
||||
{{- if not (eq $f.Type "bin.Fields") }}
|
||||
if err := {{ $s.Receiver }}.{{ $f.Name }}.EncodeTDLibJSON({{ $s.BufArg }}); err != nil {
|
||||
return fmt.Errorf("unable to encode {{ $s.RawType }}: field {{ $f.RawName }}: %w", err)
|
||||
}
|
||||
{{- end }}
|
||||
{{- else }}
|
||||
{{ $s.BufArg }}.Put{{ $f.Func }}({{ $s.Receiver }}.{{ $f.Name }})
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
{{- if $f.Conditional }}
|
||||
}
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
{{ $s.BufArg }}.Comma()
|
||||
{{- end }}
|
||||
{{ $s.BufArg }}.StripComma()
|
||||
{{ $s.BufArg }}.ObjEnd()
|
||||
return nil
|
||||
}
|
||||
{{ end }}
|
||||
@@ -0,0 +1,21 @@
|
||||
{{- /*gotype: go.mau.fi/mautrix-telegram/pkg/gotd/gen.config*/ -}}
|
||||
|
||||
{{ define "errors" }}
|
||||
{{ $pkg := $.Package }}
|
||||
{{ template "header" $ }}
|
||||
|
||||
// Telegram API error types.
|
||||
const (
|
||||
{{- range $s := $.Errors }}
|
||||
Err{{ $s.Name }} = "{{ $s.Type }}"
|
||||
{{- end }}
|
||||
)
|
||||
|
||||
{{- range $s := $.Errors }}
|
||||
// Is{{ $s.Name }} reports whether err is {{ $s.Type }}.
|
||||
func Is{{ $s.Name }}(err error) bool {
|
||||
return tgerr.Is(err, Err{{ $s.Name }})
|
||||
}
|
||||
{{ end }}
|
||||
|
||||
{{ end }}
|
||||
@@ -0,0 +1,48 @@
|
||||
{{- /*gotype: go.mau.fi/mautrix-telegram/pkg/gotd/gen.structConfig*/ -}}
|
||||
{{ define "field_mapping" }}{{- $s := .Struct -}}
|
||||
|
||||
{{- range $f := $s.Fields }}{{ if and (not $f.DoubleSlice) (ne ($f.Type) ("bin.Fields")) }}
|
||||
{{ if not $f.Slice }}
|
||||
|
||||
{{- $mappings := index ($.Config.Mappings) ($f.Type) -}}
|
||||
{{- range $mapping := $mappings }}{{- if (not $mapping.Constructor) }}
|
||||
{{- /*gotype: go.mau.fi/mautrix-telegram/pkg/gotd/gen.constructorMapping*/ -}}
|
||||
// Get{{ $f.Name }}As{{ $mapping.MapperName }} returns mapped value of {{ $f.Name }} {{ if $f.Conditional }}
|
||||
{{- if not ($f.ConditionalBool) }}conditional field and
|
||||
// boolean which is true if field was set.
|
||||
{{- else }}conditional field.
|
||||
{{- end }}
|
||||
{{- else }}field.
|
||||
{{- end }}
|
||||
func ({{ $s.Receiver }} *{{ $s.Name }}) Get{{ $f.Name }}As{{ $mapping.MapperName }}() ({{ template "print_mapper_type" $mapping }}, bool) {
|
||||
{{- if $f.Conditional }}
|
||||
if value, ok := {{ $s.Receiver }}.Get{{ $f.Name }}(); ok {
|
||||
return value.As{{ $mapping.MapperName }}()
|
||||
}
|
||||
return nil, false
|
||||
{{- else }}
|
||||
return {{ $s.Receiver }}.{{ $f.Name }}.As{{ $mapping.MapperName }}()
|
||||
{{- end }}
|
||||
}
|
||||
{{- end }}{{- end }}
|
||||
|
||||
{{- else }}
|
||||
|
||||
{{- if $f.Interface }}
|
||||
// Map{{ $f.Name }} returns field {{ $f.Name }} wrapped in {{ template "slice_field_name" $f }} helper.
|
||||
func ({{ $s.Receiver }} *{{ $s.Name }}) Map{{ $f.Name }}() (value {{ template "slice_field_name" $f }}{{ if $f.Conditional }}, ok bool{{ end }}) {
|
||||
{{- if $f.Conditional }}
|
||||
if !{{ $s.Receiver }}.{{ $f.ConditionalField }}.Has({{ $f.ConditionalIndex }}) {
|
||||
return value, false
|
||||
}
|
||||
return {{ template "slice_field_name" $f }}({{ $s.Receiver }}.{{ $f.Name }}), true
|
||||
{{- else }}
|
||||
return {{ template "slice_field_name" $f }}({{ $s.Receiver }}.{{ $f.Name }})
|
||||
{{- end }}
|
||||
}
|
||||
{{- end }}
|
||||
|
||||
{{- end }}
|
||||
{{- end }}{{- end }}
|
||||
|
||||
{{ end }}
|
||||
@@ -0,0 +1,20 @@
|
||||
{{ define "fill_from" }}{{ $s := . }}{{ if $s.Fields }}
|
||||
{{- /*gotype: go.mau.fi/mautrix-telegram/pkg/gotd/gen.structDef*/ -}}
|
||||
// FillFrom fills {{ $s.Name }} from given interface.
|
||||
func ({{ $s.Receiver }} *{{ $s.Name }}) FillFrom(from interface{
|
||||
{{- range $f := $s.Fields }}{{ if ne ($f.Type) ("bin.Fields") }}
|
||||
{{ template "getter_func_type" $f }}
|
||||
{{- end }}{{- end }}
|
||||
}) {
|
||||
{{- range $f := $s.Fields }}{{ if ne ($f.Type) ("bin.Fields") }}
|
||||
{{- /*gotype: go.mau.fi/mautrix-telegram/pkg/gotd/gen.fieldDef*/ -}}
|
||||
{{- if and ($f.Conditional) (not $f.ConditionalBool) }}
|
||||
if val, ok := from.Get{{ $f.Name }}(); ok {
|
||||
{{ $s.Receiver }}.{{ $f.Name }} = val
|
||||
}
|
||||
{{ else }}
|
||||
{{ $s.Receiver }}.{{ $f.Name }} = from.Get{{ $f.Name }}()
|
||||
{{- end }}
|
||||
{{- end }}{{- end }}
|
||||
}
|
||||
{{ end }}{{ end }}
|
||||
@@ -0,0 +1,48 @@
|
||||
{{- /*gotype: go.mau.fi/mautrix-telegram/pkg/gotd/gen.structDef*/ -}}
|
||||
{{ define "getset" }}{{ $s := . }}
|
||||
|
||||
{{- range $f := $s.Fields }}{{ if ne ($f.Type) ("bin.Fields") }}
|
||||
{{ if $f.Conditional }}
|
||||
// Set{{ $f.Name }} sets value of {{ $f.Name }} conditional field.
|
||||
func ({{ $s.Receiver }} *{{ $s.Name }}) Set{{ $f.Name }}(value {{ template "print_type" $f }}) {
|
||||
{{- if $f.ConditionalBool }}
|
||||
if value {
|
||||
{{ $s.Receiver }}.{{ $f.ConditionalField }}.Set({{ $f.ConditionalIndex }})
|
||||
{{ $s.Receiver }}.{{ $f.Name }} = true
|
||||
} else {
|
||||
{{ $s.Receiver }}.{{ $f.ConditionalField }}.Unset({{ $f.ConditionalIndex }})
|
||||
{{ $s.Receiver }}.{{ $f.Name }} = false
|
||||
}
|
||||
{{- else }}
|
||||
{{ $s.Receiver }}.{{ $f.ConditionalField }}.Set({{ $f.ConditionalIndex }})
|
||||
{{ $s.Receiver }}.{{ $f.Name }} = value
|
||||
{{- end }}
|
||||
}
|
||||
{{- end }}
|
||||
|
||||
// Get{{ $f.Name }} returns value of {{ $f.Name }} {{ if $f.Conditional }}
|
||||
{{- if not ($f.ConditionalBool) }}conditional field and
|
||||
// boolean which is true if field was set.
|
||||
{{- else }}conditional field.
|
||||
{{- end }}
|
||||
{{- else }}field.
|
||||
{{- end }}
|
||||
func ({{ $s.Receiver }} *{{ $s.Name }}) {{ template "getter_func_type" $f }} {
|
||||
if {{ $s.Receiver }} == nil {
|
||||
return
|
||||
}
|
||||
{{- if $f.Conditional }}{{ if not ($f.ConditionalBool) }}
|
||||
if !{{ $s.Receiver }}.{{ $f.ConditionalField }}.Has({{ $f.ConditionalIndex }}) {
|
||||
return value, false
|
||||
}
|
||||
return {{ $s.Receiver }}.{{ $f.Name }}, true
|
||||
{{- else }}
|
||||
return {{ $s.Receiver }}.{{ $f.ConditionalField }}.Has({{ $f.ConditionalIndex }})
|
||||
{{- end }}
|
||||
{{- else }}
|
||||
return {{ $s.Receiver }}.{{ $f.Name }}
|
||||
{{- end }}
|
||||
}
|
||||
{{- end }}{{- end }}
|
||||
|
||||
{{ end }}
|
||||
@@ -0,0 +1,93 @@
|
||||
{{ define "handlers" }}
|
||||
{{ $pkg := $.Package }}
|
||||
{{ template "header" $ }}
|
||||
|
||||
type handler = func(context.Context, Entities, UpdateClass) error
|
||||
|
||||
type UpdateDispatcher struct {
|
||||
handlers map[uint32]handler
|
||||
}
|
||||
|
||||
func NewUpdateDispatcher() UpdateDispatcher {
|
||||
return UpdateDispatcher{
|
||||
handlers: map[uint32]handler{},
|
||||
}
|
||||
}
|
||||
|
||||
type Entities struct {
|
||||
Short bool
|
||||
Users map[int64]*User
|
||||
Chats map[int64]*Chat
|
||||
Channels map[int64]*Channel
|
||||
}
|
||||
|
||||
func (u *Entities) short() {
|
||||
u.Short = true
|
||||
u.Users = make(map[int64]*User, 0)
|
||||
u.Chats = make(map[int64]*Chat, 0)
|
||||
u.Channels = make(map[int64]*Channel, 0)
|
||||
}
|
||||
|
||||
// Handle implements UpdateDispatcher.
|
||||
func (u UpdateDispatcher) Handle(ctx context.Context, updates UpdatesClass) error {
|
||||
var (
|
||||
e Entities
|
||||
upds []UpdateClass
|
||||
)
|
||||
switch u := updates.(type) {
|
||||
case *Updates:
|
||||
upds = u.Updates
|
||||
e.Users = u.MapUsers().NotEmptyToMap()
|
||||
chats := u.MapChats()
|
||||
e.Chats = chats.ChatToMap()
|
||||
e.Channels = chats.ChannelToMap()
|
||||
case *UpdatesCombined:
|
||||
upds = u.Updates
|
||||
e.Users = u.MapUsers().NotEmptyToMap()
|
||||
chats := u.MapChats()
|
||||
e.Chats = chats.ChatToMap()
|
||||
e.Channels = chats.ChannelToMap()
|
||||
case *UpdateShort:
|
||||
upds = []UpdateClass{u.Update}
|
||||
e.short()
|
||||
default:
|
||||
// *UpdateShortMessage
|
||||
// *UpdateShortChatMessage
|
||||
// *UpdateShortSentMessage
|
||||
// *UpdatesTooLong
|
||||
return nil
|
||||
}
|
||||
|
||||
var err error
|
||||
for _, update := range upds {
|
||||
multierr.AppendInto(&err, u.dispatch(ctx, e, update))
|
||||
}
|
||||
return err
|
||||
}
|
||||
|
||||
func (u UpdateDispatcher) dispatch(ctx context.Context, e Entities, update UpdateClass) error {
|
||||
if update == nil {
|
||||
return nil
|
||||
}
|
||||
typeID := update.TypeID()
|
||||
handler, ok := u.handlers[typeID]
|
||||
if !ok {
|
||||
return nil
|
||||
}
|
||||
return handler(ctx, e, update)
|
||||
}
|
||||
|
||||
{{- range $s := $.Structs }}{{ if eq $s.Interface "UpdateClass" }}
|
||||
{{ $eventName := trimPrefix $s.Name "Update"}}
|
||||
// {{ $eventName }}Handler is a {{ $eventName }} event handler.
|
||||
type {{ $eventName }}Handler func(ctx context.Context, e Entities, update *{{ $s.Name }}) error
|
||||
|
||||
// On{{ $eventName }} sets {{ $eventName }} handler.
|
||||
func (u UpdateDispatcher) On{{ $eventName }}(handler {{ $eventName }}Handler) {
|
||||
u.handlers[{{ $s.Name }}TypeID] = func(ctx context.Context, e Entities, update UpdateClass) error {
|
||||
return handler(ctx, e, update.(*{{ $s.Name }}))
|
||||
}
|
||||
}
|
||||
{{- end }}{{ end }}
|
||||
|
||||
{{ end }}
|
||||
@@ -0,0 +1,36 @@
|
||||
{{- /*gotype: go.mau.fi/mautrix-telegram/pkg/gotd/gen.config*/ -}}
|
||||
{{ define "header" }}
|
||||
// Code generated by gotdgen, DO NOT EDIT.
|
||||
|
||||
package {{ $.Package }}
|
||||
|
||||
import (
|
||||
"context"
|
||||
"errors"
|
||||
"fmt"
|
||||
"sort"
|
||||
"strings"
|
||||
|
||||
"go.uber.org/multierr"
|
||||
|
||||
"go.mau.fi/mautrix-telegram/pkg/gotd/bin"
|
||||
"go.mau.fi/mautrix-telegram/pkg/gotd/tdjson"
|
||||
"go.mau.fi/mautrix-telegram/pkg/gotd/tdp"
|
||||
"go.mau.fi/mautrix-telegram/pkg/gotd/tgerr"
|
||||
)
|
||||
|
||||
// No-op definition for keeping imports.
|
||||
var (
|
||||
_ = bin.Buffer{}
|
||||
_ = context.Background()
|
||||
_ = fmt.Stringer(nil)
|
||||
_ = strings.Builder{}
|
||||
_ = errors.Is
|
||||
_ = multierr.AppendInto
|
||||
_ = sort.Ints
|
||||
_ = tdp.Format
|
||||
_ = tgerr.Error{}
|
||||
_ = tdjson.Encoder{}
|
||||
)
|
||||
|
||||
{{ end }}
|
||||
@@ -0,0 +1,58 @@
|
||||
{{- /*gotype: go.mau.fi/mautrix-telegram/pkg/gotd/gen.interfaceConfig*/ -}}
|
||||
{{ define "interface" }}{{ $f := .Interface }}
|
||||
|
||||
// {{ $f.Name }}Name is schema name of {{ $f.Name }}.
|
||||
const {{ $f.Name }}Name = "{{ $f.RawType }}"
|
||||
|
||||
// {{ $f.Name }} represents {{ $f.RawType }} generic type.
|
||||
//
|
||||
{{- if $f.URL }}
|
||||
// See {{ $f.URL }} for reference.
|
||||
//
|
||||
{{- end }}
|
||||
// Example:
|
||||
// g, err := {{ $.Config.Package }}.Decode{{ $f.Func }}(buf)
|
||||
// if err != nil {
|
||||
// panic(err)
|
||||
// }
|
||||
// switch v := g.(type) {
|
||||
{{ range $c := $f.Constructors -}}
|
||||
// case *{{ $.Config.Package }}.{{ $c.Name }}: // {{ $c.RawType }}
|
||||
{{ end -}}
|
||||
// default: panic(v)
|
||||
// }
|
||||
type {{ $f.Name }} interface {
|
||||
{{ template "class_interface_header" $f }}
|
||||
|
||||
{{ if $.Config.Flags.TDLibJSON }}
|
||||
EncodeTDLibJSON(b tdjson.Encoder) error
|
||||
DecodeTDLibJSON(b tdjson.Decoder) error
|
||||
{{- end }}
|
||||
|
||||
{{ range $field := $f.SharedFields.Common -}}
|
||||
{{- template "print_comment" $field.Comment }}
|
||||
{{- if $field.Links }}
|
||||
{{- template "print_links" $field.Links }}
|
||||
{{- end }}
|
||||
{{ if $.Config.Flags.GetSet }}{{ template "getter_func_type" $field -}}{{ end }}
|
||||
|
||||
{{- if and ($.Config.Flags.Mapping) (not $field.DoubleSlice) }}
|
||||
{{- if not $field.Slice }}
|
||||
{{- $mappings := index ($.Config.Mappings) ($field.Type) -}}
|
||||
{{- range $mapping := $mappings -}}
|
||||
{{- template "print_comment" $field.Comment }}
|
||||
Get{{ $field.Name }}As{{ $mapping.MapperName }}() ({{ template "print_mapper_type" $mapping }}, bool)
|
||||
{{- end }}
|
||||
{{ else }}{{- if $field.Interface }}
|
||||
{{- template "print_comment" $field.Comment }}
|
||||
Map{{ $field.Name }}() (value {{ template "slice_field_name" $field }}{{ if $field.Conditional }}, ok bool{{ end }})
|
||||
{{- end }}{{- end }}
|
||||
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
{{ range $mapping := $f.Mappings -}}{{- if and ($.Config.Flags.Mapping) (not $mapping.Constructor) -}}
|
||||
// As{{ $mapping.MapperName }} tries to map {{ $f.Name }} to {{ $mapping.Name }}.
|
||||
{{ template "mapper_func_type" $mapping }}
|
||||
{{ end }}{{ end }}
|
||||
}
|
||||
{{ end }}
|
||||
@@ -0,0 +1,56 @@
|
||||
{{- /*gotype: go.mau.fi/mautrix-telegram/pkg/gotd/gen.interfaceDef*/ -}}
|
||||
{{ define "interface_mapping" }}{{ $f := . }}
|
||||
{{ range $mapping := $f.Mappings -}}
|
||||
|
||||
{{- if not ($mapping.Concrete) }}
|
||||
// {{ $mapping.Name }} represents {{ $mapping.MapperName }} subset of {{ $f.Name }}.
|
||||
type {{ $mapping.Name }} interface {
|
||||
{{ template "class_interface_header" $f }}
|
||||
|
||||
{{ range $field := index ($f.SharedFields) ($mapping.MapperName) -}}{{- /*gotype: go.mau.fi/mautrix-telegram/pkg/gotd/gen.fieldDef*/ -}}
|
||||
{{- template "print_comment" $field.Comment }}
|
||||
{{- if $field.Links }}
|
||||
{{- template "print_links" $field.Links }}
|
||||
{{- end }}
|
||||
{{ template "getter_func_type" $field}}
|
||||
{{ end }}
|
||||
}
|
||||
{{- end }}
|
||||
|
||||
{{ range $s := $f.Constructors -}}{{- if or (not $mapping.Constructor) (eq ($s.Name) ($mapping.Constructor)) }}
|
||||
// As{{ $mapping.MapperName }} tries to map {{ $s.Name }} to {{ $mapping.Name }}.
|
||||
func ({{ $s.Receiver }} *{{ $s.Name }}) {{ template "mapper_func_type" $mapping }} {
|
||||
{{- if not ($mapping.Concrete) }}
|
||||
value, ok := ({{ $f.Name }}({{ $s.Receiver }})).({{ $mapping.Name }})
|
||||
return value, ok
|
||||
{{- else }}{{- if $mapping.Fields }}
|
||||
value := new({{ $mapping.Name }})
|
||||
{{- range $pair := $mapping.Fields -}}
|
||||
{{- if and ($pair.L.Conditional) (not $pair.L.ConditionalBool) }}
|
||||
if fieldValue, ok := {{ $s.Receiver }}.Get{{ $pair.L.Name }}(); ok {
|
||||
{{- if $pair.R.Conditional }}
|
||||
value.Set{{ $pair.R.Name }}(fieldValue)
|
||||
{{- else }}
|
||||
value.{{ $pair.R.Name }} = fieldValue
|
||||
{{- end }}
|
||||
}
|
||||
{{ else }}
|
||||
{{- if $pair.R.Conditional -}}
|
||||
value.Set{{ $pair.R.Name }}({{ $s.Receiver }}.Get{{ $pair.L.Name }}())
|
||||
{{- else }}
|
||||
value.{{ $pair.R.Name }} = {{ $s.Receiver }}.Get{{ $pair.L.Name }}()
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
|
||||
return value
|
||||
{{- else }}
|
||||
{{- if eq ($s.Name) ($mapping.Name) }} return {{ $s.Receiver }}, true
|
||||
{{- else }} return nil, false {{ end }}
|
||||
{{- end }}{{- end }}
|
||||
}
|
||||
{{ end }}{{ end }}
|
||||
|
||||
{{ end }}
|
||||
{{ end }}
|
||||
|
||||
@@ -0,0 +1,94 @@
|
||||
{{- /*gotype: go.mau.fi/mautrix-telegram/pkg/gotd/gen.interfaceDef*/ -}}
|
||||
{{ define "interface_slice" }}{{ $f := . }}
|
||||
{{ template "slice" $f }}
|
||||
|
||||
{{ range $field := sortableFields ($f.SharedFields.Common) }}
|
||||
{{ template "slice_sort_by" concat ($f) ($field) }}
|
||||
{{ end }}
|
||||
|
||||
{{ range $s := $f.Constructors }}{{ if $s.Fields }}
|
||||
{{ range $field := mapCollectableFields ($f.SharedFields.Common) }}
|
||||
{{ template "slice_collect_to_map" concat ($f) ($field) ($s.Name) }}
|
||||
{{ end }}
|
||||
|
||||
// As{{ $s.Name }} returns copy with only {{ $s.Name }} constructors.
|
||||
func (s {{ template "slice_name" $f }}) As{{ $s.Name }}() (to {{ template "slice_name" $s }}) {
|
||||
for _, elem := range s {
|
||||
value, ok := elem.(*{{ $s.Name }})
|
||||
if !ok {
|
||||
continue
|
||||
}
|
||||
to = append(to, *value)
|
||||
}
|
||||
|
||||
return to
|
||||
}
|
||||
{{- end }}{{- end }}
|
||||
|
||||
{{ range $mapping := $f.Mappings }}{{- if (not $mapping.Constructor) }}
|
||||
|
||||
{{- range $field := mapCollectableFields (index ($f.SharedFields) ($mapping.MapperName)) }}
|
||||
{{- /*gotype: go.mau.fi/mautrix-telegram/pkg/gotd/gen.fieldDef*/ -}}
|
||||
// Fill{{ $mapping.MapperName }}Map fills only {{ $mapping.MapperName }} constructors to given map.
|
||||
func (s {{ template "slice_name" $f }}) Fill{{ $mapping.MapperName }}{{ template "map_collector_name" $field }}Map(to map[{{ $field.Type }}]{{ template "print_mapper_type" $mapping }}) {
|
||||
for _, elem := range s {
|
||||
value, ok := elem.As{{ $mapping.MapperName }}()
|
||||
if !ok {
|
||||
continue
|
||||
}
|
||||
to[value.Get{{ $field.Name }}()] = value
|
||||
}
|
||||
}
|
||||
|
||||
// {{ $mapping.MapperName }}ToMap collects only {{ $mapping.MapperName }} constructors to map.
|
||||
func (s {{ template "slice_name" $f }}) {{ $mapping.MapperName }}To{{ template "map_collector_name" $field }}Map() map[{{ $field.Type }}]{{ template "print_mapper_type" $mapping }} {
|
||||
r := make(map[{{ $field.Type }}]{{ template "print_mapper_type" $mapping }}, len(s))
|
||||
s.Fill{{ $mapping.MapperName }}{{ template "map_collector_name" $field }}Map(r)
|
||||
return r
|
||||
}
|
||||
{{ end }}
|
||||
|
||||
// AppendOnly{{ $mapping.MapperName }} appends only {{ $mapping.MapperName }} constructors to
|
||||
// given slice.
|
||||
func (s {{ template "slice_name" $f }}) AppendOnly{{ $mapping.MapperName }}(to []{{ template "print_mapper_type" $mapping }}) []{{ template "print_mapper_type" $mapping }} {
|
||||
for _, elem := range s {
|
||||
value, ok := elem.As{{ $mapping.MapperName }}()
|
||||
if !ok {
|
||||
continue
|
||||
}
|
||||
to = append(to, value)
|
||||
}
|
||||
|
||||
return to
|
||||
}
|
||||
|
||||
// As{{ $mapping.MapperName }} returns copy with only {{ $mapping.MapperName }} constructors.
|
||||
func (s {{ template "slice_name" $f }}) As{{ $mapping.MapperName }}() (to []{{ template "print_mapper_type" $mapping }}) {
|
||||
return s.AppendOnly{{ $mapping.MapperName }}(to)
|
||||
}
|
||||
|
||||
{{- range $method := concat ("First") ("Last") }}
|
||||
// {{ $method }}As{{ $mapping.MapperName }} returns {{ lower $method }} element of slice (if exists).
|
||||
func (s {{ template "slice_name" $f }}) {{ $method }}As{{ $mapping.MapperName }}() (v {{ template "print_mapper_type" $mapping }}, ok bool) {
|
||||
value, ok := s.{{ $method }}()
|
||||
if !ok {
|
||||
return
|
||||
}
|
||||
return value.As{{ $mapping.MapperName }}()
|
||||
}
|
||||
{{- end }}
|
||||
|
||||
{{- range $method := concat ("PopFirst") ("Pop") }}
|
||||
// {{ $method }}As{{ $mapping.MapperName }} returns element of slice (if exists).
|
||||
func (s *{{ template "slice_name" $f }}) {{ $method }}As{{ $mapping.MapperName }}() (v {{ template "print_mapper_type" $mapping }}, ok bool) {
|
||||
value, ok := s.{{ $method }}()
|
||||
if !ok {
|
||||
return
|
||||
}
|
||||
return value.As{{ $mapping.MapperName }}()
|
||||
}
|
||||
{{ end }}
|
||||
|
||||
{{- end }}{{- end }}
|
||||
|
||||
{{- end }}
|
||||
@@ -0,0 +1,31 @@
|
||||
{{- /*gotype: go.mau.fi/mautrix-telegram/pkg/gotd/gen.config*/ -}}
|
||||
|
||||
{{ define "main" }}
|
||||
{{ $pkg := $.Package }}
|
||||
{{ template "header" $ }}
|
||||
|
||||
{{ range $s := $.Structs }}
|
||||
{{ template "struct" $s }}
|
||||
{{ template "zero_derive" $s }}
|
||||
{{ template "string_derive" $s }}
|
||||
{{ if $.Flags.Mapping }}{{ template "fill_from" $s }}{{ end }}
|
||||
{{ template "type_info" $s }}
|
||||
{{ template "set_flags" $s }}
|
||||
{{ template "encode" $s }}
|
||||
{{ template "decode" $s }}
|
||||
{{- if $.Flags.TDLibJSON }}
|
||||
{{ template "encode_tdlib_json" $s }}
|
||||
{{ template "decode_tdlib_json" $s }}
|
||||
{{- end }}
|
||||
{{ if $.Flags.GetSet }}{{ template "getset" $s }}{{ end }}
|
||||
{{ if $.Flags.Mapping }}{{ template "field_mapping" newStructConfig ($s) ($) }}{{ end }}
|
||||
{{ if $.Flags.Client }}{{ template "method" $s }}{{ end }}
|
||||
{{ end }}
|
||||
|
||||
{{ range $f := $.Interfaces }}
|
||||
{{ template "interface" newInterfaceConfig ($f) ($) }}
|
||||
{{ if $.Flags.Mapping }}{{ template "interface_mapping" $f }}{{ end }}
|
||||
{{ template "box" newInterfaceConfig ($f) ($) }}
|
||||
{{ end }}
|
||||
|
||||
{{- end }}
|
||||
@@ -0,0 +1,62 @@
|
||||
{{- /*gotype: go.mau.fi/mautrix-telegram/pkg/gotd/gen.structDef*/ -}}
|
||||
{{ define "method" }}{{- $s := . -}}{{ if $s.Method }}
|
||||
// {{ $s.Method }} invokes method {{ $s.RawType }} returning error if any.
|
||||
{{- if $s.Docs }}
|
||||
{{- range $d := $s.Docs }}
|
||||
// {{ trim $d }}
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
{{- if $s.Links }}
|
||||
{{- template "print_links" $s.Links }}
|
||||
{{- end }}
|
||||
{{- if $s.Errors }}
|
||||
{{- template "print_errors" $s.Errors }}
|
||||
{{- end }}
|
||||
{{- if $s.URL }}
|
||||
//
|
||||
// See {{ $s.URL }} for reference.
|
||||
{{- end }}
|
||||
{{- if $s.BotCanUse }}
|
||||
// Can be used by bots.
|
||||
{{- end }}
|
||||
{{- if $s.Result }}
|
||||
{{- if $s.ResultSingular }}
|
||||
func (c *Client) {{ $s.Method }}({{ template "request_params" $s }}) ({{ if not $s.ResultVector }}*{{ $s.Result }}{{ else }}{{ template "slice_result_name" $s }}{{ end }}, error) {
|
||||
var result {{ $s.Result }}
|
||||
{{ template "pack_request" $s }}
|
||||
if err := c.rpc.Invoke(ctx, request, &result); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
{{- if $s.ResultVector }}
|
||||
return {{ template "slice_result_name" $s }}(result.Elems), nil
|
||||
{{- else }}
|
||||
return &result, nil
|
||||
{{- end }}
|
||||
}
|
||||
{{- else }}
|
||||
func (c *Client) {{ $s.Method }}({{ template "request_params" $s }}) ({{if ne $s.Result "BoolClass"}}{{ $s.Result }}{{ else }}bool{{ end }}, error) {
|
||||
var result {{ $s.ResultFunc }}Box
|
||||
{{ template "pack_request" $s }}
|
||||
if err := c.rpc.Invoke(ctx, request, &result); err != nil {
|
||||
{{- if ne $s.Result "BoolClass" }}return nil, err{{- else }}return false, err{{- end }}
|
||||
}
|
||||
{{- if ne $s.Result "BoolClass" }}
|
||||
return result.{{ $s.ResultBaseName }}, nil
|
||||
{{- else }}
|
||||
_, ok := result.{{ $s.ResultBaseName }}.(*BoolTrue)
|
||||
return ok, nil
|
||||
{{- end }}
|
||||
}
|
||||
{{- end }}
|
||||
{{- else }}
|
||||
func (c *Client) {{ $s.Method }}({{ template "request_params" $s }}) error {
|
||||
var ok Ok
|
||||
{{ template "pack_request" $s }}
|
||||
if err := c.rpc.Invoke(ctx, request, &ok); err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
||||
{{- end }}
|
||||
|
||||
{{ end }}{{ end }}
|
||||
@@ -0,0 +1,51 @@
|
||||
{{- /*gotype: go.mau.fi/mautrix-telegram/pkg/gotd/gen.config*/ -}}
|
||||
|
||||
{{ define "registry" }}
|
||||
{{ $pkg := $.Package }}
|
||||
{{ template "header" $ }}
|
||||
|
||||
{{- if $.Layer }}
|
||||
// Layer version of schema.
|
||||
const Layer = {{ $.Layer }}
|
||||
{{- end }}
|
||||
|
||||
// TypesMap returns mapping from type ids to TL type names.
|
||||
func TypesMap() map[uint32]string {
|
||||
return map[uint32]string {
|
||||
{{- range $elem := $.Registry }}
|
||||
{{ $elem.Name }}TypeID: "{{ $elem.Raw }}",
|
||||
{{- end }}
|
||||
}
|
||||
}
|
||||
|
||||
// NamesMap returns mapping from type names to TL type ids.
|
||||
func NamesMap() map[string]uint32 {
|
||||
return map[string]uint32 {
|
||||
{{- range $elem := $.Registry }}
|
||||
"{{ trimSuffix (trimSuffix ($elem.Raw) ($elem.HexID)) ("#") }}": {{ $elem.Name }}TypeID,
|
||||
{{- end }}
|
||||
}
|
||||
}
|
||||
|
||||
// TypesConstructorMap maps type ids to constructors.
|
||||
func TypesConstructorMap() map[uint32]func() bin.Object {
|
||||
return map[uint32]func() bin.Object {
|
||||
{{- range $elem := $.Registry }}
|
||||
{{ $elem.Name }}TypeID: func() bin.Object { return &{{ $elem.Name }}{} },
|
||||
{{- end }}
|
||||
}
|
||||
}
|
||||
|
||||
// ClassConstructorsMap maps class schema name to constructors type ids.
|
||||
func ClassConstructorsMap() map[string][]uint32 {
|
||||
return map[string][]uint32 {
|
||||
{{- range $elem := $.Interfaces }}
|
||||
{{ $elem.Name }}Name: {
|
||||
{{- range $c := $elem.Constructors }}
|
||||
{{ $c.Name }}TypeID,
|
||||
{{- end }}
|
||||
},
|
||||
{{- end }}
|
||||
}
|
||||
}
|
||||
{{ end }}
|
||||
@@ -0,0 +1,102 @@
|
||||
{{ define "server" }}
|
||||
{{ $pkg := $.Package }}
|
||||
{{ template "header" $ }}
|
||||
|
||||
type ServerDispatcher struct{
|
||||
fallback func(ctx context.Context, b *bin.Buffer) (bin.Encoder, error)
|
||||
handlers map[uint32]func(ctx context.Context, b *bin.Buffer) (bin.Encoder, error)
|
||||
}
|
||||
|
||||
func NewServerDispatcher(fallback func(ctx context.Context, b *bin.Buffer) (bin.Encoder, error)) *ServerDispatcher {
|
||||
return &ServerDispatcher{
|
||||
fallback: fallback,
|
||||
handlers: map[uint32]func(context.Context, *bin.Buffer) (bin.Encoder, error){},
|
||||
}
|
||||
}
|
||||
|
||||
func (s *ServerDispatcher) Handle(ctx context.Context, b *bin.Buffer) (bin.Encoder, error) {
|
||||
id, err := b.PeekID()
|
||||
if err != nil{
|
||||
return nil, err
|
||||
}
|
||||
|
||||
f, ok := s.handlers[id]
|
||||
if !ok {
|
||||
return s.fallback(ctx, b)
|
||||
}
|
||||
|
||||
return f(ctx, b)
|
||||
}
|
||||
|
||||
{{ range $s:= $.Structs }}{{- if notEmpty $s.Method }}
|
||||
{{- if $s.Result }}
|
||||
{{- if $s.ResultSingular }}
|
||||
func (s *ServerDispatcher) On{{ $s.Method }}(f func({{ template "request_params" $s }}) ({{ if not $s.ResultVector }}*{{ $s.Result }}{{ else }}{{ template "slice_result_name" $s }}{{ end }}, error)) {
|
||||
handler := func(ctx context.Context, b *bin.Buffer) (bin.Encoder, error) {
|
||||
var request {{ $s.Name }}
|
||||
if err := request.Decode(b); err != nil{
|
||||
return nil, err
|
||||
}
|
||||
|
||||
response, err := f({{- template "unpack_request" $s }})
|
||||
if err != nil{
|
||||
return nil, err
|
||||
}
|
||||
|
||||
{{- if $s.ResultVector }}
|
||||
return &{{ $s.Result }}{Elems: response}, nil
|
||||
{{- else }}
|
||||
return response, nil
|
||||
{{- end }}
|
||||
}
|
||||
|
||||
s.handlers[{{ $s.Name }}TypeID] = handler
|
||||
}
|
||||
{{- else }}
|
||||
func (s *ServerDispatcher) On{{ $s.Method }}(f func({{ template "request_params" $s }}) ({{if ne $s.Result "BoolClass"}}{{ $s.Result }}{{ else }}bool{{ end }}, error)) {
|
||||
handler := func(ctx context.Context, b *bin.Buffer) (bin.Encoder, error) {
|
||||
var request {{ $s.Name }}
|
||||
if err := request.Decode(b); err != nil{
|
||||
return nil, err
|
||||
}
|
||||
|
||||
response, err := f({{- template "unpack_request" $s }})
|
||||
if err != nil{
|
||||
return nil, err
|
||||
}
|
||||
|
||||
{{- if ne $s.Result "BoolClass" }}
|
||||
return &{{ $s.ResultFunc }}Box{ {{ $s.ResultBaseName }}: response }, nil
|
||||
{{- else }}
|
||||
if response {
|
||||
return &{{ $s.ResultFunc }}Box{ {{ $s.ResultBaseName }}: &BoolTrue{} }, nil
|
||||
}
|
||||
|
||||
return &{{ $s.ResultFunc }}Box{ {{ $s.ResultBaseName }}: &BoolFalse{} }, nil
|
||||
{{- end }}
|
||||
}
|
||||
|
||||
s.handlers[{{ $s.Name }}TypeID] = handler
|
||||
}
|
||||
{{- end }}
|
||||
{{- else }}
|
||||
func (s *ServerDispatcher) On{{ $s.Method }}(f func({{ template "request_params" $s }}) error) {
|
||||
handler := func(ctx context.Context, b *bin.Buffer) (bin.Encoder, error) {
|
||||
var request {{ $s.Name }}
|
||||
if err := request.Decode(b); err != nil{
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if err := f({{- template "unpack_request" $s }}); err != nil{
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return &Ok{}, nil
|
||||
}
|
||||
|
||||
s.handlers[{{ $s.Name }}TypeID] = handler
|
||||
}
|
||||
{{- end }}
|
||||
{{ end }}
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
@@ -0,0 +1,15 @@
|
||||
{{- /*gotype: go.mau.fi/mautrix-telegram/pkg/gotd/gen.structDef*/ -}}
|
||||
{{ define "set_flags" }}{{ $s := . }}
|
||||
{{- if hasFlags $s }}
|
||||
// SetFlags sets flags for non-zero fields.
|
||||
func ({{ $s.Receiver }} *{{ $s.Name }}) SetFlags() {
|
||||
{{- range $f := $s.Fields }}
|
||||
{{- if $f.Conditional }}
|
||||
if !({{ $s.Receiver }}.{{template "compare_zero" $f}}) {
|
||||
{{ $s.Receiver }}.{{ $f.ConditionalField }}.Set({{ $f.ConditionalIndex }})
|
||||
}
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
}
|
||||
{{- end }}
|
||||
{{ end }}
|
||||
@@ -0,0 +1,148 @@
|
||||
{{- /*gotype: go.mau.fi/mautrix-telegram/pkg/gotd/gen.config*/ -}}
|
||||
|
||||
{{ define "slices" }}
|
||||
//go:build !no_gotd_slices
|
||||
// +build !no_gotd_slices
|
||||
|
||||
{{ $pkg := $.Package }}
|
||||
{{ template "header" $ }}
|
||||
|
||||
{{- range $f := $.Interfaces }}
|
||||
{{ template "interface_slice" $f }}
|
||||
|
||||
{{- range $s := $.Structs }}{{- if generateSliceHelper ($s) -}}
|
||||
{{ template "struct_slice" $s }}
|
||||
{{- end }}{{- end }}
|
||||
|
||||
{{ end }}
|
||||
{{ end }}
|
||||
|
||||
{{ define "slice_sort_by" }}{{ $args := . -}}
|
||||
{{ $f := index ($args) (0) -}}
|
||||
{{ $field := index ($args) (1) -}}
|
||||
// SortBy{{ $field.Name }} sorts slice of {{ $f.Name }} by {{ $field.Name }}.
|
||||
func (s {{ template "slice_name" $f }}) SortBy{{ $field.Name }}() {{ template "slice_name" $f }} {
|
||||
return s.Sort(func(a, b {{ $f.Name }}) bool {
|
||||
return a.Get{{ $field.Name }}() < b.Get{{ $field.Name }}()
|
||||
})
|
||||
}
|
||||
|
||||
// SortStableBy{{ $field.Name }} sorts slice of {{ $f.Name }} by {{ $field.Name }}.
|
||||
func (s {{ template "slice_name" $f }}) SortStableBy{{ $field.Name }}() {{ template "slice_name" $f }} {
|
||||
return s.SortStable(func(a, b {{ $f.Name }}) bool {
|
||||
return a.Get{{ $field.Name }}() < b.Get{{ $field.Name }}()
|
||||
})
|
||||
}
|
||||
{{ end }}
|
||||
|
||||
{{ define "slice_collect_to_map" }}{{ $args := . -}}
|
||||
{{ $f := index ($args) (0) -}}
|
||||
{{ $field := index ($args) (1) -}}
|
||||
{{ $name := index ($args) (2) -}}
|
||||
// Fill{{ $name }}Map fills only {{ $name }} constructors to given map.
|
||||
func (s {{ template "slice_name" $f }}) Fill{{ $name }}{{ template "map_collector_name" $field }}Map(to map[{{ $field.Type }}]*{{ $name }} ) {
|
||||
for _, elem := range s {
|
||||
value, ok := elem.(*{{ $name }})
|
||||
if !ok {
|
||||
continue
|
||||
}
|
||||
to[value.Get{{ $field.Name }}()] = value
|
||||
}
|
||||
}
|
||||
|
||||
// {{ $name }}ToMap collects only {{ $name }} constructors to map.
|
||||
func (s {{ template "slice_name" $f }}) {{ $name }}To{{ template "map_collector_name" $field }}Map() map[{{ $field.Type }}]*{{ $name }} {
|
||||
r := make(map[{{ $field.Type }}]*{{ $name }}, len(s))
|
||||
s.Fill{{ $name }}Map(r)
|
||||
return r
|
||||
}
|
||||
{{ end }}
|
||||
|
||||
{{ define "slice_name" }}{{ $.Name }}Array{{ end }}
|
||||
{{ define "slice_field_name" }}{{ $.Type }}Array{{ end }}
|
||||
{{ define "slice_result_name" }}{{ if $.Interface }}{{ $.ResultFunc }}Array{{ else }}[]{{ $.ResultFunc }}{{ end }}{{ end }}
|
||||
|
||||
{{ define "slice" }}{{ $f := . }}
|
||||
// {{ template "slice_name" $f }} is adapter for slice of {{ $f.Name }}.
|
||||
type {{ template "slice_name" $f }} []{{ $f.Name }}
|
||||
|
||||
// Sort sorts slice of {{ $f.Name }}.
|
||||
func (s {{ template "slice_name" $f }}) Sort(less func(a, b {{ $f.Name }}) bool) {{ template "slice_name" $f }} {
|
||||
sort.Slice(s, func(i, j int) bool {
|
||||
return less(s[i], s[j])
|
||||
})
|
||||
return s
|
||||
}
|
||||
|
||||
// SortStable sorts slice of {{ $f.Name }}.
|
||||
func (s {{ template "slice_name" $f }}) SortStable(less func(a, b {{ $f.Name }}) bool) {{ template "slice_name" $f }} {
|
||||
sort.SliceStable(s, func(i, j int) bool {
|
||||
return less(s[i], s[j])
|
||||
})
|
||||
return s
|
||||
}
|
||||
|
||||
// Retain filters in-place slice of {{ $f.Name }}.
|
||||
func (s {{ template "slice_name" $f }}) Retain(keep func(x {{ $f.Name }}) bool) {{ template "slice_name" $f }} {
|
||||
n := 0
|
||||
for _, x := range s {
|
||||
if keep(x) {
|
||||
s[n] = x
|
||||
n++
|
||||
}
|
||||
}
|
||||
s = s[:n]
|
||||
|
||||
return s
|
||||
}
|
||||
|
||||
// First returns first element of slice (if exists).
|
||||
func (s {{ template "slice_name" $f }}) First() (v {{ $f.Name }}, ok bool) {
|
||||
if len(s) < 1 {
|
||||
return
|
||||
}
|
||||
return s[0], true
|
||||
}
|
||||
|
||||
// Last returns last element of slice (if exists).
|
||||
func (s {{ template "slice_name" $f }}) Last() (v {{ $f.Name }}, ok bool) {
|
||||
if len(s) < 1 {
|
||||
return
|
||||
}
|
||||
return s[len(s)-1], true
|
||||
}
|
||||
|
||||
|
||||
// PopFirst returns first element of slice (if exists) and deletes it.
|
||||
func (s *{{ template "slice_name" $f }}) PopFirst() (v {{ $f.Name }}, ok bool) {
|
||||
if s == nil || len(*s) < 1 {
|
||||
return
|
||||
}
|
||||
|
||||
a := *s
|
||||
v = a[0]
|
||||
|
||||
// Delete by index from SliceTricks.
|
||||
copy(a[0:], a[1:])
|
||||
var zero {{ $f.Name }}
|
||||
a[len(a)-1] = zero
|
||||
a = a[:len(a)-1]
|
||||
*s = a
|
||||
|
||||
return v, true
|
||||
}
|
||||
|
||||
// Pop returns last element of slice (if exists) and deletes it.
|
||||
func (s *{{ template "slice_name" $f }}) Pop() (v {{ $f.Name }}, ok bool) {
|
||||
if s == nil || len(*s) < 1 {
|
||||
return
|
||||
}
|
||||
|
||||
a := *s
|
||||
v = a[len(a)-1]
|
||||
a = a[:len(a)-1]
|
||||
*s = a
|
||||
|
||||
return v, true
|
||||
}
|
||||
{{ end }}
|
||||
@@ -0,0 +1,10 @@
|
||||
{{define "string_derive" }}{{ $s := $ }}
|
||||
// String implements fmt.Stringer.
|
||||
func ({{ $s.Receiver }} *{{ $s.Name }}) String() string {
|
||||
if {{ $s.Receiver }} == nil {
|
||||
return "{{ $.Name }}(nil)"
|
||||
}
|
||||
type Alias {{ $s.Name }}
|
||||
return fmt.Sprintf("{{ $s.Name }}%+v", Alias(*{{ $s.Receiver }}))
|
||||
}
|
||||
{{- end }}
|
||||
@@ -0,0 +1,46 @@
|
||||
{{- /*gotype: go.mau.fi/mautrix-telegram/pkg/gotd/gen.structDef*/ -}}
|
||||
{{ define "struct" }}{{ $s := . }}
|
||||
// {{ $s.Comment }}
|
||||
{{- if $s.Docs }}
|
||||
{{- template "print_comment" $s.Docs }}
|
||||
{{- end }}
|
||||
{{- if $s.Links }}
|
||||
{{- template "print_links" $s.Links }}
|
||||
{{- end }}
|
||||
{{- if $s.URL }}
|
||||
//
|
||||
// See {{ $s.URL }} for reference.
|
||||
{{- end }}
|
||||
type {{ $s.Name }} struct {
|
||||
{{- range $f := $s.Fields }}
|
||||
{{- template "print_comment" $f.Comment }}
|
||||
{{- if $f.Links}}
|
||||
{{- template "print_links" $f.Links }}
|
||||
{{- end }}
|
||||
{{- if and ($f.Conditional) (not $f.ConditionalBool) }}
|
||||
//
|
||||
// Use Set{{ $f.Name }} and Get{{ $f.Name }} helpers.
|
||||
{{- end }}
|
||||
{{ $f.Name }} {{ template "print_type" $f }}
|
||||
{{- end }}
|
||||
}
|
||||
|
||||
// {{ $s.Name }}TypeID is TL type id of {{ $s.Name }}.
|
||||
const {{ $s.Name }}TypeID = {{ if not $s.Vector }}0x{{ $s.HexID }}{{- else -}}bin.TypeVector{{- end }}
|
||||
|
||||
{{ if $s.Interface }}
|
||||
// construct implements constructor of {{ $s.Interface }}.
|
||||
func ({{ $s.Receiver }} {{ $s.Name }}) construct() {{ $s.Interface }} { return &{{ $s.Receiver }} }
|
||||
{{ end }}
|
||||
|
||||
// Ensuring interfaces in compile-time for {{ $s.Name }}.
|
||||
var (
|
||||
_ bin.Encoder = &{{ $s.Name }}{}
|
||||
_ bin.Decoder = &{{ $s.Name }}{}
|
||||
_ bin.BareEncoder = &{{ $s.Name }}{}
|
||||
_ bin.BareDecoder = &{{ $s.Name }}{}
|
||||
{{ if $s.Interface }}
|
||||
_ {{ $s.Interface }} = &{{ $s.Name }}{}
|
||||
{{ end }}
|
||||
)
|
||||
{{ end }}
|
||||
@@ -0,0 +1,23 @@
|
||||
{{- /*gotype: go.mau.fi/mautrix-telegram/pkg/gotd/gen.structDef*/ -}}
|
||||
{{ define "struct_slice" }}{{ $f := . }}
|
||||
{{ template "slice" $f }}
|
||||
|
||||
{{ range $field := sortableFields ($f.Fields) }}
|
||||
{{ template "slice_sort_by" concat ($f) ($field) }}
|
||||
{{ end }}
|
||||
{{ range $field := mapCollectableFields ($f.Fields) }}
|
||||
// FillMap fills constructors to given map.
|
||||
func (s {{ template "slice_name" $f }}) Fill{{ template "map_collector_name" $field }}Map(to map[{{ $field.Type }}]{{ $f.Name }} ) {
|
||||
for _, value := range s {
|
||||
to[value.Get{{ $field.Name }}()] = value
|
||||
}
|
||||
}
|
||||
|
||||
// ToMap collects constructors to map.
|
||||
func (s {{ template "slice_name" $f }}) To{{ template "map_collector_name" $field }}Map() map[{{ $field.Type }}]{{ $f.Name }} {
|
||||
r := make(map[{{ $field.Type }}]{{ $f.Name }}, len(s))
|
||||
s.Fill{{ template "map_collector_name" $field }}Map(r)
|
||||
return r
|
||||
}
|
||||
{{ end }}
|
||||
{{ end }}
|
||||
@@ -0,0 +1,40 @@
|
||||
{{- /*gotype: go.mau.fi/mautrix-telegram/pkg/gotd/gen.structDef*/ -}}
|
||||
{{ define "type_info" }}{{ $s := . }}
|
||||
// TypeID returns type id in TL schema.
|
||||
//
|
||||
// See https://core.telegram.org/mtproto/TL-tl#remarks.
|
||||
func (*{{ $s.Name }}) TypeID() uint32 {
|
||||
return {{ $s.Name }}TypeID
|
||||
}
|
||||
|
||||
// TypeName returns name of type in TL schema.
|
||||
func (*{{ $s.Name }}) TypeName() string {
|
||||
return "{{ $s.RawName }}"
|
||||
}
|
||||
|
||||
// TypeInfo returns info about TL type.
|
||||
func ({{ $s.Receiver }} *{{ $s.Name }}) TypeInfo() tdp.Type {
|
||||
typ := tdp.Type{
|
||||
Name: "{{ $s.RawName }}",
|
||||
ID: {{ $s.Name }}TypeID,
|
||||
}
|
||||
if {{ $s.Receiver }} == nil {
|
||||
typ.Null = true
|
||||
return typ
|
||||
}
|
||||
typ.Fields = []tdp.Field{
|
||||
{{- range $f := $s.Fields }}
|
||||
{{- if ne ($f.Type) ("bin.Fields") }}
|
||||
{
|
||||
Name: "{{ $f.Name }}",
|
||||
SchemaName: "{{ $f.RawName }}",
|
||||
{{- if $f.Conditional }}
|
||||
Null: !{{ $s.Receiver }}.{{ $f.ConditionalField }}.Has({{ $f.ConditionalIndex }}),
|
||||
{{- end }}
|
||||
},
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
}
|
||||
return typ
|
||||
}
|
||||
{{ end }}
|
||||
@@ -0,0 +1,72 @@
|
||||
{{ define "updates_classifier" }}
|
||||
{{ $pkg := $.Package }}
|
||||
{{ template "header" $ }}
|
||||
|
||||
func IsPtsUpdate(u UpdateClass) (pts, ptsCount int, ok bool) {
|
||||
switch u := u.(type) {
|
||||
{{- range $s := $.Structs }}{{ if and (eq $s.Interface "UpdateClass")
|
||||
(hasField $s.Fields "Pts" "int")
|
||||
(not (contains $s.Name "Channel")) }}
|
||||
{{- $ptsCount := or (and (hasField $s.Fields "PtsCount" "int") "u.PtsCount") "0" }}
|
||||
case *{{ $s.Name }}:
|
||||
return u.Pts, {{ $ptsCount }}, true
|
||||
{{- end }}{{ end }}
|
||||
}
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
func IsQtsUpdate(u UpdateClass) (qts int, ok bool) {
|
||||
switch u := u.(type) {
|
||||
{{- range $s := $.Structs }}{{ if and (eq $s.Interface "UpdateClass") (hasField $s.Fields "Qts" "int") }}
|
||||
case *{{ $s.Name }}:
|
||||
return u.Qts, true
|
||||
{{- end }}{{ end }}
|
||||
}
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
func IsChannelPtsUpdate(u UpdateClass) (channelID int64, pts, ptsCount int, ok bool, err error) {
|
||||
switch u := u.(type) {
|
||||
{{- range $s := $.Structs }}{{ if and (eq $s.Interface "UpdateClass")
|
||||
(hasField $s.Fields "Pts" "int")
|
||||
(contains $s.Name "Channel") }}
|
||||
{{- $ptsCount := or (and (hasField $s.Fields "PtsCount" "int") "u.PtsCount") "0" }}
|
||||
case *{{ $s.Name }}:
|
||||
{{- if (hasField $s.Fields "ChannelID" "int64") }}
|
||||
return u.ChannelID, u.Pts, {{ $ptsCount }}, true, nil
|
||||
{{- else }}
|
||||
channelID, err = extractChannelID(u.Message)
|
||||
return channelID, u.Pts, {{ $ptsCount }}, true, err
|
||||
{{- end }}{{ end }}{{ end }}
|
||||
}
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
func extractChannelID(msg MessageClass) (int64, error) {
|
||||
switch msg := msg.(type) {
|
||||
{{- range $s := $.Structs }}{{ if eq $s.Interface "MessageClass" }}
|
||||
case *{{ $s.Name }}:
|
||||
{{- range $field := $s.Fields }}{{ if eq $field.Name "PeerID" }}
|
||||
{{- if (optionalField $s $field) }}
|
||||
peer, ok := msg.GetPeerID()
|
||||
if !ok {
|
||||
return 0, errors.New("{{ $s.Name }} have no peerID field")
|
||||
}
|
||||
{{- else }}
|
||||
peer := msg.PeerID
|
||||
{{ end }}{{ end }}{{ end }}
|
||||
if c, ok := peer.(*PeerChannel); ok {
|
||||
return c.ChannelID, nil
|
||||
}
|
||||
|
||||
return 0, errors.New("unexpected peer type")
|
||||
{{- end }}{{ end }}
|
||||
default:
|
||||
return 0, errors.New("unexpected MessageClass type")
|
||||
}
|
||||
}
|
||||
|
||||
{{ end }}
|
||||
@@ -0,0 +1,88 @@
|
||||
{{ define "request_params" }}ctx context.Context{{- if .UnpackParameters }}{{- if .Fields }}
|
||||
{{- range $f := .Fields }}, {{ lowerGo $f.Name }} {{ template "print_type" $f }}{{- end }}
|
||||
{{- end }}
|
||||
{{- else }}, request *{{ .Name }}{{- end }}
|
||||
{{- end }}
|
||||
|
||||
{{ define "pack_request" }}{{- if .UnpackParameters }}
|
||||
request := &{{ $.Name }}{
|
||||
{{- range $f := $.Fields }}
|
||||
{{ $f.Name }}: {{ lowerGo $f.Name }},
|
||||
{{- end }}
|
||||
}
|
||||
{{- end }}{{- end }}
|
||||
|
||||
{{ define "unpack_request" }}ctx{{- if .UnpackParameters }}{{- if .Fields }}
|
||||
{{- range $f := $.Fields }}, request.{{ $f.Name }}
|
||||
{{- end }}{{- end }}
|
||||
{{- else }}, &request{{- end }}
|
||||
{{- end }}
|
||||
|
||||
{{ define "print_type" }}
|
||||
{{- /*gotype: go.mau.fi/mautrix-telegram/pkg/gotd/gen.fieldDef*/ -}}
|
||||
{{- if $.DoubleSlice }}[][]{{ $.Type }}
|
||||
{{- else if $.Slice }}[]{{ $.Type }}
|
||||
{{- else }}{{ $.Type }}
|
||||
{{- end }}{{- end }}
|
||||
|
||||
{{ define "getter_func_type" }}{{- /*gotype: go.mau.fi/mautrix-telegram/pkg/gotd/gen.fieldDef*/ -}}
|
||||
Get{{$.Name}}() (value {{ template "print_type" $ }}{{ if and ($.Conditional) (not $.ConditionalBool) }}, ok bool{{ end }})
|
||||
{{- end }}
|
||||
|
||||
{{ define "print_mapper_type" }}{{ $mapping := . -}}
|
||||
{{- /*gotype: go.mau.fi/mautrix-telegram/pkg/gotd/gen.constructorMapping*/ -}}
|
||||
{{- if not ($mapping.Concrete) }}{{ $mapping.Name }}{{- else }}*{{ $mapping.Name }}{{- end -}}
|
||||
{{ end }}
|
||||
|
||||
{{ define "mapper_func_type" }}{{ $mapping := . -}}
|
||||
{{- /*gotype: go.mau.fi/mautrix-telegram/pkg/gotd/gen.constructorMapping*/ -}}
|
||||
{{- if $mapping.Fields }}As{{ $mapping.MapperName }}() {{ template "print_mapper_type" $mapping }}
|
||||
{{- else }}As{{ $mapping.MapperName }}() ({{ template "print_mapper_type" $mapping }}, bool)
|
||||
{{- end }}{{- end }}
|
||||
|
||||
{{ define "print_links" }}
|
||||
//
|
||||
// Links:
|
||||
{{- range $i, $link := . }}
|
||||
// {{ add $i 1 }}) {{ $link }}
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
|
||||
{{ define "print_comment" }}
|
||||
{{- range $line := . }}
|
||||
// {{ trim $line }}
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
|
||||
{{ define "print_errors" }}
|
||||
//
|
||||
// Possible errors:
|
||||
{{- range $err := . }}
|
||||
// {{ $err.Code }} {{ $err.Type }}: {{ $err.Description }}
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
|
||||
{{ define "class_interface_header" }}{{ $f := . }}
|
||||
{{- /*gotype: go.mau.fi/mautrix-telegram/pkg/gotd/gen.interfaceDef*/ -}}
|
||||
bin.Encoder
|
||||
bin.Decoder
|
||||
bin.BareEncoder
|
||||
bin.BareDecoder
|
||||
construct() {{ $f.Name }}
|
||||
|
||||
// TypeID returns type id in TL schema.
|
||||
//
|
||||
// See https://core.telegram.org/mtproto/TL-tl#remarks.
|
||||
TypeID() uint32
|
||||
// TypeName returns name of type in TL schema.
|
||||
TypeName() string
|
||||
// String implements fmt.Stringer.
|
||||
String() string
|
||||
// Zero returns true if current object has a zero value.
|
||||
Zero() bool
|
||||
{{- end }}
|
||||
|
||||
|
||||
{{ define "map_collector_name" }}{{ $field := . }}{{- /*gotype: go.mau.fi/mautrix-telegram/pkg/gotd/gen.fieldDef*/ -}}
|
||||
{{ if ne ($field.Name) ("ID") }}{{ $field.Name }}{{ end }}
|
||||
{{- end }}
|
||||
@@ -0,0 +1,30 @@
|
||||
{{ define "zero_derive" }}{{ $s := . }}
|
||||
{{- /*gotype: go.mau.fi/mautrix-telegram/pkg/gotd/gen.structDef*/ -}}
|
||||
func ({{ $s.Receiver }} *{{ $s.Name }}) Zero() bool {
|
||||
if {{ $s.Receiver }} == nil {
|
||||
return true
|
||||
}
|
||||
{{- /*gotype: go.mau.fi/mautrix-telegram/pkg/gotd/gen.fieldDef*/ -}}
|
||||
{{- range $f := $s.Fields }}{{- if ne ($f.Name) ($f.ConditionalField) }}
|
||||
if !({{ $s.Receiver }}.{{template "compare_zero" $f}}) {
|
||||
return false
|
||||
}
|
||||
{{- end }}{{- end }}
|
||||
|
||||
return true
|
||||
}
|
||||
{{- end -}}
|
||||
|
||||
{{ define "compare_zero" }}
|
||||
{{- /*gotype: go.mau.fi/mautrix-telegram/pkg/gotd/gen.fieldDef*/ -}}
|
||||
{{- .Name -}}
|
||||
{{- if or (.Slice) (.DoubleSlice) -}} == nil
|
||||
{{- else if eq (.Type) ("bin.Int128") -}} == bin.Int128{}
|
||||
{{- else if eq (.Type) ("bin.Int256") -}} == bin.Int256{}
|
||||
{{- else if or (hasPrefix (.Type) ("int")) (hasPrefix (.Type) ("float")) }} == 0
|
||||
{{- else if eq (.Type) ("string") -}} == ""
|
||||
{{- else if eq (.Type) ("bool") -}} == false
|
||||
{{- else if eq (.Type) ("bin.Object") }} == nil
|
||||
{{- else if hasSuffix (.Type) ("Class") }} == nil
|
||||
{{- else -}}.Zero()
|
||||
{{- end -}}{{- end }}
|
||||
Reference in New Issue
Block a user