-
Notifications
You must be signed in to change notification settings - Fork 9
/
path.go
77 lines (67 loc) · 1.65 KB
/
path.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
package filter
import (
"github.com/di-wu/parser"
"github.com/di-wu/parser/ast"
"github.com/scim2/filter-parser/v2/internal/grammar"
"github.com/scim2/filter-parser/v2/internal/types"
)
// ParsePath parses the given raw data as an Path.
func ParsePath(raw []byte) (Path, error) {
return parsePath(raw, config{})
}
// ParsePathNumber parses the given raw data as an Path with json.Number.
func ParsePathNumber(raw []byte) (Path, error) {
return parsePath(raw, config{useNumber: true})
}
func parsePath(raw []byte, c config) (Path, error) {
p, err := ast.New(raw)
if err != nil {
return Path{}, err
}
node, err := grammar.Path(p)
if err != nil {
return Path{}, err
}
if _, err := p.Expect(parser.EOD); err != nil {
return Path{}, err
}
return c.parsePath(node)
}
func (p config) parsePath(node *ast.Node) (Path, error) {
children := node.Children()
if len(children) == 0 {
return Path{}, invalidLengthError(typ.Path, 1, 0)
}
// AttrPath
if node.Type == typ.AttrPath {
attrPath, err := parseAttrPath(node)
if err != nil {
return Path{}, err
}
return Path{
AttributePath: attrPath,
}, nil
}
if node.Type != typ.Path {
return Path{}, invalidTypeError(typ.Path, node.Type)
}
// ValuePath SubAttr?
valuePath, err := p.parseValuePath(children[0])
if err != nil {
return Path{}, err
}
var subAttr *string
if len(children) == 2 {
node := children[1]
if node.Type != typ.AttrName {
return Path{}, invalidTypeError(typ.AttrName, node.Type)
}
value := node.Value
subAttr = &value
}
return Path{
AttributePath: valuePath.AttributePath,
ValueExpression: valuePath.ValueFilter,
SubAttribute: subAttr,
}, nil
}