mainstay_derive_serde/
lib.rs1extern crate proc_macro;
2
3#[cfg(feature = "lazy-account")]
4mod lazy;
5
6use borsh_derive_internal::*;
7use proc_macro::TokenStream;
8use proc_macro2::{Span, TokenStream as TokenStream2};
9use syn::{Ident, Item};
10
11fn gen_borsh_serialize(input: TokenStream) -> TokenStream2 {
12 let cratename = Ident::new("borsh", Span::call_site());
13
14 let item: Item = syn::parse(input).unwrap();
15 let res = match item {
16 Item::Struct(item) => struct_ser(&item, cratename),
17 Item::Enum(item) => enum_ser(&item, cratename),
18 Item::Union(item) => union_ser(&item, cratename),
19 _ => unreachable!(),
21 };
22
23 match res {
24 Ok(res) => res,
25 Err(err) => err.to_compile_error(),
26 }
27}
28
29#[proc_macro_derive(MainstaySerialize, attributes(borsh_skip))]
30pub fn mainstay_serialize(input: TokenStream) -> TokenStream {
31 #[cfg(not(feature = "idl-build"))]
32 let ret = gen_borsh_serialize(input);
33 #[cfg(feature = "idl-build")]
34 let ret = gen_borsh_serialize(input.clone());
35
36 #[cfg(feature = "idl-build")]
37 {
38 use mainstay_syn::idl::*;
39 use quote::quote;
40
41 let idl_build_impl = match syn::parse(input).unwrap() {
42 Item::Struct(item) => impl_idl_build_struct(&item),
43 Item::Enum(item) => impl_idl_build_enum(&item),
44 Item::Union(item) => impl_idl_build_union(&item),
45 _ => unreachable!(),
47 };
48
49 return TokenStream::from(quote! {
50 #ret
51 #idl_build_impl
52 });
53 };
54
55 #[allow(unreachable_code)]
56 TokenStream::from(ret)
57}
58
59fn gen_borsh_deserialize(input: TokenStream) -> TokenStream2 {
60 let cratename = Ident::new("borsh", Span::call_site());
61
62 let item: Item = syn::parse(input).unwrap();
63 let res = match item {
64 Item::Struct(item) => struct_de(&item, cratename),
65 Item::Enum(item) => enum_de(&item, cratename),
66 Item::Union(item) => union_de(&item, cratename),
67 _ => unreachable!(),
69 };
70
71 match res {
72 Ok(res) => res,
73 Err(err) => err.to_compile_error(),
74 }
75}
76
77#[proc_macro_derive(MainstayDeserialize, attributes(borsh_skip, borsh_init))]
78pub fn borsh_deserialize(input: TokenStream) -> TokenStream {
79 #[cfg(feature = "lazy-account")]
80 {
81 let deser = gen_borsh_deserialize(input.clone());
82 let lazy = lazy::gen_lazy(input).unwrap_or_else(|e| e.to_compile_error());
83 quote::quote! {
84 #deser
85 #lazy
86 }
87 .into()
88 }
89 #[cfg(not(feature = "lazy-account"))]
90 gen_borsh_deserialize(input).into()
91}
92
93#[cfg(feature = "lazy-account")]
94#[proc_macro_derive(Lazy)]
95pub fn lazy(input: TokenStream) -> TokenStream {
96 lazy::gen_lazy(input)
97 .unwrap_or_else(|e| e.to_compile_error())
98 .into()
99}