From 870aa9e7def237303059e8b8f6c521df368fb834 Mon Sep 17 00:00:00 2001 From: Kevin Atkinson Date: Thu, 16 Aug 2018 21:51:31 -0400 Subject: [PATCH] Extract non-core functionality from go-cid into go-cidutil. --- cid-fmt/main.go | 128 ------------------------------------ cid-fmt/main_test.go | 45 ------------- format.go | 151 ------------------------------------------- format_test.go | 73 --------------------- set.go | 34 ---------- 5 files changed, 431 deletions(-) delete mode 100644 cid-fmt/main.go delete mode 100644 cid-fmt/main_test.go delete mode 100644 format.go delete mode 100644 format_test.go diff --git a/cid-fmt/main.go b/cid-fmt/main.go deleted file mode 100644 index 988126a..0000000 --- a/cid-fmt/main.go +++ /dev/null @@ -1,128 +0,0 @@ -package main - -import ( - "fmt" - "os" - "strings" - - c "github.com/ipfs/go-cid" - - mb "github.com/multiformats/go-multibase" -) - -func usage() { - fmt.Fprintf(os.Stderr, "usage: %s [-b multibase-code] [-v cid-version] ...\n\n", os.Args[0]) - fmt.Fprintf(os.Stderr, " is either 'prefix' or a printf style format string:\n%s", c.FormatRef) - os.Exit(2) -} - -func main() { - if len(os.Args) < 2 { - usage() - } - newBase := mb.Encoding(-1) - var verConv func(cid *c.Cid) (*c.Cid, error) - args := os.Args[1:] -outer: - for { - switch args[0] { - case "-b": - if len(args) < 2 { - usage() - } - encoder, err := mb.EncoderByName(args[1]) - if err != nil { - fmt.Fprintf(os.Stderr, "Error: %s\n", err.Error()) - os.Exit(2) - } - newBase = encoder.Encoding() - args = args[2:] - case "-v": - if len(args) < 2 { - usage() - } - switch args[1] { - case "0": - verConv = toCidV0 - case "1": - verConv = toCidV1 - default: - fmt.Fprintf(os.Stderr, "Error: Invalid cid version: %s\n", args[1]) - os.Exit(2) - } - args = args[2:] - default: - break outer - } - } - if len(args) < 2 { - usage() - } - fmtStr := args[0] - switch fmtStr { - case "prefix": - fmtStr = "%P" - default: - if strings.IndexByte(fmtStr, '%') == -1 { - fmt.Fprintf(os.Stderr, "Error: Invalid format string: %s\n", fmtStr) - os.Exit(2) - } - } - for _, cidStr := range args[1:] { - cid, err := c.Decode(cidStr) - if err != nil { - fmt.Fprintf(os.Stdout, "!INVALID_CID!\n") - errorMsg("%s: %v", cidStr, err) - // Don't abort on a bad cid - continue - } - base := newBase - if newBase == -1 { - base, _ = c.ExtractEncoding(cidStr) - } - if verConv != nil { - cid, err = verConv(cid) - if err != nil { - fmt.Fprintf(os.Stdout, "!ERROR!\n") - errorMsg("%s: %v", cidStr, err) - // Don't abort on a bad conversion - continue - } - } - str, err := c.Format(fmtStr, base, cid) - switch err.(type) { - case c.FormatStringError: - fmt.Fprintf(os.Stderr, "Error: %v\n", err) - os.Exit(2) - default: - fmt.Fprintf(os.Stdout, "!ERROR!\n") - errorMsg("%s: %v", cidStr, err) - // Don't abort on cid specific errors - continue - case nil: - // no error - } - fmt.Fprintf(os.Stdout, "%s\n", str) - } - os.Exit(exitCode) -} - -var exitCode = 0 - -func errorMsg(fmtStr string, a ...interface{}) { - fmt.Fprintf(os.Stderr, "Error: ") - fmt.Fprintf(os.Stderr, fmtStr, a...) - fmt.Fprintf(os.Stderr, "\n") - exitCode = 1 -} - -func toCidV0(cid *c.Cid) (*c.Cid, error) { - if cid.Type() != c.DagProtobuf { - return nil, fmt.Errorf("can't convert non-protobuf nodes to cidv0") - } - return c.NewCidV0(cid.Hash()), nil -} - -func toCidV1(cid *c.Cid) (*c.Cid, error) { - return c.NewCidV1(cid.Type(), cid.Hash()), nil -} diff --git a/cid-fmt/main_test.go b/cid-fmt/main_test.go deleted file mode 100644 index ce66c0a..0000000 --- a/cid-fmt/main_test.go +++ /dev/null @@ -1,45 +0,0 @@ -package main - -import ( - "fmt" - "testing" - - c "github.com/ipfs/go-cid" -) - -func TestCidConv(t *testing.T) { - cidv0 := "QmUNLLsPACCz1vLxQVkXqqLX5R1X345qqfHbsf67hvA3Nn" - cidv1 := "zdj7WbTaiJT1fgatdet9Ei9iDB5hdCxkbVyhyh8YTUnXMiwYi" - cid, err := c.Decode(cidv0) - if err != nil { - t.Fatal(err) - } - cid, err = toCidV1(cid) - if err != nil { - t.Fatal(err) - } - if cid.String() != cidv1 { - t.Fatal("conversion failure") - } - cid, err = toCidV0(cid) - if err != nil { - t.Fatal(err) - } - cidStr := cid.String() - if cidStr != cidv0 { - t.Error(fmt.Sprintf("conversion failure, expected: %s; but got: %s", cidv0, cidStr)) - } -} - -func TestBadCidConv(t *testing.T) { - // this cid is a raw leaf and should not be able to convert to cidv0 - cidv1 := "zb2rhhzX7uSKrtQ2ZZXFAabKiKFYZrJqKY2KE1cJ8yre2GSWZ" - cid, err := c.Decode(cidv1) - if err != nil { - t.Fatal(err) - } - cid, err = toCidV0(cid) - if err == nil { - t.Fatal("expected failure") - } -} diff --git a/format.go b/format.go deleted file mode 100644 index 78bff4c..0000000 --- a/format.go +++ /dev/null @@ -1,151 +0,0 @@ -package cid - -import ( - "bytes" - "fmt" - - mb "github.com/multiformats/go-multibase" - mh "github.com/multiformats/go-multihash" -) - -// FormatRef is a string documenting the format string for the Format function -const FormatRef = ` - %% literal % - %b multibase name - %B multibase code - %v version string - %V version number - %c codec name - %C codec code - %h multihash name - %H multihash code - %L hash digest length - %m multihash encoded in base %b (with multibase prefix) - %M multihash encoded in base %b without multibase prefix - %d hash digest encoded in base %b (with multibase prefix) - %D hash digest encoded in base %b without multibase prefix - %s cid string encoded in base %b (1) - %S cid string encoded in base %b without multibase prefix - %P cid prefix: %v-%c-%h-%L - -(1) For CID version 0 the multibase must be base58btc and no prefix is -used. For Cid version 1 the multibase prefix is included. -` - -// Format formats a cid according to the format specificer as -// documented in the FormatRef constant -func Format(fmtStr string, base mb.Encoding, cid *Cid) (string, error) { - p := cid.Prefix() - var out bytes.Buffer - var err error - encoder, err := mb.NewEncoder(base) - if err != nil { - return "", err - } - for i := 0; i < len(fmtStr); i++ { - if fmtStr[i] != '%' { - out.WriteByte(fmtStr[i]) - continue - } - i++ - if i >= len(fmtStr) { - return "", FormatStringError{"premature end of format string", ""} - } - switch fmtStr[i] { - case '%': - out.WriteByte('%') - case 'b': // base name - out.WriteString(baseToString(base)) - case 'B': // base code - out.WriteByte(byte(base)) - case 'v': // version string - fmt.Fprintf(&out, "cidv%d", p.Version) - case 'V': // version num - fmt.Fprintf(&out, "%d", p.Version) - case 'c': // codec name - out.WriteString(codecToString(p.Codec)) - case 'C': // codec code - fmt.Fprintf(&out, "%d", p.Codec) - case 'h': // hash fun name - out.WriteString(hashToString(p.MhType)) - case 'H': // hash fun code - fmt.Fprintf(&out, "%d", p.MhType) - case 'L': // hash length - fmt.Fprintf(&out, "%d", p.MhLength) - case 'm', 'M': // multihash encoded in base %b - out.WriteString(encode(encoder, cid.Hash(), fmtStr[i] == 'M')) - case 'd', 'D': // hash digest encoded in base %b - dec, err := mh.Decode(cid.Hash()) - if err != nil { - return "", err - } - out.WriteString(encode(encoder, dec.Digest, fmtStr[i] == 'D')) - case 's': // cid string encoded in base %b - str, err := cid.StringOfBase(base) - if err != nil { - return "", err - } - out.WriteString(str) - case 'S': // cid string without base prefix - out.WriteString(encode(encoder, cid.Bytes(), true)) - case 'P': // prefix - fmt.Fprintf(&out, "cidv%d-%s-%s-%d", - p.Version, - codecToString(p.Codec), - hashToString(p.MhType), - p.MhLength, - ) - default: - return "", FormatStringError{"unrecognized specifier in format string", fmtStr[i-1 : i+1]} - } - - } - return out.String(), err -} - -// FormatStringError is the error return from Format when the format -// string is ill formed -type FormatStringError struct { - Message string - Specifier string -} - -func (e FormatStringError) Error() string { - if e.Specifier == "" { - return e.Message - } else { - return fmt.Sprintf("%s: %s", e.Message, e.Specifier) - } -} - -func baseToString(base mb.Encoding) string { - baseStr, ok := mb.EncodingToStr[base] - if !ok { - return fmt.Sprintf("base?%c", base) - } - return baseStr -} - -func codecToString(num uint64) string { - name, ok := CodecToStr[num] - if !ok { - return fmt.Sprintf("codec?%d", num) - } - return name -} - -func hashToString(num uint64) string { - name, ok := mh.Codes[num] - if !ok { - return fmt.Sprintf("hash?%d", num) - } - return name -} - -func encode(base mb.Encoder, data []byte, strip bool) string { - str := base.Encode(data) - if strip { - return str[1:] - } - return str -} diff --git a/format_test.go b/format_test.go deleted file mode 100644 index 019d85c..0000000 --- a/format_test.go +++ /dev/null @@ -1,73 +0,0 @@ -package cid - -import ( - "fmt" - "testing" - - mb "github.com/multiformats/go-multibase" -) - -func TestFmt(t *testing.T) { - cids := map[string]string{ - "cidv0": "QmUNLLsPACCz1vLxQVkXqqLX5R1X345qqfHbsf67hvA3Nn", - "cidv1": "zdj7WfLr9DhLrb1hsoSi4fSdjjxuZmeqgEtBPWxMLtPbDNbFD", - } - tests := []struct { - cidId string - newBase mb.Encoding - fmtStr string - result string - }{ - {"cidv0", -1, "%P", "cidv0-protobuf-sha2-256-32"}, - {"cidv0", -1, "%b-%v-%c-%h-%L", "base58btc-cidv0-protobuf-sha2-256-32"}, - {"cidv0", -1, "%s", "QmUNLLsPACCz1vLxQVkXqqLX5R1X345qqfHbsf67hvA3Nn"}, - {"cidv0", -1, "%S", "QmUNLLsPACCz1vLxQVkXqqLX5R1X345qqfHbsf67hvA3Nn"}, - {"cidv0", -1, "ver#%V/#%C/#%H/%L", "ver#0/#112/#18/32"}, - {"cidv0", -1, "%m", "zQmUNLLsPACCz1vLxQVkXqqLX5R1X345qqfHbsf67hvA3Nn"}, - {"cidv0", -1, "%M", "QmUNLLsPACCz1vLxQVkXqqLX5R1X345qqfHbsf67hvA3Nn"}, - {"cidv0", -1, "%d", "z72gdmFAgRzYHkJzKiL8MgMMRW3BTSCGyDHroPxJbxMJn"}, - {"cidv0", -1, "%D", "72gdmFAgRzYHkJzKiL8MgMMRW3BTSCGyDHroPxJbxMJn"}, - {"cidv0", 'B', "%S", "CIQFTFEEHEDF6KLBT32BFAGLXEZL4UWFNWM4LFTLMXQBCERZ6CMLX3Y"}, - {"cidv0", 'B', "%B%S", "BCIQFTFEEHEDF6KLBT32BFAGLXEZL4UWFNWM4LFTLMXQBCERZ6CMLX3Y"}, - {"cidv1", -1, "%P", "cidv1-protobuf-sha2-256-32"}, - {"cidv1", -1, "%b-%v-%c-%h-%L", "base58btc-cidv1-protobuf-sha2-256-32"}, - {"cidv1", -1, "%s", "zdj7WfLr9DhLrb1hsoSi4fSdjjxuZmeqgEtBPWxMLtPbDNbFD"}, - {"cidv1", -1, "%S", "dj7WfLr9DhLrb1hsoSi4fSdjjxuZmeqgEtBPWxMLtPbDNbFD"}, - {"cidv1", -1, "ver#%V/#%C/#%H/%L", "ver#1/#112/#18/32"}, - {"cidv1", -1, "%m", "zQmYFbmndVP7QqAVWyKhpmMuQHMaD88pkK57RgYVimmoh5H"}, - {"cidv1", -1, "%M", "QmYFbmndVP7QqAVWyKhpmMuQHMaD88pkK57RgYVimmoh5H"}, - {"cidv1", -1, "%d", "zAux4gVVsLRMXtsZ9fd3tFEZN4jGYB6kP37fgoZNTc11H"}, - {"cidv1", -1, "%D", "Aux4gVVsLRMXtsZ9fd3tFEZN4jGYB6kP37fgoZNTc11H"}, - {"cidv1", 'B', "%s", "BAFYBEIETJGSRL3EQPQPCABV3G6IUBYTSIFVQ24XRRHD3JUETSKLTGQ7DJA"}, - {"cidv1", 'B', "%S", "AFYBEIETJGSRL3EQPQPCABV3G6IUBYTSIFVQ24XRRHD3JUETSKLTGQ7DJA"}, - {"cidv1", 'B', "%B%S", "BAFYBEIETJGSRL3EQPQPCABV3G6IUBYTSIFVQ24XRRHD3JUETSKLTGQ7DJA"}, - } - for _, tc := range tests { - name := fmt.Sprintf("%s/%s", tc.cidId, tc.fmtStr) - if tc.newBase != -1 { - name = fmt.Sprintf("%s/%c", name, tc.newBase) - } - cidStr := cids[tc.cidId] - t.Run(name, func(t *testing.T) { - testFmt(t, cidStr, tc.newBase, tc.fmtStr, tc.result) - }) - } -} - -func testFmt(t *testing.T, cidStr string, newBase mb.Encoding, fmtStr string, result string) { - cid, err := Decode(cidStr) - if err != nil { - t.Fatal(err) - } - base := newBase - if newBase == -1 { - base, _ = ExtractEncoding(cidStr) - } - str, err := Format(fmtStr, base, cid) - if err != nil { - t.Fatal(err) - } - if str != result { - t.Error(fmt.Sprintf("expected: %s; but got: %s", result, str)) - } -} diff --git a/set.go b/set.go index 1096649..7f68657 100644 --- a/set.go +++ b/set.go @@ -1,9 +1,5 @@ package cid -import ( - "context" -) - // Set is a implementation of a set of Cids, that is, a structure // to which holds a single copy of every Cids that is added to it. type Set struct { @@ -70,33 +66,3 @@ func (s *Set) ForEach(f func(c *Cid) error) error { return nil } -// StreamingSet is an extension of Set which allows to implement back-pressure -// for the Visit function -type StreamingSet struct { - Set *Set - New chan *Cid -} - -// NewStreamingSet initializes and returns new Set. -func NewStreamingSet() *StreamingSet { - return &StreamingSet{ - Set: NewSet(), - New: make(chan *Cid), - } -} - -// Visitor creates new visitor which adds a Cids to the set and emits them to -// the set.New channel -func (s *StreamingSet) Visitor(ctx context.Context) func(c *Cid) bool { - return func(c *Cid) bool { - if s.Set.Visit(c) { - select { - case s.New <- c: - case <-ctx.Done(): - } - return true - } - - return false - } -}