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
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
use std::convert::TryFrom;

use num_derive::{FromPrimitive, ToPrimitive};
use num_traits::{FromPrimitive, ToPrimitive};

#[derive(Debug, PartialEq, FromPrimitive, ToPrimitive, Clone, Copy)]
#[repr(usize)]
pub enum FunctionIndex {
    WriteFuncIndex,
    ReadFuncIndex,
    AddFuncIndex,
    NewFuncIndex,
    RetFuncIndex,
    CallContractFuncIndex,
    GetKeyFuncIndex,
    GasFuncIndex,
    HasKeyFuncIndex,
    PutKeyFuncIndex,
    IsValidURefFnIndex,
    RevertFuncIndex,
    AddAssociatedKeyFuncIndex,
    RemoveAssociatedKeyFuncIndex,
    UpdateAssociatedKeyFuncIndex,
    SetActionThresholdFuncIndex,
    LoadNamedKeysFuncIndex,
    RemoveKeyFuncIndex,
    GetCallerIndex,
    GetBlocktimeIndex,
    CreatePurseIndex,
    TransferToAccountIndex,
    TransferFromPurseToAccountIndex,
    TransferFromPurseToPurseIndex,
    GetBalanceIndex,
    GetPhaseIndex,
    GetSystemContractIndex,
    GetMainPurseIndex,
    ReadHostBufferIndex,
    CreateContractPackageAtHash,
    AddContractVersion,
    DisableContractVersion,
    CallVersionedContract,
    CreateContractUserGroup,
    #[cfg(feature = "test-support")]
    PrintIndex,
    GetRuntimeArgsizeIndex,
    GetRuntimeArgIndex,
    RemoveContractUserGroupIndex,
    ExtendContractUserGroupURefsIndex,
    RemoveContractUserGroupURefsIndex,
    Blake2b,
    RecordTransfer,
    RecordEraInfo,
    NewDictionaryFuncIndex,
    DictionaryGetFuncIndex,
    DictionaryPutFuncIndex,
    LoadCallStack,
}

impl From<FunctionIndex> for usize {
    fn from(index: FunctionIndex) -> usize {
        // NOTE: This can't fail as `FunctionIndex` is represented by usize,
        // so this serves mostly as a syntax sugar.
        index.to_usize().unwrap()
    }
}

impl TryFrom<usize> for FunctionIndex {
    type Error = &'static str;
    fn try_from(value: usize) -> Result<Self, Self::Error> {
        FromPrimitive::from_usize(value).ok_or("Invalid function index")
    }
}

#[cfg(test)]
mod tests {
    use super::FunctionIndex;
    use std::convert::TryFrom;

    #[test]
    fn primitive_to_enum() {
        FunctionIndex::try_from(19).expect("Unable to create enum from number");
    }

    #[test]
    fn enum_to_primitive() {
        let element = FunctionIndex::UpdateAssociatedKeyFuncIndex;
        let _primitive: usize = element.into();
    }

    #[test]
    fn invalid_index() {
        assert!(FunctionIndex::try_from(123_456_789usize).is_err());
    }
}