// Copyright (c) Aptos // SPDX-License-Identifier: Apache-2.0 use aptos_types::transaction::ScriptABI; use cached_framework_packages::abis; use serde_generate as serdegen; use serde_generate::SourceInstaller as _; use serde_reflection::Registry; use std::{io::Write, process::Command}; use tempfile::tempdir; use transaction_builder_generator as buildgen; fn get_aptos_registry() -> Registry { let path = "../../testsuite/generate-format/tests/staged/aptos.yaml"; let content = std::fs::read_to_string(path).unwrap(); serde_yaml::from_str::(content.as_str()).unwrap() } fn get_script_fun_abis() -> Vec { abis() } const EXPECTED_SCRIPT_FUN_OUTPUT: &str = "3 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 8 84 101 115 116 67 111 105 110 8 116 114 97 110 115 102 101 114 0 2 32 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 34 34 34 34 34 34 34 34 34 34 34 34 34 34 34 34 8 135 214 18 0 0 0 0 0 \n"; fn test_rust(abis: &[ScriptABI], demo_file: &str, expected_output: &str) { let mut registry = get_aptos_registry(); buildgen::rust::replace_keywords(&mut registry); let dir = tempdir().unwrap(); let installer = serdegen::rust::Installer::new(dir.path().to_path_buf()); let config = serdegen::CodeGeneratorConfig::new("aptos-types".to_string()); installer.install_module(&config, ®istry).unwrap(); let stdlib_dir_path = dir.path().join("framework"); std::fs::create_dir_all(stdlib_dir_path.clone()).unwrap(); let mut cargo = std::fs::File::create(&stdlib_dir_path.join("Cargo.toml")).unwrap(); write!( cargo, r#"[package] name = "framework" version = "0.1.0" edition = "2018" [dependencies] aptos-types = {{ path = "../aptos-types", version = "0.1.0" }} serde_bytes = "0.11.6" serde = {{ version = "1.0.114", features = ["derive"] }} bcs = "0.1.3" once_cell = "1.10.0" [[bin]] name = "stdlib_demo" path = "src/stdlib_demo.rs" test = false "# ) .unwrap(); std::fs::create_dir(stdlib_dir_path.join("src")).unwrap(); let source_path = stdlib_dir_path.join("src/lib.rs"); let mut source = std::fs::File::create(&source_path).unwrap(); buildgen::rust::output(&mut source, abis, /* local types */ false).unwrap(); std::fs::copy(demo_file, stdlib_dir_path.join("src/stdlib_demo.rs")).unwrap(); // Use a stable `target` dir to avoid downloading and recompiling crates everytime. let target_dir = std::env::current_dir().unwrap().join("../../target"); let status = Command::new("cargo") .current_dir(dir.path().join("framework")) .arg("build") .arg("--target-dir") .arg(target_dir.clone()) .status() .unwrap(); assert!(status.success()); let output = Command::new(target_dir.join("debug/stdlib_demo")) .output() .unwrap(); assert!(output.status.success()); assert_eq!( std::str::from_utf8(&output.stdout).unwrap(), expected_output ); } #[test] // Ignored because transactions require minting/transfering Coin, which the // transaction builder does not support (it doesn't supported typed functions yet). #[ignore] fn test_that_rust_script_fun_code_compiles() { test_rust( &get_script_fun_abis(), "examples/rust/script_fun_demo.rs", EXPECTED_SCRIPT_FUN_OUTPUT, ); }