Skip to content

Commit

Permalink
Properly pass on parsed tag values #11
Browse files Browse the repository at this point in the history
  • Loading branch information
kellerkindt committed May 7, 2020
1 parent 95d2953 commit 5d7db2b
Show file tree
Hide file tree
Showing 13 changed files with 271 additions and 234 deletions.
4 changes: 1 addition & 3 deletions asn1rs-model/src/ast/attribute.rs
Original file line number Diff line number Diff line change
Expand Up @@ -133,7 +133,6 @@ impl PrimaryContext for Type {
ident_or_literal_or_punct(*c)
.ok_or_else(|| c.error("Expected type, number or extension marker"))
})?
.to_string()
.to_lowercase();

Ok(parse_type_pre_stepped(&lowercase_ident, input)?)
Expand All @@ -150,8 +149,7 @@ impl PrimaryContext for Option<usize> {
.ok()
.as_ref()
.map(ToString::to_string)
.as_ref()
.map(String::as_str)
.as_deref()
.map(str::to_lowercase)
.map(|lowercase_ident| {
lowercase_ident
Expand Down
6 changes: 4 additions & 2 deletions asn1rs-model/src/ast/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -80,8 +80,10 @@ pub fn parse_asn_definition(
let item_span = item.span();
let attr_span = attr.span();

println!("ATTRIBUTE: {}", attr.to_string());
println!("ITEM: {}", item.to_string());
if cfg!(feature = "debug-proc-macro") {
println!("ATTRIBUTE: {}", attr.to_string());
println!("ITEM: {}", item.to_string());
}

let item = syn::parse2::<Item>(item)
.map_err(|e| compile_error_ts(item_span, format!("Invalid Item: {}", e)))?;
Expand Down
54 changes: 31 additions & 23 deletions asn1rs-model/src/gen/rust/async_psql.rs
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
use crate::gen::rust::shared_psql::*;
use crate::gen::rust::GeneratorSupplement;
use crate::gen::RustCodeGenerator;
use crate::model::rust::DataEnum;
use crate::model::rust::PlainEnum;
use crate::model::rust::{DataEnum, Field};
use crate::model::sql::{Sql, SqlType, ToSql};
use crate::model::{Definition, Model, Rust, RustType};
use codegen::{Block, Function, Impl, Scope};
Expand All @@ -20,19 +20,20 @@ impl GeneratorSupplement<Rust> for AsyncPsqlInserter {

fn impl_supplement(&self, _scope: &mut Scope, _definition: &Definition<Rust>) {}

fn extend_impl_of_struct(
&self,
name: &str,
impl_scope: &mut Impl,
fields: &[(String, RustType)],
) {
fn extend_impl_of_struct<'a>(&self, name: &str, impl_scope: &mut Impl, fields: &[Field]) {
AsyncPsqlInserter::append_retrieve_many_for_container_type(name, impl_scope);
AsyncPsqlInserter::append_retrieve_for_container_type(name, impl_scope);
AsyncPsqlInserter::append_load_struct(name, impl_scope, fields);

let fn_insert = create_insert_fn(impl_scope, true);
fn_insert.line(prepare_struct_insert_statement(name, fields));
impl_insert_fn_content(false, true, name, fields, fn_insert);
impl_insert_fn_content(
false,
true,
name,
|| fields.iter().map(Field::fallback_representation),
fn_insert,
);
}

fn extend_impl_of_enum(&self, _name: &str, impl_scope: &mut Impl, _r_enum: &PlainEnum) {
Expand Down Expand Up @@ -87,7 +88,7 @@ impl GeneratorSupplement<Rust> for AsyncPsqlInserter {
RustType::Option(Box::new(variant.r#type().clone())),
));
}
impl_insert_fn_content(false, false, name, &updated_variants[..], fn_insert);
impl_insert_fn_content(false, false, name, || updated_variants.iter(), fn_insert);
}

fn extend_impl_of_tuple(&self, name: &str, impl_scope: &mut Impl, definition: &RustType) {
Expand All @@ -104,20 +105,20 @@ impl GeneratorSupplement<Rust> for AsyncPsqlInserter {
"let statement = context.prepared(\"{}\");",
tuple_struct_insert_statement(name)
));
impl_insert_fn_content(true, true, name, &fields[..], fn_insert);
impl_insert_fn_content(true, true, name, || fields.iter(), fn_insert);
}
}

fn impl_insert_fn_content(
fn impl_insert_fn_content<'a, I: ExactSizeIterator<Item = &'a (String, RustType)>>(
is_tuple_struct: bool,
on_self: bool,
name: &str,
fields: &[(String, RustType)],
fields: impl Fn() -> I,
container: &mut impl Container,
) {
let mut params = Vec::default();
let mut to_await = Vec::default();
for insert in fields.iter().filter_map(|(field_name, r_type)| {
for insert in fields().filter_map(|(field_name, r_type)| {
let field_name = RustCodeGenerator::rust_field_name(field_name, true);
let field_name_as_variable = if field_name
.chars()
Expand Down Expand Up @@ -178,7 +179,7 @@ fn impl_insert_fn_content(
.join(", ")
));
to_await.clear();
for insert in fields.iter().filter_map(|(field_name, r_type)| {
for insert in fields().filter_map(|(field_name, r_type)| {
if r_type.is_vec() {
Some(insert_field(
is_tuple_struct,
Expand Down Expand Up @@ -211,7 +212,7 @@ fn impl_insert_fn_content(
container.line("Ok(id)");
}

fn prepare_struct_insert_statement(name: &str, fields: &[(String, RustType)]) -> String {
fn prepare_struct_insert_statement(name: &str, fields: &[Field]) -> String {
format!(
"let statement = context.prepared(\"{}\");",
struct_insert_statement(name, fields)
Expand Down Expand Up @@ -616,23 +617,30 @@ impl AsyncPsqlInserter {
fn_retrieve.line(format!("Self::{}(context, &row).await", load_fn_name()));
}

fn append_load_struct(name: &str, impl_scope: &mut Impl, fields: &[(String, RustType)]) {
fn append_load_struct(name: &str, impl_scope: &mut Impl, fields: &[Field]) {
let fn_load = create_load_fn(
impl_scope,
fields.iter().any(|(_name, f_type)| {
!Model::<Sql>::is_primitive(f_type)
|| Model::<Sql>::has_no_column_in_embedded_struct(f_type.as_no_option())
fields.iter().any(|field| {
!Model::<Sql>::is_primitive(field.r#type())
|| Model::<Sql>::has_no_column_in_embedded_struct(field.r#type().as_no_option())
}),
);
for (index, (field, f_type)) in fields.iter().enumerate() {
AsyncPsqlInserter::append_load_field(false, name, fn_load, index, field, f_type);
for (index, field) in fields.iter().enumerate() {
AsyncPsqlInserter::append_load_field(
false,
name,
fn_load,
index,
field.name(),
field.r#type(),
);
}

let mut result_block = Block::new("Ok(Self");
for (field, _type) in fields {
for field in fields {
result_block.line(format!(
"{},",
RustCodeGenerator::rust_field_name(field, true)
RustCodeGenerator::rust_field_name(field.name(), true)
));
}
result_block.after(")");
Expand Down
41 changes: 15 additions & 26 deletions asn1rs-model/src/gen/rust/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,8 +14,8 @@ pub(crate) mod shared_psql;
use self::protobuf::ProtobufSerializer;
use self::uper::UperSerializer;
use crate::gen::Generator;
use crate::model::rust::DataEnum;
use crate::model::rust::PlainEnum;
use crate::model::rust::{DataEnum, Field};
use crate::model::Model;
use crate::model::Range;
use crate::model::Rust;
Expand All @@ -42,13 +42,7 @@ const KEYWORDS: [&str; 9] = [
pub trait GeneratorSupplement<T> {
fn add_imports(&self, scope: &mut Scope);
fn impl_supplement(&self, scope: &mut Scope, definition: &Definition<T>);
fn extend_impl_of_struct(
&self,
_name: &str,
_impl_scope: &mut Impl,
_fields: &[(String, RustType)],
) {
}
fn extend_impl_of_struct(&self, _name: &str, _impl_scope: &mut Impl, _fields: &[Field]) {}
fn extend_impl_of_enum(&self, _name: &str, _impl_scope: &mut Impl, _enumeration: &PlainEnum) {}
fn extend_impl_of_data_enum(
&self,
Expand Down Expand Up @@ -184,7 +178,7 @@ impl RustCodeGenerator {
scope.raw(&Self::asn_attribute(
"enumerated",
None,
plain.extension_after_variant().map(|v| v.clone()),
plain.extension_after_variant().cloned(),
));
Self::add_enum(self.new_enum(scope, name, true), name, plain)
}
Expand All @@ -209,25 +203,20 @@ impl RustCodeGenerator {
}
}

fn add_struct(
str_ct: &mut Struct,
_name: &str,
fields: &[(String, RustType)],
pub_access: bool,
) {
for (field_name, field_type) in fields.iter() {
fn add_struct(str_ct: &mut Struct, _name: &str, fields: &[Field], pub_access: bool) {
for field in fields {
str_ct.field(
&format!(
"{} {}{}",
Self::asn_attribute(
&Self::asn_attribute_type(&field_type.clone().into_asn()),
None, // TODO missing tag
&Self::asn_attribute_type(&field.r#type().clone().into_asn()),
field.tag(),
None
),
if pub_access { "pub " } else { "" },
Self::rust_field_name(field_name, true),
Self::rust_field_name(field.name(), true),
),
field_type.to_string(),
field.r#type().to_string(),
);
}
}
Expand Down Expand Up @@ -390,19 +379,19 @@ impl RustCodeGenerator {
fn impl_struct<'a>(
scope: &'a mut Scope,
name: &str,
fields: &[(String, RustType)],
fields: &[Field],
getter_and_setter: bool,
) -> &'a mut Impl {
let implementation = scope.new_impl(name);

for (field_name, field_type) in fields.iter() {
for field in fields {
if getter_and_setter {
Self::impl_struct_field_get(implementation, field_name, field_type);
Self::impl_struct_field_get_mut(implementation, field_name, field_type);
Self::impl_struct_field_set(implementation, field_name, field_type);
Self::impl_struct_field_get(implementation, field.name(), field.r#type());
Self::impl_struct_field_get_mut(implementation, field.name(), field.r#type());
Self::impl_struct_field_set(implementation, field.name(), field.r#type());
}

Self::add_min_max_fn_if_applicable(implementation, Some(field_name), field_type);
Self::add_min_max_fn_if_applicable(implementation, Some(field.name()), field.r#type());
}
implementation
}
Expand Down
48 changes: 24 additions & 24 deletions asn1rs-model/src/gen/rust/protobuf.rs
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
use crate::gen::rust::GeneratorSupplement;
use crate::gen::rust::RustCodeGenerator;
use crate::model::protobuf::ToProtobufType;
use crate::model::rust::DataEnum;
use crate::model::rust::PlainEnum;
use crate::model::rust::{DataEnum, Field};
use crate::model::Definition;
use crate::model::ProtobufType;
use crate::model::Rust;
Expand Down Expand Up @@ -125,26 +125,26 @@ impl ProtobufSerializer {
function.line("Ok(me)");
}

fn impl_read_fn_for_struct(function: &mut Function, name: &str, fields: &[(String, RustType)]) {
for (field_name, _field_type) in fields.iter() {
fn impl_read_fn_for_struct(function: &mut Function, name: &str, fields: &[Field]) {
for field in fields.iter() {
function.line(format!(
"let mut read_{} = None;",
RustCodeGenerator::rust_field_name(field_name, false),
RustCodeGenerator::rust_field_name(field.name(), false),
));
}

let mut block_reader_loop = Block::new("while let Ok(tag) = reader.read_tag()");
let mut block_match_tag = Block::new("match tag.0");
block_match_tag.line("0 => break,");

for (prev_tag, (field_name, field_type)) in fields.iter().enumerate() {
match &field_type.clone().into_inner_type() {
for (prev_tag, field) in fields.iter().enumerate() {
match &field.r#type().clone().into_inner_type() {
RustType::Complex(name) => {
let mut block_case = Block::new(&format!(
"{} => read_{}{}(",
prev_tag + 1,
RustCodeGenerator::rust_field_name(field_name, false),
if let RustType::Vec(_) = field_type.clone().no_option() {
RustCodeGenerator::rust_field_name(field.name(), false),
if let RustType::Vec(_) = field.r#type().clone().no_option() {
".get_or_insert_with(Vec::default).push"
} else {
" = Some"
Expand All @@ -168,18 +168,18 @@ impl ProtobufSerializer {
block_match_tag.push_block(block_case);
}
role => {
if let RustType::Vec(_) = field_type.clone().no_option() {
if let RustType::Vec(_) = field.r#type().clone().no_option() {
block_match_tag.line(format!(
"{} => read_{}.get_or_insert_with(Vec::default).push({}),",
prev_tag + 1,
RustCodeGenerator::rust_field_name(field_name, false),
RustCodeGenerator::rust_field_name(field.name(), false),
format!("reader.read_{}()?", role.to_protobuf().to_string(),)
));
} else {
block_match_tag.line(format!(
"{} => read_{} = Some({}),",
prev_tag + 1,
RustCodeGenerator::rust_field_name(field_name, false),
RustCodeGenerator::rust_field_name(field.name(), false),
format!("reader.read_{}()?", role.to_protobuf().to_string(),)
));
}
Expand All @@ -194,24 +194,24 @@ impl ProtobufSerializer {
block_reader_loop.push_block(block_match_tag);
function.push_block(block_reader_loop);
let mut return_block = Block::new(&format!("Ok({}", name));
for (field_name, field_type) in fields.iter() {
for field in fields.iter() {
let as_rust_statement =
Self::get_as_rust_type_statement(&field_type.clone().into_inner_type());
Self::get_as_rust_type_statement(&field.r#type().clone().into_inner_type());
return_block.line(&format!(
"{}: read_{}{}{},",
RustCodeGenerator::rust_field_name(field_name, true),
RustCodeGenerator::rust_field_name(field_name, false),
RustCodeGenerator::rust_field_name(field.name(), true),
RustCodeGenerator::rust_field_name(field.name(), false),
if as_rust_statement.is_empty() {
"".into()
} else if let RustType::Vec(_) = field_type.clone().no_option() {
} else if let RustType::Vec(_) = field.r#type().clone().no_option() {
format!(
".map(|v| v.into_iter().map(|v| v{}).collect())",
as_rust_statement
)
} else {
format!(".map(|v| v{})", as_rust_statement)
},
if let RustType::Option(_) = field_type {
if let RustType::Option(_) = field.r#type() {
""
} else {
".unwrap_or_default()"
Expand Down Expand Up @@ -366,11 +366,11 @@ impl ProtobufSerializer {
function.push_block(block_writer);
}

fn impl_write_fn_for_struct(function: &mut Function, fields: &[(String, RustType)]) {
for (prev_tag, (field_name, field_type)) in fields.iter().enumerate() {
fn impl_write_fn_for_struct(function: &mut Function, fields: &[Field]) {
for (prev_tag, field) in fields.iter().enumerate() {
let block_: &mut Function = function;
let field_name = RustCodeGenerator::rust_field_name(field_name, true);
let mut block = if let RustType::Option(_) = field_type {
let field_name = RustCodeGenerator::rust_field_name(field.name(), true);
let mut block = if let RustType::Option(_) = field.r#type() {
Block::new(&format!(
"if let Some(ref {}) = self.{}",
&field_name, &field_name,
Expand All @@ -379,7 +379,7 @@ impl ProtobufSerializer {
Block::new("")
};

Self::impl_write_field(prev_tag + 1, field_type, &field_name, &mut block, false);
Self::impl_write_field(prev_tag + 1, field.r#type(), &field_name, &mut block, false);
block_.push_block(block);
}
}
Expand Down Expand Up @@ -551,11 +551,11 @@ impl ProtobufSerializer {
));
}
Rust::Struct(fields) => {
for (num, (field_name, _field_type)) in fields.iter().enumerate() {
for (num, field) in fields.iter().enumerate() {
if num > 0 {
function.line("&&");
}
let field_name = RustCodeGenerator::rust_field_name(field_name, true);
let field_name = RustCodeGenerator::rust_field_name(field.name(), true);
function.line(&format!(
"self.{}.{}_eq(&other.{})",
field_name,
Expand Down
Loading

0 comments on commit 5d7db2b

Please sign in to comment.