-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathvariable.go
More file actions
113 lines (97 loc) · 2.79 KB
/
variable.go
File metadata and controls
113 lines (97 loc) · 2.79 KB
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
package robolang
import (
"encoding/json"
"fmt"
"sort"
)
// VariableTable defines all the available variables for a block
type VariableTable struct {
Parent *VariableTable `json:"-"`
Variables VariableMap `json:"variables"`
}
// NewVariableTable starts a new variable table
func NewVariableTable(variables ...*VariableDefinition) *VariableTable {
table := &VariableTable{
Variables: VariableMap{},
}
if variables != nil {
for _, variable := range variables {
table.Variables[variable.Name] = variable
}
}
return table
}
// Get attempts to retrieve a value from table
func (table *VariableTable) Get(name string) (*VariableDefinition, bool) {
value, exists := table.Variables[name]
if exists {
return value, true
}
if table.Parent != nil {
return table.Parent.Get(name)
}
return nil, false
}
// Add adds a new variable to the table
func (table *VariableTable) Add(name string) (*VariableDefinition, error) {
_, exists := table.Variables[name]
if exists {
return nil, fmt.Errorf("Variable %s already exists", name)
}
value := NewVariable(name)
table.Variables[name] = value
return value, nil
}
// VariableMap is a convience wrapper to simplify the marshalling and unmarshalling of variable definitions
type VariableMap map[string]*VariableDefinition
// MarshalJSON converts a VariableMap to JSON
func (fm VariableMap) MarshalJSON() ([]byte, error) {
out, pos := make(VariableDefinitions, len(fm)), 0
for key, val := range fm {
val.Name = key
out[pos] = *val
pos++
}
sort.Sort(out)
return json.Marshal(out)
}
// UnmarshalJSON converts JSON to a VariableMap
func (fm *VariableMap) UnmarshalJSON(data []byte) error {
in := VariableDefinitions{}
if err := json.Unmarshal(data, &in); err != nil {
return err
}
for _, val := range in {
out := val
(*fm)[val.Name] = &out
}
return nil
}
// VariableDefinitions is a convience wrapper that allows sorting a list of VariableDefinition instances
type VariableDefinitions []VariableDefinition
// Len returns the number of instances in this list
func (vd VariableDefinitions) Len() int {
return len(vd)
}
// Less checks which name is the lower of two
func (vd VariableDefinitions) Less(i, j int) bool {
return vd[i].Name < vd[j].Name
}
// Swap changes the location of two variable definitions
func (vd VariableDefinitions) Swap(i, j int) {
vd[i], vd[j] = vd[j], vd[i]
}
// VariableDefinition defines a variable that holds a value
type VariableDefinition struct {
Name string `json:"name"`
Value *string `json:"value,omitempty"`
}
// NewVariable starts a new variable definition
func NewVariable(name string) *VariableDefinition {
return &VariableDefinition{Name: name}
}
// Set sets the value of the variable
func (variable *VariableDefinition) Set(value string) *VariableDefinition {
variable.Value = &value
return variable
}