use std::error::Error; use std::str::FromStr; use opengl_registry::command::Command; use proc_macro2::{LexError, TokenStream}; use quote::{format_ident, quote}; use crate::codegen::formatting::{clean_param_name, fix_type}; pub fn create_command_functions( commands: &[Command], ) -> Result, Box> { commands.iter().map(|command| { let command_name_str = command.prototype().name(); let command_name = format_ident!("{}", command.prototype().name()); let command_name_prefixless = format_ident!("{}", command.prototype() .name() .strip_prefix("gl") .unwrap_or_else(|| command.prototype().name())); let command_args = command .parameters() .iter() .map(|param| { let param_name = format_ident!("{}", clean_param_name(param.name())); let param_type = TokenStream::from_str(&fix_type(param.get_type()))?; Ok::<_, LexError>(quote! { #param_name: #param_type }) }).collect::, _>>()?; let command_return_type = TokenStream::from_str(&fix_type(command.prototype().return_type()))?; let command_arg_types = command .parameters() .iter() .map(|param| TokenStream::from_str(&fix_type(param.get_type()))) .collect::, _>>()?; let command_arg_names = command .parameters() .iter() .map(|param| format_ident!("{}", clean_param_name(param.name()))) .collect::>(); Ok(quote! { #[doc = #command_name_str] #[allow(non_snake_case, clippy::too_many_arguments)] pub unsafe fn #command_name_prefixless(#(#command_args),*) -> #command_return_type { type GLFunc = unsafe extern "C" fn(#(#command_arg_types),*) -> #command_return_type; let gl_func = std::mem::transmute::<_, GLFunc>(functions::#command_name); gl_func(#(#command_arg_names),*) } }) }).collect() }