deserialize.rs 8.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242
  1. use crate::proto_buf::util::*;
  2. use flowy_ast::*;
  3. use proc_macro2::{Span, TokenStream};
  4. pub fn make_de_token_steam(ctxt: &Ctxt, ast: &ASTContainer) -> Option<TokenStream> {
  5. let pb_ty = ast.attrs.pb_struct_type()?;
  6. let struct_ident = &ast.ident;
  7. let build_take_fields = ast
  8. .data
  9. .all_fields()
  10. .filter(|f| !f.attrs.skip_deserializing())
  11. .flat_map(|field| {
  12. if let Some(func) = field.attrs.deserialize_with() {
  13. let member = &field.member;
  14. Some(quote! { o.#member=#struct_ident::#func(pb); })
  15. } else if field.attrs.is_one_of() {
  16. token_stream_for_one_of(ctxt, field)
  17. } else {
  18. token_stream_for_field(ctxt, &field.member, field.ty, false)
  19. }
  20. });
  21. let de_token_stream: TokenStream = quote! {
  22. impl std::convert::TryFrom<bytes::Bytes> for #struct_ident {
  23. type Error = ::protobuf::ProtobufError;
  24. fn try_from(bytes: bytes::Bytes) -> Result<Self, Self::Error> {
  25. Self::try_from(&bytes)
  26. }
  27. }
  28. impl std::convert::TryFrom<&bytes::Bytes> for #struct_ident {
  29. type Error = ::protobuf::ProtobufError;
  30. fn try_from(bytes: &bytes::Bytes) -> Result<Self, Self::Error> {
  31. let pb: crate::protobuf::#pb_ty = ::protobuf::Message::parse_from_bytes(bytes)?;
  32. Ok(#struct_ident::from(pb))
  33. }
  34. }
  35. impl std::convert::TryFrom<&[u8]> for #struct_ident {
  36. type Error = ::protobuf::ProtobufError;
  37. fn try_from(bytes: &[u8]) -> Result<Self, Self::Error> {
  38. let pb: crate::protobuf::#pb_ty = ::protobuf::Message::parse_from_bytes(bytes)?;
  39. Ok(#struct_ident::from(pb))
  40. }
  41. }
  42. impl std::convert::From<crate::protobuf::#pb_ty> for #struct_ident {
  43. fn from(mut pb: crate::protobuf::#pb_ty) -> Self {
  44. let mut o = Self::default();
  45. #(#build_take_fields)*
  46. o
  47. }
  48. }
  49. };
  50. Some(de_token_stream)
  51. // None
  52. }
  53. fn token_stream_for_one_of(ctxt: &Ctxt, field: &ASTField) -> Option<TokenStream> {
  54. let member = &field.member;
  55. let ident = get_member_ident(ctxt, member)?;
  56. let ty_info = match parse_ty(ctxt, field.ty) {
  57. Ok(ty_info) => ty_info,
  58. Err(e) => {
  59. eprintln!("token_stream_for_one_of failed: {:?} with error: {}", member, e);
  60. panic!();
  61. }
  62. }?;
  63. let bracketed_ty_info = ty_info.bracket_ty_info.as_ref().as_ref();
  64. let has_func = format_ident!("has_{}", ident.to_string());
  65. match ident_category(bracketed_ty_info.unwrap().ident) {
  66. TypeCategory::Enum => {
  67. let get_func = format_ident!("get_{}", ident.to_string());
  68. let ty = bracketed_ty_info.unwrap().ty;
  69. Some(quote! {
  70. if pb.#has_func() {
  71. let enum_de_from_pb = #ty::from(&pb.#get_func());
  72. o.#member = Some(enum_de_from_pb);
  73. }
  74. })
  75. }
  76. TypeCategory::Primitive => {
  77. let get_func = format_ident!("get_{}", ident.to_string());
  78. Some(quote! {
  79. if pb.#has_func() {
  80. o.#member=Some(pb.#get_func());
  81. }
  82. })
  83. }
  84. TypeCategory::Str => {
  85. let take_func = format_ident!("take_{}", ident.to_string());
  86. Some(quote! {
  87. if pb.#has_func() {
  88. o.#member=Some(pb.#take_func());
  89. }
  90. })
  91. }
  92. TypeCategory::Array => {
  93. let take_func = format_ident!("take_{}", ident.to_string());
  94. Some(quote! {
  95. if pb.#has_func() {
  96. o.#member=Some(pb.#take_func());
  97. }
  98. })
  99. }
  100. _ => {
  101. let take_func = format_ident!("take_{}", ident.to_string());
  102. let ty = bracketed_ty_info.unwrap().ty;
  103. Some(quote! {
  104. if pb.#has_func() {
  105. let val = #ty::from(pb.#take_func());
  106. o.#member=Some(val);
  107. }
  108. })
  109. }
  110. }
  111. }
  112. fn token_stream_for_field(ctxt: &Ctxt, member: &syn::Member, ty: &syn::Type, is_option: bool) -> Option<TokenStream> {
  113. let ident = get_member_ident(ctxt, member)?;
  114. let ty_info = match parse_ty(ctxt, ty) {
  115. Ok(ty_info) => ty_info,
  116. Err(e) => {
  117. eprintln!("token_stream_for_field: {:?} with error: {}", member, e);
  118. panic!()
  119. }
  120. }?;
  121. match ident_category(ty_info.ident) {
  122. TypeCategory::Array => {
  123. assert_bracket_ty_is_some(ctxt, &ty_info);
  124. token_stream_for_vec(ctxt, member, &ty_info.bracket_ty_info.unwrap())
  125. }
  126. TypeCategory::Map => {
  127. assert_bracket_ty_is_some(ctxt, &ty_info);
  128. token_stream_for_map(ctxt, member, &ty_info.bracket_ty_info.unwrap())
  129. }
  130. TypeCategory::Protobuf => {
  131. // if the type wrapped by SingularPtrField, should call take first
  132. let take = syn::Ident::new("take", Span::call_site());
  133. // inner_type_ty would be the type of the field. (e.g value of AnyData)
  134. let ty = ty_info.ty;
  135. Some(quote! {
  136. let some_value = pb.#member.#take();
  137. if some_value.is_some() {
  138. let struct_de_from_pb = #ty::from(some_value.unwrap());
  139. o.#member = struct_de_from_pb;
  140. }
  141. })
  142. }
  143. TypeCategory::Enum => {
  144. let ty = ty_info.ty;
  145. Some(quote! {
  146. let enum_de_from_pb = #ty::from(&pb.#member);
  147. o.#member = enum_de_from_pb;
  148. })
  149. }
  150. TypeCategory::Str => {
  151. let take_ident = syn::Ident::new(&format!("take_{}", ident), Span::call_site());
  152. if is_option {
  153. Some(quote! {
  154. if pb.#member.is_empty() {
  155. o.#member = None;
  156. } else {
  157. o.#member = Some(pb.#take_ident());
  158. }
  159. })
  160. } else {
  161. Some(quote! {
  162. o.#member = pb.#take_ident();
  163. })
  164. }
  165. }
  166. TypeCategory::Opt => token_stream_for_field(ctxt, member, ty_info.bracket_ty_info.unwrap().ty, true),
  167. TypeCategory::Primitive | TypeCategory::Bytes => {
  168. // eprintln!("😄 #{:?}", &field.name().unwrap());
  169. if is_option {
  170. Some(quote! { o.#member = Some(pb.#member.clone()); })
  171. } else {
  172. Some(quote! { o.#member = pb.#member.clone(); })
  173. }
  174. }
  175. }
  176. }
  177. fn token_stream_for_vec(ctxt: &Ctxt, member: &syn::Member, bracketed_type: &TyInfo) -> Option<TokenStream> {
  178. let ident = get_member_ident(ctxt, member)?;
  179. match ident_category(bracketed_type.ident) {
  180. TypeCategory::Protobuf => {
  181. let ty = bracketed_type.ty;
  182. // Deserialize from pb struct of type vec, should call take_xx(), get the
  183. // repeated_field and then calling the into_iter。
  184. let take_ident = format_ident!("take_{}", ident.to_string());
  185. Some(quote! {
  186. o.#member = pb.#take_ident()
  187. .into_iter()
  188. .map(|m| #ty::from(m))
  189. .collect();
  190. })
  191. }
  192. TypeCategory::Bytes => {
  193. // Vec<u8>
  194. Some(quote! {
  195. o.#member = pb.#member.clone();
  196. })
  197. }
  198. _ => {
  199. // String
  200. let take_ident = format_ident!("take_{}", ident.to_string());
  201. Some(quote! {
  202. o.#member = pb.#take_ident().into_vec();
  203. })
  204. }
  205. }
  206. }
  207. fn token_stream_for_map(ctxt: &Ctxt, member: &syn::Member, ty_info: &TyInfo) -> Option<TokenStream> {
  208. let ident = get_member_ident(ctxt, member)?;
  209. let take_ident = format_ident!("take_{}", ident.to_string());
  210. let ty = ty_info.ty;
  211. match ident_category(ty_info.ident) {
  212. TypeCategory::Protobuf => Some(quote! {
  213. let mut m: std::collections::HashMap<String, #ty> = std::collections::HashMap::new();
  214. pb.#take_ident().into_iter().for_each(|(k,v)| {
  215. m.insert(k.clone(), #ty::from(v));
  216. });
  217. o.#member = m;
  218. }),
  219. _ => Some(quote! {
  220. let mut m: std::collections::HashMap<String, #ty> = std::collections::HashMap::new();
  221. pb.#take_ident().into_iter().for_each(|(k,mut v)| {
  222. m.insert(k.clone(), v);
  223. });
  224. o.#member = m;
  225. }),
  226. }
  227. }