lib.rs 2.6 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182
  1. extern crate proc_macro;
  2. use borsh_derive_internal::*;
  3. use proc_macro::TokenStream;
  4. use proc_macro2::{Span, TokenStream as TokenStream2};
  5. use syn::{Ident, Item};
  6. #[cfg(feature = "idl-build")]
  7. use {anchor_syn::idl::build::*, quote::quote};
  8. fn gen_borsh_serialize(input: TokenStream) -> TokenStream2 {
  9. let cratename = Ident::new("borsh", Span::call_site());
  10. let item: Item = syn::parse(input).unwrap();
  11. let res = match item {
  12. Item::Struct(item) => struct_ser(&item, cratename),
  13. Item::Enum(item) => enum_ser(&item, cratename),
  14. Item::Union(item) => union_ser(&item, cratename),
  15. // Derive macros can only be defined on structs, enums, and unions.
  16. _ => unreachable!(),
  17. };
  18. match res {
  19. Ok(res) => res,
  20. Err(err) => err.to_compile_error(),
  21. }
  22. }
  23. #[proc_macro_derive(AnchorSerialize, attributes(borsh_skip))]
  24. pub fn anchor_serialize(input: TokenStream) -> TokenStream {
  25. #[cfg(not(feature = "idl-build"))]
  26. let ret = gen_borsh_serialize(input);
  27. #[cfg(feature = "idl-build")]
  28. let ret = gen_borsh_serialize(input.clone());
  29. #[cfg(feature = "idl-build")]
  30. {
  31. let no_docs = get_no_docs();
  32. let idl_build_impl = match syn::parse(input).unwrap() {
  33. Item::Struct(item) => gen_idl_build_impl_for_struct(&item, no_docs),
  34. Item::Enum(item) => gen_idl_build_impl_for_enum(item, no_docs),
  35. Item::Union(item) => {
  36. // unions are not included in the IDL - TODO print a warning
  37. idl_build_impl_skeleton(quote! {None}, quote! {}, &item.ident, &item.generics)
  38. }
  39. // Derive macros can only be defined on structs, enums, and unions.
  40. _ => unreachable!(),
  41. };
  42. return TokenStream::from(quote! {
  43. #ret
  44. #idl_build_impl
  45. });
  46. };
  47. #[allow(unreachable_code)]
  48. TokenStream::from(ret)
  49. }
  50. fn gen_borsh_deserialize(input: TokenStream) -> TokenStream2 {
  51. let cratename = Ident::new("borsh", Span::call_site());
  52. let item: Item = syn::parse(input).unwrap();
  53. let res = match item {
  54. Item::Struct(item) => struct_de(&item, cratename),
  55. Item::Enum(item) => enum_de(&item, cratename),
  56. Item::Union(item) => union_de(&item, cratename),
  57. // Derive macros can only be defined on structs, enums, and unions.
  58. _ => unreachable!(),
  59. };
  60. match res {
  61. Ok(res) => res,
  62. Err(err) => err.to_compile_error(),
  63. }
  64. }
  65. #[proc_macro_derive(AnchorDeserialize, attributes(borsh_skip, borsh_init))]
  66. pub fn borsh_deserialize(input: TokenStream) -> TokenStream {
  67. TokenStream::from(gen_borsh_deserialize(input))
  68. }