1 use core::fmt::{self, Debug, Display}; 2 3 use std::error::Error as StdError; 4 5 use crate::{Diagnostic, LabeledSpan, Report, SourceCode}; 6 7 use crate as miette; 8 9 #[repr(transparent)] 10 pub(crate) struct DisplayError<M>(pub(crate) M); 11 12 #[repr(transparent)] 13 pub(crate) struct MessageError<M>(pub(crate) M); 14 15 pub(crate) struct NoneError; 16 17 impl<M> Debug for DisplayError<M> 18 where 19 M: Display, 20 { fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result21 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { 22 Display::fmt(&self.0, f) 23 } 24 } 25 26 impl<M> Display for DisplayError<M> 27 where 28 M: Display, 29 { fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result30 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { 31 Display::fmt(&self.0, f) 32 } 33 } 34 35 impl<M> StdError for DisplayError<M> where M: Display + 'static {} 36 impl<M> Diagnostic for DisplayError<M> where M: Display + 'static {} 37 38 impl<M> Debug for MessageError<M> 39 where 40 M: Display + Debug, 41 { fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result42 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { 43 Debug::fmt(&self.0, f) 44 } 45 } 46 47 impl<M> Display for MessageError<M> 48 where 49 M: Display + Debug, 50 { fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result51 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { 52 Display::fmt(&self.0, f) 53 } 54 } 55 56 impl<M> StdError for MessageError<M> where M: Display + Debug + 'static {} 57 impl<M> Diagnostic for MessageError<M> where M: Display + Debug + 'static {} 58 59 impl Debug for NoneError { fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result60 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { 61 Debug::fmt("Option was None", f) 62 } 63 } 64 65 impl Display for NoneError { fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result66 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { 67 Display::fmt("Option was None", f) 68 } 69 } 70 71 impl StdError for NoneError {} 72 impl Diagnostic for NoneError {} 73 74 #[repr(transparent)] 75 pub(crate) struct BoxedError(pub(crate) Box<dyn Diagnostic + Send + Sync>); 76 77 impl Diagnostic for BoxedError { code<'a>(&'a self) -> Option<Box<dyn Display + 'a>>78 fn code<'a>(&'a self) -> Option<Box<dyn Display + 'a>> { 79 self.0.code() 80 } 81 severity(&self) -> Option<miette::Severity>82 fn severity(&self) -> Option<miette::Severity> { 83 self.0.severity() 84 } 85 help<'a>(&'a self) -> Option<Box<dyn Display + 'a>>86 fn help<'a>(&'a self) -> Option<Box<dyn Display + 'a>> { 87 self.0.help() 88 } 89 url<'a>(&'a self) -> Option<Box<dyn Display + 'a>>90 fn url<'a>(&'a self) -> Option<Box<dyn Display + 'a>> { 91 self.0.url() 92 } 93 labels<'a>(&'a self) -> Option<Box<dyn Iterator<Item = LabeledSpan> + 'a>>94 fn labels<'a>(&'a self) -> Option<Box<dyn Iterator<Item = LabeledSpan> + 'a>> { 95 self.0.labels() 96 } 97 source_code(&self) -> Option<&dyn miette::SourceCode>98 fn source_code(&self) -> Option<&dyn miette::SourceCode> { 99 self.0.source_code() 100 } 101 related<'a>(&'a self) -> Option<Box<dyn Iterator<Item = &'a dyn Diagnostic> + 'a>>102 fn related<'a>(&'a self) -> Option<Box<dyn Iterator<Item = &'a dyn Diagnostic> + 'a>> { 103 self.0.related() 104 } 105 diagnostic_source(&self) -> Option<&dyn Diagnostic>106 fn diagnostic_source(&self) -> Option<&dyn Diagnostic> { 107 self.0.diagnostic_source() 108 } 109 } 110 111 impl Debug for BoxedError { fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result112 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { 113 Debug::fmt(&self.0, f) 114 } 115 } 116 117 impl Display for BoxedError { fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result118 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { 119 Display::fmt(&self.0, f) 120 } 121 } 122 123 impl StdError for BoxedError { source(&self) -> Option<&(dyn StdError + 'static)>124 fn source(&self) -> Option<&(dyn StdError + 'static)> { 125 self.0.source() 126 } 127 description(&self) -> &str128 fn description(&self) -> &str { 129 #[allow(deprecated)] 130 self.0.description() 131 } 132 cause(&self) -> Option<&dyn StdError>133 fn cause(&self) -> Option<&dyn StdError> { 134 #[allow(deprecated)] 135 self.0.cause() 136 } 137 } 138 139 pub(crate) struct WithSourceCode<E, C> { 140 pub(crate) error: E, 141 pub(crate) source_code: C, 142 } 143 144 impl<E: Diagnostic, C: SourceCode> Diagnostic for WithSourceCode<E, C> { code<'a>(&'a self) -> Option<Box<dyn Display + 'a>>145 fn code<'a>(&'a self) -> Option<Box<dyn Display + 'a>> { 146 self.error.code() 147 } 148 severity(&self) -> Option<miette::Severity>149 fn severity(&self) -> Option<miette::Severity> { 150 self.error.severity() 151 } 152 help<'a>(&'a self) -> Option<Box<dyn Display + 'a>>153 fn help<'a>(&'a self) -> Option<Box<dyn Display + 'a>> { 154 self.error.help() 155 } 156 url<'a>(&'a self) -> Option<Box<dyn Display + 'a>>157 fn url<'a>(&'a self) -> Option<Box<dyn Display + 'a>> { 158 self.error.url() 159 } 160 labels<'a>(&'a self) -> Option<Box<dyn Iterator<Item = LabeledSpan> + 'a>>161 fn labels<'a>(&'a self) -> Option<Box<dyn Iterator<Item = LabeledSpan> + 'a>> { 162 self.error.labels() 163 } 164 source_code(&self) -> Option<&dyn miette::SourceCode>165 fn source_code(&self) -> Option<&dyn miette::SourceCode> { 166 Some(&self.source_code) 167 } 168 related<'a>(&'a self) -> Option<Box<dyn Iterator<Item = &'a dyn Diagnostic> + 'a>>169 fn related<'a>(&'a self) -> Option<Box<dyn Iterator<Item = &'a dyn Diagnostic> + 'a>> { 170 self.error.related() 171 } 172 diagnostic_source(&self) -> Option<&dyn Diagnostic>173 fn diagnostic_source(&self) -> Option<&dyn Diagnostic> { 174 self.error.diagnostic_source() 175 } 176 } 177 178 impl<C: SourceCode> Diagnostic for WithSourceCode<Report, C> { code<'a>(&'a self) -> Option<Box<dyn Display + 'a>>179 fn code<'a>(&'a self) -> Option<Box<dyn Display + 'a>> { 180 self.error.code() 181 } 182 severity(&self) -> Option<miette::Severity>183 fn severity(&self) -> Option<miette::Severity> { 184 self.error.severity() 185 } 186 help<'a>(&'a self) -> Option<Box<dyn Display + 'a>>187 fn help<'a>(&'a self) -> Option<Box<dyn Display + 'a>> { 188 self.error.help() 189 } 190 url<'a>(&'a self) -> Option<Box<dyn Display + 'a>>191 fn url<'a>(&'a self) -> Option<Box<dyn Display + 'a>> { 192 self.error.url() 193 } 194 labels<'a>(&'a self) -> Option<Box<dyn Iterator<Item = LabeledSpan> + 'a>>195 fn labels<'a>(&'a self) -> Option<Box<dyn Iterator<Item = LabeledSpan> + 'a>> { 196 self.error.labels() 197 } 198 source_code(&self) -> Option<&dyn miette::SourceCode>199 fn source_code(&self) -> Option<&dyn miette::SourceCode> { 200 Some(&self.source_code) 201 } 202 related<'a>(&'a self) -> Option<Box<dyn Iterator<Item = &'a dyn Diagnostic> + 'a>>203 fn related<'a>(&'a self) -> Option<Box<dyn Iterator<Item = &'a dyn Diagnostic> + 'a>> { 204 self.error.related() 205 } 206 diagnostic_source(&self) -> Option<&dyn Diagnostic>207 fn diagnostic_source(&self) -> Option<&dyn Diagnostic> { 208 self.error.diagnostic_source() 209 } 210 } 211 212 impl<E: Debug, C> Debug for WithSourceCode<E, C> { fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result213 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { 214 Debug::fmt(&self.error, f) 215 } 216 } 217 218 impl<E: Display, C> Display for WithSourceCode<E, C> { fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result219 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { 220 Display::fmt(&self.error, f) 221 } 222 } 223 224 impl<E: StdError, C> StdError for WithSourceCode<E, C> { source(&self) -> Option<&(dyn StdError + 'static)>225 fn source(&self) -> Option<&(dyn StdError + 'static)> { 226 self.error.source() 227 } 228 } 229 230 impl<C> StdError for WithSourceCode<Report, C> { source(&self) -> Option<&(dyn StdError + 'static)>231 fn source(&self) -> Option<&(dyn StdError + 'static)> { 232 self.error.source() 233 } 234 } 235