fns.go 3.45 KB
Newer Older
1 2 3 4 5
package traversal

import (
	"context"

tavit ohanian's avatar
tavit ohanian committed
6
	ld "gitlab.dms3.io/ld/go-ld-prime"
7 8
)

Eric Myhre's avatar
Eric Myhre committed
9 10 11
// This file defines interfaces for things users provide,
//  plus a few of the parameters they'll need to receieve.
//--------------------------------------------------------
12

13
// VisitFn is a read-only visitor.
tavit ohanian's avatar
tavit ohanian committed
14
type VisitFn func(Progress, ld.Node) error
15 16

// TransformFn is like a visitor that can also return a new Node to replace the visited one.
tavit ohanian's avatar
tavit ohanian committed
17
type TransformFn func(Progress, ld.Node) (ld.Node, error)
18 19

// AdvVisitFn is like VisitFn, but for use with AdvTraversal: it gets additional arguments describing *why* this node is visited.
tavit ohanian's avatar
tavit ohanian committed
20
type AdvVisitFn func(Progress, ld.Node, VisitReason) error
21

22 23
// VisitReason provides additional information to traversals using AdvVisitFn.
type VisitReason byte
Eric Myhre's avatar
Eric Myhre committed
24 25

const (
26 27 28
	VisitReason_SelectionMatch     VisitReason = 'm' // Tells AdvVisitFn that this node was explicitly selected.  (This is the set of nodes that VisitFn is called for.)
	VisitReason_SelectionParent    VisitReason = 'p' // Tells AdvVisitFn that this node is a parent of one that will be explicitly selected.  (These calls only happen if the feature is enabled -- enabling parent detection requires a different algorithm and adds some overhead.)
	VisitReason_SelectionCandidate VisitReason = 'x' // Tells AdvVisitFn that this node was visited while searching for selection matches.  It is not necessarily implied that any explicit match will be a child of this node; only that we had to consider it.  (Merkle-proofs generally need to include any node in this group.)
Eric Myhre's avatar
Eric Myhre committed
29
)
30

31 32
type Progress struct {
	Cfg       *Config
tavit ohanian's avatar
tavit ohanian committed
33 34 35 36
	Path      ld.Path  // Path is how we reached the current point in the traversal.
	LastBlock struct { // LastBlock stores the Path and Link of the last block edge we had to load.  (It will always be zero in traversals with no linkloader.)
		Path ld.Path
		Link ld.Link
37 38 39
	}
}

40
type Config struct {
41
	Ctx                            context.Context                // Context carried through a traversal.  Optional; use it if you need cancellation.
tavit ohanian's avatar
tavit ohanian committed
42
	LinkSystem                     ld.LinkSystem                  // LinkSystem used for automatic link loading, and also any storing if mutation features (e.g. traversal.Transform) are used.
43
	LinkTargetNodePrototypeChooser LinkTargetNodePrototypeChooser // Chooser for Node implementations to produce during automatic link traversal.
44
}
45

46
// LinkTargetNodePrototypeChooser is a function that returns a NodePrototype based on
47
// the information in a Link and/or its LinkContext.
48
//
49
// A LinkTargetNodePrototypeChooser can be used in a traversal.Config to be clear about
50
// what kind of Node implementation to use when loading a Link.
51
// In a simple example, it could constantly return a `basicnode.Prototype__Any{}`.
52 53 54
// In a more complex example, a program using `bind` over native Go types
// could decide what kind of native type is expected, and return a
// `bind.NodeBuilder` for that specific concrete native type.
tavit ohanian's avatar
tavit ohanian committed
55
type LinkTargetNodePrototypeChooser func(ld.Link, ld.LinkContext) (ld.NodePrototype, error)
56 57 58 59 60 61 62 63 64 65 66 67 68

// SkipMe is a signalling "error" which can be used to tell traverse to skip some data.
//
// SkipMe can be returned by the Config.LinkLoader to skip entire blocks without aborting the walk.
// (This can be useful if you know you don't have data on hand,
// but want to continue the walk in other areas anyway;
// or, if you're doing a way where you know that it's valid to memoize seen
// areas based on Link alone.)
type SkipMe struct{}

func (SkipMe) Error() string {
	return "skip"
}