Skip to content

Commit

Permalink
rot13adl demo: example of creating data using synthetic view, then ac…
Browse files Browse the repository at this point in the history
…cessing substrate.

Fixed a symbol to be exported that's needed for this to be possible
when outside the package.  This still probably deserves an interface,
too, though.  Comments on that also updated, but we'll still leave
that for future work (more examples of more ADLs wanted before we try
to solidify on something there).
  • Loading branch information
warpfork committed Nov 14, 2020
1 parent 8096285 commit 6541383
Show file tree
Hide file tree
Showing 3 changed files with 39 additions and 3 deletions.
34 changes: 34 additions & 0 deletions adl/rot13adl/example_test.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package rot13adl_test

import (
"bytes"
"fmt"
"strings"

Expand Down Expand Up @@ -38,6 +39,39 @@ func ExampleUnmarshallingToADL() {
// 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()

// Create a ADL node via its builder. This is just like creating any other node in IPLD.
nb.AssignString("woohoo")
n := nb.Build()

// We can inspect the synthetic ADL node like any other node!
fmt.Printf("adl node kind: %v\n", n.ReprKind())
fmt.Printf("adl view value: %q\n", must.String(n))

// We can get the substrate view and examine that as a node too.
// (This requires a cast to see that we have an ADL, though. Not all IPLD nodes have a 'Substrate' property.)
substrateNode := n.(rot13adl.R13String).Substrate()
fmt.Printf("substrate node kind: %v\n", substrateNode.ReprKind())
fmt.Printf("substrate value: %q\n", must.String(substrateNode))

// To marshal the ADL, just use marshal methods on its substrate as normal:
var marshalBuffer bytes.Buffer
err := dagjson.Marshal(substrateNode, json.NewEncoder(&marshalBuffer, json.EncodeOptions{}))
fmt.Printf("marshalled: %v\n", marshalBuffer.String())
fmt.Printf("marshal error: %v\n", err)

// Output:
// adl node kind: string
// adl view value: "woohoo"
// substrate node kind: string
// substrate value: "jbbubb"
// marshalled: "jbbubb"
// marshal error: <nil>
}

// It's worth noting that the builders for an ADL substrate node still return the substrate.
// (This is interesting in contrast to Schemas, where codegenerated representation-level builders
// yield the type-level node values (and not the representation level node).)
Expand Down
4 changes: 3 additions & 1 deletion adl/rot13adl/rot13node.go
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,9 @@ import (

// -- Node -->

var _ ipld.Node = (*_R13String)(nil)
var _ ipld.Node = (R13String)(nil)

type R13String = *_R13String

type _R13String struct {
raw string // the raw content, before our ADL lens is applied to it.
Expand Down
4 changes: 2 additions & 2 deletions adl/rot13adl/rot13node_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -68,8 +68,8 @@ func TestInspectingSubstrate(t *testing.T) {
Require(t, err, ShouldEqual, nil)
n := nb.Build()
// Ask it about its substrate, and inspect that.
sn := n.(*_R13String).Substrate()
// TODO: the cast above isn't available outside this package: we should probably make an interface with `Substrate()` and make it available.
sn := n.(R13String).Substrate()
// TODO: It's unfortunate this is only available as a concrete type cast: we should probably make a standard feature detection interface with `Substrate()`.
// Is it reasonable to make this part of a standard feature detection pattern,
// and make that interface reside in the main IPLD package? Or in an `adl` package that contains such standard interfaces?
ss, err := sn.AsString()
Expand Down

0 comments on commit 6541383

Please sign in to comment.