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/>.
*/

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

use proc_macro2::TokenStream as TokenStream2;

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!(
        "\
/* C API */\n\
// Workaround rust rules when implementing a foreign trait on a foreign type
#[derive(Debug)]
pub struct OurResult<T, E> {{
    value: Result<T, E>,
}}
impl<T, E> std::ops::Deref for OurResult<T, E> {{
    type Target = Result<T, E>;

    fn deref(&self) -> &Self::Target {{
        &self.value
    }}
}}
impl<T, E> From<Result<T, E>> for OurResult<T, E> {{
    fn from(value: Result<T, E>) -> Self {{
        Self {{ value }}
    }}
}}

#[derive(Debug)]
pub struct OurOption<T> {{
    value: Option<T>,
}}
impl<T> std::ops::Deref for OurOption<T> {{
    type Target = Option<T>;

    fn deref(&self) -> &Self::Target {{
        &self.value
    }}
}}

impl<T> From<Option<T>> for OurOption<T> {{
    fn from(value: Option<T>) -> Self {{
        Self {{ value }}
    }}
}}
#[derive(Debug)]
pub struct OurVec<T> {{
    value: Vec<T>,
}}
impl<T> std::ops::Deref for OurVec<T> {{
    type Target = Vec<T>;

    fn deref(&self) -> &Self::Target {{
        &self.value
    }}
}}


impl<T> From<Vec<T>> for OurVec<T> {{
    fn from(value: Vec<T>) -> Self {{
        Self {{ value }}
    }}
}}
/* The real C API */\n\
{}",
        rust_code
    )
}

/// This function generates the main c API provided by Trixy.
/// This works for example like this:
/// Turning this:
/// ```text
/// nasp trinitrix {
///     struct Callback {
///         func: String,
///         timeout: String,
///     };
///
///     enum CallbackPriority {
///         High,
///         Medium,
///         Low,
///     };
///
///     fn execute_callback(callback: Callback, priority: CallbackPriority);
/// }
/// ```
/// to this:
/// ```no_run
/// pub extern "C" fn exectute_callback(callback: Callback, priority: CallbackPriority) {
///     /* Here we simply call your handler function, with the command of the function */
/// }
/// ```
pub fn generate_code(trixy: &CommandSpec, config: &TrixyConfig) -> TokenStream2 {
    let root_namespace = Namespace::from(trixy);

    root_namespace.to_c(config, &vec![])
}