use proc_macro2::TokenStream;
use quote::quote;
use crate::ir::FieldDefinition;
pub(crate) const DEFAULT_JSONRPC_CODE: i32 = -32000;
pub(crate) fn quote_option_str(opt: &Option<String>) -> TokenStream {
match opt {
Some(v) => quote! { Some(#v) },
None => quote! { None },
}
}
pub(crate) fn generate_downcast_attempts(name: &syn::Ident, method_name: &str) -> TokenStream {
let method_ident = syn::Ident::new(method_name, name.span());
quote! {
if let Some(concrete) = error.downcast_ref::<#name>() {
return Some(::apollo_errors::Error::#method_ident(concrete));
}
if let Some(boxed) = error.downcast_ref::<Box<#name>>() {
return Some(::apollo_errors::Error::#method_ident(boxed.as_ref()));
}
if let Some(arc) = error.downcast_ref::<std::sync::Arc<#name>>() {
return Some(::apollo_errors::Error::#method_ident(arc.as_ref()));
}
if let Some(box_arc) = error.downcast_ref::<Box<std::sync::Arc<#name>>>() {
return Some(::apollo_errors::Error::#method_ident(box_arc.as_ref().as_ref()));
}
None
}
}
pub(crate) fn generate_field_metadata(field: &FieldDefinition) -> TokenStream {
let rust_name = field.rust_name.to_string();
let output_name = &field.output_name;
let ty = &field.ty;
let ty_str = quote!(#ty).to_string();
let is_extension = field.is_extension;
let http_header = quote_option_str(&field.http_header);
quote! {
::apollo_errors::private::FieldMetadata {
rust_name: #rust_name,
output_name: #output_name,
ty: #ty_str,
is_extension: #is_extension,
http_header: #http_header,
}
}
}
pub(crate) fn generate_http_headers_body(
fields: &[FieldDefinition],
use_self_prefix: bool,
) -> TokenStream {
let header_fields: Vec<_> = fields
.iter()
.filter_map(|f| f.http_header.as_ref().map(|h| (f, h)))
.collect();
if header_fields.is_empty() {
quote! { Vec::new() }
} else {
let field_extractions: Vec<_> = header_fields
.iter()
.map(|(field, header_name)| {
let rust_name = &field.rust_name;
let header_name_lower = header_name.to_ascii_lowercase();
let (field_access, field_ref) = if use_self_prefix {
(quote! { self.#rust_name }, quote! { &self.#rust_name })
} else {
(quote! { #rust_name }, quote! { #rust_name })
};
if field.is_option {
quote! {
if let Some(__apollo_inner) = #field_access.as_ref() {
if let Some(__apollo_val) = ::apollo_errors::private::ToHeaderValue::to_header_value(__apollo_inner) {
__apollo_headers.push((
::apollo_errors::http::HeaderName::from_static(#header_name_lower),
__apollo_val,
));
}
}
}
} else {
quote! {
if let Some(__apollo_val) = ::apollo_errors::private::ToHeaderValue::to_header_value(#field_ref) {
__apollo_headers.push((
::apollo_errors::http::HeaderName::from_static(#header_name_lower),
__apollo_val,
));
}
}
}
})
.collect();
quote! {
{
let mut __apollo_headers = Vec::new();
#(#field_extractions)*
__apollo_headers
}
}
}
}