blob: c0415a3cdcfe485453dc970e4b157c5f903d98e4 [file] [log] [blame]
import re
class RustType(object):
OTHER = "Other"
STRUCT = "Struct"
TUPLE = "Tuple"
CSTYLE_VARIANT = "CStyleVariant"
TUPLE_VARIANT = "TupleVariant"
STRUCT_VARIANT = "StructVariant"
ENUM = "Enum"
EMPTY = "Empty"
SINGLETON_ENUM = "SingletonEnum"
REGULAR_ENUM = "RegularEnum"
COMPRESSED_ENUM = "CompressedEnum"
REGULAR_UNION = "RegularUnion"
STD_STRING = "StdString"
STD_OS_STRING = "StdOsString"
STD_STR = "StdStr"
STD_SLICE = "StdSlice"
STD_VEC = "StdVec"
STD_VEC_DEQUE = "StdVecDeque"
STD_BTREE_SET = "StdBTreeSet"
STD_BTREE_MAP = "StdBTreeMap"
STD_HASH_MAP = "StdHashMap"
STD_HASH_SET = "StdHashSet"
STD_RC = "StdRc"
STD_ARC = "StdArc"
STD_CELL = "StdCell"
STD_REF = "StdRef"
STD_REF_MUT = "StdRefMut"
STD_REF_CELL = "StdRefCell"
STD_NONZERO_NUMBER = "StdNonZeroNumber"
STD_PATH = "StdPath"
STD_PATHBUF = "StdPathBuf"
STD_STRING_REGEX = re.compile(r"^(alloc::([a-z_]+::)+)String$")
STD_STR_REGEX = re.compile(r"^&(mut )?str$")
STD_SLICE_REGEX = re.compile(r"^&(mut )?\[.+\]$")
STD_OS_STRING_REGEX = re.compile(r"^(std::ffi::([a-z_]+::)+)OsString$")
STD_VEC_REGEX = re.compile(r"^(alloc::([a-z_]+::)+)Vec<.+>$")
STD_VEC_DEQUE_REGEX = re.compile(r"^(alloc::([a-z_]+::)+)VecDeque<.+>$")
STD_BTREE_SET_REGEX = re.compile(r"^(alloc::([a-z_]+::)+)BTreeSet<.+>$")
STD_BTREE_MAP_REGEX = re.compile(r"^(alloc::([a-z_]+::)+)BTreeMap<.+>$")
STD_HASH_MAP_REGEX = re.compile(r"^(std::collections::([a-z_]+::)+)HashMap<.+>$")
STD_HASH_SET_REGEX = re.compile(r"^(std::collections::([a-z_]+::)+)HashSet<.+>$")
STD_RC_REGEX = re.compile(r"^(alloc::([a-z_]+::)+)Rc<.+>$")
STD_ARC_REGEX = re.compile(r"^(alloc::([a-z_]+::)+)Arc<.+>$")
STD_CELL_REGEX = re.compile(r"^(core::([a-z_]+::)+)Cell<.+>$")
STD_REF_REGEX = re.compile(r"^(core::([a-z_]+::)+)Ref<.+>$")
STD_REF_MUT_REGEX = re.compile(r"^(core::([a-z_]+::)+)RefMut<.+>$")
STD_REF_CELL_REGEX = re.compile(r"^(core::([a-z_]+::)+)RefCell<.+>$")
STD_NONZERO_NUMBER_REGEX = re.compile(r"^(core::([a-z_]+::)+)NonZero<.+>$")
STD_PATHBUF_REGEX = re.compile(r"^(std::([a-z_]+::)+)PathBuf$")
STD_PATH_REGEX = re.compile(r"^&(mut )?(std::([a-z_]+::)+)Path$")
TUPLE_ITEM_REGEX = re.compile(r"__\d+$")
ENCODED_ENUM_PREFIX = "RUST$ENCODED$ENUM$"
ENUM_DISR_FIELD_NAME = "<<variant>>"
STD_TYPE_TO_REGEX = {
RustType.STD_STRING: STD_STRING_REGEX,
RustType.STD_OS_STRING: STD_OS_STRING_REGEX,
RustType.STD_STR: STD_STR_REGEX,
RustType.STD_SLICE: STD_SLICE_REGEX,
RustType.STD_VEC: STD_VEC_REGEX,
RustType.STD_VEC_DEQUE: STD_VEC_DEQUE_REGEX,
RustType.STD_HASH_MAP: STD_HASH_MAP_REGEX,
RustType.STD_HASH_SET: STD_HASH_SET_REGEX,
RustType.STD_BTREE_SET: STD_BTREE_SET_REGEX,
RustType.STD_BTREE_MAP: STD_BTREE_MAP_REGEX,
RustType.STD_RC: STD_RC_REGEX,
RustType.STD_ARC: STD_ARC_REGEX,
RustType.STD_REF: STD_REF_REGEX,
RustType.STD_REF_MUT: STD_REF_MUT_REGEX,
RustType.STD_REF_CELL: STD_REF_CELL_REGEX,
RustType.STD_CELL: STD_CELL_REGEX,
RustType.STD_NONZERO_NUMBER: STD_NONZERO_NUMBER_REGEX,
RustType.STD_PATHBUF: STD_PATHBUF_REGEX,
RustType.STD_PATH: STD_PATH_REGEX,
}
def is_tuple_fields(fields):
# type: (list) -> bool
return all(TUPLE_ITEM_REGEX.match(str(field.name)) for field in fields)
def classify_struct(name, fields):
if len(fields) == 0:
return RustType.EMPTY
for ty, regex in STD_TYPE_TO_REGEX.items():
if regex.match(name):
return ty
if fields[0].name == ENUM_DISR_FIELD_NAME:
return RustType.ENUM
if is_tuple_fields(fields):
return RustType.TUPLE
return RustType.STRUCT
def classify_union(fields):
if len(fields) == 0:
return RustType.EMPTY
first_variant_name = fields[0].name
if first_variant_name is None:
if len(fields) == 1:
return RustType.SINGLETON_ENUM
else:
return RustType.REGULAR_ENUM
elif first_variant_name.startswith(ENCODED_ENUM_PREFIX):
assert len(fields) == 1
return RustType.COMPRESSED_ENUM
else:
return RustType.REGULAR_UNION