scrypto_bindgen/
types.rs

1use radix_common::prelude::*;
2use radix_rust::prelude::{hashmap, HashMap};
3
4// This structure describes function argument and return types replacements.
5#[derive(Debug)]
6pub struct FunctionSignatureReplacementsInput {
7    pub blueprint_name: String, // Name of the blueprint, which shall have replaced types
8    pub func_name: String,      // Name of the function, which shall have replaced types
9    pub replacement_map: FunctionSignatureReplacements,
10}
11
12pub type FunctionSignaturesReplacementMap = HashMap<String, FunctionSignatureReplacements>;
13pub type BlueprintFunctionSignaturesReplacementMap =
14    HashMap<String, FunctionSignaturesReplacementMap>;
15
16#[derive(Debug, Clone)]
17pub struct FunctionSignatureReplacements {
18    pub arg: HashMap<usize, String>, // Map of argument indexes and their new type names
19    pub output: Option<String>,      // Name of the new return type
20}
21
22pub fn prepare_replacement_map(
23    replacement_vec: &[FunctionSignatureReplacementsInput],
24) -> BlueprintFunctionSignaturesReplacementMap {
25    let mut blueprint_replacement_map: BlueprintFunctionSignaturesReplacementMap = hashmap!();
26
27    for item in replacement_vec {
28        if blueprint_replacement_map
29            .get(&item.blueprint_name)
30            .is_some()
31        {
32            let function_map = blueprint_replacement_map
33                .get_mut(&item.blueprint_name)
34                .unwrap();
35            function_map.insert(item.func_name.clone(), item.replacement_map.clone());
36        } else {
37            let mut function_map = hashmap!();
38            function_map.insert(item.func_name.clone(), item.replacement_map.clone());
39            blueprint_replacement_map.insert(item.blueprint_name.clone(), function_map);
40        };
41    }
42    blueprint_replacement_map
43}
44
45impl FromStr for FunctionSignatureReplacementsInput {
46    type Err = String;
47
48    // Get FunctionSignatureReplacementsInput from a string.
49    // Syntax:
50    //   blueprint_name=<blueprint_name>;func_name=<function_name>;<argument_index>:<type_replacement>;r:<type_replacement>
51    // Example:
52    //   - replace first argument and return type to FungibleBucket of the function 'new'
53    //      blueprint_name=Faucet;func_name=new;0=FungibleBucket;r=FungibleBucket
54    fn from_str(input: &str) -> Result<Self, Self::Err> {
55        let mut items = input.split(";");
56
57        let mut blueprint_name_items = items
58            .next()
59            .ok_or("Cannot determine blueprint name")?
60            .split("=");
61
62        let blueprint_name = match blueprint_name_items.next() {
63            Some(val) if val == "blueprint_name" => blueprint_name_items.next(),
64            Some(_) => None,
65            None => None,
66        }
67        .ok_or("blueprint_name not found")?
68        .to_string();
69
70        let mut func_name_items = items
71            .next()
72            .ok_or("Cannot determine function name")?
73            .split("=");
74
75        let func_name = match func_name_items.next() {
76            Some(val) if val == "func_name" => func_name_items.next(),
77            Some(_) => None,
78            None => None,
79        }
80        .ok_or("func_name not found")?
81        .to_string();
82
83        let mut arg = hashmap!();
84        let mut output = None;
85
86        for item in items {
87            let mut s = item.split("=");
88            match s.next() {
89                Some(val) if val == "r" => {
90                    let ty = s.next().ok_or("Return type not available".to_string())?;
91                    output = Some(ty.to_string());
92                }
93                Some(val) => {
94                    let idx: usize = val.parse().map_err(|_| "Failed to parse integer")?;
95                    let ty = s.next().ok_or("Arg type not available")?;
96                    arg.insert(idx, ty.to_string());
97                }
98                None => Err("Argument index or return type not available")?,
99            }
100        }
101
102        Ok(Self {
103            blueprint_name,
104            func_name,
105            replacement_map: FunctionSignatureReplacements { arg, output },
106        })
107    }
108}