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 proc_macro2::TokenStream as TokenStream2;
use quote::quote;

use crate::parser::command_spec::Structure;

impl Structure {
    /// This function generates the `Convertible` implementation for a structure
    // was: `structure_convertable_derive`
    pub fn derive_convertible(&self, paired_type: &TokenStream2) -> TokenStream2 {
        let ident = self.identifier.to_rust();

        let into_fields: TokenStream2 = self
            .contents
            .iter()
            .map(|con| {
                let ident = &con.name.to_rust();
                quote! {
                    #ident: self.#ident.into(),
                }
            })
            .collect();

        quote! {
            impl trixy::types::traits::convert_trait::Convertible for #ident {
                type Ptr = #paired_type;

                fn into_ptr(self) -> Self::Ptr {
                    Self::Ptr {
                        #into_fields
                    }
                }

                fn from_ptr(_ptr: Self::Ptr) -> Result<Self, trixy::types::error::TypeConversionError> {
                    todo!()
                }
            }
        }
    }

    /// This function generates the `TryFrom<paired_type>` trait implementation for a given structure
    /// This function is more low-level, prefer to use the [`derive_from_c_paired_rust`] and
    /// [`derive_from_rust_paired_c`] functions instead.
    pub fn derive_from_paired(
        &self,
        ident_self: &TokenStream2,
        paired_type: &TokenStream2,
    ) -> TokenStream2 {
        let try_into_fields: TokenStream2 = self
            .contents
            .iter()
            .map(|content| {
                let name = content.name.to_rust();
                quote! {
                    // #paired_type :: #name => Self :: #name,
                    #name: value.#name.try_into()?,
                }
            })
            .collect();
        quote! {
            impl TryFrom<#paired_type> for #ident_self {
                type Error = trixy::types::error::TypeConversionError;

                fn try_from(value: #paired_type) -> Result<Self, Self::Error> {
                    Ok(Self {
                        #try_into_fields
                    })
                }
            }
        }
    }

    /// This function generates the `TryFrom<paired_type>` trait implementation for a given c
    /// structure
    pub fn derive_from_c_paired_rust(&self, paired_rust_type: &TokenStream2) -> TokenStream2 {
        let c_ident = self.identifier.to_c();

        self.derive_from_paired(&c_ident, &paired_rust_type)
    }

    /// This function generates the `TryFrom<paired_type>` trait implementation for a given rust
    /// structure
    pub fn derive_from_rust_paired_c(&self, paired_c_type: &TokenStream2) -> TokenStream2 {
        let rust_ident = self.identifier.to_rust();

        self.derive_from_paired(&rust_ident, &paired_c_type)
    }
}