Skip to content

Commit 29d5ece

Browse files
committed
fix(derive): apply default handling to skip only
The `default` keyword was being picked up by the skip handler for fields which weren't tagged with the `skip` attribute.
1 parent 3fac38e commit 29d5ece

File tree

1 file changed

+19
-17
lines changed

1 file changed

+19
-17
lines changed

prost-derive/src/field/skip.rs

Lines changed: 19 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,9 @@
1-
use anyhow::{bail, Error};
1+
use anyhow::{bail, Error};
22
use proc_macro2::TokenStream;
33
use quote::quote;
4-
use syn::{Meta, Lit, MetaNameValue, Path, Expr, ExprLit};
4+
use syn::{Expr, ExprLit, Lit, Meta, MetaNameValue, Path};
55

6-
use crate::field::{set_bool, word_attr};
6+
use crate::field::{set_bool, set_option, word_attr};
77

88
#[derive(Clone)]
99
pub struct Field {
@@ -14,28 +14,21 @@ impl Field {
1414
pub fn new(attrs: &[Meta]) -> Result<Option<Field>, Error> {
1515
let mut skip = false;
1616
let mut default_fn = None;
17+
let mut default_lit = None;
1718
let mut unknown_attrs = Vec::new();
1819

1920
for attr in attrs {
2021
if word_attr("skip", attr) {
2122
set_bool(&mut skip, "duplicate skip attribute")?;
2223
} else if let Meta::NameValue(MetaNameValue { path, value, .. }) = attr {
2324
if path.is_ident("default") {
24-
let lit_str = match value {
25+
match value {
2526
// There has to be a better way...
26-
Expr::Lit(ExprLit { lit: Lit::Str(lit), .. }) => Some(lit),
27-
_ => None,
27+
Expr::Lit(ExprLit {
28+
lit: Lit::Str(lit), ..
29+
}) => set_option(&mut default_lit, lit, "duplicate default attributes")?,
30+
_ => bail!("default attribute value must be a string literal"),
2831
};
29-
if let Some(lit) = lit_str {
30-
let fn_path: Path = syn::parse_str(&lit.value())
31-
.map_err(|_| anyhow::anyhow!("invalid path for default function"))?;
32-
if default_fn.is_some() {
33-
bail!("duplicate default attribute for skipped field");
34-
}
35-
default_fn = Some(fn_path);
36-
} else {
37-
bail!("default attribute value must be a string literal");
38-
}
3932
} else {
4033
unknown_attrs.push(attr);
4134
}
@@ -55,6 +48,15 @@ impl Field {
5548
);
5649
}
5750

51+
if let Some(lit) = default_lit {
52+
let fn_path: Path = syn::parse_str(&lit.value())
53+
.map_err(|_| anyhow::anyhow!("invalid path for default function"))?;
54+
if default_fn.is_some() {
55+
bail!("duplicate default attribute for skipped field");
56+
}
57+
default_fn = Some(fn_path);
58+
}
59+
5860
Ok(Some(Field { default_fn }))
5961
}
6062

@@ -70,4 +72,4 @@ impl Field {
7072
quote! { ::core::default::Default::default() }
7173
}
7274
}
73-
}
75+
}

0 commit comments

Comments
 (0)