Skip to content

Commit b1e837b

Browse files
committed
rot13adl demo: runnable example; more docs, several review-needed comments.
1 parent acb29a2 commit b1e837b

File tree

4 files changed

+71
-11
lines changed

4 files changed

+71
-11
lines changed

adl/rot13adl/example_test.go

+59-11
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,66 @@
11
package rot13adl_test
22

3-
func ExampleWoo() {
3+
import (
4+
"fmt"
5+
"strings"
6+
7+
"github.com/polydawn/refmt/json"
8+
9+
"github.com/ipld/go-ipld-prime/adl/rot13adl"
10+
"github.com/ipld/go-ipld-prime/codec/dagjson"
11+
"github.com/ipld/go-ipld-prime/must"
12+
)
13+
14+
func ExampleUnmarshallingToADL() {
15+
// Create a NodeBuilder for the ADL's substrate.
16+
// Unmarshalling into this memory structure is optimal,
17+
// because it immediately puts data into the right memory layout for the ADL code to work on,
18+
// but you could use any other kind of NodeBuilder just as well and still get correct results.
19+
nb := rot13adl.Prototype.SubstrateRoot.NewBuilder()
20+
21+
// Unmarshal -- using the substrate's nodebuilder just like you'd unmarshal with any other nodebuilder.
22+
err := dagjson.Unmarshal(nb, json.NewDecoder(strings.NewReader(`"n pbby fgevat"`)))
23+
fmt.Printf("unmarshal error: %v\n", err)
24+
25+
// Use `Reify` to get the synthetic high-level view of the ADL data.
26+
substrateNode := nb.Build()
27+
syntheticView, err := rot13adl.Reify(substrateNode)
28+
fmt.Printf("reify error: %v\n", err)
29+
30+
// We can inspect the synthetic ADL node like any other node!
31+
fmt.Printf("adl node kind: %v\n", syntheticView.ReprKind())
32+
fmt.Printf("adl view value: %q\n", must.String(syntheticView))
433

534
// Output:
35+
// unmarshal error: <nil>
36+
// reify error: <nil>
37+
// adl node kind: string
38+
// adl view value: "a cool string"
639
}
740

8-
// An Unmarshal2 function could take a (fairly complex) argument that says what NodePrototype to use in certain positions
9-
// (is this accomplished with a Selector? that's a scary large dependency, but maybe.).
10-
// This can be used for many purposes (efficiency, misc tuning, expecting a *schema* thing part way through...),
11-
// and it could also be used to say where a NodePrototype for an ADL's substrate should be used.
41+
// It's worth noting that the builders for an ADL substrate node still return the substrate.
42+
// (This is interesting in contrast to Schemas, where codegenerated representation-level builders
43+
// yield the type-level node values (and not the representation level node).)
44+
//
45+
// To convert the substrate node to the high level synthesized view of the ADL,
46+
// use Reify as normal -- it's the same whether you've used the substrate type
47+
// or if you've used any other node implementation to hold the data.
48+
//
49+
50+
// Future work: unmarshalling which can invoke an ADL mid-structure,
51+
// and automatically places the reified ADL in place in the larger structure.
52+
//
53+
// There will be several ways to do this (it hinges around "the signalling problem",
54+
// discussed in https://github.com/ipld/specs/issues/130 ):
55+
//
56+
// The first way is to use IPLD Schemas, which provide a signalling mechanism
57+
// by leaning on the schema, and the matching of shape of surrounding data to the schema,
58+
// as a way to determine where an ADL is expected to appear.
59+
//
60+
// A second mechanism could involve new unmarshal function contracts
61+
// which would ake a (fairly complex) argument that says what NodePrototype to use in certain positions.
62+
// This could be accomplished by use of Selectors.
63+
// (This would also have many other potential purposes -- implementing this in terms of NodePrototype selection is very multi-purpose,
64+
// and could be used for efficiency and misc tuning purposes,
65+
// for expecting a *schema* thing part way through, and so forth.)
1266
//
13-
// Schemas, even the repr builders, still ultimately result in "returning" (not really, but, roll with me here) the high-level typed info.
14-
// ...
15-
// This ADL, as currently drafted, does not.
16-
// That's... maybe bad?
17-
// It can be passed through the Reify method and there's a feeling of consistency, there.
18-
// But I'm not sure.

adl/rot13adl/rot13node_test.go

+3
Original file line numberDiff line numberDiff line change
@@ -69,6 +69,9 @@ func TestInspectingSubstrate(t *testing.T) {
6969
n := nb.Build()
7070
// Ask it about its substrate, and inspect that.
7171
sn := n.(*_R13String).Substrate()
72+
// TODO: the cast above isn't available outside this package: we should probably make an interface with `Substrate()` and make it available.
73+
// Is it reasonable to make this part of a standard feature detection pattern,
74+
// and make that interface reside in the main IPLD package? Or in an `adl` package that contains such standard interfaces?
7275
ss, err := sn.AsString()
7376
Wish(t, err, ShouldEqual, nil)
7477
Wish(t, ss, ShouldEqual, "nopq")

adl/rot13adl/rot13prototypes.go

+6
Original file line numberDiff line numberDiff line change
@@ -23,3 +23,9 @@ type prototype struct {
2323
Node _R13String__Prototype
2424
SubstrateRoot _Substrate__Prototype
2525
}
26+
27+
// REVIEW: In ADLs that use codegenerated substrate types defined by an IPLD Schema, the `Prototype.SubstrateRoot` field...
28+
// should it be a `_SubstrateRoot__Prototype`, or a `_SubstrateRoot__ReprPrototype`?
29+
// Probably the latter, because the only thing an external user of this package should be interested in is how to read data into memory in an optimal path.
30+
// But does this answer all questions? Codegen ReprPrototypes currently still return the type-level node from their Build method!
31+
// This probably would functionally work -- we could make the Reify methods check for either the type-level or repr-level types -- but would it be weird/surprising/hard-to-use?

adl/rot13adl/rot13substrate.go

+3
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,9 @@ var _ ipld.Node = (*_Substrate)(nil)
2020

2121
// Somewhat unusually for an ADL, there's only one substrate node type,
2222
// and we actually made it have the same in-memory structure as the synthesized view node.
23+
//
24+
// When implementing other more complex ADLs, it will probably be more common to have
25+
// the synthesized high-level node type either embed or have a pointer to the substrate root node.
2326
type _Substrate _R13String
2427

2528
// REVIEW: what on earth we think the "TypeName" strings in error messages and other references to this node should be.

0 commit comments

Comments
 (0)