1 // We can expose more detail on the error as the need arises, but start with an 2 // opaque error type for now. 3 4 use std::error::Error as StdError; 5 use std::fmt::{self, Debug, Display}; 6 use std::iter; 7 8 #[allow(missing_docs)] 9 pub struct Error { 10 pub(crate) err: crate::gen::Error, 11 } 12 13 impl Error { 14 /// Returns the span of the error, if available. span(&self) -> Option<proc_macro2::Span>15 pub fn span(&self) -> Option<proc_macro2::Span> { 16 match &self.err { 17 crate::gen::Error::Syn(err) => Some(err.span()), 18 _ => None, 19 } 20 } 21 } 22 23 impl From<crate::gen::Error> for Error { from(err: crate::gen::Error) -> Self24 fn from(err: crate::gen::Error) -> Self { 25 Error { err } 26 } 27 } 28 29 impl Display for Error { fmt(&self, f: &mut fmt::Formatter) -> fmt::Result30 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { 31 Display::fmt(&self.err, f) 32 } 33 } 34 35 impl Debug for Error { fmt(&self, f: &mut fmt::Formatter) -> fmt::Result36 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { 37 Debug::fmt(&self.err, f) 38 } 39 } 40 41 impl StdError for Error { source(&self) -> Option<&(dyn StdError + 'static)>42 fn source(&self) -> Option<&(dyn StdError + 'static)> { 43 self.err.source() 44 } 45 } 46 47 impl IntoIterator for Error { 48 type Item = Error; 49 type IntoIter = IntoIter; 50 into_iter(self) -> Self::IntoIter51 fn into_iter(self) -> Self::IntoIter { 52 match self.err { 53 crate::gen::Error::Syn(err) => IntoIter::Syn(err.into_iter()), 54 _ => IntoIter::Other(iter::once(self)), 55 } 56 } 57 } 58 59 pub enum IntoIter { 60 Syn(<syn::Error as IntoIterator>::IntoIter), 61 Other(iter::Once<Error>), 62 } 63 64 impl Iterator for IntoIter { 65 type Item = Error; 66 next(&mut self) -> Option<Self::Item>67 fn next(&mut self) -> Option<Self::Item> { 68 match self { 69 IntoIter::Syn(iter) => iter 70 .next() 71 .map(|syn_err| Error::from(crate::gen::Error::Syn(syn_err))), 72 IntoIter::Other(iter) => iter.next(), 73 } 74 } 75 } 76