An unofficial collection of APIs used in FreeJam games and mods
Du kannst nicht mehr als 25 Themen auswählen Themen müssen entweder mit einem Buchstaben oder einer Ziffer beginnen. Sie können Bindestriche („-“) enthalten und bis zu 35 Zeichen lang sein.

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849
  1. //! Macro implementation for using #[derive(Parsable)]
  2. extern crate proc_macro;
  3. use proc_macro::{TokenStream};
  4. use syn::{DeriveInput, Data};
  5. use quote::quote;
  6. /// Macro generator
  7. #[proc_macro_derive(Parsable)]
  8. pub fn derive_parsable(struc: TokenStream) -> TokenStream {
  9. let ast: &DeriveInput = &syn::parse(struc).unwrap();
  10. let name = &ast.ident;
  11. if let Data::Struct(data_struct) = &ast.data {
  12. let mut p_fields_gen = vec![];
  13. let mut d_fields_gen = vec![];
  14. for field in &data_struct.fields {
  15. let field_ident = &field.ident.clone().expect("Expected named field");
  16. let field_type = &field.ty;
  17. p_fields_gen.push(
  18. quote! {
  19. #field_ident: <#field_type>::parse(data)?
  20. }
  21. );
  22. d_fields_gen.push(
  23. quote! {
  24. self.#field_ident.dump(data)?;
  25. }
  26. );
  27. }
  28. let final_gen = quote! {
  29. impl Parsable for #name {
  30. fn parse(data: &mut dyn std::io::Read) -> std::io::Result<Self> {
  31. Ok(Self{
  32. #(#p_fields_gen),*
  33. })
  34. }
  35. fn dump(&self, data: &mut dyn std::io::Write) -> std::io::Result<usize> {
  36. let mut write_count: usize = 0;
  37. #(write_count += #d_fields_gen;)*
  38. Ok(write_count)
  39. }
  40. }
  41. };
  42. return final_gen.into();
  43. } else {
  44. panic!("Expected Parsable auto-trait to be applied to struct");
  45. }
  46. }