github.com/ipld/go-ipld-prime@v0.21.0/traversal/selector/exploreRange.go (about) 1 package selector 2 3 import ( 4 "fmt" 5 6 "github.com/ipld/go-ipld-prime/datamodel" 7 ) 8 9 // ExploreRange traverses a list, and for each element in the range specified, 10 // will apply a next selector to those reached nodes. 11 type ExploreRange struct { 12 next Selector // selector for element we're interested in 13 start int64 14 end int64 15 interest []datamodel.PathSegment // index of element we're interested in 16 } 17 18 // Interests for ExploreRange are all path segments within the iteration range 19 func (s ExploreRange) Interests() []datamodel.PathSegment { 20 return s.interest 21 } 22 23 // Explore returns the node's selector if 24 // the path matches an index in the range of this selector 25 func (s ExploreRange) Explore(n datamodel.Node, p datamodel.PathSegment) (Selector, error) { 26 if n.Kind() != datamodel.Kind_List { 27 return nil, nil 28 } 29 index, err := p.Index() 30 if err != nil { 31 return nil, nil 32 } 33 if index < s.start || index >= s.end { 34 return nil, nil 35 } 36 return s.next, nil 37 } 38 39 // Decide always returns false because this is not a matcher 40 func (s ExploreRange) Decide(n datamodel.Node) bool { 41 return false 42 } 43 44 // Match always returns false because this is not a matcher 45 func (s ExploreRange) Match(node datamodel.Node) (datamodel.Node, error) { 46 return nil, nil 47 } 48 49 // ParseExploreRange assembles a Selector 50 // from a ExploreRange selector node 51 func (pc ParseContext) ParseExploreRange(n datamodel.Node) (Selector, error) { 52 if n.Kind() != datamodel.Kind_Map { 53 return nil, fmt.Errorf("selector spec parse rejected: selector body must be a map") 54 } 55 startNode, err := n.LookupByString(SelectorKey_Start) 56 if err != nil { 57 return nil, fmt.Errorf("selector spec parse rejected: start field must be present in ExploreRange selector") 58 } 59 startValue, err := startNode.AsInt() 60 if err != nil { 61 return nil, fmt.Errorf("selector spec parse rejected: start field must be a number in ExploreRange selector") 62 } 63 endNode, err := n.LookupByString(SelectorKey_End) 64 if err != nil { 65 return nil, fmt.Errorf("selector spec parse rejected: end field must be present in ExploreRange selector") 66 } 67 endValue, err := endNode.AsInt() 68 if err != nil { 69 return nil, fmt.Errorf("selector spec parse rejected: end field must be a number in ExploreRange selector") 70 } 71 if startValue >= endValue { 72 return nil, fmt.Errorf("selector spec parse rejected: end field must be greater than start field in ExploreRange selector") 73 } 74 next, err := n.LookupByString(SelectorKey_Next) 75 if err != nil { 76 return nil, fmt.Errorf("selector spec parse rejected: next field must be present in ExploreRange selector") 77 } 78 selector, err := pc.ParseSelector(next) 79 if err != nil { 80 return nil, err 81 } 82 x := ExploreRange{ 83 selector, 84 startValue, 85 endValue, 86 make([]datamodel.PathSegment, 0, endValue-startValue), 87 } 88 for i := startValue; i < endValue; i++ { 89 x.interest = append(x.interest, datamodel.PathSegmentOfInt(i)) 90 } 91 return x, nil 92 }