github.com/ipld/go-ipld-prime@v0.21.0/schema/typedNode.go (about)

     1  package schema
     2  
     3  import (
     4  	"github.com/ipld/go-ipld-prime/datamodel"
     5  )
     6  
     7  // schema.TypedNode is a superset of the datamodel.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
    11  // datamodel.Kind.
    12  //
    13  // There are many different implementations of schema.TypedNode.
    14  // One implementation can wrap any other existing datamodel.Node (i.e., it's zero-copy)
    15  // and promises that it has *already* been validated to match the typesystem.Type;
    16  // another implementation similarly wraps any other existing datamodel.Node, but
    17  // defers to the typesystem validation checking to fields that are accessed;
    18  // and when using code generation tools, all of the generated native Golang
    19  // types produced by the codegen will each individually implement schema.TypedNode.
    20  //
    21  // Typed nodes sometimes have slightly different behaviors than plain nodes:
    22  // For example, when looking up fields on a typed node that's a struct,
    23  // the error returned for a lookup with a key that's not a field name will
    24  // be ErrNoSuchField (instead of ErrNotExists).
    25  // These behaviors apply to the schema.TypedNode only and not their representations;
    26  // continuing the example, the .Representation().LookupByString() method on
    27  // that same node for the same key as plain `.LookupByString()` will still
    28  // return ErrNotExists, because the representation isn't a schema.TypedNode!
    29  type TypedNode interface {
    30  	// schema.TypedNode acts just like a regular Node for almost all purposes;
    31  	// which datamodel.Kind it acts as is determined by the TypeKind.
    32  	// (Note that the representation strategy of the type does *not* affect
    33  	// the Kind of schema.TypedNode -- rather, the representation strategy
    34  	// affects the `.Representation().Kind()`.)
    35  	//
    36  	// For example: if the `.Type().TypeKind()` of this node is "struct",
    37  	// it will act like Kind() == "map"
    38  	// (even if Type().(Struct).ReprStrategy() is "tuple").
    39  	datamodel.Node
    40  
    41  	// Type returns a reference to the reified schema.Type value.
    42  	Type() Type
    43  
    44  	// Representation returns a datamodel.Node which sees the data in this node
    45  	// in its representation form.
    46  	//
    47  	// For example: if the `.Type().TypeKind()` of this node is "struct",
    48  	// `.Representation().TypeKind()` may vary based on its representation strategy:
    49  	// if the representation strategy is "map", then it will be Kind=="map";
    50  	// if the streatgy is "tuple", then it will be Kind=="list".
    51  	Representation() datamodel.Node
    52  }
    53  
    54  // schema.TypedLinkNode is a superset of the schema.TypedNode interface, and has one additional behavior.
    55  //
    56  // A schema.TypedLinkNode contains a hint for the appropriate node builder to use for loading data
    57  // on the other side of the link contained within the node, so that it can be assembled
    58  // into a node representation and validated against the schema as quickly as possible
    59  //
    60  // So, for example, if you wanted to support loading the other side of a link
    61  // with a code-gen'd node builder while utilizing the automatic loading facilities
    62  // of the traversal package, you could write a LinkNodeBuilderChooser as follows:
    63  //
    64  //	func LinkNodeBuilderChooser(lnk datamodel.Link, lnkCtx linking.LinkContext) datamodel.NodePrototype {
    65  //		if tlnkNd, ok := lnkCtx.LinkNode.(schema.TypedLinkNode); ok {
    66  //			return tlnkNd.LinkTargetNodePrototype()
    67  //		}
    68  //		return basicnode.Prototype.Any
    69  //	}
    70  type TypedLinkNode interface {
    71  	LinkTargetNodePrototype() datamodel.NodePrototype
    72  }
    73  
    74  // TypedPrototype is a superset of the datamodel.Nodeprototype interface, and has
    75  // additional behaviors, much like TypedNode for datamodel.Node.
    76  type TypedPrototype interface {
    77  	datamodel.NodePrototype
    78  
    79  	// Type returns a reference to the reified schema.Type value.
    80  	Type() Type
    81  
    82  	// Representation returns a datamodel.NodePrototype for the representation
    83  	// form of the prototype.
    84  	Representation() datamodel.NodePrototype
    85  }