sim: simflash: Transition to failure

The Rust community has decided that 'failure' is the future, instead of
'error-chain'.  Migrate the flash simulator to this new error handling
package.  The changes are relatively minor, and the end result is a
similar `FlashError` type.

Signed-off-by: David Brown <david.brown@linaro.org>
diff --git a/sim/Cargo.lock b/sim/Cargo.lock
index 5daaa44..55ffdd6 100644
--- a/sim/Cargo.lock
+++ b/sim/Cargo.lock
@@ -173,6 +173,26 @@
 ]
 
 [[package]]
+name = "failure"
+version = "0.1.5"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+dependencies = [
+ "backtrace 0.3.13 (registry+https://github.com/rust-lang/crates.io-index)",
+ "failure_derive 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)",
+]
+
+[[package]]
+name = "failure_derive"
+version = "0.1.5"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+dependencies = [
+ "proc-macro2 0.4.24 (registry+https://github.com/rust-lang/crates.io-index)",
+ "quote 0.6.10 (registry+https://github.com/rust-lang/crates.io-index)",
+ "syn 0.15.24 (registry+https://github.com/rust-lang/crates.io-index)",
+ "synstructure 0.10.1 (registry+https://github.com/rust-lang/crates.io-index)",
+]
+
+[[package]]
 name = "fuchsia-zircon"
 version = "0.3.3"
 source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -396,7 +416,8 @@
 name = "simflash"
 version = "0.1.0"
 dependencies = [
- "error-chain 0.12.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "failure 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)",
+ "failure_derive 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)",
  "log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)",
  "rand 0.4.5 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
@@ -425,6 +446,17 @@
 ]
 
 [[package]]
+name = "synstructure"
+version = "0.10.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+dependencies = [
+ "proc-macro2 0.4.24 (registry+https://github.com/rust-lang/crates.io-index)",
+ "quote 0.6.10 (registry+https://github.com/rust-lang/crates.io-index)",
+ "syn 0.15.24 (registry+https://github.com/rust-lang/crates.io-index)",
+ "unicode-xid 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
+]
+
+[[package]]
 name = "termcolor"
 version = "1.0.4"
 source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -535,6 +567,8 @@
 "checksum docopt 0.8.3 (registry+https://github.com/rust-lang/crates.io-index)" = "d8acd393692c503b168471874953a2531df0e9ab77d0b6bbc582395743300a4a"
 "checksum env_logger 0.5.13 (registry+https://github.com/rust-lang/crates.io-index)" = "15b0a4d2e39f8420210be8b27eeda28029729e2fd4291019455016c348240c38"
 "checksum error-chain 0.12.0 (registry+https://github.com/rust-lang/crates.io-index)" = "07e791d3be96241c77c43846b665ef1384606da2cd2a48730abe606a12906e02"
+"checksum failure 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)" = "795bd83d3abeb9220f257e597aa0080a508b27533824adf336529648f6abf7e2"
+"checksum failure_derive 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)" = "ea1063915fd7ef4309e222a5a07cf9c319fb9c7836b1f89b85458672dbb127e1"
 "checksum fuchsia-zircon 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)" = "2e9763c69ebaae630ba35f74888db465e49e259ba1bc0eda7d06f4a067615d82"
 "checksum fuchsia-zircon-sys 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)" = "3dcaa9ae7725d12cdb85b3ad99a434db70b468c09ded17e012d86b5c1010f7a7"
 "checksum generic-array 0.12.0 (registry+https://github.com/rust-lang/crates.io-index)" = "3c0f28c2f5bfb5960175af447a2da7c18900693738343dc896ffbcabd9839592"
@@ -565,6 +599,7 @@
 "checksum stream-cipher 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "766ac134af8a81b23b0394cce9cbbf60f6939cae7a31babe470f9766fdae9d9f"
 "checksum strsim 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)" = "b4d15c810519a91cf877e7e36e63fe068815c678181439f2f29e2562147c3694"
 "checksum syn 0.15.24 (registry+https://github.com/rust-lang/crates.io-index)" = "734ecc29cd36e8123850d9bf21dfd62ef8300aaa8f879aabaa899721808be37c"
+"checksum synstructure 0.10.1 (registry+https://github.com/rust-lang/crates.io-index)" = "73687139bf99285483c96ac0add482c3776528beac1d97d444f6e91f203a2015"
 "checksum termcolor 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)" = "4096add70612622289f2fdcdbd5086dc81c1e2675e6ae58d6c4f62a16c6d7f2f"
 "checksum termion 1.5.1 (registry+https://github.com/rust-lang/crates.io-index)" = "689a3bdfaab439fd92bc87df5c4c78417d3cbe537487274e9b0b2dce76e92096"
 "checksum thread_local 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)" = "c6b53e329000edc2b34dbe8545fd20e55a333362d0a321909685a19bd28c3f1b"
