diff --git a/impl/src/valid.rs b/impl/src/valid.rs index 7b6750c..e97fb8a 100644 --- a/impl/src/valid.rs +++ b/impl/src/valid.rs @@ -18,6 +18,20 @@ impl Input<'_> { impl Struct<'_> { fn validate(&self) -> Result<()> { check_non_field_attrs(&self.attrs)?; + if let Some(transparent) = self.attrs.transparent { + if self.fields.len() != 1 { + return Err(Error::new_spanned( + transparent, + "#[error(transparent)] requires exactly one field", + )); + } + if let Some(source) = self.fields.iter().filter_map(|f| f.attrs.source).next() { + return Err(Error::new_spanned( + source, + "transparent error struct can't contain #[source]", + )); + } + } check_field_attrs(&self.fields)?; for field in &self.fields { field.validate()?; @@ -32,7 +46,8 @@ impl Enum<'_> { let has_display = self.has_display(); for variant in &self.variants { variant.validate()?; - if has_display && variant.attrs.display.is_none() { + if has_display && variant.attrs.display.is_none() && variant.attrs.transparent.is_none() + { return Err(Error::new_spanned( variant.original, "missing #[error(\"...\")] display attribute", @@ -58,6 +73,20 @@ impl Enum<'_> { impl Variant<'_> { fn validate(&self) -> Result<()> { check_non_field_attrs(&self.attrs)?; + if self.attrs.transparent.is_some() { + if self.fields.len() != 1 { + return Err(Error::new_spanned( + self.original, + "#[error(transparent)] requires exactly one field", + )); + } + if let Some(source) = self.fields.iter().filter_map(|f| f.attrs.source).next() { + return Err(Error::new_spanned( + source, + "transparent variant can't contain #[source]", + )); + } + } check_field_attrs(&self.fields)?; for field in &self.fields { field.validate()?; @@ -97,6 +126,14 @@ fn check_non_field_attrs(attrs: &Attrs) -> Result<()> { "not expected here; the #[backtrace] attribute belongs on a specific field", )); } + if let Some(display) = &attrs.display { + if attrs.transparent.is_some() { + return Err(Error::new_spanned( + display.original, + "cannot have both #[error(transparent)] and a display attribute", + )); + } + } Ok(()) }