mirror of
https://github.com/hanzoai/expr.git
synced 2026-09-24 16:58:58 +00:00
112 lines
2.8 KiB
Markdown
112 lines
2.8 KiB
Markdown
# Environment
|
|
|
|
The environment is a map or a struct that contains the variables and functions that the expression can access.
|
|
|
|
## Struct as Environment
|
|
|
|
Let's consider the following example:
|
|
|
|
```go
|
|
type Env struct {
|
|
UpdatedAt time.Time
|
|
Posts []Post
|
|
Map map[string]string `expr:"tags"`
|
|
}
|
|
```
|
|
|
|
The `Env` struct contains 3 variables that the expression can access: `UpdatedAt`, `Posts`, and `tags`.
|
|
|
|
:::info
|
|
The `expr` tag is used to rename the `Map` field to `tags` variable in the expression.
|
|
:::
|
|
|
|
The `Env` struct can also contain methods. The methods defined on the struct become functions that the expression can
|
|
call.
|
|
|
|
```go
|
|
func (Env) Format(t time.Time) string {
|
|
return t.Format(time.RFC822)
|
|
}
|
|
```
|
|
|
|
:::tip
|
|
Methods defined on embedded structs are also accessible.
|
|
```go
|
|
type Env struct {
|
|
Helpers
|
|
}
|
|
|
|
type Helpers struct{}
|
|
|
|
func (Helpers) Format(t time.Time) string {
|
|
return t.Format(time.RFC822)
|
|
}
|
|
```
|
|
:::
|
|
|
|
We can use an empty struct `Env{}` to with [expr.Env](https://pkg.go.dev/github.com/expr-lang/expr#Env) to create an environment. Expr will use reflection to find
|
|
the fields and methods of the struct.
|
|
|
|
```go
|
|
program, err := expr.Compile(code, expr.Env(Env{}))
|
|
```
|
|
|
|
Compiler will type check the expression against the environment. After the compilation, we can run the program with the environment.
|
|
You should use the same type of environment that you passed to the `expr.Env` function.
|
|
|
|
```go
|
|
output, err := expr.Run(program, Env{
|
|
UpdatedAt: time.Now(),
|
|
Posts: []Post{{Title: "Hello, World!"}},
|
|
Map: map[string]string{"tag1": "value1"},
|
|
})
|
|
```
|
|
|
|
## Map as Environment
|
|
|
|
You can also use a map as an environment.
|
|
|
|
```go
|
|
env := map[string]any{
|
|
"UpdatedAt": time.Time{},
|
|
"Posts": []Post{},
|
|
"tags": map[string]string{},
|
|
"sprintf": fmt.Sprintf,
|
|
}
|
|
|
|
program, err := expr.Compile(code, expr.Env(env))
|
|
```
|
|
|
|
A map defines variables and functions that the expression can access. The key is the variable name, and the type
|
|
is the value's type.
|
|
|
|
```go
|
|
env := map[string]any{
|
|
"object": map[string]any{
|
|
"field": 42,
|
|
},
|
|
"struct": struct {
|
|
Field int `expr:"field"`
|
|
}{42},
|
|
}
|
|
```
|
|
|
|
Expr will infer the type of the `object` variable as `map[string]any`.
|
|
Accessing fields of the `object` and `struct` variables will return the following results.
|
|
|
|
```expr
|
|
object.field // 42
|
|
object.unknown // nil (no error)
|
|
|
|
struct.field // 42
|
|
struct.unknown // error (unknown field)
|
|
|
|
foobar // error (unknown variable)
|
|
```
|
|
|
|
:::note
|
|
The `foobar` variable is not defined in the environment.
|
|
By default, Expr will return an error if unknown variables are used in the expression.
|
|
You can disable this behavior by passing [`AllowUndefinedVariables`](https://pkg.go.dev/github.com/expr-lang/expr#AllowUndefinedVariables) option to the compiler.
|
|
:::
|