Last active
October 28, 2017 21:58
-
-
Save nvh/1b09b32a335be28e47e8 to your computer and use it in GitHub Desktop.
Data loading state machine enum
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
enum DataSourceState<D,E> { | |
case Empty | |
case Loading(Box<D?>) | |
case Ready(Box<D>) | |
case Error(Box<E>,Box<D?>) | |
func toLoading() -> DataSourceState { | |
switch self { | |
case .Ready(let oldData): | |
let value: D? = oldData.value | |
return .Loading(Box(value)) | |
default: | |
return .Loading(Box(nil)) | |
} | |
} | |
func toError(error:E) -> DataSourceState { | |
switch self { | |
case .Loading(let oldData): | |
return .Error(Box(error),Box(oldData.value)) | |
default: | |
assert(false, "Invalid state transition to .Error from other than .Loading") | |
} | |
} | |
func toReady(data: D) -> DataSourceState { | |
switch self { | |
case .Loading: | |
return .Ready(Box(data)) | |
default: | |
assert(false, "Invalid state transition to .Ready from other than .Loading") | |
} | |
} | |
var data: D? { | |
switch self { | |
case .Empty: | |
return nil | |
case .Ready(let data): | |
return data.value | |
case .Loading(let data): | |
return data.value | |
case .Error(_, let data): | |
return data.value | |
} | |
} | |
var error: E? { | |
switch self { | |
case .Error(let error, _): | |
return error.value | |
default: | |
return nil | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Hi! I saw this Gist on http://nvh.github.io/2015/02/13/state-machine-inside-swift-enum.html
I really like the idea of using function to handle the validity of state changes.
However I have a question for API design.
With this API I cannot forbid somebody else using my state (for example as part of a Framework) the wrong way.
If the developer changes always state like:
then every state change works fine.
however this does not forbid them to do
and removing the checks on state validity.
Do you have any ideas on how to mask it for the enum?