summaryrefslogtreecommitdiff
path: root/internal/fsm
diff options
context:
space:
mode:
authorjwijenbergh <jeroenwijenbergh@protonmail.com>2022-09-07 18:41:01 +0200
committerjwijenbergh <jeroenwijenbergh@protonmail.com>2022-09-07 18:41:01 +0200
commit7f7b6884d11e0e2b891814b84eb906db284a50b0 (patch)
treeed3f2ec29b5efda3fbb628a09628464d98fce336 /internal/fsm
parent809bc265d11b508903313f5b0a8c1a04add7209b (diff)
Refactor: Define FSM state constants inside the public package
Diffstat (limited to 'internal/fsm')
-rw-r--r--internal/fsm/fsm.go238
1 files changed, 14 insertions, 224 deletions
diff --git a/internal/fsm/fsm.go b/internal/fsm/fsm.go
index 6178af9..63c9ac2 100644
--- a/internal/fsm/fsm.go
+++ b/internal/fsm/fsm.go
@@ -1,14 +1,11 @@
package fsm
import (
- "errors"
- "fmt"
"os"
"os/exec"
+ "fmt"
"path"
"sort"
-
- "github.com/jwijenbergh/eduvpn-common/internal/types"
)
type (
@@ -28,85 +25,6 @@ func (v FSMStateIDSlice) Swap(i, j int) {
v[i], v[j] = v[j], v[i]
}
-const (
- // Deregistered means the app is not registered with the wrapper
- DEREGISTERED FSMStateID = iota
-
- // No Server means the user has not chosen a server yet
- NO_SERVER
-
- // The user selected a Secure Internet server but needs to choose a location
- ASK_LOCATION
-
- // The user is currently selecting a server in the UI
- SEARCH_SERVER
-
- // We are loading the server details
- LOADING_SERVER
-
- // Chosen Server means the user has chosen a server to connect to
- CHOSEN_SERVER
-
- // OAuth Started means the OAuth process has started
- OAUTH_STARTED
-
- // Authorized means the OAuth process has finished and the user is now authorized with the server
- AUTHORIZED
-
- // Requested config means the user has requested a config for connecting
- REQUEST_CONFIG
-
- // Ask profile means the go code is asking for a profile selection from the UI
- ASK_PROFILE
-
- // Disconnected means the user has gotten a config for a server but is not connected yet
- DISCONNECTED
-
- // Disconnecting means the OS is disconnecting and the Go code is doing the /disconnect
- DISCONNECTING
-
- // Connecting means the OS is establishing a connection to the server
- CONNECTING
-
- // Connected means the user has been connected to the server
- CONNECTED
-)
-
-func (s FSMStateID) String() string {
- switch s {
- case DEREGISTERED:
- return "Deregistered"
- case NO_SERVER:
- return "No_Server"
- case ASK_LOCATION:
- return "Ask_Location"
- case SEARCH_SERVER:
- return "Search_Server"
- case LOADING_SERVER:
- return "Loading_Server"
- case CHOSEN_SERVER:
- return "Chosen_Server"
- case OAUTH_STARTED:
- return "OAuth_Started"
- case DISCONNECTED:
- return "Disconnected"
- case REQUEST_CONFIG:
- return "Request_Config"
- case ASK_PROFILE:
- return "Ask_Profile"
- case AUTHORIZED:
- return "Authorized"
- case DISCONNECTING:
- return "Disconnecting"
- case CONNECTING:
- return "Connecting"
- case CONNECTED:
- return "Connected"
- default:
- panic("unknown conversion of state to string")
- }
-}
-
type FSMTransition struct {
To FSMStateID
Description string
@@ -132,114 +50,24 @@ type FSM struct {
StateCallback func(FSMStateID, FSMStateID, interface{})
Directory string
Debug bool
+ GetName func(FSMStateID) string
}
func (fsm *FSM) Init(
name string,
+ current FSMStateID,
+ states map[FSMStateID]FSMState,
callback func(FSMStateID, FSMStateID, interface{}),
directory string,
+ nameGen func(FSMStateID) string,
debug bool,
) {
- fsm.States = FSMStates{
- DEREGISTERED: FSMState{Transitions: []FSMTransition{{NO_SERVER, "Client registers"}}},
- NO_SERVER: FSMState{
- Transitions: []FSMTransition{
- {NO_SERVER, "Reload list"},
- {CHOSEN_SERVER, "User chooses a server"},
- {SEARCH_SERVER, "The user is trying to choose a Server in the UI"},
- {CONNECTED, "The user is already connected"},
- {ASK_LOCATION, "Change the location in the main screen"},
- },
- },
- SEARCH_SERVER: FSMState{
- Transitions: []FSMTransition{
- {LOADING_SERVER, "User clicks a server in the UI"},
- {NO_SERVER, "Cancel or Error"},
- },
- BackState: NO_SERVER,
- },
- ASK_LOCATION: FSMState{
- Transitions: []FSMTransition{
- {CHOSEN_SERVER, "Location chosen"},
- {NO_SERVER, "Go back or Error"},
- {SEARCH_SERVER, "Cancel or Error"},
- },
- },
- LOADING_SERVER: FSMState{
- Transitions: []FSMTransition{
- {CHOSEN_SERVER, "Server info loaded"},
- {
- ASK_LOCATION,
- "User chooses a Secure Internet server but no location is configured",
- },
- {NO_SERVER, "Go back or Error"},
- },
- BackState: NO_SERVER,
- },
- CHOSEN_SERVER: FSMState{
- Transitions: []FSMTransition{
- {AUTHORIZED, "Found tokens in config"},
- {OAUTH_STARTED, "No tokens found in config"},
- },
- },
- OAUTH_STARTED: FSMState{
- Transitions: []FSMTransition{
- {AUTHORIZED, "User authorizes with browser"},
- {NO_SERVER, "Cancel or Error"},
- {SEARCH_SERVER, "Cancel or Error"},
- },
- BackState: NO_SERVER,
- },
- AUTHORIZED: FSMState{
- Transitions: []FSMTransition{
- {OAUTH_STARTED, "Re-authorize with OAuth"},
- {REQUEST_CONFIG, "Client requests a config"},
- },
- },
- REQUEST_CONFIG: FSMState{
- Transitions: []FSMTransition{
- {ASK_PROFILE, "Multiple profiles found and no profile chosen"},
- {DISCONNECTED, "Only one profile or profile already chosen"},
- {NO_SERVER, "Cancel or Error"},
- {OAUTH_STARTED, "Re-authorize"},
- },
- },
- ASK_PROFILE: FSMState{
- Transitions: []FSMTransition{
- {DISCONNECTED, "User chooses profile"},
- {NO_SERVER, "Cancel or Error"},
- {SEARCH_SERVER, "Cancel or Error"},
- },
- },
- DISCONNECTED: FSMState{
- Transitions: []FSMTransition{
- {CONNECTING, "OS reports it is trying to connect"},
- {REQUEST_CONFIG, "User reconnects"},
- {NO_SERVER, "User wants to choose a new server"},
- {OAUTH_STARTED, "Re-authorize with OAuth"},
- },
- BackState: NO_SERVER,
- },
- DISCONNECTING: FSMState{
- Transitions: []FSMTransition{
- {DISCONNECTED, "Cancel or Error"},
- {DISCONNECTED, "Done disconnecting"},
- },
- },
- CONNECTING: FSMState{
- Transitions: []FSMTransition{
- {DISCONNECTED, "Cancel or Error"},
- {CONNECTED, "Done connecting"},
- },
- },
- CONNECTED: FSMState{
- Transitions: []FSMTransition{{DISCONNECTING, "App wants to disconnect"}},
- },
- }
- fsm.Current = DEREGISTERED
+ fsm.States = states
+ fsm.Current = current
fsm.Name = name
fsm.StateCallback = callback
fsm.Directory = directory
+ fsm.GetName = nameGen
fsm.Debug = debug
}
@@ -317,59 +145,21 @@ func (fsm *FSM) generateMermaidGraph() string {
transitions := fsm.States[state].Transitions
for _, transition := range transitions {
if state == fsm.Current {
- graph += "\nstyle " + state.String() + " fill:cyan\n"
+ graph += "\nstyle " + fsm.GetName(state) + " fill:cyan\n"
} else {
- graph += "\nstyle " + state.String() + " fill:white\n"
+ graph += "\nstyle " + fsm.GetName(state) + " fill:white\n"
}
- graph += state.String() + "(" + state.String() + ") " + "-->|" + transition.Description + "| " + transition.To.String() + "\n"
+ graph += fsm.GetName(state) + "(" + fsm.GetName(state) + ") " + "-->|" + transition.Description + "| " + fsm.GetName(transition.To) + "\n"
}
}
return graph
}
func (fsm *FSM) GenerateGraph() string {
- return fsm.generateMermaidGraph()
-}
-
-type DeregisteredError struct{}
-
-func (e DeregisteredError) CustomError() *types.WrappedErrorMessage {
- return &types.WrappedErrorMessage{
- Message: "Client not registered with the GO library",
- Err: errors.New(
- "the current FSM state is deregistered, but the function needs a state that is not deregistered",
- ),
+ if fsm.GetName != nil {
+ return fsm.generateMermaidGraph()
}
-}
-
-type WrongStateTransitionError struct {
- Got FSMStateID
- Want FSMStateID
-}
-
-func (e WrongStateTransitionError) CustomError() *types.WrappedErrorMessage {
- return &types.WrappedErrorMessage{
- Message: "Wrong FSM transition",
- Err: errors.New(
- fmt.Sprintf(
- "wrong FSM state, got: %s, want: a state with a transition to: %s",
- e.Got.String(),
- e.Want.String(),
- ),
- ),
- }
-}
-type WrongStateError struct {
- Got FSMStateID
- Want FSMStateID
+ return ""
}
-func (e WrongStateError) CustomError() *types.WrappedErrorMessage {
- return &types.WrappedErrorMessage{
- Message: "Wrong FSM State",
- Err: errors.New(
- fmt.Sprintf("wrong FSM state, got: %s, want: %s", e.Got.String(), e.Want.String()),
- ),
- }
-}