Skip to content

Commit

Permalink
Merge pull request #86 from tdakkota/feature/mtprint/more-formats-str…
Browse files Browse the repository at this point in the history
…eaming

mtprint: Add JSON and pretty-print formats, stream reading
  • Loading branch information
ernado authored Dec 26, 2020
2 parents 718af61 + 1121132 commit c84aa89
Show file tree
Hide file tree
Showing 5 changed files with 161 additions and 30 deletions.
34 changes: 4 additions & 30 deletions cmd/mtprint/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,19 +3,15 @@ package main

import (
"flag"
"fmt"
"io"
"io/ioutil"
"os"

"github.com/gotd/td/bin"
"github.com/gotd/td/internal/mt"
"github.com/gotd/td/internal/tmap"
"github.com/gotd/td/tg"
"github.com/gotd/td/internal/proto/codec"
)

func main() {
inputName := flag.String("f", "", "input file (blank for stdin)")
format := flag.String("format", "go", "print format")
flag.Parse()

var reader io.Reader = os.Stdin
Expand All @@ -28,30 +24,8 @@ func main() {
reader = f
}

// TODO: Streaming mode via intermediate protocol.
buf, err := ioutil.ReadAll(reader)
if err != nil {
p := NewPrinter(reader, formats(*format), codec.Intermediate{})
if err := p.Print(os.Stdout); err != nil {
panic(err)
}

b := &bin.Buffer{Buf: buf}
id, err := b.PeekID()
if err != nil {
panic(err)
}

c := tmap.NewConstructor(
tg.TypesConstructorMap(),
mt.TypesConstructorMap(),
)
v := c.New(id)
if v == nil {
panic(fmt.Sprintf("failed to find type 0x%x", id))
}

if err := v.Decode(b); err != nil {
panic(err)
}

fmt.Print(v)
}
114 changes: 114 additions & 0 deletions cmd/mtprint/printer.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,114 @@
package main

import (
"encoding/json"
"errors"
"fmt"
"io"

"github.com/k0kubun/pp"
"golang.org/x/xerrors"

"github.com/gotd/td/bin"
"github.com/gotd/td/internal/mt"
"github.com/gotd/td/internal/proto/codec"
"github.com/gotd/td/internal/tmap"
"github.com/gotd/td/tg"
"github.com/gotd/td/transport"
)

// Formatter formats given bin.Object and prints it to io.Writer.
type Formatter interface {
Format(w io.Writer, i bin.Object) error
}

// FormatterFunc is functional adapter for Formatter.
type FormatterFunc func(w io.Writer, i bin.Object) error

// Format implements Formatter.
func (f FormatterFunc) Format(w io.Writer, i bin.Object) error {
return f(w, i)
}

func formats(name string) Formatter {
switch name {
case "json":
return FormatterFunc(func(w io.Writer, i bin.Object) error {
e := json.NewEncoder(w)
e.SetIndent("", "\t")
return e.Encode(i)
})
case "pp":
return FormatterFunc(func(w io.Writer, i bin.Object) error {
_, err := pp.Fprintln(w, i)
return err
})
default: // "go" format
return FormatterFunc(func(w io.Writer, i bin.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
}

v := m.New(id)
if v == nil {
return xerrors.Errorf("failed to find type 0x%x", id)
}

if err := v.Decode(b); err != nil {
return err
}

if err := p.format.Format(output, v); err != nil {
return err
}
}
}
38 changes: 38 additions & 0 deletions cmd/mtprint/printer_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
package main

import (
"bytes"
"testing"

"github.com/stretchr/testify/require"

"github.com/gotd/td/bin"
"github.com/gotd/td/internal/mt"
"github.com/gotd/td/internal/proto/codec"
"github.com/gotd/td/tg"
)

func Test_readAndPrint(t *testing.T) {
c := codec.Intermediate{}

input := &bytes.Buffer{}
buf := &bin.Buffer{}

objects := []bin.Object{
&mt.RPCResult{},
&mt.RPCError{},
&tg.CodeSettings{},
}
for _, o := range objects {
buf.Reset()
require.NoError(t, o.Encode(buf))
require.NoError(t, c.Write(input, buf))
}

output := &bytes.Buffer{}
require.NoError(t, NewPrinter(input, formats("go"), c).Print(output))
out := output.String()
require.Contains(t, out, "RPCResult")
require.Contains(t, out, "RPCError")
require.Contains(t, out, "CodeSettings")
}
1 change: 1 addition & 0 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ require (
github.com/gotd/neo v0.1.1
github.com/gotd/tl v0.3.0
github.com/gotd/xor v0.1.1
github.com/k0kubun/pp v2.4.0+incompatible
github.com/stephens2424/writerset v1.0.2 // indirect
github.com/stretchr/testify v1.6.1
go.uber.org/zap v1.16.0
Expand Down
4 changes: 4 additions & 0 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -142,7 +142,10 @@ github.com/jtolds/gls v4.20.0+incompatible/go.mod h1:QJZ7F/aHp+rZTRtaJ1ow/lLfFfV
github.com/juju/errors v0.0.0-20181118221551-089d3ea4e4d5/go.mod h1:W54LbzXuIE0boCoNJfwqpmkKJ1O4TCTZMetAt6jGk7Q=
github.com/juju/loggo v0.0.0-20180524022052-584905176618/go.mod h1:vgyd7OREkbtVEN/8IXZe5Ooef3LQePvuBm9UWj6ZL8U=
github.com/juju/testing v0.0.0-20180920084828-472a3e8b2073/go.mod h1:63prj8cnj0tU0S9OHjGJn+b1h0ZghCndfnbQolrYTwA=
github.com/k0kubun/colorstring v0.0.0-20150214042306-9440f1994b88 h1:uC1QfSlInpQF+M0ao65imhwqKnz3Q2z/d8PWZRMQvDM=
github.com/k0kubun/colorstring v0.0.0-20150214042306-9440f1994b88/go.mod h1:3w7q1U84EfirKl04SVQ/s7nPm1ZPhiXd34z40TNz36k=
github.com/k0kubun/pp v2.4.0+incompatible h1:M9iQzcejGfiBjDa7+Tc0rJgR7WFKP6rim/Q0DDrAT3g=
github.com/k0kubun/pp v2.4.0+incompatible/go.mod h1:GWse8YhT0p8pT4ir3ZgBbfZild3tgzSScAn6HmfYukg=
github.com/kataras/golog v0.0.9/go.mod h1:12HJgwBIZFNGL0EJnMRhmvGA0PQGx8VFwrZtM4CqbAk=
github.com/kataras/iris/v12 v12.0.1/go.mod h1:udK4vLQKkdDqMGJJVd/msuMtN6hpYJhg/lSzuxjhO+U=
github.com/kataras/neffos v0.0.10/go.mod h1:ZYmJC07hQPW67eKuzlfY7SO3bC0mw83A3j6im82hfqw=
Expand Down Expand Up @@ -240,6 +243,7 @@ github.com/xordataexchange/crypt v0.0.3-0.20170626215501-b2862e3d0a77/go.mod h1:
github.com/yalp/jsonpath v0.0.0-20180802001716-5cc68e5049a0/go.mod h1:/LWChgwKmvncFJFHJ7Gvn9wZArjbV5/FppcK2fKk/tI=
github.com/yudai/gojsondiff v1.0.0/go.mod h1:AY32+k2cwILAkW1fbgxQ5mUmMiZFgLIV+FBNExI05xg=
github.com/yudai/golcs v0.0.0-20170316035057-ecda9a501e82/go.mod h1:lgjkn3NuSvDfVJdfcVVdX+jpBxNmX4rDAzaS45IcYoM=
github.com/yudai/pp v2.0.1+incompatible h1:Q4//iY4pNF6yPLZIigmvcl7k/bPgrcTPIFIcmawg5bI=
github.com/yudai/pp v2.0.1+incompatible/go.mod h1:PuxR/8QJ7cyCkFp/aUDS+JY727OFEZkTdatxwunjIkc=
go.uber.org/atomic v1.6.0 h1:Ezj3JGmsOnG1MoRWQkPBsKLe9DwWD9QeXzTRzzldNVk=
go.uber.org/atomic v1.6.0/go.mod h1:sABNBOSYdrvTF6hTgEIbc7YasKWGhgEQZyfxyTvoXHQ=
Expand Down

0 comments on commit c84aa89

Please sign in to comment.