Help required with parsing attributes in procedural macro

I am trying to write something in line with the below code

#[derive(Debug, Setter)]
pub struct Card{
    color: String,
    #[getter(display=false)]
    suit: String,
    value: String,
}

I am able to fetch the outer attribute using somthing like

let attr_ = &field.attrs;
for attrib in attr_{
     if let syn::AttrStyle::Outer = attrib.style{
          if attrib.path.is_ident("getter"){
               return quote!{}
          }
     }
}

I am unable to parse the tokens though. In other words, I need to check if "display" is set to "false"

darling

do you have any usage examples? I cant seem to find any examples mentioned in the darling documentation.

There's an example on the GitHub page.

If you don't want to depend on ::darling, you can do it manually, especially now that you have done the most annoying part:

I've even ended up writing a helper macro for this, it's less cumbersome (I guess this is one of the many features that ::darling features, but at least it pulls no dependency and it does provide a very visible functionality: providing a Parse to be used with Attribute::parse_args):

use ::syn::{*, parse::Parse, Result};

named_attrs! { // `impl Parse for GetterArgs`
    struct GetterArgs {
        /// expect a `display` keyword, followed by a boolean literal
        display: LitBool,
    }
}

and then:

for attrib in &field.attrs {
    if attrib.path.is_ident("getter") {
        let getter_args: GetterArgs = match attr.parse_args() {
            | Ok(it) => it,
            | Err(err) => return err.to_compile_error().into(),
        };
        let display: bool = if let Some(it) = getter_args.display { it.value } else {
            // handle the missing display attr. For instance, error:
            return ::syn::Error::new_spanned(attr, "Missing `display`")
                       .to_compile_error().into()
            ;
        };
        ...
    }
}
2 Likes

This topic was automatically closed 90 days after the last reply. We invite you to open a new topic if you have further questions or comments.