Skip to content

Commit

Permalink
Merge pull request #81 from ipfs/feat/binary-marshaler
Browse files Browse the repository at this point in the history
Let Cid implement Binary[Un]Marshaler and Text[Un]Marshaler interfaces.
  • Loading branch information
hsanjuan committed Feb 20, 2019
2 parents 37bf2f9 + 0043957 commit 14b828a
Show file tree
Hide file tree
Showing 2 changed files with 78 additions and 0 deletions.
40 changes: 40 additions & 0 deletions cid.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ package cid

import (
"bytes"
"encoding"
"encoding/binary"
"encoding/json"
"errors"
Expand Down Expand Up @@ -167,6 +168,11 @@ func NewCidV1(codecType uint64, mhash mh.Multihash) Cid {
return Cid{string(buf[:n+hashlen])}
}

var _ encoding.BinaryMarshaler = Cid{}
var _ encoding.BinaryUnmarshaler = (*Cid)(nil)
var _ encoding.TextMarshaler = Cid{}
var _ encoding.TextUnmarshaler = (*Cid)(nil)

// Cid represents a self-describing content addressed
// identifier. It is formed by a Version, a Codec (which indicates
// a multicodec-packed content type) and a Multihash.
Expand Down Expand Up @@ -314,6 +320,28 @@ func Cast(data []byte) (Cid, error) {
return Cid{string(data[0 : n+cn+len(h)])}, nil
}

// UnmarshalBinary is equivalent to Cast(). It implements the
// encoding.BinaryUnmarshaler interface.
func (c *Cid) UnmarshalBinary(data []byte) error {
casted, err := Cast(data)
if err != nil {
return err
}
c.str = casted.str
return nil
}

// UnmarshalText is equivalent to Decode(). It implements the
// encoding.TextUnmarshaler interface.
func (c *Cid) UnmarshalText(text []byte) error {
decodedCid, err := Decode(string(text))
if err != nil {
return err
}
c.str = decodedCid.str
return nil
}

// Version returns the Cid version.
func (c Cid) Version() uint64 {
if len(c.str) == 34 && c.str[0] == 18 && c.str[1] == 32 {
Expand Down Expand Up @@ -404,6 +432,18 @@ func (c Cid) Bytes() []byte {
return []byte(c.str)
}

// MarshalBinary is equivalent to Bytes(). It implements the
// encoding.BinaryMarshaler interface.
func (c Cid) MarshalBinary() ([]byte, error) {
return c.Bytes(), nil
}

// MarshalText is equivalent to String(). It implements the
// encoding.TextMarshaler interface.
func (c Cid) MarshalText() ([]byte, error) {
return []byte(c.String()), nil
}

// Equals checks that two Cids are the same.
// In order for two Cids to be considered equal, the
// Version, the Codec and the Multihash must match.
Expand Down
38 changes: 38 additions & 0 deletions cid_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -158,6 +158,44 @@ func TestBasesMarshaling(t *testing.T) {
}
}

func TestBinaryMarshaling(t *testing.T) {
data := []byte("this is some test content")
hash, _ := mh.Sum(data, mh.SHA2_256, -1)
c := NewCidV1(DagCBOR, hash)
var c2 Cid

data, err := c.MarshalBinary()
if err != nil {
t.Fatal(err)
}
err = c2.UnmarshalBinary(data)
if err != nil {
t.Fatal(err)
}
if !c.Equals(c2) {
t.Errorf("cids should be the same: %s %s", c, c2)
}
}

func TestTextMarshaling(t *testing.T) {
data := []byte("this is some test content")
hash, _ := mh.Sum(data, mh.SHA2_256, -1)
c := NewCidV1(DagCBOR, hash)
var c2 Cid

data, err := c.MarshalText()
if err != nil {
t.Fatal(err)
}
err = c2.UnmarshalText(data)
if err != nil {
t.Fatal(err)
}
if !c.Equals(c2) {
t.Errorf("cids should be the same: %s %s", c, c2)
}
}

func TestEmptyString(t *testing.T) {
_, err := Decode("")
if err == nil {
Expand Down

0 comments on commit 14b828a

Please sign in to comment.