use crate::attrs::{Attributes, Idx, Kind, Level};
use crate::attrs::idx;
use proc_macro2::Span;
#[derive(Debug, Clone)]
pub struct Variants {
pub indices: Vec<Idx>,
pub attrs: Vec<Attributes>
}
impl Variants {
pub fn try_from<'a, I>(span: Span, iter: I, parent: &Attributes) -> syn::Result<Self>
where
I: IntoIterator<Item = &'a syn::Variant>
{
let mut indices = Vec::new();
let mut attrs = Vec::new();
let parent_encoding = parent.encoding().unwrap_or_default();
for v in iter.into_iter() {
let attr = Attributes::try_from_iter(Level::Variant, &v.attrs)?;
let idex = attr.index().ok_or_else(|| {
syn::Error::new(v.ident.span(), "missing `#[n(...)]` or `#[b(...)]` attribute")
})?;
if parent.flat() {
if attr.tag().is_some() {
let span = attr.span(Kind::Tag).unwrap_or_else(|| v.ident.span());
return Err(syn::Error::new(span, "flat enum does not support tags on constructors"))
}
if attr.encoding().unwrap_or(parent_encoding).is_map() {
let span = attr.span(Kind::Encoding).unwrap_or_else(|| v.ident.span());
return Err(syn::Error::new(span, "flat enum does not support map encoding"))
}
}
indices.push(idex);
attrs.push(attr);
}
idx::check_uniq(span, indices.iter().copied())?;
Ok(Variants { indices, attrs })
}
}