From 236b6f1c3e95b5aa6978ae9e5d54199799ed489d Mon Sep 17 00:00:00 2001 From: debris Date: Tue, 5 Sep 2017 12:14:03 +0200 Subject: [PATCH] UtilError uses error_chain!, moved OutOfBounds and Mismatched to unexpected crate --- Cargo.lock | 15 ++ ethcore/Cargo.toml | 1 + ethcore/src/block.rs | 2 +- ethcore/src/client/client.rs | 3 +- ethcore/src/engines/authority_round/mod.rs | 1 + ethcore/src/engines/basic_authority.rs | 1 + ethcore/src/engines/mod.rs | 1 + ethcore/src/engines/tendermint/mod.rs | 1 + .../engines/validator_set/safe_contract.rs | 1 + ethcore/src/error.rs | 5 +- ethcore/src/ethereum/ethash.rs | 1 + ethcore/src/lib.rs | 1 + ethcore/src/snapshot/service.rs | 6 +- ethcore/src/verification/verification.rs | 2 + util/Cargo.toml | 1 + util/src/error.rs | 132 +++--------------- util/src/journaldb/archivedb.rs | 3 +- util/src/journaldb/earlymergedb.rs | 3 +- util/src/journaldb/overlayrecentdb.rs | 3 +- util/src/kvdb.rs | 2 +- util/src/lib.rs | 5 +- util/src/overlaydb.rs | 6 +- util/src/snappy.rs | 8 +- util/unexpected/Cargo.toml | 6 + util/unexpected/src/lib.rs | 58 ++++++++ 25 files changed, 137 insertions(+), 131 deletions(-) create mode 100644 util/unexpected/Cargo.toml create mode 100644 util/unexpected/src/lib.rs diff --git a/Cargo.lock b/Cargo.lock index ea9a12fa6..c23b72735 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -455,6 +455,14 @@ dependencies = [ "backtrace 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)", ] +[[package]] +name = "error-chain" +version = "0.11.0-rc.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "backtrace 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)", +] + [[package]] name = "eth-secp256k1" version = "0.5.6" @@ -547,6 +555,7 @@ dependencies = [ "time 0.1.35 (registry+https://github.com/rust-lang/crates.io-index)", "transient-hashmap 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", "triehash 0.1.0", + "unexpected 0.1.0", "using_queue 0.1.0", "vm 0.1.0", "wasm 0.1.0", @@ -796,6 +805,7 @@ dependencies = [ "clippy 0.0.103 (registry+https://github.com/rust-lang/crates.io-index)", "elastic-array 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)", "env_logger 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)", + "error-chain 0.11.0-rc.2 (registry+https://github.com/rust-lang/crates.io-index)", "eth-secp256k1 0.5.6 (git+https://github.com/paritytech/rust-secp256k1)", "ethcore-bigint 0.1.3", "ethcore-bloom-journal 0.1.0", @@ -3143,6 +3153,10 @@ name = "typeable" version = "0.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" +[[package]] +name = "unexpected" +version = "0.1.0" + [[package]] name = "unicase" version = "1.4.0" @@ -3394,6 +3408,7 @@ dependencies = [ "checksum either 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)" = "3d2b503c86dad62aaf414ecf2b8c527439abedb3f8d812537f0b12bfd6f32a91" "checksum elastic-array 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)" = "258ff6a9a94f648d0379dbd79110e057edbb53eb85cc237e33eadf8e5a30df85" "checksum env_logger 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)" = "e3856f1697098606fc6cb97a93de88ca3f3bc35bb878c725920e6e82ecf05e83" +"checksum error-chain 0.11.0-rc.2 (registry+https://github.com/rust-lang/crates.io-index)" = "38d3a55d9a7a456748f2a3912c0941a5d9a68006eb15b3c3c9836b8420dc102d" "checksum error-chain 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)" = "bd5c82c815138e278b8dcdeffc49f27ea6ffb528403e9dea4194f2e3dd40b143" "checksum eth-secp256k1 0.5.6 (git+https://github.com/paritytech/rust-secp256k1)" = "" "checksum ethabi 2.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "0c3d62319ee0f35abf20afe8859dd2668195912614346447bb2dee9fb8da7c62" diff --git a/ethcore/Cargo.toml b/ethcore/Cargo.toml index e9fec51b9..d96cc2dea 100644 --- a/ethcore/Cargo.toml +++ b/ethcore/Cargo.toml @@ -66,6 +66,7 @@ wasm = { path = "wasm" } hash = { path = "../util/hash" } triehash = { path = "../util/triehash" } semantic_version = { path = "../util/semantic_version" } +unexpected = { path = "../util/unexpected" } [dev-dependencies] native-contracts = { path = "native_contracts", features = ["test_contracts"] } diff --git a/ethcore/src/block.rs b/ethcore/src/block.rs index 57ea80faa..d6fa65a41 100644 --- a/ethcore/src/block.rs +++ b/ethcore/src/block.rs @@ -26,7 +26,7 @@ use rlp::{UntrustedRlp, RlpStream, Encodable, Decodable, DecoderError}; use bigint::prelude::U256; use bigint::hash::H256; use util::{Bytes, Address}; -use util::error::{Mismatch, OutOfBounds}; +use unexpected::{Mismatch, OutOfBounds}; use basic_types::{LogBloom, Seal}; use vm::{EnvInfo, LastHashes}; diff --git a/ethcore/src/client/client.rs b/ethcore/src/client/client.rs index 0605d588e..e749bb0ae 100644 --- a/ethcore/src/client/client.rs +++ b/ethcore/src/client/client.rs @@ -25,6 +25,7 @@ use itertools::Itertools; // util use hash::keccak; use timer::PerfTimer; +use util::UtilError; use util::Bytes; use util::{journaldb, DBValue, TrieFactory, Trie}; use util::Address; @@ -252,7 +253,7 @@ impl Client { last_hashes: RwLock::new(VecDeque::new()), factories: factories, history: history, - rng: Mutex::new(OsRng::new().map_err(::util::UtilError::StdIo)?), + rng: Mutex::new(OsRng::new().map_err(UtilError::from)?), ancient_verifier: Mutex::new(None), on_user_defaults_change: Mutex::new(None), registrar: Mutex::new(None), diff --git a/ethcore/src/engines/authority_round/mod.rs b/ethcore/src/engines/authority_round/mod.rs index 4eb268000..b50ebbc4f 100644 --- a/ethcore/src/engines/authority_round/mod.rs +++ b/ethcore/src/engines/authority_round/mod.rs @@ -46,6 +46,7 @@ use bigint::prelude::{U256, U128}; use bigint::hash::{H256, H520}; use semantic_version::SemanticVersion; use parking_lot::{Mutex, RwLock}; +use unexpected::{Mismatch, OutOfBounds}; use util::*; mod finality; diff --git a/ethcore/src/engines/basic_authority.rs b/ethcore/src/engines/basic_authority.rs index 15cf15fd6..b96769837 100644 --- a/ethcore/src/engines/basic_authority.rs +++ b/ethcore/src/engines/basic_authority.rs @@ -23,6 +23,7 @@ use bigint::prelude::U256; use bigint::hash::{H256, H520}; use parking_lot::RwLock; use util::*; +use unexpected::{Mismatch, OutOfBounds}; use ethkey::{recover, public_to_address, Signature}; use account_provider::AccountProvider; use block::*; diff --git a/ethcore/src/engines/mod.rs b/ethcore/src/engines/mod.rs index 19ec62b15..fcf387f8b 100644 --- a/ethcore/src/engines/mod.rs +++ b/ethcore/src/engines/mod.rs @@ -58,6 +58,7 @@ use bigint::prelude::U256; use bigint::hash::H256; use semantic_version::SemanticVersion; use util::*; +use unexpected::{Mismatch, OutOfBounds}; /// Default EIP-210 contrat code. /// As defined in https://github.com/ethereum/EIPs/pull/210/commits/9df24a3714af42e3bf350265bdc75b486c909d7f#diff-e02a92c2fb96c1a1bfb05e4c6e2ef5daR49 diff --git a/ethcore/src/engines/tendermint/mod.rs b/ethcore/src/engines/tendermint/mod.rs index 5e902f895..ce0a0da24 100644 --- a/ethcore/src/engines/tendermint/mod.rs +++ b/ethcore/src/engines/tendermint/mod.rs @@ -34,6 +34,7 @@ use bigint::prelude::{U128, U256}; use bigint::hash::{H256, H520}; use parking_lot::RwLock; use util::*; +use unexpected::{OutOfBounds, Mismatch}; use client::EngineClient; use error::{Error, BlockError}; use header::{Header, BlockNumber}; diff --git a/ethcore/src/engines/validator_set/safe_contract.rs b/ethcore/src/engines/validator_set/safe_contract.rs index 2411f4770..1d4f9b0be 100644 --- a/ethcore/src/engines/validator_set/safe_contract.rs +++ b/ethcore/src/engines/validator_set/safe_contract.rs @@ -27,6 +27,7 @@ use parking_lot::{Mutex, RwLock}; use util::*; use util::cache::MemoryLruCache; +use unexpected::Mismatch; use rlp::{UntrustedRlp, RlpStream}; use basic_types::LogBloom; diff --git a/ethcore/src/error.rs b/ethcore/src/error.rs index 87d77feaa..ae27a0940 100644 --- a/ethcore/src/error.rs +++ b/ethcore/src/error.rs @@ -20,6 +20,7 @@ use std::fmt; use bigint::prelude::U256; use bigint::hash::H256; use util::*; +use unexpected::{Mismatch, OutOfBounds}; use io::*; use header::BlockNumber; use basic_types::LogBloom; @@ -391,7 +392,7 @@ impl From for Error { impl From<::rlp::DecoderError> for Error { fn from(err: ::rlp::DecoderError) -> Error { - Error::Util(UtilError::Decoder(err)) + Error::Util(UtilError::from(err)) } } @@ -424,7 +425,7 @@ impl From for Error { match err { BlockImportError::Block(e) => Error::Block(e), BlockImportError::Import(e) => Error::Import(e), - BlockImportError::Other(s) => Error::Util(UtilError::SimpleString(s)), + BlockImportError::Other(s) => Error::Util(UtilError::from(s)), } } } diff --git a/ethcore/src/ethereum/ethash.rs b/ethcore/src/ethereum/ethash.rs index b33d3821c..0b3cab6ef 100644 --- a/ethcore/src/ethereum/ethash.rs +++ b/ethcore/src/ethereum/ethash.rs @@ -23,6 +23,7 @@ use ethash::{quick_get_difficulty, slow_get_seedhash, EthashManager}; use bigint::prelude::U256; use bigint::hash::{H256, H64}; use util::*; +use unexpected::{OutOfBounds, Mismatch}; use block::*; use builtin::Builtin; use vm::EnvInfo; diff --git a/ethcore/src/lib.rs b/ethcore/src/lib.rs index 53ddcc512..382887543 100644 --- a/ethcore/src/lib.rs +++ b/ethcore/src/lib.rs @@ -108,6 +108,7 @@ extern crate heapsize; extern crate triehash; extern crate ansi_term; extern crate semantic_version; +extern crate unexpected; #[macro_use] extern crate rlp_derive; diff --git a/ethcore/src/snapshot/service.rs b/ethcore/src/snapshot/service.rs index 0d8704092..72ef8ccc1 100644 --- a/ethcore/src/snapshot/service.rs +++ b/ethcore/src/snapshot/service.rs @@ -102,7 +102,7 @@ impl Restoration { let block_chunks = manifest.block_hashes.iter().cloned().collect(); let raw_db = Arc::new(Database::open(params.db_config, &*params.db_path.to_string_lossy()) - .map_err(UtilError::SimpleString)?); + .map_err(UtilError::from)?); let chain = BlockChain::new(Default::default(), params.genesis, raw_db.clone()); let components = params.engine.snapshot_components() @@ -519,7 +519,7 @@ impl Service { match is_done { true => { - db.flush().map_err(::util::UtilError::SimpleString)?; + db.flush().map_err(UtilError::from)?; drop(db); return self.finalize_restoration(&mut *restoration); }, @@ -532,7 +532,7 @@ impl Service { } } }; - result.and_then(|_| db.flush().map_err(|e| ::util::UtilError::SimpleString(e).into())) + result.and_then(|_| db.flush().map_err(|e| UtilError::from(e).into())) } /// Feed a state chunk to be processed synchronously. diff --git a/ethcore/src/verification/verification.rs b/ethcore/src/verification/verification.rs index ec186dacd..62639e849 100644 --- a/ethcore/src/verification/verification.rs +++ b/ethcore/src/verification/verification.rs @@ -27,6 +27,7 @@ use triehash::ordered_trie_root; use heapsize::HeapSizeOf; use bigint::hash::H256; use util::*; +use unexpected::{Mismatch, OutOfBounds}; use engines::Engine; use error::{BlockError, Error}; use blockchain::*; @@ -274,6 +275,7 @@ mod tests { use bigint::prelude::U256; use bigint::hash::{H256, H2048}; use triehash::ordered_trie_root; + use unexpected::{Mismatch, OutOfBounds}; use util::*; use ethkey::{Random, Generator}; use header::*; diff --git a/util/Cargo.toml b/util/Cargo.toml index e4e95bad7..49b373785 100644 --- a/util/Cargo.toml +++ b/util/Cargo.toml @@ -34,6 +34,7 @@ regex = "0.2" lru-cache = "0.1.0" ethcore-logger = { path = "../logger" } triehash = { path = "triehash" } +error-chain = "0.11.0-rc.2" [features] default = [] diff --git a/util/src/error.rs b/util/src/error.rs index b0e887434..59496f86f 100644 --- a/util/src/error.rs +++ b/util/src/error.rs @@ -16,9 +16,12 @@ //! General error types for use in ethcore. +#![allow(missing_docs)] +#![allow(unknown_lints)] + +use std::{self, fmt}; use rustc_hex::FromHexError; use rlp::DecoderError; -use std::fmt; use bigint::hash::H256; #[derive(Debug)] @@ -41,124 +44,23 @@ impl fmt::Display for BaseDataError { } } -#[derive(Debug)] -/// General error type which should be capable of representing all errors in ethcore. -pub enum UtilError { - /// Error concerning the Rust standard library's IO subsystem. - StdIo(::std::io::Error), - /// Error concerning the hex conversion logic. - FromHex(FromHexError), - /// Error concerning the database abstraction logic. - BaseData(BaseDataError), - /// Error concerning the RLP decoder. - Decoder(DecoderError), - /// Miscellaneous error described by a string. - SimpleString(String), - /// Error from a bad input size being given for the needed output. - BadSize, - /// Error from snappy. - Snappy(::snappy::InvalidInput), -} - -impl fmt::Display for UtilError { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - match *self { - UtilError::StdIo(ref err) => f.write_fmt(format_args!("{}", err)), - UtilError::FromHex(ref err) => f.write_fmt(format_args!("{}", err)), - UtilError::BaseData(ref err) => f.write_fmt(format_args!("{}", err)), - UtilError::Decoder(ref err) => f.write_fmt(format_args!("{}", err)), - UtilError::SimpleString(ref msg) => f.write_str(msg), - UtilError::BadSize => f.write_str("Bad input size."), - UtilError::Snappy(ref err) => f.write_fmt(format_args!("{}", err)), - } +impl std::error::Error for BaseDataError { + fn description(&self) -> &str { + "Error in database subsystem" } } -#[derive(Debug, PartialEq, Eq, Clone, Copy)] -/// Error indicating an expected value was not found. -pub struct Mismatch { - /// Value expected. - pub expected: T, - /// Value found. - pub found: T, -} +error_chain! { + types { + UtilError, ErrorKind, ResultExt, Result; + } -impl fmt::Display for Mismatch { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - f.write_fmt(format_args!("Expected {}, found {}", self.expected, self.found)) + foreign_links { + Io(::std::io::Error); + FromHex(FromHexError); + Decoder(DecoderError); + Snappy(::snappy::InvalidInput); + BaseData(BaseDataError); } } -#[derive(Debug, PartialEq, Eq, Clone, Copy)] -/// Error indicating value found is outside of a valid range. -pub struct OutOfBounds { - /// Minimum allowed value. - pub min: Option, - /// Maximum allowed value. - pub max: Option, - /// Value found. - pub found: T, -} - -impl fmt::Display for OutOfBounds { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - let msg = match (self.min.as_ref(), self.max.as_ref()) { - (Some(min), Some(max)) => format!("Min={}, Max={}", min, max), - (Some(min), _) => format!("Min={}", min), - (_, Some(max)) => format!("Max={}", max), - (None, None) => "".into(), - }; - - f.write_fmt(format_args!("Value {} out of bounds. {}", self.found, msg)) - } -} - -impl From for UtilError { - fn from(err: FromHexError) -> UtilError { - UtilError::FromHex(err) - } -} - -impl From for UtilError { - fn from(err: BaseDataError) -> UtilError { - UtilError::BaseData(err) - } -} - -impl From<::std::io::Error> for UtilError { - fn from(err: ::std::io::Error) -> UtilError { - UtilError::StdIo(err) - } -} - -impl From<::rlp::DecoderError> for UtilError { - fn from(err: ::rlp::DecoderError) -> UtilError { - UtilError::Decoder(err) - } -} - -impl From for UtilError { - fn from(err: String) -> UtilError { - UtilError::SimpleString(err) - } -} - -impl From<::snappy::InvalidInput> for UtilError { - fn from(err: ::snappy::InvalidInput) -> UtilError { - UtilError::Snappy(err) - } -} - -// TODO: uncomment below once https://github.com/rust-lang/rust/issues/27336 sorted. -/*#![feature(concat_idents)] -macro_rules! assimilate { - ($name:ident) => ( - impl From for Error { - fn from(err: concat_idents!($name, Error)) -> Error { - Error:: $name (err) - } - } - ) -} -assimilate!(FromHex); -assimilate!(BaseData);*/ diff --git a/util/src/journaldb/archivedb.rs b/util/src/journaldb/archivedb.rs index 734378a7e..e77c908d3 100644 --- a/util/src/journaldb/archivedb.rs +++ b/util/src/journaldb/archivedb.rs @@ -26,7 +26,8 @@ use super::{DB_PREFIX_LEN, LATEST_ERA_KEY}; use super::traits::JournalDB; use kvdb::{KeyValueDB, DBTransaction}; use bigint::hash::H256; -use {Bytes, BaseDataError, UtilError}; +use error::{BaseDataError, UtilError}; +use {Bytes}; /// Implementation of the `HashDB` trait for a disk-backed database with a memory overlay /// and latent-removal semantics. diff --git a/util/src/journaldb/earlymergedb.rs b/util/src/journaldb/earlymergedb.rs index 397c18059..dd9cf4f37 100644 --- a/util/src/journaldb/earlymergedb.rs +++ b/util/src/journaldb/earlymergedb.rs @@ -29,7 +29,8 @@ use super::{DB_PREFIX_LEN, LATEST_ERA_KEY}; use super::traits::JournalDB; use kvdb::{KeyValueDB, DBTransaction}; use bigint::hash::H256; -use { BaseDataError, UtilError, Bytes}; +use error::{BaseDataError, UtilError}; +use {Bytes}; #[derive(Clone, PartialEq, Eq)] struct RefInfo { diff --git a/util/src/journaldb/overlayrecentdb.rs b/util/src/journaldb/overlayrecentdb.rs index dad0562d6..c450e53d8 100644 --- a/util/src/journaldb/overlayrecentdb.rs +++ b/util/src/journaldb/overlayrecentdb.rs @@ -28,7 +28,8 @@ use super::{DB_PREFIX_LEN, LATEST_ERA_KEY}; use kvdb::{KeyValueDB, DBTransaction}; use super::JournalDB; use bigint::hash::{H256, H256FastMap}; -use {BaseDataError, UtilError, Bytes}; +use error::{BaseDataError, UtilError}; +use {Bytes}; /// Implementation of the `JournalDB` trait for a disk-backed database with a memory overlay /// and, possibly, latent-removal semantics. diff --git a/util/src/kvdb.rs b/util/src/kvdb.rs index 50a4f127a..1e2510c0a 100644 --- a/util/src/kvdb.rs +++ b/util/src/kvdb.rs @@ -279,7 +279,7 @@ impl KeyValueDB for InMemory { } fn restore(&self, _new_db: &str) -> Result<(), UtilError> { - Err(UtilError::SimpleString("Attempted to restore in-memory database".into())) + Err("Attempted to restore in-memory database".into()) } } diff --git a/util/src/lib.rs b/util/src/lib.rs index 025e03286..a39e1df95 100644 --- a/util/src/lib.rs +++ b/util/src/lib.rs @@ -109,6 +109,9 @@ extern crate heapsize; extern crate ethcore_logger; extern crate hash as keccak; +#[macro_use] +extern crate error_chain; + #[macro_use] extern crate log as rlog; @@ -136,7 +139,7 @@ pub use overlaydb::*; pub use journaldb::JournalDB; pub use trie::{Trie, TrieMut, TrieDB, TrieDBMut, TrieFactory, TrieError, SecTrieDB, SecTrieDBMut}; pub use kvdb::*; -pub use error::*; +pub use error::UtilError; pub use bytes::*; /// 160-bit integer representing account address diff --git a/util/src/overlaydb.rs b/util/src/overlaydb.rs index f2005fb7d..b4c0beb25 100644 --- a/util/src/overlaydb.rs +++ b/util/src/overlaydb.rs @@ -19,7 +19,7 @@ use std::sync::Arc; use std::collections::HashMap; use std::collections::hash_map::Entry; -use error::*; +use error::{Result, BaseDataError}; use bigint::hash::*; use rlp::*; use hashdb::*; @@ -56,14 +56,14 @@ impl OverlayDB { /// Commit all operations in a single batch. #[cfg(test)] - pub fn commit(&mut self) -> Result { + pub fn commit(&mut self) -> Result { let mut batch = self.backing.transaction(); let res = self.commit_to_batch(&mut batch)?; self.backing.write(batch).map(|_| res).map_err(|e| e.into()) } /// Commit all operations to given batch. - pub fn commit_to_batch(&mut self, batch: &mut DBTransaction) -> Result { + pub fn commit_to_batch(&mut self, batch: &mut DBTransaction) -> Result { let mut ret = 0u32; let mut deletes = 0usize; for i in self.overlay.drain() { diff --git a/util/src/snappy.rs b/util/src/snappy.rs index fd15bd307..bfb68129a 100644 --- a/util/src/snappy.rs +++ b/util/src/snappy.rs @@ -16,7 +16,7 @@ //! Snappy compression bindings. -use std::fmt; +use std::{self, fmt}; use libc::{c_char, c_int, size_t}; const SNAPPY_OK: c_int = 0; @@ -56,6 +56,12 @@ extern { #[derive(Debug)] pub struct InvalidInput; +impl std::error::Error for InvalidInput { + fn description(&self) -> &str { + "Attempted snappy decompression with invalid input" + } +} + impl fmt::Display for InvalidInput { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { write!(f, "Attempted snappy decompression with invalid input") diff --git a/util/unexpected/Cargo.toml b/util/unexpected/Cargo.toml new file mode 100644 index 000000000..35ff1a535 --- /dev/null +++ b/util/unexpected/Cargo.toml @@ -0,0 +1,6 @@ +[package] +name = "unexpected" +version = "0.1.0" +authors = ["Parity Technologies "] + +[dependencies] diff --git a/util/unexpected/src/lib.rs b/util/unexpected/src/lib.rs new file mode 100644 index 000000000..e34b2326c --- /dev/null +++ b/util/unexpected/src/lib.rs @@ -0,0 +1,58 @@ +// Copyright 2015-2017 Parity Technologies (UK) Ltd. +// This file is part of Parity. + +// Parity is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. + +// Parity is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with Parity. If not, see . + +//! Error utils + +use std::fmt; + +#[derive(Debug, PartialEq, Eq, Clone, Copy)] +/// Error indicating an expected value was not found. +pub struct Mismatch { + /// Value expected. + pub expected: T, + /// Value found. + pub found: T, +} + +impl fmt::Display for Mismatch { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + f.write_fmt(format_args!("Expected {}, found {}", self.expected, self.found)) + } +} + +#[derive(Debug, PartialEq, Eq, Clone, Copy)] +/// Error indicating value found is outside of a valid range. +pub struct OutOfBounds { + /// Minimum allowed value. + pub min: Option, + /// Maximum allowed value. + pub max: Option, + /// Value found. + pub found: T, +} + +impl fmt::Display for OutOfBounds { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + let msg = match (self.min.as_ref(), self.max.as_ref()) { + (Some(min), Some(max)) => format!("Min={}, Max={}", min, max), + (Some(min), _) => format!("Min={}", min), + (_, Some(max)) => format!("Max={}", max), + (None, None) => "".into(), + }; + + f.write_fmt(format_args!("Value {} out of bounds. {}", self.found, msg)) + } +}