Skip to content

Commit

Permalink
Merge pull request #8 from tdakkota/feature/vector-decoding
Browse files Browse the repository at this point in the history
Vector response decoding
  • Loading branch information
ernado authored Dec 11, 2020
2 parents 5212055 + 4baf63b commit e4381ce
Show file tree
Hide file tree
Showing 51 changed files with 1,708 additions and 59 deletions.
12 changes: 11 additions & 1 deletion internal/gen/_template/main.tmpl
Original file line number Diff line number Diff line change
Expand Up @@ -30,15 +30,19 @@ type {{ $s.Name }} struct {
{{- end }}
}

{{- if not $s.Vector }}
// {{ $s.Name }}TypeID is TL type id of {{ $s.Name }}.
const {{ $s.Name }}TypeID = 0x{{ $s.HexID }};
{{- end }}

// 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 }}
{{- range $f := $s.Fields }}
{{- if not $f.ConditionalBool }}
{{- if $f.Conditional }}
Expand Down Expand Up @@ -125,9 +129,11 @@ func ({{ $s.Receiver }} *{{ $s.Name }}) Decode({{ $s.BufArg }} *bin.Buffer) erro
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 }}
{{- range $f := $s.Fields }}
{{- if $f.ConditionalBool }}
{{ $s.Receiver }}.{{ $f.Name }} = {{ $s.Receiver }}.{{ $f.ConditionalField }}.Has({{ $f.ConditionalIndex }})
Expand Down Expand Up @@ -228,12 +234,16 @@ _ {{ $s.Interface }} = &{{ $s.Name }}{}
{{- end }}
{{- if $s.Result }}
{{- if $s.ResultSingular }}
func (c *Client) {{ $s.Method }}(ctx context.Context, request *{{ $s.Name }}) (*{{ $s.Result }}, error) {
func (c *Client) {{ $s.Method }}(ctx context.Context, request *{{ $s.Name }}) ({{ if not $s.ResultVector }}*{{ $s.Result }}{{ else }}[]{{ $s.ResultFunc }}{{ end }}, error) {
var result {{ $s.Result }}
if err := c.rpc.InvokeRaw(ctx, request, &result); err != nil {
return nil, err
}
{{- if $s.ResultVector }}
return result.Elems, nil
{{- else }}
return &result, nil
{{- end }}
}
{{- else }}
func (c *Client) {{ $s.Method }}(ctx context.Context, request *{{ $s.Name }}) ({{ $s.Result }}, error) {
Expand Down
2 changes: 2 additions & 0 deletions internal/gen/_testdata/example.tl
Original file line number Diff line number Diff line change
Expand Up @@ -144,3 +144,5 @@ send msg:SMS = SMS;
sendMultipleSMS messages:vector<SMS> = Ok;

doAuth = Auth;

echoVector ids:Vector<int> = Vector<int>;
33 changes: 33 additions & 0 deletions internal/gen/example/example_test.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package td

import (
"context"
"testing"

"github.com/stretchr/testify/require"
Expand Down Expand Up @@ -148,6 +149,38 @@ func TestGetUpdatesRespNilElem(t *testing.T) {
}
}

type mockInvoker struct {
input bin.Encoder
output bin.Encoder
}

func (m *mockInvoker) InvokeRaw(ctx context.Context, input bin.Encoder, output bin.Decoder) error {
m.input = input

buf := bin.Buffer{}
err := m.output.Encode(&buf)
if err != nil {
return err
}

return output.Decode(&buf)
}

func TestVectorResponse(t *testing.T) {
elems := []int{1, 2, 3}
m := mockInvoker{
output: &IntVector{Elems: []int{1, 2, 3}},
}
client := NewClient(&m)

r, err := client.EchoVector(context.Background(), &EchoVectorRequest{})
if err != nil {
t.Fatal(err)
}

require.Equal(t, r, elems)
}

func BenchmarkDecodeBool(b *testing.B) {
b.ReportAllocs()

Expand Down
80 changes: 80 additions & 0 deletions internal/gen/example/tl_echo_vector_gen.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

60 changes: 60 additions & 0 deletions internal/gen/example/tl_int_vector_gen.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions internal/gen/example/tl_registry_gen.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

56 changes: 56 additions & 0 deletions internal/gen/generic.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
package gen

import (
"strings"

"github.com/gotd/tl"
)

func (g *Generator) instantiateVector(className string) (class classBinding, err error) {
class, ok := g.classes[className]
if ok {
return class, nil
}

elementName := strings.TrimPrefix(className[:len(className)-1], "Vector<")
goElementName := g.classes[elementName].Name
if goElementName == "" {
goElementName = elementName
}

f, err := g.makeField(tl.Parameter{
Name: "Elems",
Type: tl.Type{
Name: "Vector",
GenericArg: &tl.Type{
Name: elementName,
},
},
}, nil)
if err != nil {
return
}
f.Comment = "Elements of " + className

goName := strings.Title(goElementName) + "Vector"
class = classBinding{
Name: goName,
Func: f.Type,
Singular: true,
Vector: true,
}
g.classes[className] = class

g.structs = append(g.structs, structDef{
Name: goName,
Receiver: "vec",
BufArg: "b",
RawType: className,
Vector: true,
Fields: []fieldDef{f},
BaseName: goName,
Comment: goName + " is a box for " + className,
})

return class, nil
}
Loading

0 comments on commit e4381ce

Please sign in to comment.