pcd-rs-derive 0.13.0

Derive macros for pcd-rs crate
Documentation
use crate::common::*;
use syn::{spanned::Spanned, AttrStyle, Attribute, Error};

use crate::parse::{AttrList, AttrOption};

pub fn parse_field_attributes(attrs: &[Attribute]) -> syn::Result<Options> {
    {
        let options: Vec<_> = attrs
            .iter()
            .filter(|attr| attr.path().is_ident("pcd"))
            .map(|attr| {
                if attr.style == AttrStyle::Outer {
                    Ok(attr)
                } else {
                    Err(Error::new(
                        attr.span(),
                        "inner pcd attribute is not supported",
                    ))
                }
            })
            .map(|attr| -> syn::Result<_> {
                let attr = attr?;
                let attr_list: AttrList = attr.parse_args()?;
                Ok(attr_list)
            })
            .try_collect()?;
        let options: Vec<AttrOption> = options.into_iter().flat_map(|list| list.options).collect();

        let ignore_option = {
            let mut ignore_opts = options.iter().filter_map(|opt| opt.as_ignore()).fuse();
            let ignore_opt = ignore_opts.next();
            if let Some(opt) = ignore_opts.next() {
                return Err(syn::Error::new(
                    opt.ident.span(),
                    "ignore option cannot specified more than once",
                ));
            }
            ignore_opt
        };
        let rename_option = {
            let mut rename_opts = options.iter().filter_map(|opt| opt.as_rename()).fuse();
            let rename_opt = rename_opts.next();
            if let Some(opt) = rename_opts.next() {
                return Err(syn::Error::new(
                    opt.ident.span(),
                    "rename option cannot specified more than once",
                ));
            }
            rename_opt
        };

        Ok(Options {
            ignore: ignore_option.is_some(),
            rename: rename_option.map(|opt| opt.rename.clone()),
        })
    }
}

pub struct Options {
    pub ignore: bool,
    pub rename: Option<String>,
}