ipld_impl.go 2.36 KB
Newer Older
1 2 3 4 5 6
package ipldbridge

import (
	"bytes"
	"context"

7 8
	"github.com/ipld/go-ipld-prime/fluent"

9
	ipld "github.com/ipld/go-ipld-prime"
10 11
	"github.com/ipld/go-ipld-prime/encoding/dagcbor"
	free "github.com/ipld/go-ipld-prime/impl/free"
12 13
	ipldtraversal "github.com/ipld/go-ipld-prime/traversal"
	ipldselector "github.com/ipld/go-ipld-prime/traversal/selector"
14
	selectorbuilder "github.com/ipld/go-ipld-prime/traversal/selector/builder"
15 16 17 18 19 20 21 22 23
)

// TraversalConfig is an alias from ipld, in case it's renamed/moved.
type TraversalConfig = ipldtraversal.TraversalConfig

type ipldBridge struct {
}

// NewIPLDBridge returns an IPLD Bridge.
24 25
func NewIPLDBridge() IPLDBridge {
	return &ipldBridge{}
26 27
}

28 29 30 31 32 33 34 35 36 37 38 39
func (rb *ipldBridge) ExtractData(node ipld.Node, buildFn func(SimpleNode) interface{}) (interface{}, error) {
	var value interface{}
	err := fluent.Recover(func() {
		simpleNode := fluent.WrapNode(node)
		value = buildFn(simpleNode)
	})
	if err != nil {
		return nil, err
	}
	return value, nil
}

40 41 42 43 44 45 46 47 48 49 50 51
func (rb *ipldBridge) BuildNode(buildFn func(NodeBuilder) ipld.Node) (ipld.Node, error) {
	var node ipld.Node
	err := fluent.Recover(func() {
		nb := fluent.WrapNodeBuilder(free.NodeBuilder())
		node = buildFn(nb)
	})
	if err != nil {
		return nil, err
	}
	return node, nil
}

52 53 54
func (rb *ipldBridge) BuildSelector(buildFn func(SelectorSpecBuilder) SelectorSpec) (ipld.Node, error) {
	var node ipld.Node
	err := fluent.Recover(func() {
55
		ssb := selectorbuilder.NewSelectorSpecBuilder(free.NodeBuilder())
56 57 58 59 60 61
		node = buildFn(ssb).Node()
	})
	if err != nil {
		return nil, err
	}
	return node, nil
62 63
}

64 65 66 67 68 69 70 71 72 73 74
func (rb *ipldBridge) Traverse(ctx context.Context, loader Loader, root ipld.Link, s Selector, fn AdvVisitFn) error {
	node, err := root.Load(ctx, LinkContext{}, free.NodeBuilder(), loader)
	if err != nil {
		return err
	}
	return TraversalProgress{
		Cfg: &TraversalConfig{
			Ctx:        ctx,
			LinkLoader: loader,
		},
	}.TraverseInformatively(node, s, fn)
75 76 77 78
}

func (rb *ipldBridge) EncodeNode(node ipld.Node) ([]byte, error) {
	var buffer bytes.Buffer
79
	err := dagcbor.Encoder(node, &buffer)
80 81 82 83 84 85 86 87
	if err != nil {
		return nil, err
	}
	return buffer.Bytes(), nil
}

func (rb *ipldBridge) DecodeNode(encoded []byte) (ipld.Node, error) {
	reader := bytes.NewReader(encoded)
88
	return dagcbor.Decoder(free.NodeBuilder(), reader)
89 90
}

91 92
func (rb *ipldBridge) ParseSelector(selector ipld.Node) (Selector, error) {
	return ipldselector.ParseSelector(selector)
93
}