-
Notifications
You must be signed in to change notification settings - Fork 19
/
context.go
121 lines (100 loc) · 3.14 KB
/
context.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
package runs
import (
"github.com/nyaruka/goflow/excellent/types"
"github.com/nyaruka/goflow/flows"
"github.com/nyaruka/goflow/utils"
)
// RunContextTopLevels are the allowed top-level variables for expression evaluations
var RunContextTopLevels = []string{
"run",
"child",
"parent",
"contact",
"input",
"results",
"trigger",
"legacy_extra",
}
type runContext struct {
run flows.FlowRun
extra *legacyExtra
}
// creates a new evaluation context for the passed in run
func newRunContext(run flows.FlowRun) types.XValue {
return &runContext{run: run, extra: newLegacyExtra(run)}
}
// Resolve resolves the given top-level key in an expression
func (c *runContext) Resolve(env utils.Environment, key string) types.XValue {
switch key {
// the different runs accessible
case "run":
return c.run
case "child":
return newRelatedRunContext(c.run.Session().GetCurrentChild(c.run))
case "parent":
return newRelatedRunContext(c.run.Parent())
// shortcuts to things on the current run
case "contact":
return c.run.Contact()
case "input":
return c.run.Input()
case "results":
return c.run.Results()
// other
case "trigger":
return c.run.Session().Trigger()
case "legacy_extra":
c.extra.update()
return c.extra
}
return types.NewXResolveError(c, key)
}
// Describe returns a representation of this type for error messages
func (c *runContext) Describe() string { return "context" }
func (c *runContext) Reduce(env utils.Environment) types.XPrimitive {
return types.NewXText(string(c.run.UUID()))
}
// ToXJSON can never actually be called on the context root
func (c *runContext) ToXJSON(env utils.Environment) types.XText {
panic("shouldn't be possible to call ToXJSON on the context root")
}
var _ types.XValue = (*runContext)(nil)
var _ types.XResolvable = (*runContext)(nil)
// wraps parent/child runs and provides a reduced set of keys in the context
type relatedRunContext struct {
run flows.RunSummary
}
// creates a new context for related runs
func newRelatedRunContext(run flows.RunSummary) *relatedRunContext {
if run != nil {
return &relatedRunContext{run: run}
}
return nil
}
// Resolve resolves the given key when this related run is referenced in an expression
func (c *relatedRunContext) Resolve(env utils.Environment, key string) types.XValue {
switch key {
case "uuid":
return types.NewXText(string(c.run.UUID()))
case "contact":
return c.run.Contact()
case "flow":
return c.run.Flow()
case "status":
return types.NewXText(string(c.run.Status()))
case "results":
return c.run.Results()
}
return types.NewXResolveError(c, key)
}
// Describe returns a representation of this type for error messages
func (c *relatedRunContext) Describe() string { return "related run" }
func (c *relatedRunContext) Reduce(env utils.Environment) types.XPrimitive {
return types.NewXText(string(c.run.UUID()))
}
// ToXJSON is called when this type is passed to @(json(...))
func (c *relatedRunContext) ToXJSON(env utils.Environment) types.XText {
return types.ResolveKeys(env, c, "uuid", "contact", "flow", "status", "results").ToXJSON(env)
}
var _ types.XValue = (*relatedRunContext)(nil)
var _ types.XResolvable = (*relatedRunContext)(nil)