-
Notifications
You must be signed in to change notification settings - Fork 0
/
conditional.go
103 lines (87 loc) · 3.17 KB
/
conditional.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
package acal
import (
"encoding/json"
)
// CloseIfFunc is to be called when an if clause ends so that
// progressive variables can record the close if stage index.
type CloseIfFunc func()
// DoNothingCloseIfFunc is a CloseIfFunc that does nothing.
var DoNothingCloseIfFunc CloseIfFunc = func() {}
// StaticConditionalValue needs to be implemented by static
// Value that holds a Condition.
//
//go:generate mockery --name=StaticConditionalValue --case underscore --inpackage
type StaticConditionalValue interface {
// IsConditional returns whether a Condition is attached to this StaticConditionalValue.
IsConditional() bool
// GetCondition returns the Condition attached to this StaticConditionalValue.
GetCondition() *Condition
// AddCondition attaches the given Condition to this StaticConditionalValue.
AddCondition(*Condition)
}
// ProgressiveConditionalValue needs to be implemented by progressive
// Value that might involve conditional calculation.
//
//go:generate mockery --name=ProgressiveConditionalValue --case underscore --inpackage
type ProgressiveConditionalValue interface {
// AddCondition attaches the given Condition to this ProgressiveConditionalValue
// and returns a CloseIfFunc to close the Condition.
AddCondition(TypedValue[bool]) CloseIfFunc
}
// Condition represents an if clause in a calculation algorithm.
type Condition struct {
criteria TypedValue[bool]
prevCondition *Condition
openIfStageIdx int
closeIfStageIdx int
}
// NewCondition returns a new Condition with the provided fields.
func NewCondition(criteria TypedValue[bool]) *Condition {
return &Condition{
criteria: criteria,
}
}
// NewProgressiveCondition returns a new Condition with the provided fields.
func NewProgressiveCondition(criteria TypedValue[bool], prevCondition *Condition, openIfStageIdx int) *Condition {
return &Condition{
criteria: criteria,
prevCondition: prevCondition,
openIfStageIdx: openIfStageIdx,
}
}
// isValidProgressiveCondition returns whether this Condition contains at
// least 1 progressive stage between open and close index.
func (c *Condition) isValidProgressiveCondition() bool {
return c.closeIfStageIdx >= c.openIfStageIdx
}
// setCloseIfStageIdx updates the closeIfStageIdx of this Condition to the provided value.
func (c *Condition) setCloseIfStageIdx(closeIfStageIdx int) {
c.closeIfStageIdx = closeIfStageIdx
}
// MarshalJSON returns the JSON encoding of this Condition.
func (c *Condition) MarshalJSON() ([]byte, error) {
return json.Marshal(
&struct {
Formula *SyntaxNode
CloseIfStageIdx int `json:",omitempty"`
}{
Formula: DescribeValueAsFormula(c.criteria)(),
CloseIfStageIdx: c.closeIfStageIdx,
},
)
}
type staticConditioner struct {
condition *Condition
}
// IsConditional returns whether a Condition is attached to this iStaticConditioner.
func (c *staticConditioner) IsConditional() bool {
return c.condition != nil
}
// GetCondition returns the Condition attached to this Simple.
func (c *staticConditioner) GetCondition() *Condition {
return c.condition
}
// AddCondition attaches the given Condition to this Simple.
func (c *staticConditioner) AddCondition(condition *Condition) {
c.condition = condition
}