diff --git a/sim/simflash/Cargo.toml b/sim/simflash/Cargo.toml
index 6548e83..c8a5fff 100644
--- a/sim/simflash/Cargo.toml
+++ b/sim/simflash/Cargo.toml
@@ -5,6 +5,7 @@
 edition = "2018"
 
 [dependencies]
-error-chain = "0.12.0"
+failure = "0.1.5"
+failure_derive = "0.1.5"
 rand = "0.4.5"
 log = "0.4"
diff --git a/sim/simflash/src/lib.rs b/sim/simflash/src/lib.rs
index 7500464..2c797dd 100644
--- a/sim/simflash/src/lib.rs
+++ b/sim/simflash/src/lib.rs
@@ -3,10 +3,10 @@
 //! This module is capable of simulating the type of NOR flash commonly used in microcontrollers.
 //! These generally can be written as individual bytes, but must be erased in larger units.
 
-#[macro_use] extern crate error_chain;
 mod pdump;
 
 use crate::pdump::HexDump;
+use failure::Fail;
 use log::info;
 use rand::{
     self,
@@ -15,29 +15,37 @@
 use std::{
     collections::HashMap,
     fs::File,
-    io::Write,
+    io::{self, Write},
     iter::Enumerate,
     path::Path,
     slice,
 };
 
-error_chain! {
-    errors {
-        OutOfBounds(t: String) {
-            description("Offset is out of bounds")
-            display("Offset out of bounds: {}", t)
-        }
-        Write(t: String) {
-            description("Invalid write")
-            display("Invalid write: {}", t)
-        }
-        SimulatedFail(t: String) {
-            description("Write failed by chance")
-            display("Failed write: {}", t)
-        }
+pub type Result<T> = std::result::Result<T, FlashError>;
+
+#[derive(Fail, Debug)]
+pub enum FlashError {
+    #[fail(display = "Offset out of bounds: {}", _0)]
+    OutOfBounds(String),
+    #[fail(display = "Invalid write: {}", _0)]
+    Write(String),
+    #[fail(display = "Write failed by chance: {}", _0)]
+    SimulatedFail(String),
+    #[fail(display = "{}", _0)]
+    Io(#[cause] io::Error),
+}
+
+impl From<io::Error> for FlashError {
+    fn from(error: io::Error) -> Self {
+        FlashError::Io(error)
     }
 }
 
+// Transition from error-chain.
+macro_rules! bail {
+    ($item:expr) => (return Err($item.into());)
+}
+
 pub struct FlashPtr {
    pub ptr: *mut dyn Flash,
 }
@@ -60,18 +68,18 @@
     fn erased_val(&self) -> u8;
 }
 
-fn ebounds<T: AsRef<str>>(message: T) -> ErrorKind {
-    ErrorKind::OutOfBounds(message.as_ref().to_owned())
+fn ebounds<T: AsRef<str>>(message: T) -> FlashError {
+    FlashError::OutOfBounds(message.as_ref().to_owned())
 }
 
 #[allow(dead_code)]
-fn ewrite<T: AsRef<str>>(message: T) -> ErrorKind {
-    ErrorKind::Write(message.as_ref().to_owned())
+fn ewrite<T: AsRef<str>>(message: T) -> FlashError {
+    FlashError::Write(message.as_ref().to_owned())
 }
 
 #[allow(dead_code)]
-fn esimulatedwrite<T: AsRef<str>>(message: T) -> ErrorKind {
-    ErrorKind::SimulatedFail(message.as_ref().to_owned())
+fn esimulatedwrite<T: AsRef<str>>(message: T) -> FlashError {
+    FlashError::SimulatedFail(message.as_ref().to_owned())
 }
 
 /// An emulated flash device.  It is represented as a block of bytes, and a list of the sector
@@ -115,8 +123,8 @@
     /// Dump this image to the given file.
     #[allow(dead_code)]
     pub fn write_file<P: AsRef<Path>>(&self, path: P) -> Result<()> {
-        let mut fd = File::create(path).chain_err(|| "Unable to write image file")?;
-        fd.write_all(&self.data).chain_err(|| "Unable to write to image file")?;
+        let mut fd = File::create(path)?;
+        fd.write_all(&self.data)?;
         Ok(())
     }
 
@@ -298,7 +306,7 @@
 
 #[cfg(test)]
 mod test {
-    use super::{Flash, SimFlash, Error, ErrorKind, Result, Sector};
+    use super::{Flash, FlashError, SimFlash, Result, Sector};
 
     #[test]
     fn test_flash() {
@@ -361,7 +369,7 @@
 
         fn is_bounds(&self) -> bool {
             match *self {
-                Err(Error(ErrorKind::OutOfBounds(_), _)) => true,
+                Err(FlashError::OutOfBounds(_)) => true,
                 _ => false,
             }
         }