• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1import re
2
3
4class RustType(object):
5    OTHER = "Other"
6    STRUCT = "Struct"
7    TUPLE = "Tuple"
8    CSTYLE_VARIANT = "CStyleVariant"
9    TUPLE_VARIANT = "TupleVariant"
10    STRUCT_VARIANT = "StructVariant"
11    ENUM = "Enum"
12    EMPTY = "Empty"
13    SINGLETON_ENUM = "SingletonEnum"
14    REGULAR_ENUM = "RegularEnum"
15    COMPRESSED_ENUM = "CompressedEnum"
16    REGULAR_UNION = "RegularUnion"
17
18    STD_STRING = "StdString"
19    STD_OS_STRING = "StdOsString"
20    STD_STR = "StdStr"
21    STD_SLICE = "StdSlice"
22    STD_VEC = "StdVec"
23    STD_VEC_DEQUE = "StdVecDeque"
24    STD_BTREE_SET = "StdBTreeSet"
25    STD_BTREE_MAP = "StdBTreeMap"
26    STD_HASH_MAP = "StdHashMap"
27    STD_HASH_SET = "StdHashSet"
28    STD_RC = "StdRc"
29    STD_ARC = "StdArc"
30    STD_CELL = "StdCell"
31    STD_REF = "StdRef"
32    STD_REF_MUT = "StdRefMut"
33    STD_REF_CELL = "StdRefCell"
34    STD_NONZERO_NUMBER = "StdNonZeroNumber"
35
36
37STD_STRING_REGEX = re.compile(r"^(alloc::(\w+::)+)String$")
38STD_STR_REGEX = re.compile(r"^&(mut )?str$")
39STD_SLICE_REGEX = re.compile(r"^&(mut )?\[.+\]$")
40STD_OS_STRING_REGEX = re.compile(r"^(std::ffi::(\w+::)+)OsString$")
41STD_VEC_REGEX = re.compile(r"^(alloc::(\w+::)+)Vec<.+>$")
42STD_VEC_DEQUE_REGEX = re.compile(r"^(alloc::(\w+::)+)VecDeque<.+>$")
43STD_BTREE_SET_REGEX = re.compile(r"^(alloc::(\w+::)+)BTreeSet<.+>$")
44STD_BTREE_MAP_REGEX = re.compile(r"^(alloc::(\w+::)+)BTreeMap<.+>$")
45STD_HASH_MAP_REGEX = re.compile(r"^(std::collections::(\w+::)+)HashMap<.+>$")
46STD_HASH_SET_REGEX = re.compile(r"^(std::collections::(\w+::)+)HashSet<.+>$")
47STD_RC_REGEX = re.compile(r"^(alloc::(\w+::)+)Rc<.+>$")
48STD_ARC_REGEX = re.compile(r"^(alloc::(\w+::)+)Arc<.+>$")
49STD_CELL_REGEX = re.compile(r"^(core::(\w+::)+)Cell<.+>$")
50STD_REF_REGEX = re.compile(r"^(core::(\w+::)+)Ref<.+>$")
51STD_REF_MUT_REGEX = re.compile(r"^(core::(\w+::)+)RefMut<.+>$")
52STD_REF_CELL_REGEX = re.compile(r"^(core::(\w+::)+)RefCell<.+>$")
53STD_NONZERO_NUMBER_REGEX = re.compile(r"^core::num::([a-z_]+::)*NonZero.+$")
54
55TUPLE_ITEM_REGEX = re.compile(r"__\d+$")
56
57ENCODED_ENUM_PREFIX = "RUST$ENCODED$ENUM$"
58ENUM_DISR_FIELD_NAME = "<<variant>>"
59
60STD_TYPE_TO_REGEX = {
61    RustType.STD_STRING: STD_STRING_REGEX,
62    RustType.STD_OS_STRING: STD_OS_STRING_REGEX,
63    RustType.STD_STR: STD_STR_REGEX,
64    RustType.STD_SLICE: STD_SLICE_REGEX,
65    RustType.STD_VEC: STD_VEC_REGEX,
66    RustType.STD_VEC_DEQUE: STD_VEC_DEQUE_REGEX,
67    RustType.STD_HASH_MAP: STD_HASH_MAP_REGEX,
68    RustType.STD_HASH_SET: STD_HASH_SET_REGEX,
69    RustType.STD_BTREE_SET: STD_BTREE_SET_REGEX,
70    RustType.STD_BTREE_MAP: STD_BTREE_MAP_REGEX,
71    RustType.STD_RC: STD_RC_REGEX,
72    RustType.STD_ARC: STD_ARC_REGEX,
73    RustType.STD_REF: STD_REF_REGEX,
74    RustType.STD_REF_MUT: STD_REF_MUT_REGEX,
75    RustType.STD_REF_CELL: STD_REF_CELL_REGEX,
76    RustType.STD_CELL: STD_CELL_REGEX,
77    RustType.STD_NONZERO_NUMBER: STD_NONZERO_NUMBER_REGEX,
78}
79
80def is_tuple_fields(fields):
81    # type: (list) -> bool
82    return all(TUPLE_ITEM_REGEX.match(str(field.name)) for field in fields)
83
84
85def classify_struct(name, fields):
86    if len(fields) == 0:
87        return RustType.EMPTY
88
89    for ty, regex in STD_TYPE_TO_REGEX.items():
90        if regex.match(name):
91            return ty
92
93    if fields[0].name == ENUM_DISR_FIELD_NAME:
94        return RustType.ENUM
95
96    if is_tuple_fields(fields):
97        return RustType.TUPLE
98
99    return RustType.STRUCT
100
101
102def classify_union(fields):
103    if len(fields) == 0:
104        return RustType.EMPTY
105
106    first_variant_name = fields[0].name
107    if first_variant_name is None:
108        if len(fields) == 1:
109            return RustType.SINGLETON_ENUM
110        else:
111            return RustType.REGULAR_ENUM
112    elif first_variant_name.startswith(ENCODED_ENUM_PREFIX):
113        assert len(fields) == 1
114        return RustType.COMPRESSED_ENUM
115    else:
116        return RustType.REGULAR_UNION
117