handle Optional Iterator selector
This commit is contained in:
@@ -116,41 +116,78 @@ func resolve(sel Selector, subject ipld.Node, at []string) (ipld.Node, []ipld.No
|
|||||||
case datamodel.Kind_List:
|
case datamodel.Kind_List:
|
||||||
it := cur.ListIterator()
|
it := cur.ListIterator()
|
||||||
for !it.Done() {
|
for !it.Done() {
|
||||||
k, v, err := it.Next()
|
_, v, err := it.Next()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, nil, err
|
return nil, nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
key := fmt.Sprintf("%d", k)
|
// check if there are more iterator segments
|
||||||
o, m, err := resolve(sel[i+1:], v, append(at[:], key))
|
if len(sel) > i+1 && sel[i+1].Iterator() {
|
||||||
if err != nil {
|
if v.Kind() == datamodel.Kind_List {
|
||||||
return nil, nil, err
|
// recursively resolve the remaining selector segments
|
||||||
}
|
var o ipld.Node
|
||||||
|
var m []ipld.Node
|
||||||
if m != nil {
|
o, m, err = resolve(sel[i+1:], v, at)
|
||||||
many = append(many, m...)
|
if err != nil {
|
||||||
|
// if the segment is optional and an error occurs, skip the current iteration.
|
||||||
|
if seg.Optional() {
|
||||||
|
continue
|
||||||
|
} else {
|
||||||
|
return nil, nil, err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if m != nil {
|
||||||
|
many = append(many, m...)
|
||||||
|
} else if o != nil {
|
||||||
|
many = append(many, o)
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// if the current value is not a list and the next segment is optional, skip the current iteration
|
||||||
|
if sel[i+1].Optional() {
|
||||||
|
continue
|
||||||
|
} else {
|
||||||
|
return nil, nil, newResolutionError(fmt.Sprintf("can not iterate over kind: %s", kindString(v)), at)
|
||||||
|
}
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
many = append(many, o)
|
// if there are no more iterator segments, append the current value to the result
|
||||||
|
many = append(many, v)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
case datamodel.Kind_Map:
|
case datamodel.Kind_Map:
|
||||||
it := cur.MapIterator()
|
it := cur.MapIterator()
|
||||||
for !it.Done() {
|
for !it.Done() {
|
||||||
k, v, err := it.Next()
|
_, v, err := it.Next()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, nil, err
|
return nil, nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
key, _ := k.AsString()
|
if len(sel) > i+1 && sel[i+1].Iterator() {
|
||||||
o, m, err := resolve(sel[i+1:], v, append(at[:], key))
|
if v.Kind() == datamodel.Kind_List {
|
||||||
if err != nil {
|
var o ipld.Node
|
||||||
return nil, nil, err
|
var m []ipld.Node
|
||||||
}
|
o, m, err = resolve(sel[i+1:], v, at)
|
||||||
|
if err != nil {
|
||||||
if m != nil {
|
if seg.Optional() {
|
||||||
many = append(many, m...)
|
continue
|
||||||
|
} else {
|
||||||
|
return nil, nil, err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if m != nil {
|
||||||
|
many = append(many, m...)
|
||||||
|
} else if o != nil {
|
||||||
|
many = append(many, o)
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if sel[i+1].Optional() {
|
||||||
|
continue
|
||||||
|
} else {
|
||||||
|
return nil, nil, newResolutionError(fmt.Sprintf("can not iterate over kind: %s", kindString(v)), at)
|
||||||
|
}
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
many = append(many, o)
|
many = append(many, v)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
default:
|
default:
|
||||||
|
|||||||
Reference in New Issue
Block a user