enum-bitset-derive 0.2.1

Proc macros for the enum-bitset macro
Documentation
use proc_macro2::TokenStream as TokenStream2;
use quote::quote;
use syn::LitStr;

use crate::derive::config::EnumBitsetConfig;

impl EnumBitsetConfig {
    #[cfg(not(feature = "serde"))]
    pub fn impl_serde(&self) -> TokenStream2 {
        TokenStream2::new()
    }

    #[allow(dead_code)]
    pub(super) fn impl_serde_list(&self) -> TokenStream2 {
        let mut output = TokenStream2::new();

        if self.serde.ser {
            output.extend(self.impl_serde_list_ser());
        }

        if self.serde.de {
            output.extend(self.impl_serde_list_de());
        }

        output
    }

    #[allow(dead_code)]
    fn impl_serde_list_ser(&self) -> TokenStream2 {
        let name = &self.set_type;
        let serde = &self.serde.serde_crate;

        quote! {
            use #serde::{Serialize, Serializer, ser::{SerializeSeq}};

            const _: fn() = || {
                fn base_enum_for_bitsets_must_be_serializable<T: Serialize>() {}
                base_enum_for_bitsets_must_be_serializable::<#name>();
            };

            impl Serialize for #name {
                fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
                where
                    S: Serializer,
                {
                    let mut seq = serializer.serialize_seq(Some(self.len()))?;

                    for variant in self.iter() {
                        seq.serialize_element(&variant)?;
                    }

                    seq.end()
                }
            }
        }
    }

    #[allow(dead_code)]
    fn impl_serde_list_de(&self) -> TokenStream2 {
        let name = &self.set_type;
        let base = &self.base_type;
        let serde = &self.serde.serde_crate;

        let expect = LitStr::new(&format!("a list of `{base}` variants"), name.span());

        quote! {
            use #serde::{Deserialize, Deserializer, de::{SeqAccess, Visitor}};

            const _: fn() = || {
                fn base_enum_for_bitsets_must_be_deserializable<T: for<'de> Deserialize<'de>>() {}
                base_enum_for_bitsets_must_be_deserializable::<#name>();
            };

            impl<'de> Deserialize<'de> for #name {
                fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
                where
                    D: Deserializer<'de>,
                {
                    struct VisitList;

                    impl<'de> Visitor<'de> for VisitList {
                        type Value = #name;

                        fn expecting(&self, formatter: &mut Formatter) -> fmt::Result {
                            formatter.write_str(#expect)
                        }

                        fn visit_seq<A>(self, mut seq: A) -> Result<Self::Value, A::Error>
                        where
                            A: serde::de::SeqAccess<'de>,
                        {
                            let mut result = #name::new();
                            while let Some(variant) = seq.next_element::<#base>()? {
                                result.insert(variant);
                            }

                            Ok(result)
                        }
                    }

                    deserializer.deserialize_seq(VisitList)
                }
            }
        }
    }
}