use proc_macro2::TokenStream;
use quote::{format_ident, quote};
use crate::{dml::DmlMethod, type_system::FetchMethod};
#[derive(Debug, Clone)]
enum DerefPattern {
None, SingleDeref, DoubleDeref, }
pub fn generate_fetch_call_expr(
fetch_method: &FetchMethod,
pool_expr: &TokenStream,
) -> TokenStream {
match fetch_method {
FetchMethod::Execute => quote! { .execute(#pool_expr) },
FetchMethod::FetchOne => quote! { .fetch_one(#pool_expr) },
FetchMethod::FetchAll => quote! { .fetch_all(#pool_expr) },
FetchMethod::FetchOptional => quote! { .fetch_optional(#pool_expr) },
FetchMethod::Fetch => quote! { .fetch(#pool_expr) },
}
}
pub fn generate_pool_expr(method: &DmlMethod) -> TokenStream {
if let Some(pool_param) = method.parameters.iter().find(|p| p.is_pool) {
let pool_name = format_ident!("{}", pool_param.name);
match get_deref_pattern(&pool_param.type_) {
DerefPattern::DoubleDeref => quote! { &mut **#pool_name }, DerefPattern::SingleDeref => quote! { &mut *#pool_name }, DerefPattern::None => quote! { #pool_name }, }
} else {
quote! { self.get_pool() }
}
}
fn get_deref_pattern(ty: &syn::Type) -> DerefPattern {
let syn::Type::Reference(type_ref) = ty else {
return DerefPattern::None;
};
if type_ref.mutability.is_none() {
return DerefPattern::None;
}
let syn::Type::Path(type_path) = &*type_ref.elem else {
return DerefPattern::None;
};
let Some(segment) = type_path.path.segments.last() else {
return DerefPattern::None;
};
let segment_name = segment.ident.to_string();
match segment_name.as_str() {
"Transaction" => DerefPattern::DoubleDeref, name if name.ends_with("Connection") => DerefPattern::SingleDeref, _ => DerefPattern::None, }
}