I wanted to be able to retrieve the content from an attribute like this:
#[foreign_key(table = "some_table", column = "some_column")]
This is how I am trying:
impl TryFrom<&&Attribute> for EntityFieldAnnotation {
type Error = syn::Error;
fn try_from(attribute: &&Attribute) -> Result<Self, Self::Error> {
if attribute.path.is_ident("foreign_key") {
match attribute.parse_args()? {
syn::Meta::NameValue(nv) =>
println!("NAME VALUE: {:?}, {:?}, {:?}",
nv.path.get_ident(),
nv.eq_token.to_token_stream(),
nv.lit.to_token_stream(),
),
_ => println!("Not interesting")
}
} else {
println!("No foreign key")
}
// ... More Rust code
}
Everything works fine if I just put in there only one NameValue. When I add the comma,
everything brokes.
The only error:
error: unexpected token
How can I fix my logic to enable the possibility of have more than just one NameValue?
Thanks
UPDATE: While writing this answer, I had forgotten that
MetahasListvariant as well which gives youNestedMeta. I would generally prefer doing that instead of what I did in the answer below for more flexibility.Although, for your particular case, using
Punctuatedstill seems simpler and cleaner to me.MetaNameValuerepresents only a single name-value pair. In your case it is delimited by,, so, you need to parse all of those delimited values asMetaNameValueinstead.Instead of calling
parse_args, you can use parse_args_with along with Punctuated::parse_terminated:Above
name_valueshas type Punctuated which is an iterator. You can iterate over it to get variousMetaNameValuein your attribute.Updates based on comments:
Getting value out as
StringfromMetaNameValue: