-
Notifications
You must be signed in to change notification settings - Fork 0
/
scope.go
76 lines (62 loc) · 1.91 KB
/
scope.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
package chtml
// Scope defines an interface for managing arguments in a CHTML component.
// The CHTML component creates a new scope for each loop iteration, conditional branch, and
// component import with Spawn method.
type Scope interface {
// Parent returns the parent scope of the current scope or nil if it's the root scope.
Parent() Scope
// Spawn creates a new child scope with extra variables added to it.
Spawn(vars map[string]any) Scope
// Vars returns all variables in the scope.
Vars() map[string]any
// Closed returns a channel that is closed when the scope is not going to be rendered.
Closed() <-chan struct{}
// Touch marks the scope as changed. The change is propagated to the parent scopes.
Touch()
}
// ScopeMap is a simple implementation of the Scope interface based on map[string]any type and
// suitable to work with expr-lang's env. This implementation copies the variables from the parent
// scope to the child scope.
type ScopeMap struct {
parent Scope
vars map[string]any
}
var _ Scope = (*ScopeMap)(nil)
func NewScopeMap(parent Scope) *ScopeMap {
vars := make(map[string]any)
if parent != nil {
for k, v := range parent.Vars() {
vars[k] = v
}
}
return &ScopeMap{
parent: parent,
vars: vars,
}
}
// Parent returns the parent scope of the current scope or nil if it's the root scope.
func (s *ScopeMap) Parent() Scope {
return s.parent
}
// Spawn creates a new child scope of the current scope with its own set of arguments.
func (s *ScopeMap) Spawn(vars map[string]any) Scope {
sm := NewScopeMap(s)
for k, v := range vars {
sm.vars[k] = v
}
return sm
}
func (s *ScopeMap) Vars() map[string]any {
return s.vars
}
func (s *ScopeMap) Closed() <-chan struct{} {
return nil
}
func (s *ScopeMap) Touch() {}
// SetVars replaces internal variables with the given map.
func (s *ScopeMap) SetVars(vars map[string]any) {
if vars == nil {
vars = make(map[string]any)
}
s.vars = vars
}