diff --git a/pkg/policy/match.go b/pkg/policy/match.go index 92a095e..178b862 100644 --- a/pkg/policy/match.go +++ b/pkg/policy/match.go @@ -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 } diff --git a/pkg/policy/selector/selector.go b/pkg/policy/selector/selector.go index e4a1401..f5ed2ad 100644 --- a/pkg/policy/selector/selector.go +++ b/pkg/policy/selector/selector.go @@ -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 { diff --git a/pkg/policy/selector/selector_test.go b/pkg/policy/selector/selector_test.go index e961291..fdbfd69 100644 --- a/pkg/policy/selector/selector_test.go +++ b/pkg/policy/selector/selector_test.go @@ -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) }) } diff --git a/pkg/policy/selector/supported_test.go b/pkg/policy/selector/supported_test.go index a7e9917..dcb41ec 100644 --- a/pkg/policy/selector/supported_test.go +++ b/pkg/policy/selector/supported_test.go @@ -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)