Skip to content

Commit 80d082a

Browse files
committed
Move docs to godoc.org
1 parent a37f937 commit 80d082a

File tree

3 files changed

+282
-123
lines changed

3 files changed

+282
-123
lines changed

README.md

+4-123
Original file line numberDiff line numberDiff line change
@@ -6,12 +6,12 @@ The purpose of the package is to allow users to use expressions inside configura
66
It is a perfect candidate for the foundation of a _business rule engine_.
77
The idea is to let configure things in a dynamic way without recompile of a program:
88

9-
```ruby
9+
```coffeescript
1010
# Get the special price if
1111
user.Group in ["good_customers", "collaborator"]
1212

1313
# Promote article to the homepage when
14-
article.CommentCount > 100 and article.Category not in ["misc"]
14+
len(article.Comments) > 100 and article.Category not in ["misc"]
1515

1616
# Send an alert when
1717
product.Stock < 15
@@ -29,127 +29,8 @@ go get -u github.com/antonmedv/expr
2929

3030
## Documentation
3131

32-
### Usage
33-
```go
34-
// Evaluate expression on data.
35-
result, err := expr.Eval("expression", data)
36-
37-
// Or precompile expression to ast first.
38-
node, err := expr.Parse("expression")
39-
40-
// And run later.
41-
result, err := expr.Run(node, data)
42-
```
43-
44-
### Expression Syntax
45-
See [The Expression Syntax](https://github.com/antonmedv/expr/wiki/The-Expression-Syntax) to learn the syntax of the Expr expressions.
46-
47-
### Passing in Variables
48-
You can pass variables into the expression, which can be of any valid Go type (including structs):
49-
```go
50-
// Maps
51-
data := map[string]interface{}{
52-
"Foo": ...
53-
"Bar": ...
54-
}
55-
56-
// Structs
57-
data := Payload{
58-
Foo: ...
59-
Bar: ...
60-
}
61-
62-
// Pass object
63-
result, err := expr.Eval("Foo == Bar", data)
64-
```
65-
66-
Expr uses reflection for accessing and iterating passed data.
67-
For example you can pass nested structures without any modification or preparation:
68-
69-
```go
70-
type Cookie struct {
71-
Key string
72-
Value string
73-
}
74-
type User struct {
75-
UserAgent string
76-
Cookies []Cookie
77-
}
78-
type Request struct {
79-
User user
80-
}
81-
82-
req := Request{User{
83-
Cookies: []cookie{{"origin", "www"}},
84-
UserAgent: "Firefox",
85-
}}
86-
87-
ok, err := expr.Eval(`User.UserAgent matches "Firefox" and User.Cookies[0].Value == "www"`, req)
88-
```
89-
90-
### Passing in Functions
91-
You can also pass functions into the expression:
92-
```go
93-
data := map[string]interface{}{
94-
"Request": req,
95-
"Values": func(xs []Cookie) []string {
96-
vs := make([]string, 0)
97-
for _, x := range xs {
98-
vs = append(vs, x.Value)
99-
}
100-
return vs
101-
},
102-
}
103-
104-
ok, err := expr.Eval(`"www" in Values(Request.User.Cookies)`, data)
105-
```
106-
107-
### Caching
108-
If you planning to execute some expression lots times, it's good to compile it first and only one time:
109-
110-
```go
111-
// Precompile
112-
node, err := expr.Parse(expression)
113-
114-
// Run
115-
ok, err := expr.Run(node, data)
116-
```
117-
118-
### Checking variables and functions
119-
It is possible to check used variables and functions during parsing of the expression.
120-
121-
```go
122-
expression := `Request.User.UserAgent matches "Firefox" && "www" in Values(Request.User.Cookies)`
123-
124-
node, err := expr.Parse(expression, expr.Names("Request"), expr.Funcs("Values"))
125-
```
126-
127-
Only `Request` and `Values` will be available inside expression, otherwise parse error.
128-
129-
### Printing
130-
Compiled ast can be compiled back to string expression using _String()_:
131-
132-
```go
133-
node, err := expr.Parse(expression)
134-
code := fmt.Sprintf("%v", node)
135-
```
136-
137-
### Number type
138-
Inside Expr engine there is no distinguish between int, uint and float types (as in JavaScript).
139-
All numbers inside Expr engine represented as `float64`.
140-
You should remember about it if you use any of binary operators (`+`, `-`, `/`, `*`, etc).
141-
Otherwise type remain unchanged.
142-
143-
```go
144-
data := map[string]int{
145-
"Foo": 1,
146-
"Bar": 2,
147-
}
148-
149-
out, err := expr.Eval(`Foo`, data) // int
150-
151-
out, err := expr.Eval(`Foo + Bar`, data) // float64
152-
```
32+
* See [godoc.org/github.com/antonmedv/expr](https://godoc.org/github.com/antonmedv/expr) for developer documentation,
33+
* See [The Expression Syntax](https://github.com/antonmedv/expr/wiki/The-Expression-Syntax) page to learn the syntax of the Expr expressions.
15334

15435
## License
15536

doc.go

+121
Original file line numberDiff line numberDiff line change
@@ -10,5 +10,126 @@ Package expr is an engine that can evaluate expressions.
1010
// And run later.
1111
result, err := expr.Run(node, data)
1212
13+
14+
Passing in Variables
15+
16+
You can pass variables into the expression, which can be of any valid Go type (including structs):
17+
18+
// Maps
19+
data := map[string]interface{}{
20+
"Foo": ...
21+
"Bar": ...
22+
}
23+
24+
// Structs
25+
data := Payload{
26+
Foo: ...
27+
Bar: ...
28+
}
29+
30+
// Pass object
31+
result, err := expr.Eval("Foo == Bar", data)
32+
33+
Expr uses reflection for accessing and iterating passed data.
34+
For example you can pass nested structures without any modification or preparation:
35+
36+
type Cookie struct {
37+
Key string
38+
Value string
39+
}
40+
type User struct {
41+
UserAgent string
42+
Cookies []Cookie
43+
}
44+
type Request struct {
45+
User user
46+
}
47+
48+
req := Request{User{
49+
Cookies: []Cookie{{"origin", "www"}},
50+
UserAgent: "Firefox",
51+
}}
52+
53+
ok, err := expr.Eval(`User.UserAgent matches "Firefox" and User.Cookies[0].Value == "www"`, req)
54+
55+
56+
Passing in Functions
57+
58+
You can also pass functions into the expression:
59+
60+
data := map[string]interface{}{
61+
"Request": req,
62+
"Values": func(xs []Cookie) []string {
63+
vs := make([]string, 0)
64+
for _, x := range xs {
65+
vs = append(vs, x.Value)
66+
}
67+
return vs
68+
},
69+
}
70+
71+
ok, err := expr.Eval(`"www" in Values(Request.User.Cookies)`, data)
72+
73+
74+
Caching
75+
76+
If you planning to execute some expression lots times, it's good to compile it first and only one time:
77+
78+
// Precompile
79+
node, err := expr.Parse(expression)
80+
81+
// Run
82+
ok, err := expr.Run(node, data)
83+
84+
85+
Checking variables and functions
86+
87+
It is possible to check used variables and functions during parsing of the expression.
88+
89+
90+
expression := `Request.User.UserAgent matches "Firefox" && "www" in Values(Request.User.Cookies)`
91+
92+
node, err := expr.Parse(expression, expr.Names("Request"), expr.Funcs("Values"))
93+
94+
95+
Only `Request` and `Values` will be available inside expression, otherwise parse error.
96+
97+
If you try to use some undeclared variables or functions, an error will be returned during compilation:
98+
99+
expression := `Unknown(Request.User.UserAgent)`
100+
node, err := expr.Parse(expression, expr.Names("Request"), expr.Funcs("Values"))
101+
102+
// err.Error():
103+
104+
unknown func Unknown
105+
Unknown(Request.User.UserAgent)
106+
-------^
107+
108+
109+
Printing
110+
111+
Compiled ast can be compiled back to string expression using stringer fmt.Stringer interface:
112+
113+
node, err := expr.Parse(expression)
114+
code := fmt.Sprintf("%v", node)
115+
116+
117+
Number type
118+
119+
Inside Expr engine there is no distinguish between int, uint and float types (as in JavaScript).
120+
All numbers inside Expr engine represented as `float64`.
121+
You should remember about it if you use any of binary operators (`+`, `-`, `/`, `*`, etc).
122+
Otherwise type remain unchanged.
123+
124+
data := map[string]int{
125+
"Foo": 1,
126+
"Bar": 2,
127+
}
128+
129+
out, err := expr.Eval(`Foo`, data) // int
130+
131+
out, err := expr.Eval(`Foo + Bar`, data) // float64
132+
133+
13134
*/
14135
package expr

0 commit comments

Comments
 (0)