mirror of
https://github.com/fluencelabs/marine-rs-sdk-test
synced 2024-12-04 15:20:18 +00:00
update record der
This commit is contained in:
parent
913317c78e
commit
5b26474d49
@ -16,9 +16,11 @@
|
||||
|
||||
mod record_serializer;
|
||||
mod record_deserializer;
|
||||
mod field_values_builder;
|
||||
|
||||
use record_serializer::*;
|
||||
use field_values_builder::*;
|
||||
use record_deserializer::*;
|
||||
use record_serializer::*;
|
||||
|
||||
use crate::new_ident;
|
||||
use crate::ast_types::AstRecordItem;
|
||||
|
@ -0,0 +1,257 @@
|
||||
use crate::new_ident;
|
||||
use crate::parsed_type::ParsedType;
|
||||
use crate::ast_types::*;
|
||||
|
||||
use proc_macro2::TokenStream;
|
||||
use quote::quote;
|
||||
|
||||
pub(super) struct FieldValuesBuilder {
|
||||
value_id: usize,
|
||||
fields_der: TokenStream,
|
||||
field_value_idents: Vec<syn::Ident>,
|
||||
}
|
||||
|
||||
/// Contains all necessary info to construct record fields.
|
||||
pub(super) struct FieldValuesOutcome {
|
||||
/// Generated deserializer for each record field.
|
||||
pub(super) fields_der: TokenStream,
|
||||
|
||||
/// Idents of each record field.
|
||||
pub(super) field_value_idents: Vec<syn::Ident>,
|
||||
}
|
||||
|
||||
impl FieldValuesBuilder {
|
||||
pub(super) fn build<'a>(
|
||||
fields: impl ExactSizeIterator<Item = &'a AstRecordField>,
|
||||
) -> FieldValuesOutcome {
|
||||
let values_builder = Self::new(fields.len());
|
||||
values_builder.build_impl(fields)
|
||||
}
|
||||
|
||||
fn new(fields_count: usize) -> Self {
|
||||
Self {
|
||||
value_id: 0,
|
||||
fields_der: TokenStream::new(),
|
||||
field_value_idents: Vec::with_capacity(fields_count),
|
||||
}
|
||||
}
|
||||
|
||||
fn build_impl<'r>(
|
||||
mut self,
|
||||
fields: impl ExactSizeIterator<Item = &'r AstRecordField>,
|
||||
) -> FieldValuesOutcome {
|
||||
for (id, ast_field) in fields.enumerate() {
|
||||
let field_value_ident = new_ident!(format!("field_{}", id));
|
||||
let field_der = self.field_der(ast_field, &field_value_ident);
|
||||
|
||||
self.field_value_idents.push(field_value_ident);
|
||||
self.fields_der.extend(field_der);
|
||||
}
|
||||
|
||||
let outcome = FieldValuesOutcome {
|
||||
fields_der: self.fields_der,
|
||||
field_value_idents: self.field_value_idents,
|
||||
};
|
||||
|
||||
outcome
|
||||
}
|
||||
|
||||
fn field_der(&mut self, ast_field: &AstRecordField, field: &syn::Ident) -> TokenStream {
|
||||
let der = match &ast_field.ty {
|
||||
ParsedType::Boolean(_) => self.bool_der(field),
|
||||
ParsedType::I8(_) => self.i8_der(field),
|
||||
ParsedType::I16(_) => self.i16_der(field),
|
||||
ParsedType::I32(_) => self.i32_der(field),
|
||||
ParsedType::I64(_) => self.i64_der(field),
|
||||
ParsedType::U8(_) => self.u8_der(field),
|
||||
ParsedType::U16(_) => self.u16_der(field),
|
||||
ParsedType::U32(_) => self.u32_der(field),
|
||||
ParsedType::U64(_) => self.u64_der(field),
|
||||
ParsedType::F32(_) => self.f32_der(field),
|
||||
ParsedType::F64(_) => self.f64_der(field),
|
||||
ParsedType::Utf8Str(_) | ParsedType::Utf8String(_) => self.string_der(field),
|
||||
ParsedType::Vector(ty, _) => self.vector_der(ty, field),
|
||||
ParsedType::Record(name, _) => self.record_der(name, field),
|
||||
};
|
||||
|
||||
der
|
||||
}
|
||||
|
||||
fn bool_der(&mut self, field: &syn::Ident) -> TokenStream {
|
||||
let value_id = self.value_id;
|
||||
let result = quote! { let #field = raw_record[#value_id] != 0; };
|
||||
self.value_id += 1;
|
||||
result
|
||||
}
|
||||
|
||||
fn i8_der(&mut self, field: &syn::Ident) -> TokenStream {
|
||||
let value_id = self.value_id;
|
||||
let result = quote! { let #field = raw_record[#value_id] as i8; };
|
||||
self.value_id += 1;
|
||||
result
|
||||
}
|
||||
|
||||
fn i16_der(&mut self, field: &syn::Ident) -> TokenStream {
|
||||
let value_id = self.value_id;
|
||||
let result = quote! { let #field = i16::from_le_bytes([
|
||||
raw_record[#value_id],
|
||||
raw_record[#value_id + 1],
|
||||
]);
|
||||
};
|
||||
|
||||
self.value_id += 2;
|
||||
result
|
||||
}
|
||||
|
||||
fn i32_der(&mut self, field: &syn::Ident) -> TokenStream {
|
||||
let value_id = self.value_id;
|
||||
let result = quote! { let #field = i32::from_le_bytes([
|
||||
raw_record[#value_id],
|
||||
raw_record[#value_id + 1],
|
||||
raw_record[#value_id + 2],
|
||||
raw_record[#value_id + 3],
|
||||
]);
|
||||
};
|
||||
|
||||
self.value_id += 4;
|
||||
result
|
||||
}
|
||||
|
||||
fn i64_der(&mut self, field: &syn::Ident) -> TokenStream {
|
||||
let value_id = self.value_id;
|
||||
let result = quote! { let #field = i64::from_le_bytes([
|
||||
raw_record[#value_id],
|
||||
raw_record[#value_id + 1],
|
||||
raw_record[#value_id + 2],
|
||||
raw_record[#value_id + 3],
|
||||
raw_record[#value_id + 4],
|
||||
raw_record[#value_id + 5],
|
||||
raw_record[#value_id + 6],
|
||||
raw_record[#value_id + 7],
|
||||
]);
|
||||
};
|
||||
|
||||
self.value_id += 8;
|
||||
result
|
||||
}
|
||||
|
||||
fn u8_der(&mut self, field: &syn::Ident) -> TokenStream {
|
||||
let value_id = self.value_id;
|
||||
let result = quote! { let #field = raw_record[#value_id] as u8; };
|
||||
self.value_id += 1;
|
||||
result
|
||||
}
|
||||
|
||||
fn u16_der(&mut self, field: &syn::Ident) -> TokenStream {
|
||||
let value_id = self.value_id;
|
||||
let result = quote! { let #field = u16::from_le_bytes([
|
||||
raw_record[#value_id],
|
||||
raw_record[#value_id + 1],
|
||||
]);
|
||||
};
|
||||
|
||||
self.value_id += 2;
|
||||
result
|
||||
}
|
||||
|
||||
fn u32_der(&mut self, field: &syn::Ident) -> TokenStream {
|
||||
let value_id = self.value_id;
|
||||
let result = quote! { let #field = u32::from_le_bytes([
|
||||
raw_record[#value_id],
|
||||
raw_record[#value_id + 1],
|
||||
raw_record[#value_id + 2],
|
||||
raw_record[#value_id + 3],
|
||||
]);
|
||||
};
|
||||
|
||||
self.value_id += 4;
|
||||
result
|
||||
}
|
||||
|
||||
fn u64_der(&mut self, field: &syn::Ident) -> TokenStream {
|
||||
let value_id = self.value_id;
|
||||
let result = quote! { let #field = u64::from_le_bytes([
|
||||
raw_record[#value_id],
|
||||
raw_record[#value_id + 1],
|
||||
raw_record[#value_id + 2],
|
||||
raw_record[#value_id + 3],
|
||||
raw_record[#value_id + 4],
|
||||
raw_record[#value_id + 5],
|
||||
raw_record[#value_id + 6],
|
||||
raw_record[#value_id + 7],
|
||||
]);
|
||||
};
|
||||
|
||||
self.value_id += 8;
|
||||
result
|
||||
}
|
||||
|
||||
fn f32_der(&mut self, field: &syn::Ident) -> TokenStream {
|
||||
let value_id = self.value_id;
|
||||
let result = quote! { let #field = f32::from_le_bytes([
|
||||
raw_record[#value_id],
|
||||
raw_record[#value_id + 1],
|
||||
raw_record[#value_id + 2],
|
||||
raw_record[#value_id + 3],
|
||||
]);
|
||||
};
|
||||
|
||||
self.value_id += 4;
|
||||
result
|
||||
}
|
||||
|
||||
fn f64_der(&mut self, field: &syn::Ident) -> TokenStream {
|
||||
let value_id = self.value_id;
|
||||
let result = quote! { let #field = f64::from_le_bytes([
|
||||
raw_record[#value_id],
|
||||
raw_record[#value_id + 1],
|
||||
raw_record[#value_id + 2],
|
||||
raw_record[#value_id + 3],
|
||||
raw_record[#value_id + 4],
|
||||
raw_record[#value_id + 5],
|
||||
raw_record[#value_id + 6],
|
||||
raw_record[#value_id + 7],
|
||||
]);
|
||||
};
|
||||
|
||||
self.value_id += 8;
|
||||
result
|
||||
}
|
||||
|
||||
fn string_der(&mut self, field: &syn::Ident) -> TokenStream {
|
||||
let ptr_id = self.value_id;
|
||||
let size_id = self.value_id + 1;
|
||||
self.value_id += 1;
|
||||
|
||||
quote! {
|
||||
let #field = unsafe { String::from_raw_parts(raw_record[#ptr_id] as _, raw_record[#size_id] as _, raw_record[#size_id] as _) };
|
||||
}
|
||||
}
|
||||
|
||||
fn vector_der(&mut self, ty: &ParsedType, field: &syn::Ident) -> TokenStream {
|
||||
let generated_der_name = format!("__fce_generated_vec_deserializer_{}", self.value_id);
|
||||
let generated_der_name = crate::utils::prepare_ident(generated_der_name);
|
||||
let generated_der_ident = new_ident!(generated_der_name);
|
||||
|
||||
let vector_deserializer =
|
||||
crate::parsed_type::generate_vector_deserializer(ty, &generated_der_name);
|
||||
|
||||
let ptr_id = self.value_id;
|
||||
let size_id = self.value_id + 1;
|
||||
self.value_id += 1;
|
||||
|
||||
quote! {
|
||||
#vector_deserializer
|
||||
let #field = unsafe { #generated_der_ident(raw_record[#ptr_id] as _, raw_record[#size_id] as _) };
|
||||
}
|
||||
}
|
||||
|
||||
fn record_der(&mut self, name: &str, field: &syn::Ident) -> TokenStream {
|
||||
let ptr_id = self.value_id;
|
||||
let record_ident = new_ident!(name);
|
||||
|
||||
quote! {
|
||||
let #field = #record_ident::__fce_generated_deserialize(raw_record[#ptr_id] as _);
|
||||
}
|
||||
}
|
||||
}
|
@ -15,15 +15,16 @@
|
||||
*/
|
||||
|
||||
use crate::new_ident;
|
||||
use crate::parsed_type::ParsedType;
|
||||
use crate::ast_types::*;
|
||||
use super::FieldValuesBuilder;
|
||||
|
||||
use proc_macro2::TokenStream;
|
||||
use quote::quote;
|
||||
|
||||
#[derive(Default)]
|
||||
pub(super) struct RecordDerDescriptor {
|
||||
pub(super) fields_der: proc_macro2::TokenStream,
|
||||
pub(super) record_ctor: proc_macro2::TokenStream,
|
||||
pub(super) fields_der: TokenStream,
|
||||
pub(super) record_ctor: TokenStream,
|
||||
}
|
||||
|
||||
/// This trait could be used to generate various parts of a record serializer func.
|
||||
@ -61,127 +62,10 @@ fn record_der_from_unnamed(fields: &[AstRecordField]) -> RecordDerDescriptor {
|
||||
}
|
||||
}
|
||||
|
||||
struct FieldValuesBuilder {
|
||||
value_id: usize,
|
||||
fields_der: proc_macro2::TokenStream,
|
||||
field_value_idents: Vec<syn::Ident>,
|
||||
}
|
||||
|
||||
/// Contains all necessary info to construct record fields.
|
||||
struct FieldValuesOutcome {
|
||||
/// Generated deserializer for each record field.
|
||||
fields_der: proc_macro2::TokenStream,
|
||||
|
||||
/// Idents of each record field.
|
||||
field_value_idents: Vec<syn::Ident>,
|
||||
}
|
||||
|
||||
impl FieldValuesBuilder {
|
||||
pub(self) fn build<'a>(
|
||||
fields: impl ExactSizeIterator<Item = &'a AstRecordField>,
|
||||
) -> FieldValuesOutcome {
|
||||
let values_builder = Self::new(fields.len());
|
||||
values_builder.build_impl(fields)
|
||||
}
|
||||
|
||||
fn new(fields_count: usize) -> Self {
|
||||
Self {
|
||||
value_id: 0,
|
||||
fields_der: proc_macro2::TokenStream::new(),
|
||||
field_value_idents: Vec::with_capacity(fields_count),
|
||||
}
|
||||
}
|
||||
|
||||
fn build_impl<'r>(
|
||||
mut self,
|
||||
fields: impl ExactSizeIterator<Item = &'r AstRecordField>,
|
||||
) -> FieldValuesOutcome {
|
||||
for (id, ast_field) in fields.enumerate() {
|
||||
let field_value_ident = new_ident!(format!("field_{}", id));
|
||||
let field_der = self.field_der(ast_field, &field_value_ident);
|
||||
|
||||
self.field_value_idents.push(field_value_ident);
|
||||
self.fields_der.extend(field_der);
|
||||
}
|
||||
|
||||
let outcome = FieldValuesOutcome {
|
||||
fields_der: self.fields_der,
|
||||
field_value_idents: self.field_value_idents,
|
||||
};
|
||||
|
||||
outcome
|
||||
}
|
||||
|
||||
fn field_der(
|
||||
&mut self,
|
||||
ast_field: &AstRecordField,
|
||||
field: &syn::Ident,
|
||||
) -> proc_macro2::TokenStream {
|
||||
let value_id = self.value_id;
|
||||
let der = match &ast_field.ty {
|
||||
ParsedType::Boolean(_) => quote! { let #field = raw_record[#value_id] != 0; },
|
||||
ParsedType::I8(_) => quote! { let #field = raw_record[#value_id] as i8; },
|
||||
ParsedType::I16(_) => quote! { let #field = raw_record[#value_id] as i16; },
|
||||
ParsedType::I32(_) => quote! { let #field = raw_record[#value_id] as i32; },
|
||||
ParsedType::I64(_) => quote! { let #field = raw_record[#value_id] as i64; },
|
||||
ParsedType::U8(_) => quote! { let #field = raw_record[#value_id] as u8; },
|
||||
ParsedType::U16(_) => quote! { let #field = raw_record[#value_id] as u16; },
|
||||
ParsedType::U32(_) => quote! { let #field = raw_record[#value_id] as u32; },
|
||||
ParsedType::U64(_) => quote! { let #field = raw_record[#value_id] as u64; },
|
||||
ParsedType::F32(_) => quote! { let #field = raw_record[#value_id] as f32; },
|
||||
ParsedType::F64(_) => quote! { let #field = f64::from_bits(raw_record[#value_id]); },
|
||||
ParsedType::Utf8Str(_) | ParsedType::Utf8String(_) => self.string_der(field),
|
||||
ParsedType::Vector(ty, _) => self.vector_der(ty, field),
|
||||
ParsedType::Record(name, _) => self.record_der(name, field),
|
||||
};
|
||||
|
||||
self.value_id += 1;
|
||||
|
||||
der
|
||||
}
|
||||
|
||||
fn string_der(&mut self, field: &syn::Ident) -> proc_macro2::TokenStream {
|
||||
let ptr_id = self.value_id;
|
||||
let size_id = self.value_id + 1;
|
||||
self.value_id += 1;
|
||||
|
||||
quote! {
|
||||
let #field = unsafe { String::from_raw_parts(raw_record[#ptr_id] as _, raw_record[#size_id] as _, raw_record[#size_id] as _) };
|
||||
}
|
||||
}
|
||||
|
||||
fn vector_der(&mut self, ty: &ParsedType, field: &syn::Ident) -> proc_macro2::TokenStream {
|
||||
let generated_der_name = format!("__fce_generated_vec_deserializer_{}", self.value_id);
|
||||
let generated_der_name = crate::utils::prepare_ident(generated_der_name);
|
||||
let generated_der_ident = new_ident!(generated_der_name);
|
||||
|
||||
let vector_deserializer =
|
||||
crate::parsed_type::generate_vector_deserializer(ty, &generated_der_name);
|
||||
|
||||
let ptr_id = self.value_id;
|
||||
let size_id = self.value_id + 1;
|
||||
self.value_id += 1;
|
||||
|
||||
quote! {
|
||||
#vector_deserializer
|
||||
let #field = unsafe { #generated_der_ident(raw_record[#ptr_id] as _, raw_record[#size_id] as _) };
|
||||
}
|
||||
}
|
||||
|
||||
fn record_der(&mut self, name: &str, field: &syn::Ident) -> proc_macro2::TokenStream {
|
||||
let ptr_id = self.value_id;
|
||||
let record_ident = new_ident!(name);
|
||||
|
||||
quote! {
|
||||
let #field = #record_ident::__fce_generated_deserialize(raw_record[#ptr_id] as _);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn field_ctors_from_named<'a, 'v>(
|
||||
ast_fields: impl ExactSizeIterator<Item = &'a AstRecordField>,
|
||||
field_values: impl ExactSizeIterator<Item = &'v syn::Ident>,
|
||||
) -> proc_macro2::TokenStream {
|
||||
) -> TokenStream {
|
||||
let field_names = ast_fields
|
||||
.map(|ast_field| {
|
||||
new_ident!(ast_field
|
||||
@ -200,7 +84,7 @@ fn field_ctors_from_named<'a, 'v>(
|
||||
|
||||
fn field_ctor_from_unnamed<'v>(
|
||||
field_values: impl ExactSizeIterator<Item = &'v syn::Ident>,
|
||||
) -> proc_macro2::TokenStream {
|
||||
) -> TokenStream {
|
||||
quote! {
|
||||
Self {
|
||||
#(#field_values),*
|
||||
|
@ -60,13 +60,14 @@ pub fn get_record_size<'a>(
|
||||
let mut size = 0;
|
||||
|
||||
for field in fields {
|
||||
let params_count = match field {
|
||||
ParsedType::Vector(..) | ParsedType::Utf8Str(_) | ParsedType::Utf8String(_) => 2,
|
||||
_ => 1,
|
||||
size += match field {
|
||||
ParsedType::U8(_) | ParsedType::I8(_) | ParsedType::Boolean(_) => 1,
|
||||
ParsedType::U16(_) | ParsedType::I16(_) => 2,
|
||||
ParsedType::U32(_) | ParsedType::I32(_) | ParsedType::F32(_) => 4,
|
||||
ParsedType::U64(_) | ParsedType::I64(_) | ParsedType::F64(_) => 8,
|
||||
ParsedType::Record(..) => 4,
|
||||
ParsedType::Vector(..) | ParsedType::Utf8Str(_) | ParsedType::Utf8String(_) => 2 * 4,
|
||||
};
|
||||
|
||||
// internally record is being serialized to a vector of u64.
|
||||
size += std::mem::size_of::<u64>() * params_count;
|
||||
}
|
||||
|
||||
size
|
||||
|
Loading…
Reference in New Issue
Block a user