Compare commits
4 Commits
cont-namin
...
v1.0.0
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
e218b49577 | ||
|
|
4c81ac778e | ||
|
|
7ae65e7c8e | ||
|
|
7f9cb6426c |
@@ -57,7 +57,7 @@ Not implemented yet:
|
||||
|
||||
Besides that, `go-ucan` also includes:
|
||||
- a simplified [DID](https://www.w3.org/TR/did-core/) and [did-key](https://w3c-ccg.github.io/did-method-key/) implementation
|
||||
- a [token container](https://github.com/ucan-wg/go-ucan/tree/v1/pkg/container) with CBOR and CAR format, to package and carry tokens together
|
||||
- a [token container](https://github.com/ucan-wg/go-ucan/tree/v1/pkg/container) with CBOR and CAR format, to package and carry tokens together, see [SPEC](pkg/container/SPEC.md)
|
||||
- support for encrypted values in token's metadata
|
||||
|
||||
## Getting Help
|
||||
|
||||
@@ -81,7 +81,7 @@ func statementFromIPLD(path string, node datamodel.Node) (Statement, error) {
|
||||
}
|
||||
case 3:
|
||||
switch op {
|
||||
case KindEqual, KindLessThan, KindLessThanOrEqual, KindGreaterThan, KindGreaterThanOrEqual:
|
||||
case KindEqual, KindNotEqual, KindLessThan, KindLessThanOrEqual, KindGreaterThan, KindGreaterThanOrEqual:
|
||||
sel, err := arg2AsSelector(op)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
|
||||
@@ -1,11 +1,14 @@
|
||||
package policy
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"testing"
|
||||
|
||||
"github.com/ipld/go-ipld-prime"
|
||||
"github.com/ipld/go-ipld-prime/codec/dagjson"
|
||||
"github.com/stretchr/testify/require"
|
||||
|
||||
"github.com/ucan-wg/go-ucan/pkg/policy/literal"
|
||||
)
|
||||
|
||||
func TestIpldRoundTrip(t *testing.T) {
|
||||
@@ -21,10 +24,31 @@ func TestIpldRoundTrip(t *testing.T) {
|
||||
]
|
||||
]`
|
||||
|
||||
// must contain all the operators
|
||||
const allOps = `
|
||||
[
|
||||
["and", [
|
||||
["==", ".foo1", ".bar1"],
|
||||
["!=", ".foo2", ".bar2"]
|
||||
]],
|
||||
["or", [
|
||||
[">", ".foo5", 5.2],
|
||||
[">=", ".foo6", 6.2]
|
||||
]],
|
||||
["not", ["like", ".foo7", "*@example.com"]],
|
||||
["all", ".foo8",
|
||||
["<", ".foo3", 3]
|
||||
],
|
||||
["any", ".foo9",
|
||||
["<=", ".foo4", 4]
|
||||
]
|
||||
]`
|
||||
|
||||
for _, tc := range []struct {
|
||||
name, dagJsonStr string
|
||||
}{
|
||||
{"illustrativeExample", illustrativeExample},
|
||||
{"allOps", allOps},
|
||||
} {
|
||||
nodes, err := ipld.Decode([]byte(tc.dagJsonStr), dagjson.Decode)
|
||||
require.NoError(t, err)
|
||||
@@ -41,3 +65,19 @@ func TestIpldRoundTrip(t *testing.T) {
|
||||
require.JSONEq(t, tc.dagJsonStr, string(wroteAsDagJson))
|
||||
}
|
||||
}
|
||||
|
||||
func TestFoo(t *testing.T) {
|
||||
fmt.Println(MustConstruct(
|
||||
And(
|
||||
Equal(".foo1", literal.String(".bar1")),
|
||||
NotEqual(".foo2", literal.String(".bar2")),
|
||||
),
|
||||
Or(
|
||||
GreaterThan(".foo5", literal.Float(5.2)),
|
||||
GreaterThanOrEqual(".foo6", literal.Float(6.2)),
|
||||
),
|
||||
Not(Like(".foo7", "*@example.com")),
|
||||
All(".foo8", LessThan(".foo3", literal.Int(3))),
|
||||
Any(".foo9", LessThanOrEqual(".foo4", literal.Int(4))),
|
||||
))
|
||||
}
|
||||
|
||||
@@ -82,6 +82,17 @@ func matchStatement(cur Statement, node ipld.Node) (_ matchResult, leafMost Stat
|
||||
}
|
||||
return boolToRes(datamodel.DeepEqual(s.value, res))
|
||||
}
|
||||
case KindNotEqual:
|
||||
if s, ok := cur.(equality); ok {
|
||||
res, err := s.selector.Select(node)
|
||||
if err != nil {
|
||||
return matchResultNoData, cur
|
||||
}
|
||||
if res == nil { // optional selector didn't match
|
||||
return matchResultOptionalNoData, nil
|
||||
}
|
||||
return boolToRes(!datamodel.DeepEqual(s.value, res))
|
||||
}
|
||||
case KindGreaterThan:
|
||||
if s, ok := cur.(equality); ok {
|
||||
res, err := s.selector.Select(node)
|
||||
|
||||
@@ -16,7 +16,7 @@ import (
|
||||
|
||||
func TestMatch(t *testing.T) {
|
||||
t.Run("equality", func(t *testing.T) {
|
||||
t.Run("string", func(t *testing.T) {
|
||||
t.Run("eq string", func(t *testing.T) {
|
||||
nd := literal.String("test")
|
||||
|
||||
pol := MustConstruct(Equal(".", literal.String("test")))
|
||||
@@ -35,7 +35,7 @@ func TestMatch(t *testing.T) {
|
||||
require.Equal(t, pol[0], leaf)
|
||||
})
|
||||
|
||||
t.Run("int", func(t *testing.T) {
|
||||
t.Run("eq int", func(t *testing.T) {
|
||||
nd := literal.Int(138)
|
||||
|
||||
pol := MustConstruct(Equal(".", literal.Int(138)))
|
||||
@@ -54,7 +54,7 @@ func TestMatch(t *testing.T) {
|
||||
require.Equal(t, pol[0], leaf)
|
||||
})
|
||||
|
||||
t.Run("float", func(t *testing.T) {
|
||||
t.Run("eq float", func(t *testing.T) {
|
||||
nd := literal.Float(1.138)
|
||||
|
||||
pol := MustConstruct(Equal(".", literal.Float(1.138)))
|
||||
@@ -73,7 +73,7 @@ func TestMatch(t *testing.T) {
|
||||
require.Equal(t, pol[0], leaf)
|
||||
})
|
||||
|
||||
t.Run("IPLD Link", func(t *testing.T) {
|
||||
t.Run("eq IPLD Link", func(t *testing.T) {
|
||||
l0 := cidlink.Link{Cid: cid.MustParse("bafybeif4owy5gno5lwnixqm52rwqfodklf76hsetxdhffuxnplvijskzqq")}
|
||||
l1 := cidlink.Link{Cid: cid.MustParse("bafkreifau35r7vi37tvbvfy3hdwvgb4tlflqf7zcdzeujqcjk3rsphiwte")}
|
||||
|
||||
@@ -95,7 +95,7 @@ func TestMatch(t *testing.T) {
|
||||
require.Equal(t, pol[0], leaf)
|
||||
})
|
||||
|
||||
t.Run("string in map", func(t *testing.T) {
|
||||
t.Run("eq string in map", func(t *testing.T) {
|
||||
nd, _ := literal.Map(map[string]any{
|
||||
"foo": "bar",
|
||||
})
|
||||
@@ -121,7 +121,7 @@ func TestMatch(t *testing.T) {
|
||||
require.Equal(t, pol[0], leaf)
|
||||
})
|
||||
|
||||
t.Run("string in list", func(t *testing.T) {
|
||||
t.Run("eq string in list", func(t *testing.T) {
|
||||
nd, _ := literal.List([]any{"foo"})
|
||||
|
||||
pol := MustConstruct(Equal(".[0]", literal.String("foo")))
|
||||
@@ -134,6 +134,132 @@ func TestMatch(t *testing.T) {
|
||||
require.False(t, ok)
|
||||
require.Equal(t, pol[0], leaf)
|
||||
})
|
||||
|
||||
t.Run("neq string", func(t *testing.T) {
|
||||
nd := literal.String("test")
|
||||
|
||||
pol := MustConstruct(NotEqual(".", literal.String("test")))
|
||||
ok, leaf := pol.Match(nd)
|
||||
require.False(t, ok)
|
||||
require.Equal(t, pol[0], leaf)
|
||||
|
||||
pol = MustConstruct(NotEqual(".", literal.String("test2")))
|
||||
ok, leaf = pol.Match(nd)
|
||||
require.True(t, ok)
|
||||
require.Nil(t, leaf)
|
||||
|
||||
pol = MustConstruct(NotEqual(".", literal.Int(138)))
|
||||
ok, leaf = pol.Match(nd)
|
||||
require.True(t, ok)
|
||||
require.Nil(t, leaf)
|
||||
})
|
||||
|
||||
t.Run("neq int", func(t *testing.T) {
|
||||
nd := literal.Int(138)
|
||||
|
||||
pol := MustConstruct(NotEqual(".", literal.Int(138)))
|
||||
ok, leaf := pol.Match(nd)
|
||||
require.False(t, ok)
|
||||
require.Equal(t, pol[0], leaf)
|
||||
|
||||
pol = MustConstruct(NotEqual(".", literal.Int(1138)))
|
||||
ok, leaf = pol.Match(nd)
|
||||
require.True(t, ok)
|
||||
require.Nil(t, leaf)
|
||||
|
||||
pol = MustConstruct(NotEqual(".", literal.String("138")))
|
||||
ok, leaf = pol.Match(nd)
|
||||
require.True(t, ok)
|
||||
require.Nil(t, leaf)
|
||||
})
|
||||
|
||||
t.Run("neq float", func(t *testing.T) {
|
||||
nd := literal.Float(1.138)
|
||||
|
||||
pol := MustConstruct(NotEqual(".", literal.Float(1.138)))
|
||||
ok, leaf := pol.Match(nd)
|
||||
require.False(t, ok)
|
||||
require.Equal(t, pol[0], leaf)
|
||||
|
||||
pol = MustConstruct(NotEqual(".", literal.Float(11.38)))
|
||||
ok, leaf = pol.Match(nd)
|
||||
require.True(t, ok)
|
||||
require.Nil(t, leaf)
|
||||
|
||||
pol = MustConstruct(NotEqual(".", literal.String("138")))
|
||||
ok, leaf = pol.Match(nd)
|
||||
require.True(t, ok)
|
||||
require.Nil(t, leaf)
|
||||
})
|
||||
|
||||
t.Run("neq IPLD Link", func(t *testing.T) {
|
||||
l0 := cidlink.Link{Cid: cid.MustParse("bafybeif4owy5gno5lwnixqm52rwqfodklf76hsetxdhffuxnplvijskzqq")}
|
||||
l1 := cidlink.Link{Cid: cid.MustParse("bafkreifau35r7vi37tvbvfy3hdwvgb4tlflqf7zcdzeujqcjk3rsphiwte")}
|
||||
|
||||
nd := literal.Link(l0)
|
||||
|
||||
pol := MustConstruct(NotEqual(".", literal.Link(l0)))
|
||||
ok, leaf := pol.Match(nd)
|
||||
require.False(t, ok)
|
||||
require.Equal(t, pol[0], leaf)
|
||||
|
||||
pol = MustConstruct(NotEqual(".", literal.Link(l1)))
|
||||
ok, leaf = pol.Match(nd)
|
||||
require.True(t, ok)
|
||||
require.Nil(t, leaf)
|
||||
|
||||
pol = MustConstruct(NotEqual(".", literal.String("bafybeif4owy5gno5lwnixqm52rwqfodklf76hsetxdhffuxnplvijskzqq")))
|
||||
ok, leaf = pol.Match(nd)
|
||||
require.True(t, ok)
|
||||
require.Nil(t, leaf)
|
||||
})
|
||||
|
||||
t.Run("neq string in map", func(t *testing.T) {
|
||||
nd, _ := literal.Map(map[string]any{
|
||||
"foo": "bar",
|
||||
})
|
||||
|
||||
pol := MustConstruct(NotEqual(".foo", literal.String("bar")))
|
||||
ok, leaf := pol.Match(nd)
|
||||
require.False(t, ok)
|
||||
require.Equal(t, pol[0], leaf)
|
||||
|
||||
pol = MustConstruct(NotEqual(".[\"foo\"]", literal.String("bar")))
|
||||
ok, leaf = pol.Match(nd)
|
||||
require.False(t, ok)
|
||||
require.Equal(t, pol[0], leaf)
|
||||
|
||||
pol = MustConstruct(NotEqual(".foo", literal.String("baz")))
|
||||
ok, leaf = pol.Match(nd)
|
||||
require.True(t, ok)
|
||||
require.Nil(t, leaf)
|
||||
|
||||
// missing data will fail, as not optional
|
||||
pol = MustConstruct(NotEqual(".foobar", literal.String("bar")))
|
||||
ok, leaf = pol.Match(nd)
|
||||
require.False(t, ok)
|
||||
require.Equal(t, pol[0], leaf)
|
||||
})
|
||||
|
||||
t.Run("neq string in list", func(t *testing.T) {
|
||||
nd, _ := literal.List([]any{"foo"})
|
||||
|
||||
pol := MustConstruct(NotEqual(".[0]", literal.String("foo")))
|
||||
ok, leaf := pol.Match(nd)
|
||||
require.False(t, ok)
|
||||
require.Equal(t, pol[0], leaf)
|
||||
|
||||
pol = MustConstruct(NotEqual(".[0]", literal.String("bar")))
|
||||
ok, leaf = pol.Match(nd)
|
||||
require.True(t, ok)
|
||||
require.Nil(t, leaf)
|
||||
|
||||
// missing data will fail, as not optional
|
||||
pol = MustConstruct(NotEqual(".[1]", literal.String("foo")))
|
||||
ok, leaf = pol.Match(nd)
|
||||
require.False(t, ok)
|
||||
require.Equal(t, pol[0], leaf)
|
||||
})
|
||||
})
|
||||
|
||||
t.Run("inequality", func(t *testing.T) {
|
||||
@@ -245,20 +371,61 @@ func TestMatch(t *testing.T) {
|
||||
require.False(t, ok)
|
||||
require.Equal(t, pol[0], leaf)
|
||||
})
|
||||
|
||||
t.Run("lt float", func(t *testing.T) {
|
||||
nd := literal.Float(1.38)
|
||||
|
||||
pol := MustConstruct(LessThan(".", literal.Float(1)))
|
||||
ok, leaf := pol.Match(nd)
|
||||
require.False(t, ok)
|
||||
require.Equal(t, pol[0], leaf)
|
||||
|
||||
pol = MustConstruct(LessThan(".", literal.Float(2)))
|
||||
ok, leaf = pol.Match(nd)
|
||||
require.True(t, ok)
|
||||
require.Nil(t, leaf)
|
||||
})
|
||||
|
||||
t.Run("lte float", func(t *testing.T) {
|
||||
nd := literal.Float(1.38)
|
||||
|
||||
pol := MustConstruct(LessThanOrEqual(".", literal.Float(1)))
|
||||
ok, leaf := pol.Match(nd)
|
||||
require.False(t, ok)
|
||||
require.Equal(t, pol[0], leaf)
|
||||
|
||||
pol = MustConstruct(GreaterThanOrEqual(".", literal.Float(1.38)))
|
||||
ok, leaf = pol.Match(nd)
|
||||
require.True(t, ok)
|
||||
require.Nil(t, leaf)
|
||||
|
||||
pol = MustConstruct(LessThanOrEqual(".", literal.Float(2)))
|
||||
ok, leaf = pol.Match(nd)
|
||||
require.True(t, ok)
|
||||
require.Nil(t, leaf)
|
||||
})
|
||||
})
|
||||
|
||||
t.Run("negation", func(t *testing.T) {
|
||||
nd := literal.Bool(false)
|
||||
nd, _ := literal.Map(map[string]any{
|
||||
"foo": false,
|
||||
})
|
||||
|
||||
pol := MustConstruct(Not(Equal(".", literal.Bool(true))))
|
||||
pol := MustConstruct(Not(Equal(".foo", literal.Bool(true))))
|
||||
ok, leaf := pol.Match(nd)
|
||||
require.True(t, ok)
|
||||
require.Nil(t, leaf)
|
||||
|
||||
pol = MustConstruct(Not(Equal(".", literal.Bool(false))))
|
||||
pol = MustConstruct(Not(Equal(".foo", literal.Bool(false))))
|
||||
ok, leaf = pol.Match(nd)
|
||||
require.False(t, ok)
|
||||
require.Equal(t, pol[0], leaf)
|
||||
|
||||
// missing data will fail, as not optional
|
||||
pol = MustConstruct(Not(Equal(".foobar", literal.Bool(true))))
|
||||
ok, leaf = pol.Match(nd)
|
||||
require.False(t, ok)
|
||||
require.Equal(t, MustConstruct(Equal(".foobar", literal.Bool(true)))[0], leaf)
|
||||
})
|
||||
|
||||
t.Run("conjunction", func(t *testing.T) {
|
||||
@@ -482,6 +649,7 @@ func FuzzMatch(f *testing.F) {
|
||||
f.Add([]byte(`[["all", ".reviewer", ["like", ".email", "*@example.com"]]]`), []byte(`{"reviewer": [{"email": "alice@example.com"}, {"email": "bob@example.com"}]}`))
|
||||
f.Add([]byte(`[["any", ".tags", ["or", [["==", ".", "news"], ["==", ".", "press"]]]]]`), []byte(`{"tags": ["news", "press"]}`))
|
||||
f.Add([]byte(`[["==", ".name", "Alice"]]`), []byte(`{"name": "Alice"}`))
|
||||
f.Add([]byte(`[["!=", ".name", "Alice"]]`), []byte(`{"name": "Alice"}`))
|
||||
f.Add([]byte(`[[">", ".age", 30]]`), []byte(`{"age": 31}`))
|
||||
f.Add([]byte(`[["<=", ".height", 180]]`), []byte(`{"height": 170}`))
|
||||
f.Add([]byte(`[["not", ["==", ".status", "inactive"]]]`), []byte(`{"status": "active"}`))
|
||||
|
||||
@@ -14,6 +14,7 @@ import (
|
||||
|
||||
const (
|
||||
KindEqual = "==" // implemented by equality
|
||||
KindNotEqual = "!=" // implemented by equality
|
||||
KindGreaterThan = ">" // implemented by equality
|
||||
KindGreaterThanOrEqual = ">=" // implemented by equality
|
||||
KindLessThan = "<" // implemented by equality
|
||||
@@ -87,6 +88,13 @@ func Equal(selector string, value ipld.Node) Constructor {
|
||||
}
|
||||
}
|
||||
|
||||
func NotEqual(selector string, value ipld.Node) Constructor {
|
||||
return func() (Statement, error) {
|
||||
sel, err := selpkg.Parse(selector)
|
||||
return equality{kind: KindNotEqual, selector: sel, value: value}, err
|
||||
}
|
||||
}
|
||||
|
||||
func GreaterThan(selector string, value ipld.Node) Constructor {
|
||||
return func() (Statement, error) {
|
||||
sel, err := selpkg.Parse(selector)
|
||||
@@ -125,7 +133,7 @@ func (n negation) Kind() string {
|
||||
|
||||
func (n negation) String() string {
|
||||
child := n.statement.String()
|
||||
return fmt.Sprintf(`["%s", "%s"]`, n.Kind(), strings.ReplaceAll(child, "\n", "\n "))
|
||||
return fmt.Sprintf(`["%s", %s]`, n.Kind(), strings.ReplaceAll(child, "\n", "\n "))
|
||||
}
|
||||
|
||||
func Not(cstor Constructor) Constructor {
|
||||
@@ -149,7 +157,7 @@ func (c connective) String() string {
|
||||
for i, statement := range c.statements {
|
||||
childs[i] = strings.ReplaceAll(statement.String(), "\n", "\n ")
|
||||
}
|
||||
return fmt.Sprintf("[\"%s\", [\n %s]]\n", c.kind, strings.Join(childs, ",\n "))
|
||||
return fmt.Sprintf("[\"%s\", [\n %s\n]]", c.kind, strings.Join(childs, ",\n "))
|
||||
}
|
||||
|
||||
func And(cstors ...Constructor) Constructor {
|
||||
@@ -208,7 +216,7 @@ func (n quantifier) Kind() string {
|
||||
|
||||
func (n quantifier) String() string {
|
||||
child := n.statement.String()
|
||||
return fmt.Sprintf("[\"%s\", \"%s\",\n %s]", n.Kind(), n.selector, strings.ReplaceAll(child, "\n", "\n "))
|
||||
return fmt.Sprintf("[\"%s\", \"%s\",\n %s\n]", n.Kind(), n.selector, strings.ReplaceAll(child, "\n", "\n "))
|
||||
}
|
||||
|
||||
func All(selector string, cstor Constructor) Constructor {
|
||||
|
||||
@@ -28,12 +28,14 @@ func ExamplePolicy() {
|
||||
// [
|
||||
// ["==", ".status", "draft"],
|
||||
// ["all", ".reviewer",
|
||||
// ["like", ".email", "*@example.com"]],
|
||||
// ["like", ".email", "*@example.com"]
|
||||
// ],
|
||||
// ["any", ".tags",
|
||||
// ["or", [
|
||||
// ["==", ".", "news"],
|
||||
// ["==", ".", "press"]]]
|
||||
// ]
|
||||
// ["==", ".", "press"]
|
||||
// ]]
|
||||
// ]
|
||||
// ]
|
||||
}
|
||||
|
||||
@@ -59,12 +61,14 @@ func ExamplePolicy_accumulate() {
|
||||
// [
|
||||
// ["==", ".status", "draft"],
|
||||
// ["all", ".reviewer",
|
||||
// ["like", ".email", "*@example.com"]],
|
||||
// ["like", ".email", "*@example.com"]
|
||||
// ],
|
||||
// ["any", ".tags",
|
||||
// ["or", [
|
||||
// ["==", ".", "news"],
|
||||
// ["==", ".", "press"]]]
|
||||
// ]
|
||||
// ["==", ".", "press"]
|
||||
// ]]
|
||||
// ]
|
||||
// ]
|
||||
}
|
||||
|
||||
|
||||
@@ -2,6 +2,7 @@ package policytest
|
||||
|
||||
import (
|
||||
"github.com/ipld/go-ipld-prime"
|
||||
|
||||
"github.com/ucan-wg/go-ucan/pkg/args"
|
||||
"github.com/ucan-wg/go-ucan/pkg/policy"
|
||||
"github.com/ucan-wg/go-ucan/pkg/policy/literal"
|
||||
@@ -10,9 +11,8 @@ import (
|
||||
// EmptyPolicy provides a Policy with no statements.
|
||||
var EmptyPolicy = policy.Policy{}
|
||||
|
||||
// ExampleValidationPolicy provides a instantiated SpecPolicy containing the
|
||||
// statements that are included in the second code block of the [Validation]
|
||||
// section of the delegation specification.
|
||||
// SpecPolicy provides a valid Policy containing the statements that are included
|
||||
// in the second code block of the [Validation] section of the delegation specification.
|
||||
//
|
||||
// [Validation]: https://github.com/ucan-wg/delegation/tree/v1_ipld#validation
|
||||
var SpecPolicy = policy.MustConstruct(
|
||||
@@ -24,8 +24,8 @@ var SpecPolicy = policy.MustConstruct(
|
||||
// specification has been finished/merged.
|
||||
|
||||
// SpecValidArguments provides valid, instantiated Arguments containing
|
||||
// the key/value pairs that are included in portion of the the second code
|
||||
// block of the [Validation] section of the delegation specification.
|
||||
// the key/value pairs that are included in portion of the second code block
|
||||
// of the [Validation] section of the delegation specification.
|
||||
//
|
||||
// [Validation]: https://github.com/ucan-wg/delegation/tree/v1_ipld#validation
|
||||
var SpecValidArguments = args.NewBuilder().
|
||||
@@ -41,8 +41,8 @@ var SpecValidArguments = args.NewBuilder().
|
||||
var specValidArgumentsIPLD = mustIPLD(SpecValidArguments)
|
||||
|
||||
// SpecInvalidArguments provides invalid, instantiated Arguments containing
|
||||
// the key/value pairs that are included in portion of the the second code
|
||||
// block of the [Validation] section of the delegation specification.
|
||||
// the key/value pairs that are included in portion of the second code block
|
||||
// of the [Validation] section of the delegation specification.
|
||||
//
|
||||
// [Validation]: https://github.com/ucan-wg/delegation/tree/v1_ipld#validation
|
||||
var SpecInvalidArguments = args.NewBuilder().
|
||||
|
||||
@@ -173,37 +173,37 @@ func tokenize(str string) []string {
|
||||
return toks
|
||||
}
|
||||
|
||||
type parseerr struct {
|
||||
type parseErr struct {
|
||||
msg string
|
||||
src string
|
||||
col int
|
||||
tok string
|
||||
}
|
||||
|
||||
func (p parseerr) Name() string {
|
||||
func (p parseErr) Name() string {
|
||||
return "ParseError"
|
||||
}
|
||||
|
||||
func (p parseerr) Message() string {
|
||||
func (p parseErr) Message() string {
|
||||
return p.msg
|
||||
}
|
||||
|
||||
func (p parseerr) Column() int {
|
||||
func (p parseErr) Column() int {
|
||||
return p.col
|
||||
}
|
||||
|
||||
func (p parseerr) Error() string {
|
||||
func (p parseErr) Error() string {
|
||||
return p.msg
|
||||
}
|
||||
|
||||
func (p parseerr) Source() string {
|
||||
func (p parseErr) Source() string {
|
||||
return p.src
|
||||
}
|
||||
|
||||
func (p parseerr) Token() string {
|
||||
func (p parseErr) Token() string {
|
||||
return p.tok
|
||||
}
|
||||
|
||||
func newParseError(message string, source string, column int, token string) error {
|
||||
return parseerr{message, source, column, token}
|
||||
return parseErr{message, source, column, token}
|
||||
}
|
||||
|
||||
@@ -19,7 +19,7 @@ type Selector []segment
|
||||
// Select perform the selection described by the selector on the input IPLD DAG.
|
||||
// Select can return:
|
||||
// - exactly one matched IPLD node
|
||||
// - a resolutionerr error if not being able to resolve to a node
|
||||
// - a resolutionErr error if not being able to resolve to a node
|
||||
// - nil and no errors, if the selector couldn't match on an optional segment (with ?).
|
||||
func (s Selector) Select(subject ipld.Node) (ipld.Node, error) {
|
||||
return resolve(s, subject, nil)
|
||||
@@ -316,27 +316,27 @@ func kindString(n datamodel.Node) string {
|
||||
return n.Kind().String()
|
||||
}
|
||||
|
||||
type resolutionerr struct {
|
||||
type resolutionErr struct {
|
||||
msg string
|
||||
at []string
|
||||
}
|
||||
|
||||
func (r resolutionerr) Name() string {
|
||||
func (r resolutionErr) Name() string {
|
||||
return "ResolutionError"
|
||||
}
|
||||
|
||||
func (r resolutionerr) Message() string {
|
||||
func (r resolutionErr) Message() string {
|
||||
return fmt.Sprintf("can not resolve path: .%s", strings.Join(r.at, "."))
|
||||
}
|
||||
|
||||
func (r resolutionerr) At() []string {
|
||||
func (r resolutionErr) At() []string {
|
||||
return r.at
|
||||
}
|
||||
|
||||
func (r resolutionerr) Error() string {
|
||||
func (r resolutionErr) Error() string {
|
||||
return r.Message()
|
||||
}
|
||||
|
||||
func newResolutionError(message string, at []string) error {
|
||||
return resolutionerr{message, at}
|
||||
return resolutionErr{message, at}
|
||||
}
|
||||
|
||||
@@ -133,7 +133,7 @@ func TestSelect(t *testing.T) {
|
||||
require.Error(t, err)
|
||||
require.Empty(t, res)
|
||||
|
||||
require.ErrorAs(t, err, &resolutionerr{}, "error should be a resolution error")
|
||||
require.ErrorAs(t, err, &resolutionErr{}, "error should be a resolution error")
|
||||
})
|
||||
|
||||
t.Run("optional not exists", func(t *testing.T) {
|
||||
@@ -351,7 +351,7 @@ func FuzzParseAndSelect(f *testing.F) {
|
||||
|
||||
// look for panic()
|
||||
_, err = sel.Select(node)
|
||||
if err != nil && !errors.As(err, &resolutionerr{}) {
|
||||
if err != nil && !errors.As(err, &resolutionErr{}) {
|
||||
// not normal, we should only have resolution errors
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
@@ -272,12 +272,14 @@ func ExampleFromSealed() {
|
||||
// Policy (pol): [
|
||||
// ["==", ".status", "draft"],
|
||||
// ["all", ".reviewer",
|
||||
// ["like", ".email", "*@example.com"]],
|
||||
// ["like", ".email", "*@example.com"]
|
||||
// ],
|
||||
// ["any", ".tags",
|
||||
// ["or", [
|
||||
// ["==", ".", "news"],
|
||||
// ["==", ".", "press"]]]
|
||||
// ]
|
||||
// ["==", ".", "press"]
|
||||
// ]]
|
||||
// ]
|
||||
// ]
|
||||
// Nonce (nonce): 000102030405060708090a0b
|
||||
// Meta (meta): {}
|
||||
|
||||
Reference in New Issue
Block a user