assemble_core/
exception.rs

1//! Build time exceptions
2
3use crate::error::PayloadError;
4
5use std::error::Error;
6use std::fmt::{Debug, Display, Formatter};
7use crate::identifier::InvalidId;
8use crate::lazy_evaluation::ProviderError;
9use crate::{lazy_evaluation, payload_from};
10use crate::prelude::ProjectError;
11
12pub enum BuildException {
13    StopAction,
14    StopTask,
15    Error(Box<dyn Display + Send + Sync>),
16}
17
18impl BuildException {
19    pub fn new<E: 'static + Display + Send + Sync>(e: E) -> Self {
20        let boxed: Box<dyn Display + Send + Sync> = Box::new(e);
21        BuildException::Error(boxed)
22    }
23
24    pub fn custom(e: &str) -> Self {
25        let boxed: Box<dyn Display + Send + Sync> = Box::new(e.to_string());
26        BuildException::Error(boxed)
27    }
28}
29
30impl<E: 'static + Error + Send + Sync> From<E> for BuildException {
31    fn from(e: E) -> Self {
32        Self::new(e)
33    }
34}
35
36impl Debug for BuildException {
37    fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
38        match self {
39            BuildException::StopAction => f.debug_struct("StopAction").finish(),
40            BuildException::StopTask => f.debug_struct("StopTask").finish(),
41            BuildException::Error(e) => f
42                .debug_struct("Error")
43                .field("inner", &e.to_string())
44                .finish(),
45        }
46    }
47}
48
49impl Display for BuildException {
50    fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
51        match self {
52            BuildException::StopAction => f.debug_struct("StopAction").finish(),
53            BuildException::StopTask => f.debug_struct("StopTask").finish(),
54            BuildException::Error(e) => write!(f, "{}", e),
55        }
56    }
57}
58//
59// impl<T> From<T> for PayloadError<BuildException>
60// where
61//     T: Into<BuildException>,
62// {
63//     fn from(err: T) -> Self {
64//         PayloadError::new(err.into())
65//     }
66// }
67
68pub type BuildResult<T = ()> = Result<T, PayloadError<BuildException>>;
69
70
71macro_rules! build_exception_from {
72    ($($ty:ty),* $(,)?) => {
73        $(
74          payload_from!($ty, BuildException);
75        )*
76    };
77}
78
79build_exception_from!(
80    ProviderError,
81    ProjectError,
82    std::io::Error,
83    std::fmt::Error,
84    InvalidId,
85    BuildError,
86    lazy_evaluation::Error,
87);
88
89/// Represents any error
90#[derive(Debug)]
91pub struct BuildError {
92    message: String,
93    inner: Option<Box<dyn Error + Send + Sync>>,
94}
95
96impl BuildError {
97    /// Create a new, arbitrary build error
98    pub fn new(message: impl AsRef<str>) -> Self {
99        Self {
100            message: message.as_ref().to_string(),
101            inner: None,
102        }
103    }
104
105    /// Create a new, arbitrary build error
106    pub fn with_inner<S: AsRef<str>, E: Error + Send + Sync + 'static>(
107        message: S,
108        error: E,
109    ) -> Self {
110        Self {
111            message: message.as_ref().to_string(),
112            inner: Some(Box::new(error)),
113        }
114    }
115}
116
117impl Display for BuildError {
118    fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
119        match &self.inner {
120            None => {
121                write!(f, "{}", self.message)
122            }
123            Some(e) => {
124                write!(f, "{} (inner = {})", self.message, e)
125            }
126        }
127    }
128}
129
130impl Error for BuildError {}