Simplify storage of source and backtrace attrs

This commit is contained in:
David Tolnay 2019-10-12 16:22:47 -07:00
parent cb73bf9ccc
commit f16952290d
No known key found for this signature in database
GPG key ID: F9BA143B95FF6D82
2 changed files with 12 additions and 28 deletions

View file

@ -9,8 +9,8 @@ use syn::{
pub struct Attrs<'a> {
pub display: Option<Display<'a>>,
pub source: Option<Source<'a>>,
pub backtrace: Option<Backtrace<'a>>,
pub source: Option<&'a Attribute>,
pub backtrace: Option<&'a Attribute>,
}
#[derive(Clone)]
@ -21,14 +21,6 @@ pub struct Display<'a> {
pub was_shorthand: bool,
}
pub struct Source<'a> {
pub original: &'a Attribute,
}
pub struct Backtrace<'a> {
pub original: &'a Attribute,
}
pub fn get(input: &[Attribute]) -> Result<Attrs> {
let mut attrs = Attrs {
display: None,
@ -47,17 +39,17 @@ pub fn get(input: &[Attribute]) -> Result<Attrs> {
}
attrs.display = Some(display);
} else if attr.path.is_ident("source") {
let source = parse_source(attr)?;
require_empty_attribute(attr)?;
if attrs.source.is_some() {
return Err(Error::new_spanned(attr, "duplicate #[source] attribute"));
}
attrs.source = Some(source);
attrs.source = Some(attr);
} else if attr.path.is_ident("backtrace") {
let backtrace = parse_backtrace(attr)?;
require_empty_attribute(attr)?;
if attrs.backtrace.is_some() {
return Err(Error::new_spanned(attr, "duplicate #[backtrace] attribute"));
}
attrs.backtrace = Some(backtrace);
attrs.backtrace = Some(attr);
}
}
@ -125,14 +117,9 @@ fn parse_token_expr(input: ParseStream, mut last_is_comma: bool) -> Result<Token
Ok(tokens)
}
fn parse_source(attr: &Attribute) -> Result<Source> {
fn require_empty_attribute(attr: &Attribute) -> Result<()> {
syn::parse2::<Nothing>(attr.tokens.clone())?;
Ok(Source { original: attr })
}
fn parse_backtrace(attr: &Attribute) -> Result<Backtrace> {
syn::parse2::<Nothing>(attr.tokens.clone())?;
Ok(Backtrace { original: attr })
Ok(())
}
impl ToTokens for Display<'_> {

View file

@ -67,13 +67,13 @@ impl Field<'_> {
fn check_no_source_or_backtrace(attrs: &Attrs) -> Result<()> {
if let Some(source) = &attrs.source {
return Err(Error::new_spanned(
source.original,
source,
"not expected here; the #[source] attribute belongs on a specific field",
));
}
if let Some(backtrace) = &attrs.backtrace {
return Err(Error::new_spanned(
backtrace.original,
backtrace,
"not expected here; the #[backtrace] attribute belongs on a specific field",
));
}
@ -86,17 +86,14 @@ fn check_no_duplicate_source_or_backtrace(fields: &[Field]) -> Result<()> {
for field in fields {
if let Some(source) = &field.attrs.source {
if has_source {
return Err(Error::new_spanned(
source.original,
"duplicate #[source] attribute",
));
return Err(Error::new_spanned(source, "duplicate #[source] attribute"));
}
has_source = true;
}
if let Some(backtrace) = &field.attrs.backtrace {
if has_backtrace {
return Err(Error::new_spanned(
backtrace.original,
backtrace,
"duplicate #[backtrace] attribute",
));
}