use quote::ToTokens;
use syn::{Attribute, Error};
use crate::{naming, utils::has_zlink_bool_attr};
pub(crate) enum FieldMode {
Normal,
Skip,
Flatten,
}
pub(crate) fn field_mode<S>(attrs: &[Attribute], span: &S) -> Result<FieldMode, Error>
where
S: ToTokens,
{
let skip = has_zlink_bool_attr(attrs, "skip");
let flatten = has_zlink_bool_attr(attrs, "flatten");
let renamed = naming::parse_rename(attrs)?.is_some();
match (skip, flatten) {
(true, true) => Err(Error::new_spanned(
span,
"`#[zlink(skip)]` and `#[zlink(flatten)]` are mutually exclusive",
)),
(true, false) if renamed => Err(Error::new_spanned(
span,
"`#[zlink(skip)]` cannot be combined with `#[zlink(rename)]`: a skipped field has no \
wire name to rename",
)),
(true, false) => Ok(FieldMode::Skip),
(false, true) if renamed => Err(Error::new_spanned(
span,
"`#[zlink(rename)]` has no effect on a `#[zlink(flatten)]` field: the field's own name \
never appears on the wire; the inlined fields keep their own names",
)),
(false, true) => Ok(FieldMode::Flatten),
(false, false) => Ok(FieldMode::Normal),
}
}