Skip to content

Commit 14b828a

Browse files
authored
Merge pull request #81 from ipfs/feat/binary-marshaler
Let Cid implement Binary[Un]Marshaler and Text[Un]Marshaler interfaces.
2 parents 37bf2f9 + 0043957 commit 14b828a

File tree

2 files changed

+78
-0
lines changed

2 files changed

+78
-0
lines changed

cid.go

+40
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ package cid
2121

2222
import (
2323
"bytes"
24+
"encoding"
2425
"encoding/binary"
2526
"encoding/json"
2627
"errors"
@@ -167,6 +168,11 @@ func NewCidV1(codecType uint64, mhash mh.Multihash) Cid {
167168
return Cid{string(buf[:n+hashlen])}
168169
}
169170

171+
var _ encoding.BinaryMarshaler = Cid{}
172+
var _ encoding.BinaryUnmarshaler = (*Cid)(nil)
173+
var _ encoding.TextMarshaler = Cid{}
174+
var _ encoding.TextUnmarshaler = (*Cid)(nil)
175+
170176
// Cid represents a self-describing content addressed
171177
// identifier. It is formed by a Version, a Codec (which indicates
172178
// a multicodec-packed content type) and a Multihash.
@@ -314,6 +320,28 @@ func Cast(data []byte) (Cid, error) {
314320
return Cid{string(data[0 : n+cn+len(h)])}, nil
315321
}
316322

323+
// UnmarshalBinary is equivalent to Cast(). It implements the
324+
// encoding.BinaryUnmarshaler interface.
325+
func (c *Cid) UnmarshalBinary(data []byte) error {
326+
casted, err := Cast(data)
327+
if err != nil {
328+
return err
329+
}
330+
c.str = casted.str
331+
return nil
332+
}
333+
334+
// UnmarshalText is equivalent to Decode(). It implements the
335+
// encoding.TextUnmarshaler interface.
336+
func (c *Cid) UnmarshalText(text []byte) error {
337+
decodedCid, err := Decode(string(text))
338+
if err != nil {
339+
return err
340+
}
341+
c.str = decodedCid.str
342+
return nil
343+
}
344+
317345
// Version returns the Cid version.
318346
func (c Cid) Version() uint64 {
319347
if len(c.str) == 34 && c.str[0] == 18 && c.str[1] == 32 {
@@ -404,6 +432,18 @@ func (c Cid) Bytes() []byte {
404432
return []byte(c.str)
405433
}
406434

435+
// MarshalBinary is equivalent to Bytes(). It implements the
436+
// encoding.BinaryMarshaler interface.
437+
func (c Cid) MarshalBinary() ([]byte, error) {
438+
return c.Bytes(), nil
439+
}
440+
441+
// MarshalText is equivalent to String(). It implements the
442+
// encoding.TextMarshaler interface.
443+
func (c Cid) MarshalText() ([]byte, error) {
444+
return []byte(c.String()), nil
445+
}
446+
407447
// Equals checks that two Cids are the same.
408448
// In order for two Cids to be considered equal, the
409449
// Version, the Codec and the Multihash must match.

cid_test.go

+38
Original file line numberDiff line numberDiff line change
@@ -158,6 +158,44 @@ func TestBasesMarshaling(t *testing.T) {
158158
}
159159
}
160160

161+
func TestBinaryMarshaling(t *testing.T) {
162+
data := []byte("this is some test content")
163+
hash, _ := mh.Sum(data, mh.SHA2_256, -1)
164+
c := NewCidV1(DagCBOR, hash)
165+
var c2 Cid
166+
167+
data, err := c.MarshalBinary()
168+
if err != nil {
169+
t.Fatal(err)
170+
}
171+
err = c2.UnmarshalBinary(data)
172+
if err != nil {
173+
t.Fatal(err)
174+
}
175+
if !c.Equals(c2) {
176+
t.Errorf("cids should be the same: %s %s", c, c2)
177+
}
178+
}
179+
180+
func TestTextMarshaling(t *testing.T) {
181+
data := []byte("this is some test content")
182+
hash, _ := mh.Sum(data, mh.SHA2_256, -1)
183+
c := NewCidV1(DagCBOR, hash)
184+
var c2 Cid
185+
186+
data, err := c.MarshalText()
187+
if err != nil {
188+
t.Fatal(err)
189+
}
190+
err = c2.UnmarshalText(data)
191+
if err != nil {
192+
t.Fatal(err)
193+
}
194+
if !c.Equals(c2) {
195+
t.Errorf("cids should be the same: %s %s", c, c2)
196+
}
197+
}
198+
161199
func TestEmptyString(t *testing.T) {
162200
_, err := Decode("")
163201
if err == nil {

0 commit comments

Comments
 (0)