1use syn::Error;
2
3#[derive(Default)]
5pub struct OptionalError(Option<Error>);
6
7impl OptionalError {
8 pub fn new(error: Error) -> Self {
10 Self(Some(error))
11 }
12
13 pub fn error(&self) -> Option<&Error> {
15 self.0.as_ref()
16 }
17
18 pub fn error_mut(&mut self) -> Option<&mut Error> {
20 self.0.as_mut()
21 }
22
23 pub fn take(&mut self) -> Option<Error> {
25 self.0.take()
26 }
27
28 pub fn replace(&mut self, error: Error) -> Option<Error> {
32 self.0.replace(error)
33 }
34
35 pub fn combine(&mut self, error: Error) {
38 match self.0 {
39 None => self.0 = Some(error),
40 Some(ref mut prev) => prev.combine(error),
41 }
42 }
43
44 pub fn try_throw(self) -> Result<(), Error> {
48 match self.0 {
49 None => Ok(()),
50 Some(err) => Err(err),
51 }
52 }
53}
54
55#[cfg(test)]
56mod tests {
57 use syn::__private::Span;
58 use super::*;
59
60 #[test]
61 fn should_combine() {
62 let mut collector = OptionalError::new(Error::new(Span::call_site(), "First Error"));
63 collector.combine(Error::new(Span::call_site(), "Second Error"));
64
65 let expected = r#"compile_error ! { "First Error" } compile_error ! { "Second Error" }"#;
66 let received = collector.try_throw().expect_err("expected error").to_compile_error().to_string();
67 assert_eq!(expected, received);
68 }
69
70 #[test]
71 fn should_replace() {
72 let mut collector = OptionalError::new(Error::new(Span::call_site(), "First Error"));
73 let existing = collector.replace(Error::new(Span::call_site(), "Second Error"));
74
75 let expected = r#"compile_error ! { "First Error" }"#;
76 let received = existing.expect("expected error").to_compile_error().to_string();
77 assert_eq!(expected, received);
78
79 let expected = r#"compile_error ! { "Second Error" }"#;
80 let received = collector.try_throw().expect_err("expected error").to_compile_error().to_string();
81 assert_eq!(expected, received);
82 }
83
84 #[test]
85 fn should_take() {
86 let mut collector = OptionalError::new(Error::new(Span::call_site(), "First Error"));
87 let existing = collector.take();
88
89 let expected = r#"compile_error ! { "First Error" }"#;
90 let received = existing.expect("expected error").to_compile_error().to_string();
91 assert_eq!(expected, received);
92 assert!(collector.try_throw().is_ok());
93 }
94}