diff --git a/mfm_machine/Cargo.lock b/mfm_machine/Cargo.lock index f944e69..bed9dd0 100644 --- a/mfm_machine/Cargo.lock +++ b/mfm_machine/Cargo.lock @@ -2,6 +2,15 @@ # It is not intended for manual editing. version = 3 +[[package]] +name = "anyhow" +version = "1.0.75" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a4668cab20f66d8d020e1fbc0ebe47217433c1b6c8f2040faf858554e394ace6" + [[package]] name = "mfm_machine" version = "0.1.0" +dependencies = [ + "anyhow", +] diff --git a/mfm_machine/Cargo.toml b/mfm_machine/Cargo.toml index f4619e7..c5ac536 100644 --- a/mfm_machine/Cargo.toml +++ b/mfm_machine/Cargo.toml @@ -6,3 +6,4 @@ edition = "2021" # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html [dependencies] +anyhow = "1.0.75" diff --git a/mfm_machine/src/state/mod.rs b/mfm_machine/src/state/mod.rs index b2f6ce8..c23afaa 100644 --- a/mfm_machine/src/state/mod.rs +++ b/mfm_machine/src/state/mod.rs @@ -1,3 +1,5 @@ +use std::fmt; + #[derive(Debug)] enum States { Setup(T), @@ -8,6 +10,50 @@ trait StateHandler { fn handler(&self); } +#[derive(Debug)] +enum StateErrorRecoverability { + Recoverable, + Unrecoverable, +} + +#[derive(Debug)] +enum StateError { + Unknown(StateErrorRecoverability), + RpcConnection(StateErrorRecoverability), + StorageAccess(StateErrorRecoverability), + OnChainError(StateErrorRecoverability), + OffChainError(StateErrorRecoverability), + ParsingInput(StateErrorRecoverability), +} + +impl StateError { + pub fn is_recoverable(&self) -> bool { + match self { + Self::Unknown(recov) => matches!(recov, StateErrorRecoverability::Recoverable), + Self::RpcConnection(recov) => matches!(recov, StateErrorRecoverability::Recoverable), + Self::StorageAccess(recov) => matches!(recov, StateErrorRecoverability::Recoverable), + Self::OnChainError(recov) => matches!(recov, StateErrorRecoverability::Recoverable), + Self::OffChainError(recov) => matches!(recov, StateErrorRecoverability::Recoverable), + Self::ParsingInput(recov) => matches!(recov, StateErrorRecoverability::Recoverable), + } + } +} + +impl fmt::Display for StateError { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + match self { + Self::Unknown(_) => write!(f, "unknown error"), + Self::RpcConnection(_) => write!(f, "RPC connection error"), + Self::StorageAccess(_) => write!(f, "storage access error"), + Self::OnChainError(_) => write!(f, "on-chain error"), + Self::OffChainError(_) => write!(f, "off-chain error"), + Self::ParsingInput(_) => write!(f, "parsing input error"), + } + } +} + +impl std::error::Error for StateError {} + struct SetupState; impl StateHandler for SetupState { fn handler(&self) { @@ -34,4 +80,10 @@ mod test { _ => panic!("expected Setup state"), } } + + #[test] + fn custom_error_to_anyhow_error() { + let f = |error: StateError| -> anyhow::Error { error.into() }; + f(StateError::Unknown(StateErrorRecoverability::Unrecoverable)); + } }