ipldutil.go 2.08 KB
Newer Older
1
package ipldutil
2 3 4 5

import (
	"bytes"
	"context"
6
	"errors"
7 8

	ipld "github.com/ipld/go-ipld-prime"
9
	dagpb "github.com/ipld/go-ipld-prime-proto"
Hannah Howard's avatar
Hannah Howard committed
10 11
	"github.com/ipld/go-ipld-prime/codec/dagcbor"
	basicnode "github.com/ipld/go-ipld-prime/node/basic"
12
	"github.com/ipld/go-ipld-prime/traversal"
13
	ipldtraversal "github.com/ipld/go-ipld-prime/traversal"
14
	"github.com/ipld/go-ipld-prime/traversal/selector"
15 16 17
	ipldselector "github.com/ipld/go-ipld-prime/traversal/selector"
)

18
var errDoNotFollow = errors.New("Dont Follow Me")
19

20 21 22
// ErrDoNotFollow is just a wrapper for whatever IPLD's ErrDoNotFollow ends up looking like
func ErrDoNotFollow() error {
	return errDoNotFollow
23 24
}

25
var (
Hannah Howard's avatar
Hannah Howard committed
26 27
	defaultChooser traversal.LinkTargetNodeStyleChooser = dagpb.AddDagPBSupportToChooser(func(ipld.Link, ipld.LinkContext) (ipld.NodeStyle, error) {
		return basicnode.Style.Any, nil
28 29 30
	})
)

Hannah Howard's avatar
Hannah Howard committed
31
func Traverse(ctx context.Context, loader ipld.Loader, chooser traversal.LinkTargetNodeStyleChooser, root ipld.Link, s selector.Selector, fn traversal.AdvVisitFn) error {
32 33 34
	if chooser == nil {
		chooser = defaultChooser
	}
Hannah Howard's avatar
Hannah Howard committed
35
	ns, err := chooser(root, ipld.LinkContext{})
36 37 38
	if err != nil {
		return err
	}
Hannah Howard's avatar
Hannah Howard committed
39 40
	nb := ns.NewBuilder()
	err = root.Load(ctx, ipld.LinkContext{}, nb, loader)
41 42 43
	if err != nil {
		return err
	}
Hannah Howard's avatar
Hannah Howard committed
44
	node := nb.Build()
45 46
	return traversal.Progress{
		Cfg: &traversal.Config{
Hannah Howard's avatar
Hannah Howard committed
47 48 49
			Ctx:                        ctx,
			LinkLoader:                 loader,
			LinkTargetNodeStyleChooser: chooser,
50
		},
Edgar Lee's avatar
Edgar Lee committed
51
	}.WalkAdv(node, s, fn)
52 53
}

54
func WalkMatching(node ipld.Node, s selector.Selector, fn traversal.VisitFn) error {
55 56 57
	return ipldtraversal.WalkMatching(node, s, fn)
}

58
func EncodeNode(node ipld.Node) ([]byte, error) {
59
	var buffer bytes.Buffer
60
	err := dagcbor.Encoder(node, &buffer)
61 62 63 64 65 66
	if err != nil {
		return nil, err
	}
	return buffer.Bytes(), nil
}

67
func DecodeNode(encoded []byte) (ipld.Node, error) {
Hannah Howard's avatar
Hannah Howard committed
68 69 70 71 72
	nb := basicnode.Style.Any.NewBuilder()
	if err := dagcbor.Decoder(nb, bytes.NewReader(encoded)); err != nil {
		return nil, err
	}
	return nb.Build(), nil
73 74
}

75
func ParseSelector(selector ipld.Node) (selector.Selector, error) {
76
	return ipldselector.ParseSelector(selector)
77
}