Documentation
mod derive;
mod structs;

use proc_macro::TokenStream;
use quote::ToTokens;
use structs::Object;
use syn::parse_macro_input;

#[proc_macro_derive(Object)]
pub fn object(input: TokenStream) -> TokenStream {
  let object = parse_macro_input!(input as Object);
  object.to_token_stream().into()
//   let DeriveInput {
//     ident: name,
//     data,
//     generics, 
//     attrs, 
//     vis 
//   } = parse_macro_input!(input as DeriveInput);

//   // let description_str = match data {
//   //   Struct(my_struct) => gen_description_str_for_struct(my_struct),
//   //   Enum(my_enum) => gen_description_str_for_enum(my_enum),
//   //   Union(my_union) => gen_description_str_for_union(my_union),
//   // };
//   let struct_fields = match data {
//     Struct(my_struct) => gen_description_str_for_struct(my_struct),
//     Enum(_) => Vec::new(),
//     Union(_) => Vec::new(),
//   };

//   println!("{:?}", struct_fields);

//   quote!{
//     impl #name { 
//       pub fn stringify(&self) -> String{
//         let id = self.get_field_value("id");
//         let name = self.get_field_value("name");
//         // println!("{} {}", stringify!(#name), #description_str);
//         let string = format!("{{\"id\":\"{}\", \"name\": \"{}\"}}",id, name);
//         string
//       }
//       fn get_field_value(&self, field: &str) -> &String{
//         match field {
//           "id" => &self.id,
//           "name" => &self.name,
//           &_ => todo!()
//         }
//       }
//     }
//   }.into()
// }

// fn gen_description_str_for_struct(my_struct: DataStruct) -> Vec<StructField> {
//   // match my_struct.fields {
//   //   Named(fields) => handle_named_fields(fields),
//   //   Unnamed(fields) => handle_unnamed_fields(fields),
//   //   Unit => handle_unit(),
//   // }
//   match my_struct.fields {
//     Named(fields) => handle_named_fields(fields),
//     Unnamed(fields) => Vec::new(),
//     Unit => Vec::new(),
//   }
// }

// fn handle_named_fields(fields: FieldsNamed) -> Vec<StructField> {
//   let mut struct_fields: Vec<StructField> = Vec::new();
//   let fields = fields.named.iter();
//   for field in fields{
//     let struct_field = StructField::new(&field);
//     match struct_field{
//         Some(struct_field) => {
//           struct_fields.push(struct_field);
//         },
//         None => (),
//     }
//   }

//   // format!(
//   //   "a struct with these named fields",
//   //   // quote! {#(#field_names), *}
//   // )
//   struct_fields
// }

// fn handle_unnamed_fields(fields: FieldsUnnamed) -> String {
//   let my_unnamed_fields_count = fields.unnamed.iter().count();
//   format!("a struct with {} unnamed fields", my_unnamed_fields_count)
// }

// fn handle_unit() -> String {
//   format!("a unit struct")
// }

// fn gen_description_str_for_enum(my_enum: DataEnum) -> String {
//   let my_variant_idents = my_enum.variants.iter().map(|it| &it.ident);
//   format!(
//     "an enum with these variants: {}",
//     quote! {#(#my_variant_idents),*}
//   )
// }

// fn gen_description_str_for_union(my_union: DataUnion) -> Vec<StructField> {
//   handle_named_fields(my_union.fields)
}