I am writing a macro for a struct and implementing a method based on the field type. e.g. u8, Array or str.
let us say I have this enum represented as u32.
#[repr(u32)]
#[derive(Debug, Clone, Copy)]
pub enum ServerGreetingMode {
  Unavailable = 0,
  Unauthenticated = 1,
  Authenticated = 2,
  Encrypted = 4,
}
And I am applying a macro ToBytes on a struct field
#[repr(packed)]
#[derive(ToBytes, Debug, Clone, Copy)]
pub struct ServerGreetingFrame {
  pub unused: [u8; 12],
  pub mode: ServerGreetingMode,
  pub challenge: [u8; 16],
  pub salt: [u8; 16],
  pub count: u32,
  pub mbz: [u8; 12],
}
I am able to get it to a part where I am getting the type as ServerGreetingMode but I am unable to tell if it is an enum or not.
Here is my current implementation.
#[proc_macro_derive(ToBytes)]
pub fn derive(tokens: TokenStream) -> TokenStream {
  let tokens_item = tokens.clone();
  let items = syn::parse_macro_input!(tokens_item as syn::Item);
  let output = match items {
    syn::Item::Struct(item) => {
      let name = &item.ident;
      let statements = match &item.fields {
        syn::Fields::Named(ref fields) => {
          // eprint!("{:#?}", field);
          let vary_by_type = fields.named.iter().map(|field| {
            let field_name = &field.ident;
            let field_type = &field.ty;
            let statement = match field_type {
              syn::Type::Array(syn::TypeArray { elem, .. }) => {
                let ty = elem.as_ref();
                match ty {
                  syn::Type::Path(typepath)
                    if typepath.qself.is_none()
                      && typepath.path.leading_colon.is_none()
                      && typepath.path.segments.len() == 1 && typepath.path.is_ident("u8") =>
                  {
                    quote! {
                      bytes.extend_from_slice(&self.#field_name);
                    }
                  },
                  _ => todo!(),
                }
              }
              syn::Type::Path(ty) if ty.path.clone().is_ident("u32") => {
                quote! {
                  bytes.extend_from_slice(&(self.#field_name as u32).to_be_bytes().to_vec());
                }
              },
              _ => todo!(),
            };
            statement
          });
          vary_by_type
        }
        _ => todo!(),
      };
      quote! {
        impl #name {
          fn to_bytes(&self) -> Vec<u8> {
            let mut bytes: Vec<u8> = Vec::new();
            #(
              #statements
            )*
            bytes
          }
        }
      }
    }
    _ => todo!(),
  };
  output.into()
  // let s = syn::parse_macro_input!(tokens_struct as syn::ItemStruct);
  // let n = &s.ident;
  // let expanded = quote! {
  //   impl #n {
  //     fn to_bytes(&self) -> Vec<u8> {
  //       let mut bytes: Vec<u8> = Vec::new();
  //       bytes
  //     }
  //   }
  // };
  // expanded.into()
}
Thanks.