Skip to content

Instantly share code, notes, and snippets.

@Phaiax
Created June 20, 2017 13:15
Show Gist options
  • Save Phaiax/11d07664eafde953ba83acb9b11a89a2 to your computer and use it in GitHub Desktop.
Save Phaiax/11d07664eafde953ba83acb9b11a89a2 to your computer and use it in GitHub Desktop.
#[macro_use] extern crate error_chain;
// All errors that can occour everywhere in the crate
pub mod errors {
error_chain!{
errors {
Pig { description("Pig-Descr") display("Pig-Display")}
Bat {}
Uhu {}
}
}
}
pub use errors::*;
// Every public fn is preceeded by this macro which indicates the valid
// variants of errors that can occour.
// can_err!( AErrorKinds, AResult, {Pig, Bat})
////////////////////////////////////////////////////////
////////// THIS WOULD BE GENERATED BY THE MACRO can_err!
////////////////////////////////////////////////////////
#[derive(Debug)]
pub enum AErrorKinds {
Pig{k : Error},
Bat{k : Error}
}
pub type AResult<T> = std::result::Result<T, AErrorKinds>;
impl AErrorKinds {
pub fn kind(&self) -> &ErrorKind {
match self {
&AErrorKinds::Pig { ref k } => k.kind(),
&AErrorKinds::Bat { ref k } => k.kind(),
}
}
pub fn kind_reduced(&self) -> &AErrorKinds {
self
}
pub fn description(&self) -> &str {
self.kind().description()
}
}
impl std::fmt::Display for AErrorKinds {
fn fmt(&self, fmt: &mut std::fmt::Formatter) -> std::fmt::Result {
//use std::fmt::Display;
self.kind().fmt(fmt)
}
}
impl From<ErrorKind> for AErrorKinds {
fn from(ek: ErrorKind) -> Self {
let e : Error = ek.into();
let n = match e.kind() {
&ErrorKind::Pig{..} => 1,
&ErrorKind::Bat{..} => 2,
_ => unreachable!()
};
match n {
1 => AErrorKinds::Pig { k:e },
2 => AErrorKinds::Bat { k:e },
_ => unreachable!()
}
}
}
////////////////////////////////////////////////////////
/////////////////// END MACRO
////////////////////////////////////////////////////////
fn some_internal_helper() -> AResult<u8> {
// Uhu is an invalid error for this
// function, so the following line will go to unreachable! and panic.
Err(ErrorKind::Uhu.into())
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn it_works() {
if let Err(err) = some_internal_helper() {
match *err.kind() {
ErrorKind::Msg(_) => {}
ErrorKind::Pig => {},
ErrorKind::Bat => {}
ErrorKind::Uhu => {}
}
// the actual errors that can be generated by the function
// are combined in a distict enum that allows exhaustive
// matching
match *err.kind_reduced() {
AErrorKinds::Pig{..} => {},
AErrorKinds::Bat{..} => {}
}
println!("Descr: {}", err.description());
println!("Displ: {}", err);
println!("Debug: {:?}", err);
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment