rust_to_dtr 0.16.0

Convert Rust Soroban contracts to DTR format.
Documentation
use crate::common::compilation_state;
use crate::errors::not_translatable_error::NotTranslatableError;
use crate::instruction::Instruction;
use crate::translate::expression::parse_expression;
use crate::translate::type_name::parse_path;
use syn::ExprStruct;

pub fn handle_struct_expression(
    expr: &ExprStruct,
    compilation_state: &mut compilation_state::CompilationState,
) -> Result<Vec<Instruction>, NotTranslatableError> {
    let mut instructions: Vec<Instruction> = Vec::new();
    let path_value: String = parse_path(&expr.path);

    let mut field_names: Vec<String> = Vec::new();

    expr.fields.iter().for_each(|field| {
        let field_name = match field.member {
            syn::Member::Named(ref ident) => ident.to_string(),
            syn::Member::Unnamed(_) => "".to_string(),
        };
        let field_value = field.expr.clone();

        let original_assignment = compilation_state.next_assignment.clone();

        let field_value_parsed = parse_expression(
            &field_value,
            &mut compilation_state.with_assignment(Some(field_name.clone())),
        );

        compilation_state.with_assignment(original_assignment);

        instructions.extend(field_value_parsed.unwrap_or(Vec::new()));
        field_names.push(field_name.clone());
    });

    field_names.insert(0, path_value.clone());
    field_names.insert(0, "UDT".to_string());

    instructions.push(Instruction::new(
        compilation_state.get_global_uuid(),
        "instantiate_object".to_string(),
        field_names,
        compilation_state.next_assignment.clone().unwrap_or(format!(
            "STRUCT_EXPRESSION_RESULT_{}",
            compilation_state.get_global_uuid()
        )),
        compilation_state.scope(),
    ));

    Ok(instructions)
}

#[cfg(test)]
mod tests {
    use crate::instruction::Instruction;
    use crate::{
        common::compilation_state::CompilationState,
        translate::expression::struct_expression::handle_struct_expression,
    };
    use syn::{parse_quote, ExprStruct};

    #[test]
    fn test_handle_struct_expression() {
        let mut compilation_state = CompilationState::new();
        let expr: ExprStruct = parse_quote! { Struct { a: 1, b: 2 } };
        let instructions = handle_struct_expression(&expr, &mut compilation_state).unwrap();
        assert_eq!(
            instructions,
            vec![
                Instruction::new(
                    0,
                    "assign".to_string(),
                    vec!["1".to_string()],
                    "a".to_string(),
                    0
                ),
                Instruction::new(
                    1,
                    "assign".to_string(),
                    vec!["2".to_string()],
                    "b".to_string(),
                    0
                ),
                Instruction::new(
                    2,
                    "instantiate_object".to_string(),
                    vec![
                        "UDT".to_string(),
                        "Struct".to_string(),
                        "a".to_string(),
                        "b".to_string()
                    ],
                    "STRUCT_EXPRESSION_RESULT_3".to_string(),
                    0
                )
            ]
        );
    }
}