trixy 0.4.0

A rust crate used to generate multi-language apis for your application
Documentation
/*
* Copyright (C) 2023 - 2024:
* The Trinitrix Project <soispha@vhack.eu, antifallobst@systemausfall.org>
* SPDX-License-Identifier: GPL-3.0-or-later
*
* This file is part of the Trixy crate for Trinitrix.
*
* Trixy is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as
* published by the Free Software Foundation, either version 3 of
* the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* and the GNU General Public License along with this program.
* If not, see <https://www.gnu.org/licenses/>.
*/

//! This module is responsible for generating the rust code used to interface with the api.
//! That includes the structs and enums declared in the trixy file and the enum used to describe the
//! command being executed.

use proc_macro2::TokenStream as TokenStream2;
use quote::quote;

use crate::{
    macros::{config::trixy::TrixyConfig, generate::host::format_rust},
    parser::command_spec::{CommandSpec, Enumeration, Namespace, Structure},
};

pub fn generate(trixy: &CommandSpec, config: &TrixyConfig) -> String {
    let host_rust_code = generate_code(&trixy, &config);

    let rust_code = format_rust(host_rust_code);

    format!(
        "\
/* Rust API */\n\
{}",
        rust_code
    )
}

/// This function turns, for example, the following trixy input into this rust code:
/// ```text
/// mod trinitrix {
///    struct Callback {
///        func: String,
///        timeout: String,
///    };
///
///    enum CallbackPriority {
///        High,
///        Medium,
///        Low,
///    };
///
///    fn execute_callback(callback: Callback, priority: CallbackPriority) -> String;
/// }
/// ```
/// ```no_run
/// #[derive(Debug)]
/// pub enum Commands {
///     Trinitrix(trinitrix::Trinitrix),
/// }
/// pub mod trinitrix {
///     #[allow(non_camel_case_types)]
///     #[derive(Debug)]
///     struct Callback {
///         func: String,
///         timeout: String,
///     }
///     #[allow(non_camel_case_types)]
///     #[derive(Debug)]
///     enum CallbackPriority {
///         High,
///         Medium,
///         Low,
///     }
///     #[derive(Debug)]
///     pub enum Trinitrix {
///         #[allow(non_camel_case_types)]
///         execute_callback {
///             callback: Callback,
///             priority: CallbackPriority,
///             trixy_output: trixy::oneshot::channel<String>
///         },
///     }
/// }
/// ```
pub fn generate_code(trixy: &CommandSpec, _config: &TrixyConfig) -> TokenStream2 {
    let modules: TokenStream2 = trixy
        .namespaces
        .iter()
        .map(|nasp| nasp.to_rust_module(&vec![]))
        .collect();
    let structures: TokenStream2 = trixy.structures.iter().map(Structure::to_rust).collect();
    let enumerations: TokenStream2 = trixy
        .enumerations
        .iter()
        .map(Enumeration::to_rust)
        .collect();
    let functions: Vec<TokenStream2> = trixy
        .functions
        .iter()
        .map(|r#fn| r#fn.to_rust(&[]))
        .collect();
    let namespace_modules: Vec<TokenStream2> = trixy
        .namespaces
        .iter()
        .map(Namespace::to_rust_module_enum)
        .collect();

    quote! {
        #structures
        #enumerations
        #[derive(Debug)]
        pub enum Commands {
            #(#functions,)*
            #(#namespace_modules),*
        }
        #modules
    }
}