From e36330d430ab36ee264798a912d683fd0779b179 Mon Sep 17 00:00:00 2001 From: "Masih H. Derkani" Date: Wed, 10 Nov 2021 21:53:18 +0000 Subject: [PATCH] Implement handling of `Link` and `[]byte` in `printer` (#294) Implement textual representation for types `Link` and `[]byte` by `printer`. Represent `Link` as its string value, and `[]byte` as its hex encoded value. --- printer/printer.go | 13 ++++++- printer/printer_test.go | 84 ++++++++++++++++++++++++++++++++--------- 2 files changed, 78 insertions(+), 19 deletions(-) diff --git a/printer/printer.go b/printer/printer.go index 6589c4f1..2e25a121 100644 --- a/printer/printer.go +++ b/printer/printer.go @@ -1,6 +1,7 @@ package printer import ( + "encoding/hex" "io" "os" "strconv" @@ -350,8 +351,16 @@ func (z *printBuf) doString(indentLevel int, printState uint8, n datamodel.Node) z.writeString(strconv.QuoteToGraphic(x)) z.writeString("}") case datamodel.Kind_Bytes: - panic("TODO") + x, _ := n.AsBytes() + z.writeString("{") + dst := make([]byte, hex.EncodedLen(len(x))) + hex.Encode(dst, x) + z.writeString(string(dst)) + z.writeString("}") case datamodel.Kind_Link: - panic("TODO") + x, _ := n.AsLink() + z.writeString("{") + z.writeString(x.String()) + z.writeString("}") } } diff --git a/printer/printer_test.go b/printer/printer_test.go index c808effa..534a4c5b 100644 --- a/printer/printer_test.go +++ b/printer/printer_test.go @@ -6,27 +6,35 @@ import ( qt "github.com/frankban/quicktest" "github.com/warpfork/go-wish" + "github.com/ipfs/go-cid" "github.com/ipld/go-ipld-prime/datamodel" "github.com/ipld/go-ipld-prime/fluent/qp" + cidlink "github.com/ipld/go-ipld-prime/linking/cid" "github.com/ipld/go-ipld-prime/node/basicnode" "github.com/ipld/go-ipld-prime/node/bindnode" "github.com/ipld/go-ipld-prime/schema" ) +var testLink = func() datamodel.Link { + someCid, _ := cid.Cast([]byte{1, 85, 0, 5, 0, 1, 2, 3, 4}) + return cidlink.Link{Cid: someCid} +}() + func TestSimpleData(t *testing.T) { - n, _ := qp.BuildMap(basicnode.Prototype.Any, -1, func(ma datamodel.MapAssembler) { - qp.MapEntry(ma, "some key", qp.String("some value")) - qp.MapEntry(ma, "another key", qp.String("another value")) - qp.MapEntry(ma, "nested map", qp.Map(2, func(ma datamodel.MapAssembler) { - qp.MapEntry(ma, "deeper entries", qp.String("deeper values")) - qp.MapEntry(ma, "more deeper entries", qp.String("more deeper values")) - })) - qp.MapEntry(ma, "nested list", qp.List(2, func(la datamodel.ListAssembler) { - qp.ListEntry(la, qp.Int(1)) - qp.ListEntry(la, qp.Int(2)) - })) - }) - qt.Check(t, Sprint(n), qt.CmpEquals(), wish.Dedent(` + t.Run("nested-maps", func(t *testing.T) { + n, _ := qp.BuildMap(basicnode.Prototype.Any, -1, func(ma datamodel.MapAssembler) { + qp.MapEntry(ma, "some key", qp.String("some value")) + qp.MapEntry(ma, "another key", qp.String("another value")) + qp.MapEntry(ma, "nested map", qp.Map(2, func(ma datamodel.MapAssembler) { + qp.MapEntry(ma, "deeper entries", qp.String("deeper values")) + qp.MapEntry(ma, "more deeper entries", qp.String("more deeper values")) + })) + qp.MapEntry(ma, "nested list", qp.List(2, func(la datamodel.ListAssembler) { + qp.ListEntry(la, qp.Int(1)) + qp.ListEntry(la, qp.Int(2)) + })) + }) + qt.Check(t, Sprint(n), qt.CmpEquals(), wish.Dedent(` map{ string{"some key"}: string{"some value"} string{"another key"}: string{"another value"} @@ -39,27 +47,69 @@ func TestSimpleData(t *testing.T) { 1: int{2} } }`, - )) + )) + }) + + t.Run("map-with-link-and-bytes", func(t *testing.T) { + n, _ := qp.BuildMap(basicnode.Prototype.Any, -1, func(ma datamodel.MapAssembler) { + qp.MapEntry(ma, "some key", qp.Link(testLink)) + qp.MapEntry(ma, "another key", qp.String("another value")) + qp.MapEntry(ma, "nested map", qp.Map(2, func(ma datamodel.MapAssembler) { + qp.MapEntry(ma, "deeper entries", qp.String("deeper values")) + qp.MapEntry(ma, "more deeper entries", qp.Link(testLink)) + qp.MapEntry(ma, "yet another deeper entries", qp.Bytes([]byte("fish"))) + })) + qp.MapEntry(ma, "nested list", qp.List(2, func(la datamodel.ListAssembler) { + qp.ListEntry(la, qp.Bytes([]byte("ghoti"))) + qp.ListEntry(la, qp.Int(1)) + qp.ListEntry(la, qp.Link(testLink)) + })) + }) + qt.Check(t, Sprint(n), qt.CmpEquals(), wish.Dedent(` + map{ + string{"some key"}: link{bafkqabiaaebagba} + string{"another key"}: string{"another value"} + string{"nested map"}: map{ + string{"deeper entries"}: string{"deeper values"} + string{"more deeper entries"}: link{bafkqabiaaebagba} + string{"yet another deeper entries"}: bytes{66697368} + } + string{"nested list"}: list{ + 0: bytes{67686f7469} + 1: int{1} + 2: link{bafkqabiaaebagba} + } + }`, + )) + }) } func TestTypedData(t *testing.T) { t.Run("structs", func(t *testing.T) { type FooBar struct { - Foo string - Bar string + Foo string + Bar string + Baz []byte + Jazz datamodel.Link } ts := schema.MustTypeSystem( schema.SpawnString("String"), + schema.SpawnBytes("Bytes"), + schema.SpawnLink("Link"), schema.SpawnStruct("FooBar", []schema.StructField{ schema.SpawnStructField("foo", "String", false, false), schema.SpawnStructField("bar", "String", false, false), + schema.SpawnStructField("baz", "Bytes", false, false), + schema.SpawnStructField("jazz", "Link", false, false), }, nil), ) - n := bindnode.Wrap(&FooBar{"x", "y"}, ts.TypeByName("FooBar")) + n := bindnode.Wrap(&FooBar{"x", "y", []byte("zed"), testLink}, ts.TypeByName("FooBar")) qt.Check(t, Sprint(n), qt.CmpEquals(), wish.Dedent(` struct{ foo: string{"x"} bar: string{"y"} + baz: bytes{7a6564} + jazz: link{bafkqabiaaebagba} }`, )) })