Skip to main content

zyn_core/extract/
variants.rs

1use syn::spanned::Spanned;
2
3use crate::diagnostic::Diagnostics;
4use crate::types::Input;
5
6use super::FromInput;
7
8/// Element extractor that pulls enum variants from the input.
9///
10/// Errors at compile time if the input is not an enum. Access the inner
11/// `Vec<syn::Variant>` via `Deref` or the `inner()` method.
12///
13/// ```ignore
14/// #[zyn::element]
15/// fn my_element(#[zyn(input)] variants: zyn::Variants) -> proc_macro2::TokenStream {
16///     // variants.iter() — accessed via Deref to Vec<syn::Variant>
17/// }
18/// ```
19pub struct Variants(Vec<syn::Variant>);
20
21impl Variants {
22    /// Consumes the wrapper and returns the inner `Vec<syn::Variant>`.
23    pub fn inner(self) -> Vec<syn::Variant> {
24        self.0
25    }
26}
27
28impl std::ops::Deref for Variants {
29    type Target = Vec<syn::Variant>;
30
31    fn deref(&self) -> &Self::Target {
32        &self.0
33    }
34}
35
36impl std::ops::DerefMut for Variants {
37    fn deref_mut(&mut self) -> &mut Self::Target {
38        &mut self.0
39    }
40}
41
42impl FromInput for Variants {
43    fn from_input(input: &Input) -> crate::Result<Self> {
44        match input {
45            Input::Derive(d) => match &d.data {
46                syn::Data::Enum(e) => Ok(Variants(e.variants.iter().cloned().collect())),
47                _ => Err(Diagnostics::error(
48                    d.ident.span(),
49                    "expected enum input for Variants extractor",
50                )),
51            },
52            Input::Item(syn::Item::Enum(e)) => Ok(Variants(e.variants.iter().cloned().collect())),
53            _ => Err(Diagnostics::error(
54                input.span(),
55                "expected enum input for Variants extractor",
56            )),
57        }
58    }
59}