getargs-derive-macros 0.1.0

Internal implementation detail of getargs-derive. Not meant for direct use; depend on getargs-derive instead.
Documentation
use super::{DefaultSource, DefaultValue, RawField};
use crate::model::attr::require_value;
use proc_macro2::Span;
use syn::{Expr, Lit, meta::ParseNestedMeta, spanned::Spanned};

fn set_default(
    slot: &mut Option<(DefaultSource, DefaultValue)>,
    source: DefaultSource,
    value: DefaultValue,
    span: Span,
) -> syn::Result<()> {
    if let Some((existing, _)) = slot {
        let message = if *existing == source {
            format!("duplicate {} attribute", source.describe())
        } else {
            format!(
                "conflicting default values: {} and {} cannot be used together; use only one of them",
                existing.describe(),
                source.describe()
            )
        };
        return Err(syn::Error::new(span, message));
    }
    *slot = Some((source, value));
    Ok(())
}

pub(super) fn default_value(meta: &ParseNestedMeta, raw: &mut RawField) -> syn::Result<()> {
    let literal = match require_value(meta, "default_value", "default_value = \"4\"")?
        .parse::<Lit>()?
    {
        Lit::Str(literal) => literal,
        other => {
            return Err(syn::Error::new(
                other.span(),
                "`default_value` expects a string literal; use `default_value_t = expr` for a typed value",
            ));
        }
    };
    set_default(
        &mut raw.default,
        DefaultSource::DefaultValue,
        DefaultValue::Literal(literal),
        meta.path.span(),
    )
}

pub(super) fn default_value_t(meta: &ParseNestedMeta, raw: &mut RawField) -> syn::Result<()> {
    let expr: Expr = require_value(meta, "default_value_t", "default_value_t = 4")?.parse()?;
    set_default(
        &mut raw.default,
        DefaultSource::DefaultValueT,
        DefaultValue::Expr(expr),
        meta.path.span(),
    )
}