fluence_sdk_wit/token_stream_generator/
record_generator.rs1mod record_serializer;
18mod record_deserializer;
19mod field_values_builder;
20
21use field_values_builder::*;
22use record_deserializer::*;
23use record_serializer::*;
24
25use crate::new_ident;
26use crate::ast_types::AstRecord;
27use crate::ast_types::AstRecordFields;
28
29impl quote::ToTokens for AstRecord {
30 fn to_tokens(&self, tokens: &mut proc_macro2::TokenStream) {
31 let original = &self.original;
32 crate::prepare_global_data!(
33 Record,
34 self,
35 self.name,
36 data,
37 data_size,
38 global_static_name,
39 section_name
40 );
41 let record_name = new_ident!(self.name);
42
43 let serializer_fn = generate_serializer_fn(self);
44 let deserializer_fn = generate_deserializer_fn(self);
45
46 let glue_code = quote::quote! {
47 #original
48
49 #[cfg(target_arch = "wasm32")]
52 #[doc(hidden)]
53 #[allow(clippy::all)]
54 impl #record_name {
55 #serializer_fn
56
57 #deserializer_fn
58 }
59
60 #[cfg(target_arch = "wasm32")]
61 #[doc(hidden)]
62 #[allow(clippy::all)]
63 #[link_section = #section_name]
64 pub static #global_static_name: [u8; #data_size] = { *#data };
65 };
66
67 tokens.extend(glue_code);
68 }
69}
70
71fn generate_serializer_fn(record: &AstRecord) -> proc_macro2::TokenStream {
72 let serializer = record.generate_serializer();
73 let fields_count = match &record.fields {
74 AstRecordFields::Named(fields) => fields.len(),
75 AstRecordFields::Unnamed(fields) => fields.len(),
76 AstRecordFields::Unit => return proc_macro2::TokenStream::new(),
77 };
78
79 quote::quote! {
80 pub fn __fce_generated_serialize(&self) -> *const u8 {
81 let mut raw_record: Vec<u8> = Vec::with_capacity(4 * #fields_count);
83
84 #serializer
85
86 let raw_record_ptr = raw_record.as_ptr();
87 fluence::internal::add_object_to_release(Box::new(raw_record));
88
89 raw_record_ptr as _
90 }
91 }
92}
93
94fn generate_deserializer_fn(record: &AstRecord) -> proc_macro2::TokenStream {
95 let RecordDerDescriptor {
96 fields_der,
97 record_ctor,
98 } = record.generate_der();
99
100 let fields = match &record.fields {
101 AstRecordFields::Named(fields) => fields,
102 AstRecordFields::Unnamed(fields) => fields,
103 AstRecordFields::Unit => return proc_macro2::TokenStream::new(),
104 };
105
106 let record_size = crate::utils::get_record_size(fields.iter().map(|ast_field| &ast_field.ty));
107
108 quote::quote! {
109 pub unsafe fn __fce_generated_deserialize(record_ptr: *const u8) -> Self {
110 let raw_record: Vec<u8> = Vec::from_raw_parts(record_ptr as _, #record_size, #record_size);
111
112 #fields_der
113
114 #record_ctor
115 }
116 }
117}