github.com/ipld/go-ipld-prime@v0.21.0/traversal/select_links.go (about) 1 package traversal 2 3 import ( 4 "github.com/ipld/go-ipld-prime/datamodel" 5 ) 6 7 // SelectLinks walks a Node tree and returns a slice of all Links encountered. 8 // SelectLinks will recurse down into any maps and lists, 9 // but does not attempt to load any of the links it encounters nor recurse further through them 10 // (in other words, it's confined to one "block"). 11 // 12 // SelectLinks only returns the list of links; it does not return any other information 13 // about them such as position in the tree, etc. 14 // 15 // An error may be returned if any of the nodes returns errors during iteration; 16 // this is generally only possible if one of the Nodes is an ADL, 17 // and unable to be fully walked because of the inability to load or process some data inside the ADL. 18 // Nodes already fully in memory should not encounter such errors, 19 // and it should be safe to ignore errors from this method when used in that situation. 20 // In case of an error, a partial list will still be returned. 21 // 22 // If an identical link is found several times during the walk, 23 // it is reported several times in the resulting list; 24 // no deduplication is performed by this method. 25 func SelectLinks(n datamodel.Node) ([]datamodel.Link, error) { 26 var answer []datamodel.Link 27 err := accumulateLinks(&answer, n) 28 return answer, err 29 } 30 31 func accumulateLinks(a *[]datamodel.Link, n datamodel.Node) error { 32 switch n.Kind() { 33 case datamodel.Kind_Map: 34 for itr := n.MapIterator(); !itr.Done(); { 35 _, v, err := itr.Next() 36 if err != nil { 37 return err 38 } 39 accumulateLinks(a, v) 40 } 41 case datamodel.Kind_List: 42 for itr := n.ListIterator(); !itr.Done(); { 43 _, v, err := itr.Next() 44 if err != nil { 45 return err 46 } 47 accumulateLinks(a, v) 48 } 49 case datamodel.Kind_Link: 50 lnk, _ := n.AsLink() 51 *a = append(*a, lnk) 52 } 53 return nil 54 }