Guest User

Untitled

a guest
Dec 14th, 2018
94
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 4.21 KB | None | 0 0
  1. use std::error::Error;
  2.  
  3. trait ChainError {
  4. fn new(
  5. line: u32,
  6. filename: &'static str,
  7. description: String,
  8. error_cause: Box<dyn Error + 'static>,
  9. ) -> Self;
  10.  
  11. fn root_cause(&self) -> Option<&(dyn Error + 'static)>;
  12. fn find_cause<T: Error + 'static>(&self) -> Option<&(dyn Error + 'static)>;
  13. }
  14.  
  15. #[macro_export]
  16. macro_rules! chain_error {
  17. ( $t:ident, $v:expr $(, $more:expr)* ) => {
  18. |e| $t :: new(line!(), file!(), format!($v, $( $more )*), e.into())
  19. };
  20. }
  21.  
  22. #[macro_export]
  23. macro_rules! new_chain_error {
  24. ($e:ident) => {
  25. struct $e {
  26. line: u32,
  27. filename: &'static str,
  28. description: String,
  29. error_cause: Box<dyn Error + 'static>,
  30. }
  31.  
  32. impl ChainError for $e {
  33. fn new(
  34. line: u32,
  35. filename: &'static str,
  36. description: String,
  37. error_cause: Box<dyn Error + 'static>,
  38. ) -> Self {
  39. $e {
  40. line,
  41. filename,
  42. description,
  43. error_cause,
  44. }
  45. }
  46.  
  47. fn root_cause(&self) -> Option<&(dyn Error + 'static)> {
  48. let mut cause = self.error_cause.as_ref();
  49. while let Some(c) = cause.source() {
  50. cause = c;
  51. }
  52. Some(cause)
  53. }
  54.  
  55. fn find_cause<T: Error + 'static>(&self) -> Option<&(dyn Error + 'static)> {
  56. let mut cause = self as &(dyn Error + 'static);
  57. loop {
  58. if cause.is::<T>() {
  59. return Some(cause);
  60. }
  61.  
  62. match cause.source() {
  63. Some(c) => cause = c,
  64. None => return None,
  65. }
  66. }
  67. }
  68. }
  69.  
  70. impl Error for $e {
  71. fn description(&self) -> &str {
  72. &self.description
  73. }
  74.  
  75. fn source(&self) -> Option<&(dyn Error + 'static)> {
  76. Some(self.error_cause.as_ref())
  77. }
  78. }
  79.  
  80. impl ::std::fmt::Display for $e {
  81. fn fmt(&self, f: &mut ::std::fmt::Formatter) -> ::std::fmt::Result {
  82. writeln!(f, "{}", self.description)?;
  83. if let Some(e) = self.source() {
  84. writeln!(f, "\nCaused by:")?;
  85. ::std::fmt::Display::fmt(&e, f)?;
  86. }
  87. Ok(())
  88. }
  89. }
  90.  
  91. impl ::std::fmt::Debug for $e {
  92. fn fmt(&self, f: &mut ::std::fmt::Formatter) -> ::std::fmt::Result {
  93. writeln!(f, "{}:{}: {}", self.filename, self.line, self.description)?;
  94. if let Some(e) = self.source() {
  95. writeln!(f, "\nCaused by:")?;
  96. ::std::fmt::Debug::fmt(&e, f)?;
  97. }
  98. Ok(())
  99. }
  100. }
  101. };
  102. }
  103.  
  104. //////////////////////////////////////////////////////////
  105.  
  106. new_chain_error!(MyError);
  107. new_chain_error!(MyMainError);
  108.  
  109. fn throw_error() -> Result<(), MyError> {
  110. let directory = String::from("ldfhgdfkgjdf");
  111. ::std::fs::remove_dir(&directory).map_err(chain_error!(
  112. MyError,
  113. "Could not remove directory '{}'!",
  114. &directory
  115. ))?;
  116. Ok(())
  117. }
  118.  
  119. fn main() -> Result<(), Box<Error>> {
  120. let res = throw_error().map_err(chain_error!(MyMainError, "I has an error."));
  121.  
  122. if let Err(ref my_err) = res {
  123. if let Some(source) = my_err.source() {
  124. assert!(source.is::<MyError>());
  125. }
  126. println!("\nRoot cause is {:#?}\n", my_err.root_cause());
  127.  
  128. assert!(my_err.root_cause().unwrap().is::<::std::io::Error>());
  129. assert!(my_err.find_cause::<::std::io::Error>().is_some());
  130.  
  131. if my_err.find_cause::<::std::io::Error>().is_some() {
  132. println!("Has cause io::Error");
  133. }
  134. if my_err.find_cause::<MyError>().is_some() {
  135. println!("Has cause MyError");
  136. }
  137.  
  138. println!("-----------");
  139. println!("Display Error:\n{}", my_err);
  140. println!("-----------");
  141. println!("Debug Error: \n{:#?}", my_err);
  142. println!("-----------");
  143. };
  144. res?;
  145. Ok(())
  146. }
Add Comment
Please, Sign In to add comment