use command_enum_parsing::DataCommandEnum; use config::TrixyConfig; use proc_macro::TokenStream; use proc_macro2::TokenStream as TokenStream2; use quote::quote; use syn::parse_macro_input; use crate::trixy_lang::parse_trixy_lang; mod command_enum_parsing; mod config; mod generate; mod trixy_lang; /// This is the heart of the command api /// It mainly does two things: /// - Generate a command enum /// - Wrap the enum in all supported languages (only lua for now) /// - Generate wrapper lua function for each command /// - Generate a `add_lua_functions_to_globals` function, which adds /// the rust wrapper functions to the lua globals. /// /// The input and output values of the wrapped functions are derived from the values specified in /// the input to the `parse_command_enum` proc macro. /// /// For example this rust code: /// ```no_run /// parse_command_enum! { /// /// Greets the user /// greet: fn(String) -> String, /// } /// ``` /// results in this expanded code: /// ```no_run /// #[derive(Debug)] /// pub enum Command { /// Greet(String), /// } /// pub fn add_lua_functions_to_globals( /// lua: mlua::Lua, /// tx: tokio::sync::mpsc::Sender, /// ) -> mlua::Lua { /// lua.set_app_data(tx); /// let globals = lua.globals(); /// { /// let wrapped_lua_function_greet = lua /// .create_async_function(greet) /// .expect( /// format!( /// "The function: `{}` should be defined", /// "greet", /// ) /// ); /// globals /// .set("greet", wrapped_lua_function_greet) /// .expect("Setting a static global value should work"); /// } /// drop(globals); /// lua /// } /// async fn greet(lua: &mlua::Lua, input: String) -> Result { /// let (callback_tx, callback_rx) = tokio::sync::oneshot::channel::(); /// let tx: core::cell::Ref> = lua /// .app_data_ref() /// .expect("This should exist, it was set before"); /// (*tx) /// .send(Event::CommandEvent(Command::Greet(input.clone()), Some(callback_tx))) /// .await /// .expect("This should work, as the receiver is not dropped"); /// match callback_rx.await { /// Ok(output) => { /// return Ok(output); /// } /// Err(err) => { /// return Err(mlua::Error::ExternalError(std::sync::Arc::new(err))); /// } /// }; /// } /// ``` #[proc_macro] pub fn trixy_generate(input: TokenStream) -> TokenStream { let input = parse_macro_input!(input as TrixyConfig); let trixy_code = parse_trixy_lang(input.get_path()); todo!() // // Build the language wrappers // let lua_wrapper: TokenStream2 = generate::lua_wrapper(&input); // // // Build the final enum // let command_enum = generate::command_enum(&input); // let output = quote! { // #command_enum // #lua_wrapper // }; // output.into() }