typedNode.go 3.79 KB
Newer Older
1 2 3 4 5 6 7 8
package schema

import (
	"github.com/ipld/go-ipld-prime"
)

// schema.TypedNode is a superset of the ipld.Node interface, and has additional behaviors.
//
9
// A schema.TypedNode can be inspected for its schema.Type and schema.TypeKind,
10
// which conveys much more and richer information than the Data Model layer
11
// ipld.Kind.
12 13 14 15 16 17 18 19 20 21 22 23 24 25
//
// There are many different implementations of schema.TypedNode.
// One implementation can wrap any other existing ipld.Node (i.e., it's zero-copy)
// and promises that it has *already* been validated to match the typesystem.Type;
// another implementation similarly wraps any other existing ipld.Node, but
// defers to the typesystem validation checking to fields that are accessed;
// and when using code generation tools, all of the generated native Golang
// types produced by the codegen will each individually implement schema.TypedNode.
//
// Typed nodes sometimes have slightly different behaviors than plain nodes:
// For example, when looking up fields on a typed node that's a struct,
// the error returned for a lookup with a key that's not a field name will
// be ErrNoSuchField (instead of ErrNotExists).
// These behaviors apply to the schema.TypedNode only and not their representations;
26 27
// continuing the example, the .Representation().LookupByString() method on
// that same node for the same key as plain `.LookupByString()` will still
28 29 30
// return ErrNotExists, because the representation isn't a schema.TypedNode!
type TypedNode interface {
	// schema.TypedNode acts just like a regular Node for almost all purposes;
31
	// which ipld.Kind it acts as is determined by the TypeKind.
32
	// (Note that the representation strategy of the type does *not* affect
33 34
	// the Kind of schema.TypedNode -- rather, the representation strategy
	// affects the `.Representation().Kind()`.)
35
	//
36 37
	// For example: if the `.Type().TypeKind()` of this node is "struct",
	// it will act like Kind() == "map"
38 39 40 41 42 43 44 45 46
	// (even if Type().(Struct).ReprStrategy() is "tuple").
	ipld.Node

	// Type returns a reference to the reified schema.Type value.
	Type() Type

	// Representation returns an ipld.Node which sees the data in this node
	// in its representation form.
	//
47 48 49 50
	// For example: if the `.Type().TypeKind()` of this node is "struct",
	// `.Representation().TypeKind()` may vary based on its representation strategy:
	// if the representation strategy is "map", then it will be Kind=="map";
	// if the streatgy is "tuple", then it will be Kind=="list".
51 52
	Representation() ipld.Node
}
53 54 55 56 57 58 59 60 61 62 63

// schema.TypedLinkNode is a superset of the schema.TypedNode interface, and has one additional behavior.
//
// A schema.TypedLinkNode contains a hint for the appropriate node builder to use for loading data
// on the other side of the link contained within the node, so that it can be assembled
// into a node representation and validated against the schema as quickly as possible
//
// So, for example, if you wanted to support loading the other side of a link
// with a code-gen'd node builder while utilizing the automatic loading facilities
// of the traversal package, you could write a LinkNodeBuilderChooser as follows:
//
64
//		func LinkNodeBuilderChooser(lnk ipld.Link, lnkCtx ipld.LinkContext) ipld.NodePrototype {
65
//			if tlnkNd, ok := lnkCtx.LinkNode.(schema.TypedLinkNode); ok {
66
//				return tlnkNd.LinkTargetNodePrototype()
67
//			}
68
//			return basicnode.Prototype__Any{}
69 70 71
//		}
//
type TypedLinkNode interface {
72
	LinkTargetNodePrototype() ipld.NodePrototype
73
}
Daniel Martí's avatar
Daniel Martí committed
74 75 76 77 78 79 80 81 82 83 84 85 86

// TypedPrototype is a superset of the ipld.Nodeprototype interface, and has
// additional behaviors, much like TypedNode for ipld.Node.
type TypedPrototype interface {
	ipld.NodePrototype

	// Type returns a reference to the reified schema.Type value.
	Type() Type

	// Representation returns an ipld.NodePrototype for the representation
	// form of the prototype.
	Representation() ipld.NodePrototype
}