selector: Select is now a method

This commit is contained in:
Michael Muré
2024-10-15 17:26:49 +02:00
parent 2ad3aeb6da
commit 081d382028
4 changed files with 27 additions and 29 deletions

View File

@@ -7,8 +7,6 @@ import (
"github.com/ipld/go-ipld-prime"
"github.com/ipld/go-ipld-prime/datamodel"
"github.com/ipld/go-ipld-prime/must"
"github.com/ucan-wg/go-ucan/pkg/policy/selector"
)
// Match determines if the IPLD node matches the policy document.
@@ -26,7 +24,7 @@ func matchStatement(statement Statement, node ipld.Node) bool {
switch statement.Kind() {
case KindEqual:
if s, ok := statement.(equality); ok {
one, many, err := selector.Select(s.selector, node)
one, many, err := s.selector.Select(node)
if err != nil {
return false
}
@@ -45,7 +43,7 @@ func matchStatement(statement Statement, node ipld.Node) bool {
}
case KindGreaterThan:
if s, ok := statement.(equality); ok {
one, _, err := selector.Select(s.selector, node)
one, _, err := s.selector.Select(node)
if err != nil || one == nil {
return false
}
@@ -53,7 +51,7 @@ func matchStatement(statement Statement, node ipld.Node) bool {
}
case KindGreaterThanOrEqual:
if s, ok := statement.(equality); ok {
one, _, err := selector.Select(s.selector, node)
one, _, err := s.selector.Select(node)
if err != nil || one == nil {
return false
}
@@ -61,7 +59,7 @@ func matchStatement(statement Statement, node ipld.Node) bool {
}
case KindLessThan:
if s, ok := statement.(equality); ok {
one, _, err := selector.Select(s.selector, node)
one, _, err := s.selector.Select(node)
if err != nil || one == nil {
return false
}
@@ -69,7 +67,7 @@ func matchStatement(statement Statement, node ipld.Node) bool {
}
case KindLessThanOrEqual:
if s, ok := statement.(equality); ok {
one, _, err := selector.Select(s.selector, node)
one, _, err := s.selector.Select(node)
if err != nil || one == nil {
return false
}
@@ -104,7 +102,7 @@ func matchStatement(statement Statement, node ipld.Node) bool {
}
case KindLike:
if s, ok := statement.(wildcard); ok {
one, _, err := selector.Select(s.selector, node)
one, _, err := s.selector.Select(node)
if err != nil || one == nil {
return false
}
@@ -116,7 +114,7 @@ func matchStatement(statement Statement, node ipld.Node) bool {
}
case KindAll:
if s, ok := statement.(quantifier); ok {
_, many, err := selector.Select(s.selector, node)
_, many, err := s.selector.Select(node)
if err != nil || many == nil {
return false
}
@@ -130,7 +128,7 @@ func matchStatement(statement Statement, node ipld.Node) bool {
}
case KindAny:
if s, ok := statement.(quantifier); ok {
one, many, err := selector.Select(s.selector, node)
one, many, err := s.selector.Select(node)
if err != nil {
return false
}

View File

@@ -15,6 +15,12 @@ import (
// https://github.com/ucan-wg/delegation/blob/4094d5878b58f5d35055a3b93fccda0b8329ebae/README.md#selectors
type Selector []segment
// Select perform the selection described by the selector on the input IPLD DAG.
// If no error, Select returns either one ipld.Node or a []ipld.Node.
func (s Selector) Select(subject ipld.Node) (ipld.Node, []ipld.Node, error) {
return resolve(s, subject, nil)
}
func (s Selector) String() string {
var res strings.Builder
for _, seg := range s {
@@ -74,12 +80,6 @@ func (s segment) Index() int {
return s.index
}
// Select uses a selector to extract an IPLD node or set of nodes from the
// passed subject node.
func Select(sel Selector, subject ipld.Node) (ipld.Node, []ipld.Node, error) {
return resolve(sel, subject, nil)
}
func resolve(sel Selector, subject ipld.Node, at []string) (ipld.Node, []ipld.Node, error) {
cur := subject
for i, seg := range sel {

View File

@@ -313,7 +313,7 @@ func TestSelect(t *testing.T) {
sel, err := Parse(".")
require.NoError(t, err)
one, many, err := Select(sel, anode)
one, many, err := sel.Select(anode)
require.NoError(t, err)
require.NotEmpty(t, one)
require.Empty(t, many)
@@ -328,7 +328,7 @@ func TestSelect(t *testing.T) {
sel, err := Parse(".name.first")
require.NoError(t, err)
one, many, err := Select(sel, anode)
one, many, err := sel.Select(anode)
require.NoError(t, err)
require.NotEmpty(t, one)
require.Empty(t, many)
@@ -338,7 +338,7 @@ func TestSelect(t *testing.T) {
name := must.String(one)
require.Equal(t, alice.Name.First, name)
one, many, err = Select(sel, bnode)
one, many, err = sel.Select(bnode)
require.NoError(t, err)
require.NotEmpty(t, one)
require.Empty(t, many)
@@ -353,7 +353,7 @@ func TestSelect(t *testing.T) {
sel, err := Parse(".name.middle?")
require.NoError(t, err)
one, many, err := Select(sel, anode)
one, many, err := sel.Select(anode)
require.NoError(t, err)
require.NotEmpty(t, one)
require.Empty(t, many)
@@ -363,7 +363,7 @@ func TestSelect(t *testing.T) {
name := must.String(one)
require.Equal(t, *alice.Name.Middle, name)
one, many, err = Select(sel, bnode)
one, many, err = sel.Select(bnode)
require.NoError(t, err)
require.Empty(t, one)
require.Empty(t, many)
@@ -373,7 +373,7 @@ func TestSelect(t *testing.T) {
sel, err := Parse(".name.foo")
require.NoError(t, err)
one, many, err := Select(sel, anode)
one, many, err := sel.Select(anode)
require.Error(t, err)
require.Empty(t, one)
require.Empty(t, many)
@@ -387,7 +387,7 @@ func TestSelect(t *testing.T) {
sel, err := Parse(".name.foo?")
require.NoError(t, err)
one, many, err := Select(sel, anode)
one, many, err := sel.Select(anode)
require.NoError(t, err)
require.Empty(t, one)
require.Empty(t, many)
@@ -397,7 +397,7 @@ func TestSelect(t *testing.T) {
sel, err := Parse(".interests[]")
require.NoError(t, err)
one, many, err := Select(sel, anode)
one, many, err := sel.Select(anode)
require.NoError(t, err)
require.Empty(t, one)
require.NotEmpty(t, many)
@@ -417,7 +417,7 @@ func TestSelect(t *testing.T) {
sel, err := Parse(".interests[0][]")
require.NoError(t, err)
one, many, err := Select(sel, anode)
one, many, err := sel.Select(anode)
require.NoError(t, err)
require.Empty(t, one)
require.NotEmpty(t, many)
@@ -494,6 +494,6 @@ func FuzzParseAndSelect(f *testing.F) {
}
// look for panic()
_, _, _ = Select(sel, node)
_, _, _ = sel.Select(node)
})
}

View File

@@ -52,7 +52,7 @@ func TestSupportedForms(t *testing.T) {
require.NoError(t, err)
// attempt to select
node, nodes, err := selector.Select(sel, makeNode(t, tc.Input))
node, nodes, err := sel.Select(makeNode(t, tc.Input))
require.NoError(t, err)
require.NotEqual(t, node != nil, len(nodes) > 0) // XOR (only one of node or nodes should be set)
@@ -97,7 +97,7 @@ func TestSupportedForms(t *testing.T) {
require.NoError(t, err)
// attempt to select
node, nodes, err := selector.Select(sel, makeNode(t, tc.Input))
node, nodes, err := sel.Select(makeNode(t, tc.Input))
require.NoError(t, err)
// TODO: should Select return a single node which is sometimes a list or null?
// require.Equal(t, datamodel.Null, node)
@@ -124,7 +124,7 @@ func TestSupportedForms(t *testing.T) {
require.NoError(t, err)
// attempt to select
node, nodes, err := selector.Select(sel, makeNode(t, tc.Input))
node, nodes, err := sel.Select(makeNode(t, tc.Input))
require.Error(t, err)
assert.Nil(t, node)
assert.Empty(t, nodes)