mirror of
				https://github.com/haraldh/chainerror.git
				synced 2025-11-04 08:18:08 +01:00 
			
		
		
		
	macro hygiene
This commit is contained in:
		
							parent
							
								
									a558c35ba4
								
							
						
					
					
						commit
						ae6c01aab2
					
				
					 6 changed files with 372 additions and 68 deletions
				
			
		| 
						 | 
				
			
			@ -1,6 +1,6 @@
 | 
			
		|||
[package]
 | 
			
		||||
name = "chainerror"
 | 
			
		||||
version = "0.4.4"
 | 
			
		||||
version = "0.5.0"
 | 
			
		||||
authors = ["Harald Hoyer <harald@redhat.com>"]
 | 
			
		||||
edition = "2018"
 | 
			
		||||
license = "MIT/Apache-2.0"
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -1,8 +1,9 @@
 | 
			
		|||
use chainerror::*;
 | 
			
		||||
use std::error::Error;
 | 
			
		||||
use std::io;
 | 
			
		||||
use std::result::Result;
 | 
			
		||||
 | 
			
		||||
use chainerror::*;
 | 
			
		||||
 | 
			
		||||
fn do_some_io() -> Result<(), Box<Error + Send + Sync>> {
 | 
			
		||||
    Err(io::Error::from(io::ErrorKind::NotFound))?;
 | 
			
		||||
    Ok(())
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -15,7 +15,7 @@ pub mod mycrate {
 | 
			
		|||
        Ok(())
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    #[derive(Debug)]
 | 
			
		||||
    #[derive(Debug, Clone)]
 | 
			
		||||
    pub enum ErrorKind {
 | 
			
		||||
        Func2,
 | 
			
		||||
        IO(String),
 | 
			
		||||
| 
						 | 
				
			
			@ -42,7 +42,7 @@ pub mod mycrate {
 | 
			
		|||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
fn main() -> Result<(), Box<std::error::Error>> {
 | 
			
		||||
fn main() -> Result<(), Box<std::error::Error + Send + Sync>> {
 | 
			
		||||
    use mycrate::func1;
 | 
			
		||||
    use mycrate::ErrorKind;
 | 
			
		||||
    use std::error::Error;
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -182,7 +182,7 @@ pub mod mycrate {
 | 
			
		|||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
fn main() -> Result<(), Box<std::error::Error>> {
 | 
			
		||||
fn main() -> Result<(), Box<std::error::Error + Send + Sync>> {
 | 
			
		||||
    use mycrate::func1;
 | 
			
		||||
    use mycrate::ErrorKind;
 | 
			
		||||
    use std::error::Error;
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
							
								
								
									
										139
									
								
								examples/tutorial15.rs
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										139
									
								
								examples/tutorial15.rs
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,139 @@
 | 
			
		|||
pub mod mycrate {
 | 
			
		||||
    use std::io;
 | 
			
		||||
 | 
			
		||||
    use chainerror::*;
 | 
			
		||||
 | 
			
		||||
    fn do_some_io(_f: &str) -> std::result::Result<(), io::Error> {
 | 
			
		||||
        Err(io::Error::from(io::ErrorKind::NotFound))?;
 | 
			
		||||
        Ok(())
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    derive_str_cherr!(Func2Error);
 | 
			
		||||
 | 
			
		||||
    fn func2() -> std::result::Result<(), Box<std::error::Error + Send + Sync>> {
 | 
			
		||||
        let filename = "foo.txt";
 | 
			
		||||
        do_some_io(filename)
 | 
			
		||||
            .map_err(|e| cherr!(e, Func2Error(format!("Error reading '{}'", filename))))?;
 | 
			
		||||
        Ok(())
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    #[derive(Debug, Clone)]
 | 
			
		||||
    pub enum ErrorKind {
 | 
			
		||||
        Func2,
 | 
			
		||||
        IO(String),
 | 
			
		||||
        FatalError(String),
 | 
			
		||||
        Unknown,
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    derive_err_kind!(Error, ErrorKind);
 | 
			
		||||
    pub type Result<T> = std::result::Result<T, Error>;
 | 
			
		||||
 | 
			
		||||
    impl std::fmt::Display for ErrorKind {
 | 
			
		||||
        fn fmt(&self, f: &mut ::std::fmt::Formatter) -> std::fmt::Result {
 | 
			
		||||
            match self {
 | 
			
		||||
                ErrorKind::FatalError(e) => write!(f, "fatal error {}", e),
 | 
			
		||||
                ErrorKind::Unknown => write!(f, "unknown error"),
 | 
			
		||||
                ErrorKind::Func2 => write!(f, "func1 error calling func2"),
 | 
			
		||||
                ErrorKind::IO(filename) => write!(f, "Error reading '{}'", filename),
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    impl ErrorKind {
 | 
			
		||||
        fn from_io_error(e: &io::Error, f: String) -> Self {
 | 
			
		||||
            match e.kind() {
 | 
			
		||||
                io::ErrorKind::BrokenPipe => panic!("Should not happen"),
 | 
			
		||||
                io::ErrorKind::ConnectionReset => {
 | 
			
		||||
                    ErrorKind::FatalError(format!("While reading `{}`: {}", f, e))
 | 
			
		||||
                }
 | 
			
		||||
                _ => ErrorKind::IO(f),
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    impl From<&(dyn std::error::Error + 'static + Send + Sync)> for ErrorKind {
 | 
			
		||||
        fn from(e: &(dyn std::error::Error + 'static  + Send + Sync)) -> Self {
 | 
			
		||||
            if let Some(_) = e.downcast_ref::<io::Error>() {
 | 
			
		||||
                ErrorKind::IO(String::from("Unknown filename"))
 | 
			
		||||
            } else if let Some(_) = e.downcast_inner_ref::<Func2Error>() {
 | 
			
		||||
                ErrorKind::Func2
 | 
			
		||||
            } else {
 | 
			
		||||
                ErrorKind::Unknown
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    impl From<&std::boxed::Box<dyn std::error::Error + 'static  + Send + Sync>> for ErrorKind {
 | 
			
		||||
        fn from(e: &std::boxed::Box<dyn std::error::Error + 'static  + Send + Sync>) -> Self {
 | 
			
		||||
            Self::from(&**e)
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    impl From<&Func2Error> for ErrorKind {
 | 
			
		||||
        fn from(_: &Func2Error) -> Self {
 | 
			
		||||
            ErrorKind::Func2
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    impl From<&io::Error> for ErrorKind {
 | 
			
		||||
        fn from(e: &io::Error) -> Self {
 | 
			
		||||
            ErrorKind::IO(format!("{}", e))
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    pub fn func1() -> Result<()> {
 | 
			
		||||
        func2().map_err(|e| cherr!(e, ErrorKind::from(&e)))?;
 | 
			
		||||
 | 
			
		||||
        let filename = "bar.txt";
 | 
			
		||||
 | 
			
		||||
        do_some_io(filename)
 | 
			
		||||
            .map_err(|e| cherr!(e, ErrorKind::from_io_error(&e, filename.into())))?;
 | 
			
		||||
        do_some_io(filename).map_err(|e| cherr!(e, ErrorKind::IO(filename.into())))?;
 | 
			
		||||
        do_some_io(filename).map_err(|e| cherr!(e, ErrorKind::from(&e)))?;
 | 
			
		||||
        do_some_io(filename).map_err(minto_cherr!(ErrorKind))?;
 | 
			
		||||
 | 
			
		||||
        Ok(())
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    pub fn super_func1() -> Result<()> {
 | 
			
		||||
        func1().map_err(minto_cherr!(ErrorKind))?;
 | 
			
		||||
        Ok(())
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
fn main() -> Result<(), Box<std::error::Error + Send + Sync>> {
 | 
			
		||||
    use mycrate::super_func1;
 | 
			
		||||
    use mycrate::ErrorKind;
 | 
			
		||||
    use std::error::Error;
 | 
			
		||||
    use std::io;
 | 
			
		||||
 | 
			
		||||
    if let Err(e) = super_func1() {
 | 
			
		||||
        match e.kind() {
 | 
			
		||||
            ErrorKind::FatalError(f) => eprintln!("Main Error Report: Fatal Error: {}", f),
 | 
			
		||||
            ErrorKind::Unknown => eprintln!("Main Error Report: Unknown error occurred"),
 | 
			
		||||
            ErrorKind::Func2 => eprintln!("Main Error Report: func1 error calling func2"),
 | 
			
		||||
            ErrorKind::IO(ref filename) => {
 | 
			
		||||
                eprintln!("Main Error Report: func1 error reading '{}'", filename)
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        eprintln!();
 | 
			
		||||
        let mut s: &Error = &e;
 | 
			
		||||
        while let Some(c) = s.source() {
 | 
			
		||||
            if let Some(ioerror) = c.downcast_ref::<io::Error>() {
 | 
			
		||||
                eprintln!("caused by: std::io::Error: {}", ioerror);
 | 
			
		||||
                match ioerror.kind() {
 | 
			
		||||
                    io::ErrorKind::NotFound => eprintln!("of kind: std::io::ErrorKind::NotFound"),
 | 
			
		||||
                    _ => {}
 | 
			
		||||
                }
 | 
			
		||||
            } else {
 | 
			
		||||
                eprintln!("caused by: {}", c);
 | 
			
		||||
            }
 | 
			
		||||
            s = c;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        eprintln!("\nDebug Error:\n{:?}", e);
 | 
			
		||||
    }
 | 
			
		||||
    Ok(())
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										290
									
								
								src/lib.rs
									
										
									
									
									
								
							
							
						
						
									
										290
									
								
								src/lib.rs
									
										
									
									
									
								
							| 
						 | 
				
			
			@ -174,7 +174,6 @@
 | 
			
		|||
    keyword_idents,
 | 
			
		||||
    macro_use_extern_crate,
 | 
			
		||||
    missing_debug_implementations,
 | 
			
		||||
    missing_docs,
 | 
			
		||||
    trivial_numeric_casts,
 | 
			
		||||
    unused_extern_crates,
 | 
			
		||||
    unused_import_braces,
 | 
			
		||||
| 
						 | 
				
			
			@ -243,10 +242,10 @@ impl<T: 'static + Display + Debug> ChainError<T> {
 | 
			
		|||
    /// # Examples
 | 
			
		||||
    ///
 | 
			
		||||
    /// ```rust
 | 
			
		||||
    /// # use crate::chainerror::*;
 | 
			
		||||
    /// # use std::error::Error;
 | 
			
		||||
    /// # use std::io;
 | 
			
		||||
    /// # use std::result::Result;
 | 
			
		||||
    /// use chainerror::*;
 | 
			
		||||
    /// use std::error::Error;
 | 
			
		||||
    /// use std::io;
 | 
			
		||||
    ///
 | 
			
		||||
    /// fn do_some_io() -> Result<(), Box<Error + Send + Sync>> {
 | 
			
		||||
    ///     Err(io::Error::from(io::ErrorKind::NotFound))?;
 | 
			
		||||
    ///     Ok(())
 | 
			
		||||
| 
						 | 
				
			
			@ -296,7 +295,7 @@ impl<T: 'static + Display + Debug> ChainError<T> {
 | 
			
		|||
    /// # Examples
 | 
			
		||||
    ///
 | 
			
		||||
    /// ```rust
 | 
			
		||||
    /// # use chainerror::{ChainError, derive_str_cherr};
 | 
			
		||||
    /// # use chainerror::*;
 | 
			
		||||
    /// # derive_str_cherr!(FooError);
 | 
			
		||||
    /// # let err = ChainError::new(String::new(), None, None);
 | 
			
		||||
    /// // Instead of writing
 | 
			
		||||
| 
						 | 
				
			
			@ -319,7 +318,7 @@ impl<T: 'static + Display + Debug> ChainError<T> {
 | 
			
		|||
    /// # Examples
 | 
			
		||||
    ///
 | 
			
		||||
    /// ```rust
 | 
			
		||||
    /// # use chainerror::{ChainError, derive_str_cherr};
 | 
			
		||||
    /// # use chainerror::*;
 | 
			
		||||
    /// # derive_str_cherr!(FooErrorKind);
 | 
			
		||||
    /// # let err = ChainError::new(String::new(), None, None);
 | 
			
		||||
    /// // Instead of writing
 | 
			
		||||
| 
						 | 
				
			
			@ -348,10 +347,10 @@ impl<T: 'static + Display + Debug> ChainError<T> {
 | 
			
		|||
    /// # Examples
 | 
			
		||||
    ///
 | 
			
		||||
    /// ```rust
 | 
			
		||||
    /// # use crate::chainerror::*;
 | 
			
		||||
    /// # use std::error::Error;
 | 
			
		||||
    /// # use std::io;
 | 
			
		||||
    /// # use std::result::Result;
 | 
			
		||||
    /// use chainerror::*;
 | 
			
		||||
    /// use std::error::Error;
 | 
			
		||||
    /// use std::io;
 | 
			
		||||
    ///
 | 
			
		||||
    /// fn do_some_io() -> Result<(), Box<Error + Send + Sync>> {
 | 
			
		||||
    ///     Err(io::Error::from(io::ErrorKind::NotFound))?;
 | 
			
		||||
    ///     Ok(())
 | 
			
		||||
| 
						 | 
				
			
			@ -449,6 +448,10 @@ pub trait ChainErrorDown {
 | 
			
		|||
    fn downcast_chain_ref<T: 'static + Display + Debug>(&self) -> Option<&ChainError<T>>;
 | 
			
		||||
    /// Downcast to a mutable reference of `ChainError<T>`
 | 
			
		||||
    fn downcast_chain_mut<T: 'static + Display + Debug>(&mut self) -> Option<&mut ChainError<T>>;
 | 
			
		||||
    /// Downcast to T of `ChainError<T>`
 | 
			
		||||
    fn downcast_inner_ref<T: 'static + Error>(&self) -> Option<&T>;
 | 
			
		||||
    /// Downcast to T mutable reference of `ChainError<T>`
 | 
			
		||||
    fn downcast_inner_mut<T: 'static + Error>(&mut self) -> Option<&mut T>;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
impl<U: 'static + Display + Debug> ChainErrorDown for ChainError<U> {
 | 
			
		||||
| 
						 | 
				
			
			@ -482,6 +485,31 @@ impl<U: 'static + Display + Debug> ChainErrorDown for ChainError<U> {
 | 
			
		|||
            None
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
    #[inline]
 | 
			
		||||
    fn downcast_inner_ref<T: 'static + Error>(&self) -> Option<&T> {
 | 
			
		||||
        if self.is_chain::<T>() {
 | 
			
		||||
            #[allow(clippy::cast_ptr_alignment)]
 | 
			
		||||
            unsafe {
 | 
			
		||||
                #[allow(trivial_casts)]
 | 
			
		||||
                Some(&(*(self as *const dyn Error as *const &ChainError<T>)).kind)
 | 
			
		||||
            }
 | 
			
		||||
        } else {
 | 
			
		||||
            None
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    #[inline]
 | 
			
		||||
    fn downcast_inner_mut<T: 'static + Error>(&mut self) -> Option<&mut T> {
 | 
			
		||||
        if self.is_chain::<T>() {
 | 
			
		||||
            #[allow(clippy::cast_ptr_alignment)]
 | 
			
		||||
            unsafe {
 | 
			
		||||
                #[allow(trivial_casts)]
 | 
			
		||||
                Some(&mut (*(self as *mut dyn Error as *mut &mut ChainError<T>)).kind)
 | 
			
		||||
            }
 | 
			
		||||
        } else {
 | 
			
		||||
            None
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
impl ChainErrorDown for dyn Error + 'static {
 | 
			
		||||
| 
						 | 
				
			
			@ -499,6 +527,22 @@ impl ChainErrorDown for dyn Error + 'static {
 | 
			
		|||
    fn downcast_chain_mut<T: 'static + Display + Debug>(&mut self) -> Option<&mut ChainError<T>> {
 | 
			
		||||
        self.downcast_mut::<ChainError<T>>()
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    #[inline]
 | 
			
		||||
    fn downcast_inner_ref<T: 'static + Error>(&self) -> Option<&T> {
 | 
			
		||||
        self.downcast_ref::<T>()
 | 
			
		||||
            .or_else(|| self.downcast_ref::<ChainError<T>>().map(|e| e.kind()))
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    #[inline]
 | 
			
		||||
    fn downcast_inner_mut<T: 'static + Error>(&mut self) -> Option<&mut T> {
 | 
			
		||||
        if self.is::<T>() {
 | 
			
		||||
            return self.downcast_mut::<T>();
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        self.downcast_mut::<ChainError<T>>()
 | 
			
		||||
            .and_then(|e| e.downcast_inner_mut::<T>())
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
impl ChainErrorDown for dyn Error + 'static + Send {
 | 
			
		||||
| 
						 | 
				
			
			@ -516,6 +560,22 @@ impl ChainErrorDown for dyn Error + 'static + Send {
 | 
			
		|||
    fn downcast_chain_mut<T: 'static + Display + Debug>(&mut self) -> Option<&mut ChainError<T>> {
 | 
			
		||||
        self.downcast_mut::<ChainError<T>>()
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    #[inline]
 | 
			
		||||
    fn downcast_inner_ref<T: 'static + Error>(&self) -> Option<&T> {
 | 
			
		||||
        self.downcast_ref::<T>()
 | 
			
		||||
            .or_else(|| self.downcast_ref::<ChainError<T>>().map(|e| e.kind()))
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    #[inline]
 | 
			
		||||
    fn downcast_inner_mut<T: 'static + Error>(&mut self) -> Option<&mut T> {
 | 
			
		||||
        if self.is::<T>() {
 | 
			
		||||
            return self.downcast_mut::<T>();
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        self.downcast_mut::<ChainError<T>>()
 | 
			
		||||
            .and_then(|e| e.downcast_inner_mut::<T>())
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
impl ChainErrorDown for dyn Error + 'static + Send + Sync {
 | 
			
		||||
| 
						 | 
				
			
			@ -533,26 +593,48 @@ impl ChainErrorDown for dyn Error + 'static + Send + Sync {
 | 
			
		|||
    fn downcast_chain_mut<T: 'static + Display + Debug>(&mut self) -> Option<&mut ChainError<T>> {
 | 
			
		||||
        self.downcast_mut::<ChainError<T>>()
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    #[inline]
 | 
			
		||||
    fn downcast_inner_ref<T: 'static + Error>(&self) -> Option<&T> {
 | 
			
		||||
        self.downcast_ref::<T>()
 | 
			
		||||
            .or_else(|| self.downcast_ref::<ChainError<T>>().map(|e| e.kind()))
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    #[inline]
 | 
			
		||||
    fn downcast_inner_mut<T: 'static + Error>(&mut self) -> Option<&mut T> {
 | 
			
		||||
        if self.is::<T>() {
 | 
			
		||||
            return self.downcast_mut::<T>();
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        self.downcast_mut::<ChainError<T>>()
 | 
			
		||||
            .and_then(|e| e.downcast_inner_mut::<T>())
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
impl<T: 'static + Display + Debug> Error for ChainError<T> {
 | 
			
		||||
    #[inline]
 | 
			
		||||
    fn source(&self) -> Option<&(dyn Error + 'static)> {
 | 
			
		||||
        self.error_cause.as_ref().map(|e| e.as_ref() as &(dyn Error + 'static))
 | 
			
		||||
        self.error_cause
 | 
			
		||||
            .as_ref()
 | 
			
		||||
            .map(|e| e.as_ref() as &(dyn Error + 'static))
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
impl<T: 'static + Display + Debug> Error for &ChainError<T> {
 | 
			
		||||
    #[inline]
 | 
			
		||||
    fn source(&self) -> Option<&(dyn Error + 'static)> {
 | 
			
		||||
        self.error_cause.as_ref().map(|e| e.as_ref() as &(dyn Error + 'static))
 | 
			
		||||
        self.error_cause
 | 
			
		||||
            .as_ref()
 | 
			
		||||
            .map(|e| e.as_ref() as &(dyn Error + 'static))
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
impl<T: 'static + Display + Debug> Error for &mut ChainError<T> {
 | 
			
		||||
    #[inline]
 | 
			
		||||
    fn source(&self) -> Option<&(dyn Error + 'static)> {
 | 
			
		||||
        self.error_cause.as_ref().map(|e| e.as_ref() as &(dyn Error + 'static))
 | 
			
		||||
        self.error_cause
 | 
			
		||||
            .as_ref()
 | 
			
		||||
            .map(|e| e.as_ref() as &(dyn Error + 'static))
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -629,28 +711,34 @@ where
 | 
			
		|||
    #[inline]
 | 
			
		||||
    fn chain_error_from(t: T, line_filename: Option<&'static str>) -> ChainError<Self> {
 | 
			
		||||
        let e: U = t.into();
 | 
			
		||||
        ChainError::<_>::new(e, None, line_filename)
 | 
			
		||||
        ChainError::new(e, None, line_filename)
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/// map into `ChainError<T>` with `IntoChainError`
 | 
			
		||||
/*
 | 
			
		||||
impl<T, U> ChainErrorFrom<T> for U
 | 
			
		||||
    where
 | 
			
		||||
        T: 'static + Error + Into<Box<T>> + Clone,
 | 
			
		||||
        U: 'static + Display + Debug + From<T>,
 | 
			
		||||
{
 | 
			
		||||
    #[inline]
 | 
			
		||||
    fn chain_error_from(t: T, line_filename: Option<&'static str>) -> ChainError<Self> {
 | 
			
		||||
        ChainError::new(U::from(t.clone()), Some(Box::from(t)), line_filename)
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
*/
 | 
			
		||||
 | 
			
		||||
/// map into `ChainError<T>` with `T::from(err)`
 | 
			
		||||
///
 | 
			
		||||
/// adds `line!()` and `file!()` information
 | 
			
		||||
#[macro_export]
 | 
			
		||||
macro_rules! minto_cherr {
 | 
			
		||||
    ( ) => {
 | 
			
		||||
        |e| ChainErrorFrom::chain_error_from(e, Some(concat!(file!(), ":", line!(), ": ")))
 | 
			
		||||
    };
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/// into `ChainError<T>` with `IntoChainError`
 | 
			
		||||
///
 | 
			
		||||
/// adds `line!()` and `file!()` information
 | 
			
		||||
#[macro_export]
 | 
			
		||||
macro_rules! into_cherr {
 | 
			
		||||
    ( $t:expr ) => {
 | 
			
		||||
        ChainErrorFrom::chain_error_from($t, Some(concat!(file!(), ":", line!(), ": ")))
 | 
			
		||||
    };
 | 
			
		||||
    ( $k:ident ) => (
 | 
			
		||||
        |e| $crate::cherr!(e, $k::from(&e))
 | 
			
		||||
    );
 | 
			
		||||
    ( $enum:ident $(:: $enum_path:ident)* ) => (
 | 
			
		||||
        |e| $crate::cherr!(e, $enum $(:: $enum_path)*::from(&e))
 | 
			
		||||
    );
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/// Creates a new `ChainError<T>`
 | 
			
		||||
| 
						 | 
				
			
			@ -734,32 +822,23 @@ macro_rules! into_cherr {
 | 
			
		|||
#[macro_export]
 | 
			
		||||
macro_rules! cherr {
 | 
			
		||||
    ( $k:expr ) => ({
 | 
			
		||||
        ChainError::new($k, None, Some(concat!(file!(), ":", line!(), ": ")))
 | 
			
		||||
        $crate::ChainError::new($k, None, Some(concat!(file!(), ":", line!(), ": ")))
 | 
			
		||||
    });
 | 
			
		||||
    ( None, $k:expr ) => ({
 | 
			
		||||
        ChainError::new($k, None, Some(concat!(file!(), ":", line!(), ": ")))
 | 
			
		||||
        $crate::ChainError::new($k, None, Some(concat!(file!(), ":", line!(), ": ")))
 | 
			
		||||
    });
 | 
			
		||||
    ( None, $fmt:expr, $($arg:tt)+ ) => ({
 | 
			
		||||
        cherr!(None, format!($fmt, $($arg)+ ))
 | 
			
		||||
        $crate::cherr!(None, format!($fmt, $($arg)+ ))
 | 
			
		||||
    });
 | 
			
		||||
    ( None, $fmt:expr, $($arg:tt)+ ) => ({
 | 
			
		||||
        cherr!(None, format!($fmt, $($arg)+ ))
 | 
			
		||||
        $crate::cherr!(None, format!($fmt, $($arg)+ ))
 | 
			
		||||
    });
 | 
			
		||||
    ( $e:path, $k:expr ) => ({
 | 
			
		||||
        ChainError::new($k, Some(Box::from($e)), Some(concat!(file!(), ":", line!(), ": ")))
 | 
			
		||||
        $crate::ChainError::new($k, Some(Box::from($e)), Some(concat!(file!(), ":", line!(), ": ")))
 | 
			
		||||
    });
 | 
			
		||||
    ( $e:path, $fmt:expr, $($arg:tt)+ ) => ({
 | 
			
		||||
        cherr!($e, format!($fmt, $($arg)+ ))
 | 
			
		||||
        $crate::cherr!($e, format!($fmt, $($arg)+ ))
 | 
			
		||||
    });
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/// shortcut for |e| cherr!(e, $k)
 | 
			
		||||
#[macro_export]
 | 
			
		||||
macro_rules! mcherr {
 | 
			
		||||
    ( $k:expr ) => {{
 | 
			
		||||
        |e| cherr!(e, $k)
 | 
			
		||||
    }};
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/// Convenience macro for `|e| cherr!(e, format!(…))`
 | 
			
		||||
| 
						 | 
				
			
			@ -846,22 +925,22 @@ macro_rules! mcherr {
 | 
			
		|||
#[macro_export]
 | 
			
		||||
macro_rules! mstrerr {
 | 
			
		||||
    ( $t:path, $msg:expr ) => ({
 | 
			
		||||
        |e| cherr!(e, $t ($msg.to_string()))
 | 
			
		||||
        |e| $crate::cherr!(e, $t ($msg.to_string()))
 | 
			
		||||
    });
 | 
			
		||||
    ( $t:path, $msg:expr, ) => ({
 | 
			
		||||
        |e| cherr!(e, $t ($msg.to_string()))
 | 
			
		||||
        |e| $crate::cherr!(e, $t ($msg.to_string()))
 | 
			
		||||
    });
 | 
			
		||||
    ( $t:path, $fmt:expr, $($arg:tt)+ ) => ({
 | 
			
		||||
        |e| cherr!(e, $t (format!($fmt, $($arg)+ )))
 | 
			
		||||
        |e| $crate::cherr!(e, $t (format!($fmt, $($arg)+ )))
 | 
			
		||||
    });
 | 
			
		||||
    ($msg:expr) => ({
 | 
			
		||||
        |e| cherr!(e, $msg.to_string())
 | 
			
		||||
        |e| $crate::cherr!(e, $msg.to_string())
 | 
			
		||||
    });
 | 
			
		||||
    ($msg:expr, ) => ({
 | 
			
		||||
        |e| cherr!(e, $msg.to_string())
 | 
			
		||||
        |e| $crate::cherr!(e, $msg.to_string())
 | 
			
		||||
    });
 | 
			
		||||
    ($fmt:expr, $($arg:tt)+) => ({
 | 
			
		||||
        |e| cherr!(e, format!($fmt, $($arg)+ ))
 | 
			
		||||
        |e| $crate::cherr!(e, format!($fmt, $($arg)+ ))
 | 
			
		||||
    });
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -882,7 +961,7 @@ macro_rules! mstrerr {
 | 
			
		|||
///
 | 
			
		||||
/// derive_str_cherr!(Func1Error);
 | 
			
		||||
///
 | 
			
		||||
/// fn func1() -> Result<(), Box<Error + Send + Sync>> {
 | 
			
		||||
/// fn func1() -> Result<(), Box<Error>> {
 | 
			
		||||
///     func2().map_err(mstrerr!(Func1Error, "func1 error"))?;
 | 
			
		||||
///     Ok(())
 | 
			
		||||
/// }
 | 
			
		||||
| 
						 | 
				
			
			@ -902,22 +981,22 @@ macro_rules! mstrerr {
 | 
			
		|||
#[macro_export]
 | 
			
		||||
macro_rules! strerr {
 | 
			
		||||
    ( $t:path, $msg:expr ) => ({
 | 
			
		||||
        cherr!($t ($msg.to_string()))
 | 
			
		||||
        $crate::cherr!($t ($msg.to_string()))
 | 
			
		||||
    });
 | 
			
		||||
    ( $t:path, $msg:expr, ) => ({
 | 
			
		||||
        cherr!($t ($msg.to_string()))
 | 
			
		||||
        $crate::cherr!($t ($msg.to_string()))
 | 
			
		||||
    });
 | 
			
		||||
    ( $t:path, $fmt:expr, $($arg:tt)+ ) => ({
 | 
			
		||||
        cherr!($t (format!($fmt, $($arg)+ )))
 | 
			
		||||
        $crate::cherr!($t (format!($fmt, $($arg)+ )))
 | 
			
		||||
    });
 | 
			
		||||
    ($msg:expr) => ({
 | 
			
		||||
        cherr!($msg.to_string())
 | 
			
		||||
        $crate::cherr!($msg.to_string())
 | 
			
		||||
    });
 | 
			
		||||
    ($msg:expr, ) => ({
 | 
			
		||||
        cherr!($msg.to_string())
 | 
			
		||||
        $crate::cherr!($msg.to_string())
 | 
			
		||||
    });
 | 
			
		||||
    ($fmt:expr, $($arg:tt)+) => ({
 | 
			
		||||
        cherr!(format!($fmt, $($arg)+ ))
 | 
			
		||||
        $crate::cherr!(format!($fmt, $($arg)+ ))
 | 
			
		||||
    });
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -944,7 +1023,7 @@ macro_rules! strerr {
 | 
			
		|||
///
 | 
			
		||||
/// derive_str_cherr!(Func1Error);
 | 
			
		||||
///
 | 
			
		||||
/// fn func1() -> Result<(), Box<Error + Send + Sync>> {
 | 
			
		||||
/// fn func1() -> Result<(), Box<Error>> {
 | 
			
		||||
///     func2().map_err(mstrerr!(Func1Error, "func1 error"))?;
 | 
			
		||||
///     Ok(())
 | 
			
		||||
/// }
 | 
			
		||||
| 
						 | 
				
			
			@ -980,13 +1059,76 @@ macro_rules! derive_str_cherr {
 | 
			
		|||
    };
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/// Derive an Error, which wraps ChainError and implements a kind() method
 | 
			
		||||
/// Derive an Error for an ErrorKind, which wraps a `ChainError` and implements a `kind()` method
 | 
			
		||||
///
 | 
			
		||||
/// e.kind() returns the kind
 | 
			
		||||
/// It basically hides `ChainError` to the outside and only exposes the `kind()`
 | 
			
		||||
/// method.
 | 
			
		||||
///
 | 
			
		||||
/// Error::kind() returns the ErrorKind
 | 
			
		||||
/// Error::source() returns the parent error
 | 
			
		||||
///
 | 
			
		||||
/// # Examples
 | 
			
		||||
///
 | 
			
		||||
/// ```rust
 | 
			
		||||
/// use std::io;
 | 
			
		||||
/// use chainerror::*;
 | 
			
		||||
///
 | 
			
		||||
/// fn do_some_io(_f: &str) -> std::result::Result<(), io::Error> {
 | 
			
		||||
///     return Err(io::Error::from(io::ErrorKind::NotFound));
 | 
			
		||||
/// }
 | 
			
		||||
///
 | 
			
		||||
/// #[derive(Debug, Clone)]
 | 
			
		||||
/// pub enum ErrorKind {
 | 
			
		||||
///     IO(String),
 | 
			
		||||
///     FatalError(String),
 | 
			
		||||
///     Unknown,
 | 
			
		||||
/// }
 | 
			
		||||
///
 | 
			
		||||
/// derive_err_kind!(Error, ErrorKind);
 | 
			
		||||
///
 | 
			
		||||
/// impl std::fmt::Display for ErrorKind {
 | 
			
		||||
///     fn fmt(&self, f: &mut ::std::fmt::Formatter) -> std::fmt::Result {
 | 
			
		||||
///         match self {
 | 
			
		||||
///             ErrorKind::FatalError(e) => write!(f, "fatal error {}", e),
 | 
			
		||||
///             ErrorKind::Unknown => write!(f, "unknown error"),
 | 
			
		||||
///             ErrorKind::IO(filename) => write!(f, "Error reading '{}'", filename),
 | 
			
		||||
///         }
 | 
			
		||||
///     }
 | 
			
		||||
/// }
 | 
			
		||||
///
 | 
			
		||||
/// impl ErrorKind {
 | 
			
		||||
///     fn from_io_error(e: &io::Error, f: String) -> Self {
 | 
			
		||||
///         match e.kind() {
 | 
			
		||||
///             io::ErrorKind::BrokenPipe => panic!("Should not happen"),
 | 
			
		||||
///             io::ErrorKind::ConnectionReset => {
 | 
			
		||||
///                 ErrorKind::FatalError(format!("While reading `{}`: {}", f, e))
 | 
			
		||||
///             }
 | 
			
		||||
///             _ => ErrorKind::IO(f),
 | 
			
		||||
///         }
 | 
			
		||||
///     }
 | 
			
		||||
/// }
 | 
			
		||||
///
 | 
			
		||||
/// impl From<&io::Error> for ErrorKind {
 | 
			
		||||
///     fn from(e: &io::Error) -> Self {
 | 
			
		||||
///         ErrorKind::IO(format!("{}", e))
 | 
			
		||||
///     }
 | 
			
		||||
/// }
 | 
			
		||||
///
 | 
			
		||||
/// pub fn func1() -> std::result::Result<(), Error> {
 | 
			
		||||
///     let filename = "bar.txt";
 | 
			
		||||
///
 | 
			
		||||
///     do_some_io(filename)
 | 
			
		||||
///         .map_err(|e| cherr!(e, ErrorKind::from_io_error(&e, filename.into())))?;
 | 
			
		||||
///     do_some_io(filename).map_err(|e| cherr!(e, ErrorKind::IO(filename.into())))?;
 | 
			
		||||
///     do_some_io(filename).map_err(|e| cherr!(e, ErrorKind::from(&e)))?;
 | 
			
		||||
///     do_some_io(filename).map_err(minto_cherr!(ErrorKind))?;
 | 
			
		||||
///     Ok(())
 | 
			
		||||
/// }
 | 
			
		||||
/// ```
 | 
			
		||||
#[macro_export]
 | 
			
		||||
macro_rules! derive_err_kind {
 | 
			
		||||
    ($e:ident, $k:ident) => {
 | 
			
		||||
        pub struct $e(ChainError<$k>);
 | 
			
		||||
        pub struct $e($crate::ChainError<$k>);
 | 
			
		||||
 | 
			
		||||
        impl $e {
 | 
			
		||||
            pub fn kind(&self) -> &$k {
 | 
			
		||||
| 
						 | 
				
			
			@ -996,16 +1138,38 @@ macro_rules! derive_err_kind {
 | 
			
		|||
 | 
			
		||||
        impl From<$k> for $e {
 | 
			
		||||
            fn from(e: $k) -> Self {
 | 
			
		||||
                $e(ChainError::new(e, None, None))
 | 
			
		||||
                $e($crate::ChainError::new(e, None, None))
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        impl From<ChainError<$k>> for $e {
 | 
			
		||||
            fn from(e: ChainError<$k>) -> Self {
 | 
			
		||||
            fn from(e: $crate::ChainError<$k>) -> Self {
 | 
			
		||||
                $e(e)
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        impl From<&$e> for $k
 | 
			
		||||
        where
 | 
			
		||||
            $k: Clone,
 | 
			
		||||
        {
 | 
			
		||||
            fn from(e: &$e) -> Self {
 | 
			
		||||
                e.kind().clone()
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        impl $crate::ChainErrorFrom<$e> for $k
 | 
			
		||||
        where
 | 
			
		||||
            $k: Clone,
 | 
			
		||||
        {
 | 
			
		||||
            #[inline]
 | 
			
		||||
            fn chain_error_from(
 | 
			
		||||
                t: $e,
 | 
			
		||||
                line_filename: Option<&'static str>,
 | 
			
		||||
            ) -> $crate::ChainError<$k> {
 | 
			
		||||
                $crate::ChainError::new((*t.kind()).clone(), Some(Box::from(t)), line_filename)
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        impl std::error::Error for $e {
 | 
			
		||||
            fn source(&self) -> Option<&(dyn std::error::Error + 'static)> {
 | 
			
		||||
                self.0.source()
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue