github.com/nspcc-dev/neo-go@v0.105.2-0.20240517133400-6be757af3eba/pkg/vm/vmstate/state.go (about) 1 /* 2 Package vmstate contains a set of VM state flags along with appropriate type. 3 It provides a set of conversion/marshaling functions/methods for this type as 4 well. This package is made to make VM state reusable across all of the other 5 components that need it without importing whole VM package. 6 */ 7 package vmstate 8 9 import ( 10 "errors" 11 "strings" 12 ) 13 14 // State of the VM. It's a set of flags stored in the integer number. 15 type State uint8 16 17 // Available States. 18 const ( 19 // Halt represents HALT VM state (finished normally). 20 Halt State = 1 << iota 21 // Fault represents FAULT VM state (finished with an error). 22 Fault 23 // Break represents BREAK VM state (running, debug mode). 24 Break 25 // None represents NONE VM state (not started yet). 26 None State = 0 27 ) 28 29 // HasFlag checks for State flag presence. 30 func (s State) HasFlag(f State) bool { 31 return s&f != 0 32 } 33 34 // String implements the fmt.Stringer interface. 35 func (s State) String() string { 36 if s == None { 37 return "NONE" 38 } 39 40 ss := make([]string, 0, 3) 41 if s.HasFlag(Halt) { 42 ss = append(ss, "HALT") 43 } 44 if s.HasFlag(Fault) { 45 ss = append(ss, "FAULT") 46 } 47 if s.HasFlag(Break) { 48 ss = append(ss, "BREAK") 49 } 50 return strings.Join(ss, ", ") 51 } 52 53 // FromString converts a string into the State. 54 func FromString(s string) (st State, err error) { 55 if s = strings.TrimSpace(s); s == "NONE" { 56 return None, nil 57 } 58 59 ss := strings.Split(s, ",") 60 for _, state := range ss { 61 switch state = strings.TrimSpace(state); state { 62 case "HALT": 63 st |= Halt 64 case "FAULT": 65 st |= Fault 66 case "BREAK": 67 st |= Break 68 default: 69 return 0, errors.New("unknown state") 70 } 71 } 72 return 73 } 74 75 // MarshalJSON implements the json.Marshaler interface. 76 func (s State) MarshalJSON() (data []byte, err error) { 77 return []byte(`"` + s.String() + `"`), nil 78 } 79 80 // UnmarshalJSON implements the json.Marshaler interface. 81 func (s *State) UnmarshalJSON(data []byte) (err error) { 82 l := len(data) 83 if l < 2 || data[0] != '"' || data[l-1] != '"' { 84 return errors.New("wrong format") 85 } 86 87 *s, err = FromString(string(data[1 : l-1])) 88 return 89 }