Commit b18fd134 authored by hannahhoward's avatar hannahhoward

feat(ipldbridge): define bridge interface

Define an interface for interacting with go-ipld-prime and write semi-functional implementation
parent cf3f02de
......@@ -45,6 +45,10 @@ github.com/ipfs/go-ipfs-util v0.0.1 h1:Wz9bL2wB2YBJqggkA4dD7oSmqB4cAnpNbGrlHJulv
github.com/ipfs/go-ipfs-util v0.0.1/go.mod h1:spsl5z8KUnrve+73pOhSVZND1SIxPW5RyBCNzQxlJBc=
github.com/ipfs/go-log v0.0.1 h1:9XTUN/rW64BCG1YhPK9Hoy3q8nr4gOmHHBpgFdfw6Lc=
github.com/ipfs/go-log v0.0.1/go.mod h1:kL1d2/hzSpI0thNYjiKfjanbVNU+IIGA/WnNESY9leM=
github.com/ipld/go-ipld-prime v0.0.0-20190227132703-aaea73ad73c5 h1:Fm+tk5iaitTL/3L1nRlwibgLFtI5Eld4nIrjX4ajcKY=
github.com/ipld/go-ipld-prime v0.0.0-20190227132703-aaea73ad73c5/go.mod h1:hSGXgXt4BSdqvjA3Kkxhzcg4Rsk9yvIeEuEVCPCi7/A=
github.com/ipld/go-ipld-prime v0.0.0-20190306022502-066284669cf6 h1:FJW7rDl8g/580E6ZuR5rXzDT/9SsJvCuAEQCq8cbdPQ=
github.com/ipld/go-ipld-prime v0.0.0-20190306022502-066284669cf6/go.mod h1:hSGXgXt4BSdqvjA3Kkxhzcg4Rsk9yvIeEuEVCPCi7/A=
github.com/jbenet/go-random v0.0.0-20190219211222-123a90aedc0c h1:uUx61FiAa1GI6ZmVd2wf2vULeQZIKG66eybjNXKYCz4=
github.com/jbenet/go-random v0.0.0-20190219211222-123a90aedc0c/go.mod h1:sdx1xVM9UuLw1tXnhJWN3piypTUO3vCIHYmG15KE/dU=
github.com/jbenet/goprocess v0.0.0-20160826012719-b497e2f366b8 h1:bspPhN+oKYFk5fcGNuQzp6IGzYQSenLEgH3s6jkXrWw=
......@@ -103,6 +107,8 @@ github.com/opentracing/opentracing-go v1.0.2 h1:3jA2P6O1F9UOrWVpwrIo17pu01KWvNWg
github.com/opentracing/opentracing-go v1.0.2/go.mod h1:UkNAQd3GIcIGf0SeVgPpRdFStlNbqXla1AfSYxPUl2o=
github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
github.com/polydawn/refmt v0.0.0-20190221155625-df39d6c2d992 h1:bzMe+2coZJYHnhGgVlcQKuRy4FSny4ds8dLQjw5P1XE=
github.com/polydawn/refmt v0.0.0-20190221155625-df39d6c2d992/go.mod h1:uIp+gprXxxrWSjjklXD+mN4wed/tMfjMMmN/9+JsA9o=
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
github.com/syndtr/goleveldb v1.0.0/go.mod h1:ZVVdQEZoIme9iO1Ch2Jdy24qqXrMMOU6lpPAyBWyWuQ=
......
package ipldbridge
import (
"bytes"
"context"
"errors"
ipld "github.com/ipld/go-ipld-prime"
ipldfree "github.com/ipld/go-ipld-prime/impl/free"
ipldrepose "github.com/ipld/go-ipld-prime/repose"
ipldtraversal "github.com/ipld/go-ipld-prime/traversal"
ipldselector "github.com/ipld/go-ipld-prime/traversal/selector"
ipldtypesystem "github.com/ipld/go-ipld-prime/typed/system"
)
// not sure how these will come into being or from where
var cidRootedSelectorType ipldtypesystem.Type
var universe ipldtypesystem.Universe
// TraversalConfig is an alias from ipld, in case it's renamed/moved.
type TraversalConfig = ipldtraversal.TraversalConfig
type ipldBridge struct {
nodeBuilderChooser NodeBuilderChooser
multicodecTable MulticodecDecodeTable
}
// NewIPLDBridge returns an IPLD Bridge.
func NewIPLDBridge(nodeBuilderChooser NodeBuilderChooser,
multicodecTable MulticodecDecodeTable) IPLDBridge {
return &ipldBridge{nodeBuilderChooser, multicodecTable}
}
func (rb *ipldBridge) ComposeLinkLoader(
actualLoader RawLoader) LinkLoader {
return ipldrepose.ComposeLinkLoader(actualLoader, rb.nodeBuilderChooser, rb.multicodecTable)
}
func (rb *ipldBridge) Traverse(ctx context.Context, loader LinkLoader, root ipld.Node, s Selector, fn AdvVisitFn) error {
config := &TraversalConfig{Ctx: ctx, LinkLoader: loader}
return TraversalProgress{TraversalConfig: config}.TraverseInformatively(root, s, fn)
}
func (rb *ipldBridge) ValidateSelectorSpec(cidRootedSelector ipld.Node) []error {
return ipldtypesystem.Validate(universe, cidRootedSelectorType, cidRootedSelector)
}
func (rb *ipldBridge) EncodeNode(node ipld.Node) ([]byte, error) {
var buffer bytes.Buffer
err := ipldrepose.EncoderDagCbor(node, &buffer)
if err != nil {
return nil, err
}
return buffer.Bytes(), nil
}
func (rb *ipldBridge) DecodeNode(encoded []byte) (ipld.Node, error) {
reader := bytes.NewReader(encoded)
return ipldrepose.DecoderDagCbor(ipldfree.NodeBuilder(), reader)
}
func (rb *ipldBridge) DecodeSelectorSpec(cidRootedSelector ipld.Node) (ipld.Node, Selector, error) {
errs := rb.ValidateSelectorSpec(cidRootedSelector)
if len(errs) != 0 {
return nil, nil, errors.New("Node does not validate as selector spec")
}
root, err := cidRootedSelector.TraverseField("root")
if err != nil {
return nil, nil, err
}
rootCid, err := root.AsLink()
if err != nil {
return nil, nil, err
}
node, err := ipldfree.NodeBuilder().CreateLink(rootCid)
if err != nil {
return nil, nil, err
}
selector, err := ipldselector.ReifySelector(cidRootedSelector)
if err != nil {
return nil, nil, err
}
return node, selector, nil
}
package ipldbridge
import (
"context"
ipld "github.com/ipld/go-ipld-prime"
ipldrepose "github.com/ipld/go-ipld-prime/repose"
ipldtraversal "github.com/ipld/go-ipld-prime/traversal"
ipldselector "github.com/ipld/go-ipld-prime/traversal/selector"
)
// MulticodecDecodeTable is an alias from ipld, in case it's renamed/moved.
type MulticodecDecodeTable = ipldrepose.MulticodecDecodeTable
// NodeBuilderChooser is an an alias from ipld, in case it's renamed/moved.
type NodeBuilderChooser = ipldrepose.NodeBuilderChooser
// LinkLoader is alias from ipld, in case it.s renamed/moved.
type LinkLoader = ipldtraversal.LinkLoader
// RawLoader is an alias from ipld, in case it's renamed/moved.
type RawLoader = ipldrepose.ActualLoader
// AdvVisitFn is an alias from ipld, in case it's renamed/moved.
type AdvVisitFn = ipldtraversal.AdvVisitFn
// Selector is an alias from ipld, in case it's renamed/moved.
type Selector = ipldselector.Selector
// LinkContext is an alias from ipld, in case it's renamed/moved.
type LinkContext = ipldtraversal.LinkContext
// TraversalProgress is an alias from ipld, in case it's renamed/moved.
type TraversalProgress = ipldtraversal.TraversalProgress
// TraversalReason is an alias from ipld, in case it's renamed/moved.
type TraversalReason = ipldtraversal.TraversalReason
// IPLDBridge is an interface for making calls to IPLD, which can be
// replaced with alternative implementations
type IPLDBridge interface {
ComposeLinkLoader(actualLoader RawLoader) LinkLoader
ValidateSelectorSpec(cidRootedSelector ipld.Node) []error
EncodeNode(ipld.Node) ([]byte, error)
DecodeNode([]byte) (ipld.Node, error)
DecodeSelectorSpec(cidRootedSelector ipld.Node) (ipld.Node, Selector, error)
Traverse(ctx context.Context, loader LinkLoader, root ipld.Node, s Selector, fn AdvVisitFn) error
}
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment