-
Notifications
You must be signed in to change notification settings - Fork 79
/
state.go
89 lines (78 loc) · 2.01 KB
/
state.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
/*
Package vmstate contains a set of VM state flags along with appropriate type.
It provides a set of conversion/marshaling functions/methods for this type as
well. This package is made to make VM state reusable across all of the other
components that need it without importing whole VM package.
*/
package vmstate
import (
"errors"
"strings"
)
// State of the VM. It's a set of flags stored in the integer number.
type State uint8
// Available States.
const (
// Halt represents HALT VM state (finished normally).
Halt State = 1 << iota
// Fault represents FAULT VM state (finished with an error).
Fault
// Break represents BREAK VM state (running, debug mode).
Break
// None represents NONE VM state (not started yet).
None State = 0
)
// HasFlag checks for State flag presence.
func (s State) HasFlag(f State) bool {
return s&f != 0
}
// String implements the fmt.Stringer interface.
func (s State) String() string {
if s == None {
return "NONE"
}
ss := make([]string, 0, 3)
if s.HasFlag(Halt) {
ss = append(ss, "HALT")
}
if s.HasFlag(Fault) {
ss = append(ss, "FAULT")
}
if s.HasFlag(Break) {
ss = append(ss, "BREAK")
}
return strings.Join(ss, ", ")
}
// FromString converts a string into the State.
func FromString(s string) (st State, err error) {
if s = strings.TrimSpace(s); s == "NONE" {
return None, nil
}
ss := strings.Split(s, ",")
for _, state := range ss {
switch state = strings.TrimSpace(state); state {
case "HALT":
st |= Halt
case "FAULT":
st |= Fault
case "BREAK":
st |= Break
default:
return 0, errors.New("unknown state")
}
}
return
}
// MarshalJSON implements the json.Marshaler interface.
func (s State) MarshalJSON() (data []byte, err error) {
return []byte(`"` + s.String() + `"`), nil
}
// UnmarshalJSON implements the json.Marshaler interface.
func (s *State) UnmarshalJSON(data []byte) (err error) {
l := len(data)
if l < 2 || data[0] != '"' || data[l-1] != '"' {
return errors.New("wrong format")
}
*s, err = FromString(string(data[1 : l-1]))
return
}