You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

120 lines
3.0KB

  1. extern crate image;
  2. extern crate syntect;
  3. extern crate tera;
  4. extern crate toml;
  5. use std::convert::Into;
  6. use std::error::Error as StdError;
  7. use std::fmt;
  8. #[derive(Debug)]
  9. pub enum ErrorKind {
  10. Msg(String),
  11. Tera(tera::Error),
  12. Io(::std::io::Error),
  13. Toml(toml::de::Error),
  14. Image(image::ImageError),
  15. Syntect(syntect::LoadingError),
  16. }
  17. /// The Error type
  18. #[derive(Debug)]
  19. pub struct Error {
  20. /// Kind of error
  21. pub kind: ErrorKind,
  22. pub source: Option<Box<dyn StdError>>,
  23. }
  24. unsafe impl Sync for Error {}
  25. unsafe impl Send for Error {}
  26. impl StdError for Error {
  27. fn source(&self) -> Option<&(dyn StdError + 'static)> {
  28. let mut source = self.source.as_ref().map(|c| &**c);
  29. if source.is_none() {
  30. match self.kind {
  31. ErrorKind::Tera(ref err) => {
  32. source = err.source()
  33. },
  34. _ => ()
  35. };
  36. }
  37. source
  38. }
  39. }
  40. impl fmt::Display for Error {
  41. fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
  42. match self.kind {
  43. ErrorKind::Msg(ref message) => write!(f, "{}", message),
  44. ErrorKind::Tera(ref e) => write!(f, "{}", e),
  45. ErrorKind::Io(ref e) => write!(f, "{}", e),
  46. ErrorKind::Toml(ref e) => write!(f, "{}", e),
  47. ErrorKind::Image(ref e) => write!(f, "{}", e),
  48. ErrorKind::Syntect(ref e) => write!(f, "{}", e),
  49. }
  50. }
  51. }
  52. impl Error {
  53. /// Creates generic error
  54. pub fn msg(value: impl ToString) -> Self {
  55. Self { kind: ErrorKind::Msg(value.to_string()), source: None }
  56. }
  57. /// Creates generic error with a cause
  58. pub fn chain(value: impl ToString, source: impl Into<Box<dyn StdError>>) -> Self {
  59. Self { kind: ErrorKind::Msg(value.to_string()), source: Some(source.into()) }
  60. }
  61. }
  62. impl From<&str> for Error {
  63. fn from(e: &str) -> Self {
  64. Self::msg(e)
  65. }
  66. }
  67. impl From<String> for Error {
  68. fn from(e: String) -> Self {
  69. Self::msg(e)
  70. }
  71. }
  72. impl From<toml::de::Error> for Error {
  73. fn from(e: toml::de::Error) -> Self {
  74. Self { kind: ErrorKind::Toml(e), source: None }
  75. }
  76. }
  77. impl From<syntect::LoadingError> for Error {
  78. fn from(e: syntect::LoadingError) -> Self {
  79. Self { kind: ErrorKind::Syntect(e), source: None }
  80. }
  81. }
  82. impl From<tera::Error> for Error {
  83. fn from(e: tera::Error) -> Self {
  84. Self { kind: ErrorKind::Tera(e), source: None }
  85. }
  86. }
  87. impl From<::std::io::Error> for Error {
  88. fn from(e: ::std::io::Error) -> Self {
  89. Self { kind: ErrorKind::Io(e), source: None }
  90. }
  91. }
  92. impl From<image::ImageError> for Error {
  93. fn from(e: image::ImageError) -> Self {
  94. Self { kind: ErrorKind::Image(e), source: None }
  95. }
  96. }
  97. /// Convenient wrapper around std::Result.
  98. pub type Result<T> = ::std::result::Result<T, Error>;
  99. // So we can use bail! in all other crates
  100. #[macro_export]
  101. macro_rules! bail {
  102. ($e:expr) => {
  103. return Err($e.into());
  104. };
  105. ($fmt:expr, $($arg:tt)+) => {
  106. return Err(format!($fmt, $($arg)+).into());
  107. };
  108. }