select_links.go 1.7 KB
Newer Older
1 2 3
package traversal

import (
tavit ohanian's avatar
tavit ohanian committed
4
	"gitlab.dms3.io/ld/go-ld-prime"
5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24
)

// SelectLinks walks a Node tree and returns a slice of all Links encountered.
// SelectLinks will recurse down into any maps and lists,
// but does not attempt to load any of the links it encounters nor recurse further through them
// (in other words, it's confined to one "block").
//
// SelectLinks only returns the list of links; it does not return any other information
// about them such as position in the tree, etc.
//
// An error may be returned if any of the nodes returns errors during iteration;
// this is generally only possible if one of the Nodes is an ADL,
// and unable to be fully walked because of the inability to load or process some data inside the ADL.
// Nodes already fully in memory should not encounter such errors,
// and it should be safe to ignore errors from this method when used in that situation.
// In case of an error, a partial list will still be returned.
//
// If an identical link is found several times during the walk,
// it is reported several times in the resulting list;
// no deduplication is performed by this method.
tavit ohanian's avatar
tavit ohanian committed
25 26
func SelectLinks(n ld.Node) ([]ld.Link, error) {
	var answer []ld.Link
27 28 29 30
	err := accumulateLinks(&answer, n)
	return answer, err
}

tavit ohanian's avatar
tavit ohanian committed
31
func accumulateLinks(a *[]ld.Link, n ld.Node) error {
32
	switch n.Kind() {
tavit ohanian's avatar
tavit ohanian committed
33
	case ld.Kind_Map:
34 35 36 37 38 39 40
		for itr := n.MapIterator(); !itr.Done(); {
			_, v, err := itr.Next()
			if err != nil {
				return err
			}
			accumulateLinks(a, v)
		}
tavit ohanian's avatar
tavit ohanian committed
41
	case ld.Kind_List:
42 43 44 45 46 47 48
		for itr := n.ListIterator(); !itr.Done(); {
			_, v, err := itr.Next()
			if err != nil {
				return err
			}
			accumulateLinks(a, v)
		}
tavit ohanian's avatar
tavit ohanian committed
49
	case ld.Kind_Link:
50 51 52 53 54
		lnk, _ := n.AsLink()
		*a = append(*a, lnk)
	}
	return nil
}