(fields: &[Field])
| 149 | } |
| 150 | |
| 151 | fn check_field_attrs(fields: &[Field]) -> Result<()> { |
| 152 | let mut from_field = None; |
| 153 | let mut source_field = None; |
| 154 | let mut backtrace_field = None; |
| 155 | let mut has_backtrace = false; |
| 156 | for field in fields { |
| 157 | if let Some(from) = field.attrs.from { |
| 158 | if from_field.is_some() { |
| 159 | return Err(Error::new_spanned( |
| 160 | from.original, |
| 161 | "duplicate #[from] attribute", |
| 162 | )); |
| 163 | } |
| 164 | from_field = Some(field); |
| 165 | } |
| 166 | if let Some(source) = field.attrs.source { |
| 167 | if source_field.is_some() { |
| 168 | return Err(Error::new_spanned( |
| 169 | source.original, |
| 170 | "duplicate #[source] attribute", |
| 171 | )); |
| 172 | } |
| 173 | source_field = Some(field); |
| 174 | } |
| 175 | if let Some(backtrace) = field.attrs.backtrace { |
| 176 | if backtrace_field.is_some() { |
| 177 | return Err(Error::new_spanned( |
| 178 | backtrace, |
| 179 | "duplicate #[backtrace] attribute", |
| 180 | )); |
| 181 | } |
| 182 | backtrace_field = Some(field); |
| 183 | has_backtrace = true; |
| 184 | } |
| 185 | if let Some(transparent) = field.attrs.transparent { |
| 186 | return Err(Error::new_spanned( |
| 187 | transparent.original, |
| 188 | "#[error(transparent)] needs to go outside the enum or struct, not on an individual field", |
| 189 | )); |
| 190 | } |
| 191 | has_backtrace |= field.is_backtrace(); |
| 192 | } |
| 193 | if let (Some(from_field), Some(source_field)) = (from_field, source_field) { |
| 194 | if from_field.member != source_field.member { |
| 195 | return Err(Error::new_spanned( |
| 196 | from_field.attrs.from.unwrap().original, |
| 197 | "#[from] is only supported on the source field, not any other field", |
| 198 | )); |
| 199 | } |
| 200 | } |
| 201 | if let Some(from_field) = from_field { |
| 202 | let max_expected_fields = match backtrace_field { |
| 203 | Some(backtrace_field) => 1 + (from_field.member != backtrace_field.member) as usize, |
| 204 | None => 1 + has_backtrace as usize, |
| 205 | }; |
| 206 | if fields.len() > max_expected_fields { |
| 207 | return Err(Error::new_spanned( |
| 208 | from_field.attrs.from.unwrap().original, |
no test coverage detected