From 0d9d96fa6c9f8091721d90c8b19909883a47eee6 Mon Sep 17 00:00:00 2001 From: Matthias Beyer Date: Mon, 27 Jun 2016 15:12:08 +0200 Subject: [PATCH 1/4] Add result helper --- libimagerror/src/error_gen.rs | 37 +++++++++++++++++++++++++++++++++++ 1 file changed, 37 insertions(+) diff --git a/libimagerror/src/error_gen.rs b/libimagerror/src/error_gen.rs index 9511c988..a9939ae5 100644 --- a/libimagerror/src/error_gen.rs +++ b/libimagerror/src/error_gen.rs @@ -116,6 +116,41 @@ macro_rules! generate_custom_error_types { } } +#[macro_export] +macro_rules! generate_result_helper { + ( + $name: ident, + $kindname: ident + ) => { + /// Trait to replace + /// + /// ```ignore + /// foo.map_err(Box::new).map_err(|e| SomeType::SomeErrorKind.into_error_with_cause(e)) + /// // or: + /// foo.map_err(|e| SomeType::SomeErrorKind.into_error_with_cause(Box::new(e))) + /// ``` + /// + /// with much nicer + /// + /// ```ignore + /// foo.map_err_into(SomeType::SomeErrorKind) + /// ``` + /// + pub trait MapErrInto { + fn map_err_into(self, error_kind: $kindname) -> Result; + } + + impl MapErrInto for Result { + + fn map_err_into(self, error_kind: $kindname) -> Result { + self.map_err(Box::new) + .map_err(|e| error_kind.into_error_with_cause(e)) + } + + } + } +} + #[macro_export] macro_rules! generate_error_types { ( @@ -128,6 +163,8 @@ macro_rules! generate_error_types { generate_custom_error_types!($name, $kindname, SomeNotExistingTypeWithATypeNameNoOneWillEverChoose, $($kind => $string),*); + + generate_result_helper!($name, $kindname); } } From 320c1e4bd8d93ef75466846b111c6b66b59da3ce Mon Sep 17 00:00:00 2001 From: Matthias Beyer Date: Mon, 27 Jun 2016 15:12:17 +0200 Subject: [PATCH 2/4] Add Option helper --- libimagerror/src/error_gen.rs | 32 ++++++++++++++++++++++++++++++++ 1 file changed, 32 insertions(+) diff --git a/libimagerror/src/error_gen.rs b/libimagerror/src/error_gen.rs index a9939ae5..048facb5 100644 --- a/libimagerror/src/error_gen.rs +++ b/libimagerror/src/error_gen.rs @@ -151,6 +151,37 @@ macro_rules! generate_result_helper { } } +#[macro_export] +macro_rules! generate_option_helper { + ( + $name: ident, + $kindname: ident + ) => { + /// Trait to replace + /// + /// ```ignore + /// foo.ok_or(SomeType::SomeErrorKind.into_error()) + /// ``` + /// + /// with + /// + /// ```ignore + /// foo.ok_or_errkind(SomeType::SomeErrorKind) + /// ``` + pub trait OkOrErr { + fn ok_or_errkind(self, kind: $kindname) -> Result; + } + + impl OkOrErr for Option { + + fn ok_or_errkind(self, kind: $kindname) -> Result { + self.ok_or(kind.into_error()) + } + + } + } +} + #[macro_export] macro_rules! generate_error_types { ( @@ -165,6 +196,7 @@ macro_rules! generate_error_types { $($kind => $string),*); generate_result_helper!($name, $kindname); + generate_option_helper!($name, $kindname); } } From 5c8dbac34daf22f83b2a74cad4a4e5715b86ee41 Mon Sep 17 00:00:00 2001 From: Matthias Beyer Date: Sat, 25 Jun 2016 18:36:04 +0200 Subject: [PATCH 3/4] Add test for error kind mapping --- libimagerror/src/error_gen.rs | 44 +++++++++++++++++++++++++++++++++++ 1 file changed, 44 insertions(+) diff --git a/libimagerror/src/error_gen.rs b/libimagerror/src/error_gen.rs index 048facb5..61540b36 100644 --- a/libimagerror/src/error_gen.rs +++ b/libimagerror/src/error_gen.rs @@ -324,4 +324,48 @@ mod test { assert_eq!(TestErrorKind::TestErrorKindA, e.err_type()); assert_eq!(String::from("[testerrorkind B]"), format!("{}", e.cause().unwrap())); } + + #[test] + fn test_error_kind_mapping() { + use std::io::{Error, ErrorKind}; + use self::error::{OkOrErr, MapErrInto}; + use self::error::TestErrorKind; + + let err : Result<(), _> = Err(Error::new(ErrorKind::Other, "")); + let err : Result<(), _> = err.map_err_into(TestErrorKind::TestErrorKindA); + + assert!(err.is_err()); + let err = err.unwrap_err(); + + match err.err_type() { + TestErrorKind::TestErrorKindA => assert!(true), + _ => assert!(false), + } + } + + #[test] + fn test_error_kind_double_mapping() { + use std::io::{Error, ErrorKind}; + use self::error::{OkOrErr, MapErrInto}; + use self::error::TestErrorKind; + + let err : Result<(), _> = Err(Error::new(ErrorKind::Other, "")); + let err : Result<(), _> = err.map_err_into(TestErrorKind::TestErrorKindA) + .map_err_into(TestErrorKind::TestErrorKindB); + + assert!(err.is_err()); + let err = err.unwrap_err(); + match err.err_type() { + TestErrorKind::TestErrorKindB => assert!(true), + _ => assert!(false), + } + + // not sure how to test that the inner error is of TestErrorKindA, actually... + match err.cause() { + Some(_) => assert!(true), + None => assert!(false), + } + + } + } From 7ffd28b5927994af6839010860bd9994950f9a47 Mon Sep 17 00:00:00 2001 From: Matthias Beyer Date: Sat, 25 Jun 2016 18:51:43 +0200 Subject: [PATCH 4/4] Add tests for Option::ok_or_errkind() extension function --- libimagerror/src/error_gen.rs | 24 ++++++++++++++++++++++++ 1 file changed, 24 insertions(+) diff --git a/libimagerror/src/error_gen.rs b/libimagerror/src/error_gen.rs index 61540b36..3a84fd90 100644 --- a/libimagerror/src/error_gen.rs +++ b/libimagerror/src/error_gen.rs @@ -368,4 +368,28 @@ mod test { } + #[test] + fn test_error_option_good() { + use self::error::{OkOrErr, MapErrInto}; + use self::error::TestErrorKind; + + let something = Some(1); + match something.ok_or_errkind(TestErrorKind::TestErrorKindA) { + Ok(1) => assert!(true), + _ => assert!(false), + } + } + + #[test] + fn test_error_option_bad() { + use self::error::{OkOrErr, MapErrInto}; + use self::error::TestErrorKind; + + let something : Option = None; + match something.ok_or_errkind(TestErrorKind::TestErrorKindA) { + Ok(_) => assert!(false), + Err(e) => assert!(true), + } + } + }