-
Notifications
You must be signed in to change notification settings - Fork 6
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Create a CID encoder that optionally upgrades a CIDv0 to CIDv1
- Loading branch information
Showing
3 changed files
with
122 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -43,3 +43,4 @@ func TestBadCidConv(t *testing.T) { | |
t.Fatal("expected failure") | ||
} | ||
} | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,59 @@ | ||
package cidenc | ||
|
||
import ( | ||
cid "github.com/ipfs/go-cid" | ||
mbase "github.com/multiformats/go-multibase" | ||
) | ||
|
||
// Encoder is a basic Encoder that will encode Cid's using a specifed | ||
// base and optionally upgrade a CIDv0 to CIDv1 | ||
type Encoder struct { | ||
Base mbase.Encoder // The multibase to use | ||
Upgrade bool // If true upgrade CIDv0 to CIDv1 when encoding | ||
} | ||
|
||
// Default return a new default encoder | ||
func Default() Encoder { | ||
return Encoder{Base: mbase.MustNewEncoder(mbase.Base58BTC)} | ||
} | ||
|
||
// Encode encoded the cid using the parameters of the Encoder | ||
func (enc Encoder) Encode(c cid.Cid) string { | ||
if enc.Upgrade && c.Version() == 0 { | ||
c = cid.NewCidV1(c.Type(), c.Hash()) | ||
} | ||
return c.Encode(enc.Base) | ||
} | ||
|
||
// Recode reencodes the cid string to match the parameters of the | ||
// encoder | ||
func (enc Encoder) Recode(v string) (string, error) { | ||
skip, err := enc.noopRecode(v) | ||
if skip || err != nil { | ||
return v, err | ||
} | ||
|
||
c, err := cid.Decode(v) | ||
if err != nil { | ||
return v, err | ||
} | ||
|
||
return enc.Encode(c), nil | ||
} | ||
|
||
func (enc Encoder) noopRecode(v string) (bool, error) { | ||
if len(v) < 2 { | ||
return false, cid.ErrCidTooShort | ||
} | ||
ver := cidVer(v) | ||
skip := ver == 0 && !enc.Upgrade || ver == 1 && v[0] == byte(enc.Base.Encoding()) | ||
return skip, nil | ||
} | ||
|
||
func cidVer(v string) int { | ||
if len(v) == 46 && v[:2] == "Qm" { | ||
return 0 | ||
} else { | ||
return 1 | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,62 @@ | ||
package cidenc | ||
|
||
import ( | ||
"testing" | ||
|
||
cid "github.com/ipfs/go-cid" | ||
mbase "github.com/multiformats/go-multibase" | ||
) | ||
|
||
func TestCidEncoder(t *testing.T) { | ||
cidv0str := "QmdfTbBqBPQ7VNxZEYEj14VmRuZBkqFbiwReogJgS1zR1n" | ||
cidv1str := "zdj7Wkkhxcu2rsiN6GUyHCLsSLL47kdUNfjbFqBUUhMFTZKBi" | ||
cidb32str := "bafybeihdwdcefgh4dqkjv67uzcmw7ojee6xedzdetojuzjevtenxquvyku" | ||
cidv0, _ := cid.Decode(cidv0str) | ||
cidv1, _ := cid.Decode(cidv1str) | ||
|
||
testEncode := func(enc Encoder, cid cid.Cid, expect string) { | ||
actual := enc.Encode(cid) | ||
if actual != expect { | ||
t.Errorf("%+v.Encode(%s): expected %s but got %s", enc, cid, expect, actual) | ||
} | ||
} | ||
|
||
testRecode := func(enc Encoder, cid string, expect string) { | ||
actual, err := enc.Recode(cid) | ||
if err != nil { | ||
t.Errorf("%+v.Recode(%s): %s", enc, cid, err) | ||
return | ||
} | ||
if actual != expect { | ||
t.Errorf("%+v.Recode(%s): expected %s but got %s", enc, cid, expect, actual) | ||
} | ||
} | ||
|
||
enc := Encoder{Base: mbase.MustNewEncoder(mbase.Base58BTC), Upgrade: false} | ||
testEncode(enc, cidv0, cidv0str) | ||
testEncode(enc, cidv1, cidv1str) | ||
testRecode(enc, cidv0str, cidv0str) | ||
testRecode(enc, cidv1str, cidv1str) | ||
testRecode(enc, cidb32str, cidv1str) | ||
|
||
enc = Encoder{Base: mbase.MustNewEncoder(mbase.Base58BTC), Upgrade: true} | ||
testEncode(enc, cidv0, cidv1str) | ||
testEncode(enc, cidv1, cidv1str) | ||
testRecode(enc, cidv0str, cidv1str) | ||
testRecode(enc, cidv1str, cidv1str) | ||
testRecode(enc, cidb32str, cidv1str) | ||
|
||
enc = Encoder{Base: mbase.MustNewEncoder(mbase.Base32), Upgrade: false} | ||
testEncode(enc, cidv0, cidv0str) | ||
testEncode(enc, cidv1, cidb32str) | ||
testRecode(enc, cidv0str, cidv0str) | ||
testRecode(enc, cidv1str, cidb32str) | ||
testRecode(enc, cidb32str, cidb32str) | ||
|
||
enc = Encoder{Base: mbase.MustNewEncoder(mbase.Base32), Upgrade: true} | ||
testEncode(enc, cidv0, cidb32str) | ||
testEncode(enc, cidv1, cidb32str) | ||
testRecode(enc, cidv0str, cidb32str) | ||
testRecode(enc, cidv1str, cidb32str) | ||
testRecode(enc, cidb32str, cidb32str) | ||
} |