1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
// Copyright (c) The Diem Core Contributors
// SPDX-License-Identifier: Apache-2.0

use crate::{account_address::AccountAddress, value::MoveValue};
use serde::{Deserialize, Serialize};
use std::fmt;

#[derive(Clone, Hash, Eq, PartialEq, Serialize, Deserialize)]
pub enum TransactionArgument {
    U8(u8),
    U64(u64),
    U128(u128),
    Address(AccountAddress),
    U8Vector(#[serde(with = "serde_bytes")] Vec<u8>),
    Bool(bool),
}

impl fmt::Debug for TransactionArgument {
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
        match self {
            TransactionArgument::U8(value) => write!(f, "{{U8: {}}}", value),
            TransactionArgument::U64(value) => write!(f, "{{U64: {}}}", value),
            TransactionArgument::U128(value) => write!(f, "{{U128: {}}}", value),
            TransactionArgument::Bool(boolean) => write!(f, "{{BOOL: {}}}", boolean),
            TransactionArgument::Address(address) => write!(f, "{{ADDRESS: {:?}}}", address),
            TransactionArgument::U8Vector(vector) => {
                write!(f, "{{U8Vector: 0x{}}}", hex::encode(vector))
            }
        }
    }
}

/// Convert the transaction arguments into Move values.
pub fn convert_txn_args(args: &[TransactionArgument]) -> Vec<Vec<u8>> {
    args.iter()
        .map(|arg| {
            let mv = match arg {
                TransactionArgument::U8(i) => MoveValue::U8(*i),
                TransactionArgument::U64(i) => MoveValue::U64(*i),
                TransactionArgument::U128(i) => MoveValue::U128(*i),
                TransactionArgument::Address(a) => MoveValue::Address(*a),
                TransactionArgument::Bool(b) => MoveValue::Bool(*b),
                TransactionArgument::U8Vector(v) => MoveValue::vector_u8(v.clone()),
            };
            mv.simple_serialize()
                .expect("transaction arguments must serialize")
        })
        .collect()
}

/// Struct for encoding vector<vector<u8>> arguments for script functions
#[derive(Clone, Hash, Eq, PartialEq, Deserialize)]
pub struct VecBytes(Vec<serde_bytes::ByteBuf>);

impl VecBytes {
    pub fn from(vec_bytes: Vec<Vec<u8>>) -> Self {
        VecBytes(
            vec_bytes
                .into_iter()
                .map(serde_bytes::ByteBuf::from)
                .collect(),
        )
    }

    pub fn into_vec(self) -> Vec<Vec<u8>> {
        self.0
            .into_iter()
            .map(|byte_buf| byte_buf.into_vec())
            .collect()
    }
}