Unverified Commit 74065785 authored by Eric Myhre's avatar Eric Myhre Committed by GitHub

Merge pull request #158 from ipld/feat/add-reification-to-link-system

feat(linksystem): add reification to LinkSystem
parents dc342a99 9340af55
......@@ -2,14 +2,19 @@ package rot13adl_test
import (
"bytes"
"context"
"fmt"
"strings"
"github.com/ipfs/go-cid"
"github.com/polydawn/refmt/json"
"github.com/ipld/go-ipld-prime"
"github.com/ipld/go-ipld-prime/adl/rot13adl"
"github.com/ipld/go-ipld-prime/codec/dagjson"
cidlink "github.com/ipld/go-ipld-prime/linking/cid"
"github.com/ipld/go-ipld-prime/must"
"github.com/ipld/go-ipld-prime/storage"
)
func ExampleUnmarshallingToADL() {
......@@ -38,7 +43,51 @@ func ExampleUnmarshallingToADL() {
// adl node kind: string
// adl view value: "a cool string"
}
func ExampleLoadingToADL() {
// Create a NodeBuilder for the ADL's substrate.
// Unmarshalling into this memory structure is optimal,
// because it immediately puts data into the right memory layout for the ADL code to work on,
// but you could use any other kind of NodeBuilder just as well and still get correct results.
nb := rot13adl.Prototype.SubstrateRoot.NewBuilder()
// Unmarshal -- using the substrate's nodebuilder just like you'd unmarshal with any other nodebuilder.
err := dagjson.Unmarshal(nb, json.NewDecoder(strings.NewReader(`"n pbby fgevat"`)), true)
fmt.Printf("unmarshal error: %v\n", err)
substrateNode := nb.Build()
// now save the node to storage
lp := cidlink.LinkPrototype{cid.Prefix{
Version: 1,
Codec: 0x129,
MhType: 0x13,
MhLength: 4,
}}
linkSystem := cidlink.DefaultLinkSystem()
storage := &storage.Memory{}
linkSystem.StorageReadOpener = storage.OpenRead
linkSystem.StorageWriteOpener = storage.OpenWrite
linkSystem.NodeReifier = func(_ ipld.LinkContext, nd ipld.Node, _ *ipld.LinkSystem) (ipld.Node, error) {
return rot13adl.Reify(nd)
}
lnk, err := linkSystem.Store(ipld.LinkContext{Ctx: context.Background()}, lp, substrateNode)
fmt.Printf("storage error: %v\n", err)
// reload from storage, but this time the NodeReifier function should give us the ADL
syntheticView, err := linkSystem.Load(ipld.LinkContext{Ctx: context.Background()}, lnk, rot13adl.Prototype.SubstrateRoot)
fmt.Printf("load error: %v\n", err)
// We can inspect the synthetic ADL node like any other node!
fmt.Printf("adl node kind: %v\n", syntheticView.Kind())
fmt.Printf("adl view value: %q\n", must.String(syntheticView))
// Output:
// unmarshal error: <nil>
// storage error: <nil>
// load error: <nil>
// adl node kind: string
// adl view value: "a cool string"
}
func ExampleCreatingViaADL() {
// Create a NodeBuilder for the ADL -- the high-level synthesized thing (not the substrate).
nb := rot13adl.Prototype.Node.NewBuilder()
......
......@@ -24,7 +24,11 @@ func (lsys *LinkSystem) Load(lnkCtx LinkContext, lnk Link, np NodePrototype) (No
if err := lsys.Fill(lnkCtx, lnk, nb); err != nil {
return nil, err
}
return nb.Build(), nil
nd := nb.Build()
if lsys.NodeReifier == nil {
return nd, nil
}
return lsys.NodeReifier(lnkCtx, nd, lsys)
}
func (lsys *LinkSystem) MustLoad(lnkCtx LinkContext, lnk Link, np NodePrototype) Node {
......
......@@ -33,6 +33,7 @@ type LinkSystem struct {
StorageWriteOpener BlockWriteOpener
StorageReadOpener BlockReadOpener
TrustedStorage bool
NodeReifier NodeReifier
}
// The following two types define the two directions of transform that a codec can be expected to perform:
......@@ -206,6 +207,21 @@ type (
// See the documentation of BlockWriteOpener for more description of this
// and an example of how this is likely to be reduced to practice.
BlockWriteCommitter func(Link) error
// NodeReifier defines the shape of a function that given a node with no schema
// or a basic schema, constructs Advanced Data Layout node
//
// The LinkSystem itself is passed to the NodeReifier along with a link context
// because Node interface methods on an ADL may actually traverse links to other
// pieces of context addressed data that need to be loaded with the Link system
//
// A NodeReifier return one of three things:
// - original node, no error = no reification occurred, just use original node
// - reified node, no error = the simple node was converted to an ADL
// - nil, error = the simple node should have been converted to an ADL but something
// went wrong when we tried to do so
//
NodeReifier func(LinkContext, Node, *LinkSystem) (Node, error)
)
// ErrLinkingSetup is returned by methods on LinkSystem when some part of the system is not set up correctly,
......
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