typedNode.go 3.76 KB
Newer Older
1 2
package schema

3 4 5 6
import (
	ld "gitlab.dms3.io/ld/go-ld-prime"
)

tavit ohanian's avatar
tavit ohanian committed
7
// schema.TypedNode is a superset of the ld.Node interface, and has additional behaviors.
8
//
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
tavit ohanian's avatar
tavit ohanian committed
11
// ld.Kind.
12 13
//
// There are many different implementations of schema.TypedNode.
tavit ohanian's avatar
tavit ohanian committed
14
// One implementation can wrap any other existing ld.Node (i.e., it's zero-copy)
15
// and promises that it has *already* been validated to match the typesystem.Type;
tavit ohanian's avatar
tavit ohanian committed
16
// another implementation similarly wraps any other existing ld.Node, but
17 18 19 20 21 22 23 24 25
// 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;
tavit ohanian's avatar
tavit ohanian committed
31
	// which ld.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
	// (even if Type().(Struct).ReprStrategy() is "tuple").
tavit ohanian's avatar
tavit ohanian committed
39
	ld.Node
40 41 42 43

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

tavit ohanian's avatar
tavit ohanian committed
44
	// Representation returns an ld.Node which sees the data in this node
45 46
	// 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".
tavit ohanian's avatar
tavit ohanian committed
51
	Representation() ld.Node
52
}
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:
//
tavit ohanian's avatar
tavit ohanian committed
64
//		func LinkNodeBuilderChooser(lnk ld.Link, lnkCtx ld.LinkContext) ld.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 {
tavit ohanian's avatar
tavit ohanian committed
72
	LinkTargetNodePrototype() ld.NodePrototype
73
}
Daniel Martí's avatar
Daniel Martí committed
74

tavit ohanian's avatar
tavit ohanian committed
75 76
// TypedPrototype is a superset of the ld.Nodeprototype interface, and has
// additional behaviors, much like TypedNode for ld.Node.
Daniel Martí's avatar
Daniel Martí committed
77
type TypedPrototype interface {
tavit ohanian's avatar
tavit ohanian committed
78
	ld.NodePrototype
Daniel Martí's avatar
Daniel Martí committed
79 80 81 82

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

tavit ohanian's avatar
tavit ohanian committed
83
	// Representation returns an ld.NodePrototype for the representation
Daniel Martí's avatar
Daniel Martí committed
84
	// form of the prototype.
tavit ohanian's avatar
tavit ohanian committed
85
	Representation() ld.NodePrototype
Daniel Martí's avatar
Daniel Martí committed
86
}