Compare commits

...

3 Commits

@ -1,7 +1,7 @@
use quote::quote;
use syn::parse::{Parse, ParseStream};
use syn::punctuated::Punctuated;
use syn::{bracketed, parse_macro_input, Expr, Ident, LitStr, Token};
use syn::{bracketed, parse_macro_input, Ident, Expr, LitStr, Token};
extern crate proc_macro;
@ -21,7 +21,7 @@ pub fn query_parsed(input: proc_macro::TokenStream) -> proc_macro::TokenStream {
.await.expect("Query failed").into_iter().peekable()
};
let parse = generate_parse_expression(&column_mapping);
let parse = generate_parse_expression(&column_mapping, None);
let result = quote! {
{
@ -43,10 +43,10 @@ pub fn query_parsed(input: proc_macro::TokenStream) -> proc_macro::TokenStream {
proc_macro::TokenStream::from(result)
}
fn generate_parse_expression(value: &TypeMapping) -> proc_macro2::TokenStream {
fn generate_parse_expression(value: &TypeMapping, parent_id_column: Option<&Ident>) -> proc_macro2::TokenStream {
match value.clone() {
TypeMapping::Column(name) => generate_parse_column(name),
TypeMapping::Vec(mapping) => generate_parse_vec(mapping),
TypeMapping::Vec(mapping) => generate_parse_vec(mapping, parent_id_column),
TypeMapping::Object {
struct_name,
properties,
@ -55,6 +55,8 @@ fn generate_parse_expression(value: &TypeMapping) -> proc_macro2::TokenStream {
}
fn generate_parse_column(column: Ident) -> proc_macro2::TokenStream {
let col_name : LitStr = LitStr::new(column.to_string().as_str(), column.span());
quote! {
{
let mut parse_closure = || -> joinrs::anyhow::Result<_> {
@ -64,7 +66,7 @@ fn generate_parse_column(column: Ident) -> proc_macro2::TokenStream {
if let Some(column) = col_opt {
Ok(column)
} else {
Err(joinrs::err::QueryError::NullColumn("#column".to_string()).into())
Err(joinrs::err::QueryError::NullColumn(#col_name.to_string()).into())
}
};
parse_closure()
@ -76,12 +78,21 @@ fn generate_parse_object(
struct_name: Ident,
properties: Vec<TypeProperty>,
) -> proc_macro2::TokenStream {
let id_property = properties.iter().find_map(|property| -> Option<&Ident> {
if property.name.to_string().eq("uuid") {
if let TypeMapping::Column(column_name) = &property.mapping {
return Some(&column_name)
}
};
None
});
let property_lines =
properties
.iter()
.map(|property: &TypeProperty| -> proc_macro2::TokenStream {
let name = &property.name;
let value = generate_parse_expression(&property.mapping);
let value = generate_parse_expression(&property.mapping, id_property);
quote! {
#name: #value?
}
@ -99,21 +110,40 @@ fn generate_parse_object(
}
}
fn generate_parse_vec(inner_type: Box<TypeMapping>) -> proc_macro2::TokenStream {
let value_expression = generate_parse_expression(&*inner_type);
fn generate_parse_vec(inner_type: Box<TypeMapping>, parent_id_column: Option<&Ident>) -> proc_macro2::TokenStream {
let value_expression = generate_parse_expression(&*inner_type, parent_id_column);
quote! {
{
let mut parse_closure = || -> joinrs::anyhow::Result<_> {
let mut vec = Vec::new();
let parse_result = #value_expression;
let first_row = rows.peek();
let parent_id;
if let Some(row) = &first_row {
parent_id = row.#parent_id_column;
} else {
return Ok(vec)
}
if let Ok(value) = parse_result {
vec.push(value);
while let Some(_current_row) = rows.peek() {
if let Ok(current_row_value) = #value_expression {
vec.push(current_row_value);
if let Some(_next_row) = rows.peek() {
if _next_row.#parent_id_column == parent_id {
rows.next();
continue
}
}
} else {
break;
}
}
Ok(vec)
};
parse_closure()
}
}

Loading…
Cancel
Save