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    pub fn inner(self) -> Vec<syn::Variant> {
23        self.0
24    }
25}
26
27impl std::ops::Deref for Variants {
28    type Target = Vec<syn::Variant>;
29
30    fn deref(&self) -> &Self::Target {
31        &self.0
32    }
33}
34
35impl std::ops::DerefMut for Variants {
36    fn deref_mut(&mut self) -> &mut Self::Target {
37        &mut self.0
38    }
39}
40
41impl FromInput for Variants {
42    fn from_input(input: &Input) -> crate::Result<Self> {
43        match input {
44            Input::Derive(d) => match &d.data {
45                syn::Data::Enum(e) => Ok(Variants(e.variants.iter().cloned().collect())),
46                _ => Err(Diagnostics::error(
47                    d.ident.span(),
48                    "expected enum input for Variants extractor",
49                )),
50            },
51            Input::Item(syn::Item::Enum(e)) => Ok(Variants(e.variants.iter().cloned().collect())),
52            _ => Err(Diagnostics::error(
53                input.span(),
54                "expected enum input for Variants extractor",
55            )),
56        }
57    }
58}