mirror of
https://github.com/fluencelabs/marine-rs-sdk-test
synced 2024-12-04 15:20:18 +00:00
refactor export_types
This commit is contained in:
parent
8ea8e219ef
commit
913317c78e
@ -32,6 +32,23 @@ pub(crate) struct AstFnSignature {
|
||||
pub output_type: Option<ParsedType>,
|
||||
}
|
||||
|
||||
#[derive(Clone)]
|
||||
pub(crate) struct AstRecordItem {
|
||||
pub name: String,
|
||||
pub fields: AstRecordFields,
|
||||
pub original: syn::ItemStruct,
|
||||
}
|
||||
|
||||
#[allow(dead_code)] // at the moment tuple and unit structs aren't supported
|
||||
#[derive(Debug, Clone, PartialEq)]
|
||||
pub(crate) enum AstRecordFields {
|
||||
Named(Vec<AstRecordField>),
|
||||
// named and unnamed variants have the same inner field types because of it's easy to handle it,
|
||||
// for additional info look at https://github.com/dtolnay/syn/issues/698
|
||||
Unnamed(Vec<AstRecordField>),
|
||||
Unit,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, PartialEq)]
|
||||
pub(crate) struct AstRecordField {
|
||||
// fields of tuple structs haven't got name
|
||||
@ -39,13 +56,6 @@ pub(crate) struct AstRecordField {
|
||||
pub ty: ParsedType,
|
||||
}
|
||||
|
||||
#[derive(Clone)]
|
||||
pub(crate) struct AstRecordItem {
|
||||
pub name: String,
|
||||
pub fields: Vec<AstRecordField>,
|
||||
pub original: syn::ItemStruct,
|
||||
}
|
||||
|
||||
#[derive(Clone)]
|
||||
pub(crate) struct AstExternFnItem {
|
||||
pub link_name: Option<String>,
|
||||
|
@ -34,6 +34,21 @@ pub struct FnSignature {
|
||||
pub output_type: Option<ParsedType>,
|
||||
}
|
||||
|
||||
#[derive(Clone, Serialize, Deserialize)]
|
||||
pub struct RecordItem {
|
||||
pub name: String,
|
||||
pub fields: RecordFields,
|
||||
}
|
||||
|
||||
#[derive(Clone, Serialize, Deserialize)]
|
||||
pub enum RecordFields {
|
||||
Named(Vec<RecordField>),
|
||||
// named and unnamed variants have the same inner field types because of it's easy to handle it,
|
||||
// for additional info look at https://github.com/dtolnay/syn/issues/698
|
||||
Unnamed(Vec<RecordField>),
|
||||
Unit,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
|
||||
pub struct RecordField {
|
||||
// fields of tuple structs haven't got name
|
||||
@ -41,12 +56,6 @@ pub struct RecordField {
|
||||
pub ty: ParsedType,
|
||||
}
|
||||
|
||||
#[derive(Clone, Serialize, Deserialize)]
|
||||
pub struct RecordItem {
|
||||
pub name: String,
|
||||
pub fields: Vec<RecordField>,
|
||||
}
|
||||
|
||||
#[derive(Clone, Serialize, Deserialize)]
|
||||
pub struct ExternFnItem {
|
||||
pub link_name: Option<String>,
|
||||
@ -76,7 +85,7 @@ pub enum SDKAst {
|
||||
|
||||
use crate::ast_types::{
|
||||
AstFnItem, AstFnSignature, AstFnArgument, AstExternModItem, AstExternFnItem, AstRecordField,
|
||||
AstRecordItem,
|
||||
AstRecordItem, AstRecordFields,
|
||||
};
|
||||
|
||||
impl From<AstFnItem> for SDKAst {
|
||||
@ -121,11 +130,25 @@ impl From<AstExternModItem> for ExternModItem {
|
||||
|
||||
impl From<AstRecordItem> for RecordItem {
|
||||
fn from(ast_record_item: AstRecordItem) -> Self {
|
||||
let fields = ast_record_item.fields.into_iter().map(Into::into).collect();
|
||||
|
||||
Self {
|
||||
name: ast_record_item.name,
|
||||
fields,
|
||||
fields: ast_record_item.fields.into(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl From<AstRecordFields> for RecordFields {
|
||||
fn from(ast_record_item: AstRecordFields) -> Self {
|
||||
match ast_record_item {
|
||||
AstRecordFields::Named(fields) => {
|
||||
let fields = fields.into_iter().map(Into::into).collect();
|
||||
Self::Named(fields)
|
||||
}
|
||||
AstRecordFields::Unnamed(fields) => {
|
||||
let fields = fields.into_iter().map(Into::into).collect();
|
||||
Self::Unnamed(fields)
|
||||
}
|
||||
AstRecordFields::Unit => Self::Unit,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -17,6 +17,7 @@
|
||||
use super::ParseMacroInput;
|
||||
use crate::ast_types;
|
||||
use crate::ast_types::AstRecordField;
|
||||
use crate::ast_types::AstRecordFields;
|
||||
use crate::ast_types::FCEAst;
|
||||
use crate::syn_error;
|
||||
use crate::parsed_type::ParsedType;
|
||||
@ -34,6 +35,7 @@ impl ParseMacroInput for syn::ItemStruct {
|
||||
};
|
||||
|
||||
let fields = fields_into_ast(fields)?;
|
||||
let fields = AstRecordFields::Named(fields);
|
||||
|
||||
let name = self.ident.to_string();
|
||||
let ast_record_item = ast_types::AstRecordItem {
|
||||
|
@ -21,9 +21,10 @@ use record_serializer::*;
|
||||
use record_deserializer::*;
|
||||
|
||||
use crate::new_ident;
|
||||
use crate::ast_types;
|
||||
use crate::ast_types::AstRecordItem;
|
||||
use crate::ast_types::AstRecordFields;
|
||||
|
||||
impl quote::ToTokens for ast_types::AstRecordItem {
|
||||
impl quote::ToTokens for AstRecordItem {
|
||||
fn to_tokens(&self, tokens: &mut proc_macro2::TokenStream) {
|
||||
let original = &self.original;
|
||||
crate::prepare_global_data!(
|
||||
@ -65,9 +66,13 @@ impl quote::ToTokens for ast_types::AstRecordItem {
|
||||
}
|
||||
}
|
||||
|
||||
fn generate_serializer_fn(record: &ast_types::AstRecordItem) -> proc_macro2::TokenStream {
|
||||
fn generate_serializer_fn(record: &AstRecordItem) -> proc_macro2::TokenStream {
|
||||
let serializer = record.generate_serializer();
|
||||
let fields_count = record.fields.len();
|
||||
let fields_count = match &record.fields {
|
||||
AstRecordFields::Named(fields) => fields.len(),
|
||||
AstRecordFields::Unnamed(fields) => fields.len(),
|
||||
AstRecordFields::Unit => return proc_macro2::TokenStream::new(),
|
||||
};
|
||||
|
||||
quote::quote! {
|
||||
pub fn __fce_generated_serialize(&self) -> *const u8 {
|
||||
@ -83,14 +88,19 @@ fn generate_serializer_fn(record: &ast_types::AstRecordItem) -> proc_macro2::Tok
|
||||
}
|
||||
}
|
||||
|
||||
fn generate_deserializer_fn(record: &ast_types::AstRecordItem) -> proc_macro2::TokenStream {
|
||||
fn generate_deserializer_fn(record: &AstRecordItem) -> proc_macro2::TokenStream {
|
||||
let RecordDerDescriptor {
|
||||
fields_der,
|
||||
record_ctor,
|
||||
} = record.generate_der();
|
||||
|
||||
let record_size =
|
||||
crate::utils::get_record_size(record.fields.iter().map(|ast_field| &ast_field.ty));
|
||||
let fields = match &record.fields {
|
||||
AstRecordFields::Named(fields) => fields,
|
||||
AstRecordFields::Unnamed(fields) => fields,
|
||||
AstRecordFields::Unit => return proc_macro2::TokenStream::new(),
|
||||
};
|
||||
|
||||
let record_size = crate::utils::get_record_size(fields.iter().map(|ast_field| &ast_field.ty));
|
||||
|
||||
quote::quote! {
|
||||
pub unsafe fn __fce_generated_deserialize(record_ptr: *const u8) -> Self {
|
||||
|
@ -16,10 +16,11 @@
|
||||
|
||||
use crate::new_ident;
|
||||
use crate::parsed_type::ParsedType;
|
||||
use crate::ast_types;
|
||||
use crate::ast_types::*;
|
||||
|
||||
use quote::quote;
|
||||
|
||||
#[derive(Default)]
|
||||
pub(super) struct RecordDerDescriptor {
|
||||
pub(super) fields_der: proc_macro2::TokenStream,
|
||||
pub(super) record_ctor: proc_macro2::TokenStream,
|
||||
@ -30,17 +31,33 @@ pub(super) trait RecordDerGlueCodeGenerator {
|
||||
fn generate_der(&self) -> RecordDerDescriptor;
|
||||
}
|
||||
|
||||
impl RecordDerGlueCodeGenerator for ast_types::AstRecordItem {
|
||||
impl RecordDerGlueCodeGenerator for AstRecordItem {
|
||||
fn generate_der(&self) -> RecordDerDescriptor {
|
||||
let builder = FieldValuesBuilder::build(self.fields.iter());
|
||||
let record_ctor = build_record_ctor(self.fields.iter(), builder.field_value_idents.iter());
|
||||
match &self.fields {
|
||||
AstRecordFields::Named(fields) => record_der_from_named(fields),
|
||||
AstRecordFields::Unnamed(fields) => record_der_from_unnamed(fields),
|
||||
AstRecordFields::Unit => RecordDerDescriptor::default(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
let descriptor = RecordDerDescriptor {
|
||||
fields_der: builder.fields_der,
|
||||
record_ctor,
|
||||
};
|
||||
fn record_der_from_named(fields: &[AstRecordField]) -> RecordDerDescriptor {
|
||||
let builder = FieldValuesBuilder::build(fields.iter());
|
||||
let record_ctor = field_ctors_from_named(fields.iter(), builder.field_value_idents.iter());
|
||||
|
||||
descriptor
|
||||
RecordDerDescriptor {
|
||||
fields_der: builder.fields_der,
|
||||
record_ctor,
|
||||
}
|
||||
}
|
||||
|
||||
fn record_der_from_unnamed(fields: &[AstRecordField]) -> RecordDerDescriptor {
|
||||
let builder = FieldValuesBuilder::build(fields.iter());
|
||||
let record_ctor = field_ctor_from_unnamed(builder.field_value_idents.iter());
|
||||
|
||||
RecordDerDescriptor {
|
||||
fields_der: builder.fields_der,
|
||||
record_ctor,
|
||||
}
|
||||
}
|
||||
|
||||
@ -61,7 +78,7 @@ struct FieldValuesOutcome {
|
||||
|
||||
impl FieldValuesBuilder {
|
||||
pub(self) fn build<'a>(
|
||||
fields: impl ExactSizeIterator<Item = &'a ast_types::AstRecordField>,
|
||||
fields: impl ExactSizeIterator<Item = &'a AstRecordField>,
|
||||
) -> FieldValuesOutcome {
|
||||
let values_builder = Self::new(fields.len());
|
||||
values_builder.build_impl(fields)
|
||||
@ -77,7 +94,7 @@ impl FieldValuesBuilder {
|
||||
|
||||
fn build_impl<'r>(
|
||||
mut self,
|
||||
fields: impl ExactSizeIterator<Item = &'r ast_types::AstRecordField>,
|
||||
fields: impl ExactSizeIterator<Item = &'r AstRecordField>,
|
||||
) -> FieldValuesOutcome {
|
||||
for (id, ast_field) in fields.enumerate() {
|
||||
let field_value_ident = new_ident!(format!("field_{}", id));
|
||||
@ -97,7 +114,7 @@ impl FieldValuesBuilder {
|
||||
|
||||
fn field_der(
|
||||
&mut self,
|
||||
ast_field: &ast_types::AstRecordField,
|
||||
ast_field: &AstRecordField,
|
||||
field: &syn::Ident,
|
||||
) -> proc_macro2::TokenStream {
|
||||
let value_id = self.value_id;
|
||||
@ -161,25 +178,8 @@ impl FieldValuesBuilder {
|
||||
}
|
||||
}
|
||||
|
||||
fn build_record_ctor<'a, 'v>(
|
||||
ast_fields: impl ExactSizeIterator<Item = &'a ast_types::AstRecordField>,
|
||||
field_values: impl ExactSizeIterator<Item = &'v syn::Ident>,
|
||||
) -> proc_macro2::TokenStream {
|
||||
let mut ast_fields = ast_fields.peekable();
|
||||
let is_fields_named = match ast_fields.peek() {
|
||||
Some(ast_field) => ast_field.name.is_some(),
|
||||
None => return proc_macro2::TokenStream::new(),
|
||||
};
|
||||
|
||||
if is_fields_named {
|
||||
build_named_fields_ctor(ast_fields, field_values)
|
||||
} else {
|
||||
build_unnamed_fields_ctor(field_values)
|
||||
}
|
||||
}
|
||||
|
||||
fn build_named_fields_ctor<'a, 'v>(
|
||||
ast_fields: impl ExactSizeIterator<Item = &'a ast_types::AstRecordField>,
|
||||
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 {
|
||||
let field_names = ast_fields
|
||||
@ -198,7 +198,7 @@ fn build_named_fields_ctor<'a, 'v>(
|
||||
}
|
||||
}
|
||||
|
||||
fn build_unnamed_fields_ctor<'v>(
|
||||
fn field_ctor_from_unnamed<'v>(
|
||||
field_values: impl ExactSizeIterator<Item = &'v syn::Ident>,
|
||||
) -> proc_macro2::TokenStream {
|
||||
quote! {
|
||||
|
@ -16,19 +16,27 @@
|
||||
|
||||
use crate::new_ident;
|
||||
use crate::parsed_type::ParsedType;
|
||||
use crate::ast_types;
|
||||
use crate::ast_types::AstRecordItem;
|
||||
use crate::ast_types::AstRecordField;
|
||||
use crate::ast_types::AstRecordFields;
|
||||
|
||||
use quote::quote;
|
||||
|
||||
/// This trait could be used to generate various parts of a record serializer func.
|
||||
pub(super) trait RecordSerializerGlueCodeGenerator {
|
||||
pub(super) trait RecordSerGlueCodeGenerator {
|
||||
fn generate_serializer(&self) -> proc_macro2::TokenStream;
|
||||
}
|
||||
|
||||
impl RecordSerializerGlueCodeGenerator for ast_types::AstRecordItem {
|
||||
impl RecordSerGlueCodeGenerator for AstRecordItem {
|
||||
fn generate_serializer(&self) -> proc_macro2::TokenStream {
|
||||
let mut serializer = proc_macro2::TokenStream::new();
|
||||
for (id, field) in self.fields.iter().enumerate() {
|
||||
let fields = match &self.fields {
|
||||
AstRecordFields::Named(fields) => fields,
|
||||
AstRecordFields::Unnamed(fields) => fields,
|
||||
AstRecordFields::Unit => return proc_macro2::TokenStream::new(),
|
||||
};
|
||||
|
||||
for (id, field) in fields.iter().enumerate() {
|
||||
let field_ident = field_ident(field, id);
|
||||
|
||||
let field_serialization = match &field.ty {
|
||||
@ -82,7 +90,7 @@ impl RecordSerializerGlueCodeGenerator for ast_types::AstRecordItem {
|
||||
}
|
||||
}
|
||||
|
||||
fn field_ident(field: &ast_types::AstRecordField, id: usize) -> proc_macro2::TokenStream {
|
||||
fn field_ident(field: &AstRecordField, id: usize) -> proc_macro2::TokenStream {
|
||||
match &field.name {
|
||||
Some(name) => {
|
||||
let name = new_ident!(name);
|
||||
|
Loading…
Reference in New Issue
Block a user