-
Notifications
You must be signed in to change notification settings - Fork 9
/
ast.go
179 lines (154 loc) · 4.51 KB
/
ast.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
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
package filter
import (
"fmt"
)
const (
// PR is an abbreviation for 'present'.
PR CompareOperator = "pr"
// EQ is an abbreviation for 'equals'.
EQ CompareOperator = "eq"
// NE is an abbreviation for 'not equals'.
NE CompareOperator = "ne"
// CO is an abbreviation for 'contains'.
CO CompareOperator = "co"
// SW is an abbreviation for 'starts with'.
SW CompareOperator = "sw"
// EW an abbreviation for 'ends with'.
EW CompareOperator = "ew"
// GT is an abbreviation for 'greater than'.
GT CompareOperator = "gt"
// LT is an abbreviation for 'less than'.
LT CompareOperator = "lt"
// GE is an abbreviation for 'greater or equal than'.
GE CompareOperator = "ge"
// LE is an abbreviation for 'less or equal than'.
LE CompareOperator = "le"
// AND is the logical operation and (&&).
AND LogicalOperator = "and"
// OR is the logical operation or (||).
OR LogicalOperator = "or"
)
// AttributeExpression represents an attribute expression/filter.
type AttributeExpression struct {
AttributePath AttributePath
Operator CompareOperator
CompareValue interface{}
}
func (e AttributeExpression) String() string {
s := fmt.Sprintf("%v %s", e.AttributePath, e.Operator)
if e.CompareValue != nil {
switch e.CompareValue.(type) {
case string:
s += fmt.Sprintf(" %q", e.CompareValue)
default:
s += fmt.Sprintf(" %v", e.CompareValue)
}
}
return s
}
func (*AttributeExpression) exprNode() {}
// AttributePath represents an attribute path. Both URIPrefix and SubAttr are
// optional values and can be nil.
// e.g. urn:ietf:params:scim:schemas:core:2.0:User:name.givenName
// ^ ^ ^
// URIPrefix | SubAttribute
// AttributeName
type AttributePath struct {
URIPrefix *string
AttributeName string
SubAttribute *string
}
func (p AttributePath) String() string {
s := p.AttributeName
if p.URIPrefix != nil {
s = fmt.Sprintf("%s:%s", p.URI(), s)
}
if p.SubAttribute != nil {
s = fmt.Sprintf("%s.%s", s, p.SubAttributeName())
}
return s
}
// SubAttributeName returns the sub attribute name if present.
// Returns an empty string otherwise.
func (p *AttributePath) SubAttributeName() string {
if p.SubAttribute != nil {
return *p.SubAttribute
}
return ""
}
// URI returns the URI if present.
// Returns an empty string otherwise.
func (p *AttributePath) URI() string {
if p.URIPrefix != nil {
return *p.URIPrefix
}
return ""
}
// CompareOperator represents a compare operation.
type CompareOperator string
// Expression is a type to assign to implemented expressions.
// Valid expressions are:
// - ValuePath
// - AttributeExpression
// - LogicalExpression
// - NotExpression
type Expression interface {
exprNode()
}
// LogicalExpression represents an 'and' / 'or' node.
type LogicalExpression struct {
Left, Right Expression
Operator LogicalOperator
}
func (e LogicalExpression) String() string {
return fmt.Sprintf("%v %s %v", e.Left, e.Operator, e.Right)
}
func (*LogicalExpression) exprNode() {}
// LogicalOperator represents a logical operation such as 'and' / 'or'.
type LogicalOperator string
// NotExpression represents an 'not' node.
type NotExpression struct {
Expression Expression
}
func (e NotExpression) String() string {
return fmt.Sprintf("not(%v)", e.Expression)
}
func (*NotExpression) exprNode() {}
// Path describes the target of a PATCH operation. Path can have an optional
// ValueExpression and SubAttribute.
// e.g. members[value eq "2819c223-7f76-453a-919d-413861904646"].displayName
// ^ ^ ^
// | ValueExpression SubAttribute
// AttributePath
type Path struct {
AttributePath AttributePath
ValueExpression Expression
SubAttribute *string
}
func (p Path) String() string {
s := p.AttributePath.String()
if p.ValueExpression != nil {
s += fmt.Sprintf("[%s]", p.ValueExpression)
}
if p.SubAttribute != nil {
s += fmt.Sprintf(".%s", *p.SubAttribute)
}
return s
}
// SubAttributeName returns the sub attribute name if present.
// Returns an empty string otherwise.
func (p *Path) SubAttributeName() string {
if p.SubAttribute != nil {
return *p.SubAttribute
}
return ""
}
// ValuePath represents a filter on a attribute path.
type ValuePath struct {
AttributePath AttributePath
ValueFilter Expression
}
func (e ValuePath) String() string {
return fmt.Sprintf("%v[%v]", e.AttributePath, e.ValueFilter)
}
func (*ValuePath) exprNode() {}