forked from trinitrix/core
1
0
Fork 0
core/trixy/src/lib.rs

98 lines
3.0 KiB
Rust

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<Event>,
/// ) -> 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<String, mlua::Error> {
/// let (callback_tx, callback_rx) = tokio::sync::oneshot::channel::<String>();
/// let tx: core::cell::Ref<tokio::sync::mpsc::Sender<Event>> = 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()
}