rsbind 0.6.0

Provide tools to bind rust trait with other language and export library artifact directly. Invoke rust functions just like you write it in native language.
Documentation
use rstgen::swift::{local, Argument, Constructor, Field, Method, Modifier, Swift};
use rstgen::{swift, IntoTokens};

use crate::ast::contract::desc::StructDesc;
use crate::base::lang::{Convertible, Direction};
use crate::errors::*;
use crate::swift::converter::SwiftConvert;
use crate::swift::types::{to_swift_file, SwiftType};

pub(crate) struct StructGen<'a> {
    pub desc: &'a StructDesc,
}

impl<'a> StructGen<'a> {
    pub fn gen(&self) -> Result<String> {
        let mut struct_ = swift::Struct::new(self.desc.name.clone());
        struct_.modifiers.push(Modifier::Public);
        struct_.implements.push(local("Codable"));

        let mut constructor1 = Constructor::new();
        constructor1.modifiers = vec![Modifier::Public];
        for arg in self.desc.fields.iter() {
            let field_ty = SwiftType::new(arg.ty.clone());
            let swift_ty = Swift::from(field_ty);
            let mut swift_field = Field::new(swift_ty.clone(), arg.name.clone());
            swift_field.modifiers = vec![Modifier::Public];
            struct_.fields.push(swift_field);

            constructor1
                .arguments
                .push(Argument::new(swift_ty.clone(), arg.name.clone()));
            push_f!(constructor1.body, "self.{} = {}", arg.name, arg.name);
        }
        struct_.constructors.push(constructor1);
        struct_.constructors.push(self.create_proxy_constructor());
        struct_.methods.push(self.create_into_proxy_fn());

        to_swift_file(struct_.into_tokens())
    }

    fn create_into_proxy_fn(&self) -> Method {
        let mut method = swift::Method::new("intoProxy");
        method.modifiers = vec![Modifier::Internal];
        method.returns(swift::local(format!("Proxy{}", &self.desc.name)));
        push_f!(method.body, "return Proxy{} (", self.desc.name);
        for (index, field) in self.desc.fields.iter().enumerate() {
            let convert = SwiftConvert {
                ty: field.ty.clone(),
            }
            .native_to_transferable(format!("self.{}", &field.name), Direction::Down);
            nested_f!(method.body, "{} : {}", field.name, convert);
            if index != self.desc.fields.len() - 1 {
                method.body.append(",")
            }
        }
        push!(method.body, ")");

        method
    }

    fn create_proxy_constructor(&self) -> Constructor {
        let mut constructor2 = Constructor::new();
        constructor2.modifiers = vec![Modifier::Internal];
        constructor2.arguments.push(Argument::new(
            swift::local(format!("Proxy{}", &self.desc.name)),
            "proxy",
        ));

        for field in self.desc.fields.iter() {
            let convert = SwiftConvert {
                ty: field.ty.clone(),
            }
            .transferable_to_native(format!("proxy.{}", &field.name), Direction::Down);
            push_f!(constructor2.body, "self.{} = {}", field.name, convert);
        }

        constructor2
    }
}