|
|
|
@ -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()
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|