github.com/onflow/flow-go@v0.35.7-crescendo-preview.23-atree-inlining/model/flow/role.go (about) 1 package flow 2 3 import ( 4 "fmt" 5 "sort" 6 7 "github.com/pkg/errors" 8 ) 9 10 // Role represents a role in the flow system. 11 type Role uint8 12 13 // Enumeration of the available flow node roles. 14 const ( 15 RoleCollection Role = 1 16 RoleConsensus Role = 2 17 RoleExecution Role = 3 18 RoleVerification Role = 4 19 RoleAccess Role = 5 20 ) 21 22 func (r Role) Valid() bool { 23 return r >= 1 && r <= 5 24 } 25 26 // String returns a string version of role. 27 func (r Role) String() string { 28 switch r { 29 case RoleCollection: 30 return "collection" 31 case RoleConsensus: 32 return "consensus" 33 case RoleExecution: 34 return "execution" 35 case RoleVerification: 36 return "verification" 37 case RoleAccess: 38 return "access" 39 default: 40 panic(fmt.Sprintf("invalid role (%d)", r)) 41 } 42 } 43 44 // ParseRole will parse a role from string. 45 func ParseRole(role string) (Role, error) { 46 switch role { 47 case "collection": 48 return RoleCollection, nil 49 case "consensus": 50 return RoleConsensus, nil 51 case "execution": 52 return RoleExecution, nil 53 case "verification": 54 return RoleVerification, nil 55 case "access": 56 return RoleAccess, nil 57 default: 58 return 0, errors.Errorf("invalid role string (%s)", role) 59 } 60 } 61 62 func (r Role) MarshalText() ([]byte, error) { 63 return []byte(r.String()), nil 64 } 65 66 func (r *Role) UnmarshalText(text []byte) error { 67 var err error 68 *r, err = ParseRole(string(text)) 69 return err 70 } 71 72 func Roles() RoleList { 73 return []Role{RoleCollection, RoleConsensus, RoleExecution, RoleVerification, RoleAccess} 74 } 75 76 // RoleList defines a slice of roles in flow system. 77 type RoleList []Role 78 79 // Contains returns true if RoleList contains the role, otherwise false. 80 func (r RoleList) Contains(role Role) bool { 81 for _, each := range r { 82 if each == role { 83 return true 84 } 85 } 86 return false 87 } 88 89 // Union returns a new role list containing every role that occurs in 90 // either `r`, or `other`, or both. There are no duplicate roles in the output, 91 func (r RoleList) Union(other RoleList) RoleList { 92 // stores the output, the union of the two lists 93 union := make(RoleList, 0, len(r)+len(other)) 94 95 // efficient lookup to avoid duplicates 96 added := make(map[Role]struct{}) 97 98 // adds all roles, skips duplicates 99 for _, role := range append(r, other...) { 100 if _, exists := added[role]; exists { 101 continue 102 } 103 union = append(union, role) 104 added[role] = struct{}{} 105 } 106 107 return union 108 } 109 110 // Len returns length of the RoleList in the number of stored roles. 111 // It satisfies the sort.Interface making the RoleList sortable. 112 func (r RoleList) Len() int { 113 return len(r) 114 } 115 116 // Less returns true if element i in the RoleList is less than j based on the numerical value of its role. 117 // Otherwise it returns true. 118 // It satisfies the sort.Interface making the RoleList sortable. 119 func (r RoleList) Less(i, j int) bool { 120 return r[i] < r[j] 121 } 122 123 // Swap swaps the element i and j in the RoleList. 124 // It satisfies the sort.Interface making the RoleList sortable. 125 func (r RoleList) Swap(i, j int) { 126 r[i], r[j] = r[j], r[i] 127 } 128 129 // ID returns hash of the content of RoleList. It first sorts the RoleList and then takes its 130 // hash value. 131 func (r RoleList) ID() Identifier { 132 sort.Sort(r) 133 return MakeID(r) 134 }