fixtures_proc 2.4.0

Run tests against fixtures
Documentation
use syn::{
    parse::{Parse, ParseStream},
    Ident, LitStr, Token,
};

use super::assignment::Assignment;

pub struct IgnoreArgs {
    pub paths: LitStr,
    pub reason: Option<LitStr>,
}

impl Parse for IgnoreArgs {
    fn parse(input: ParseStream) -> syn::Result<Self> {
        if input.peek(Ident) {
            Self::parse_fields(input)
        } else {
            Self::parse_literal(input)
        }
    }
}

impl IgnoreArgs {
    fn parse_literal(input: ParseStream) -> syn::Result<Self> {
        let path = input.parse::<LitStr>()?;
        if !input.is_empty() {
            return Err(syn::Error::new(input.span(), "Unexpected token."));
        }
        Ok(Self {
            paths: path,
            reason: None,
        })
    }

    fn parse_fields(input: ParseStream) -> syn::Result<Self> {
        let error_span = input.span();
        let mut paths = None;
        let mut reason = None;

        while !input.is_empty() {
            let assignment = input.parse::<Assignment<LitStr>>()?;

            match assignment.ident().to_string().as_str() {
                "paths" => {
                    if paths.is_some() {
                        return Err(syn::Error::new(
                            assignment.ident().span(),
                            "Duplicate assignment.",
                        ));
                    }
                    paths = Some(assignment.into_value());
                }
                "reason" => {
                    if reason.is_some() {
                        return Err(syn::Error::new(
                            assignment.ident().span(),
                            "Duplicate assignment.",
                        ));
                    }
                    reason = Some(assignment.into_value());
                }
                _ => {
                    return Err(syn::Error::new(
                        assignment.ident().span(),
                        "Invalid field identifier. Expected 'paths' or 'reason'.",
                    ))
                }
            }

            if input.is_empty() {
                break;
            }

            input.parse::<Token![,]>()?;
        }

        Ok(Self {
            paths: paths
                .ok_or_else(|| syn::Error::new(error_span, "The 'path' field is missing."))?,
            reason,
        })
    }
}