1from .abi import *
2from .markdown_naming import *
3
4
5class RustNaming:
6    def __init__(self):
7        pass
8
9    def typename(self, type):
10        if isinstance(type, VoidType):
11            return '()'
12        elif isinstance(type, IntType):
13            if type.name == 'char':
14                return 'u8'
15            elif type.name == 'size':
16                return 'usize'
17            elif type.name[0:3] == 'int':
18                return 'i' + type.name[3:]
19            elif type.name[0:4] == 'uint':
20                return 'u' + type.name[4:]
21            else:
22                raise Exception('Unknown int type: {}'.format(type.name))
23        elif isinstance(type, UserDefinedType):
24            return type.name
25        elif isinstance(type, AtomicType):
26            # TODO: Update once rust has generic atomic types
27            return self.typename(type.target_type)
28        elif isinstance(type, PointerType):
29            if isinstance(type.target_type, FunctionType):
30                return self.typename(type.target_type)
31            mut = 'const' if type.const else 'mut'
32            return '*{} {}'.format(mut, self.typename(type.target_type))
33        elif isinstance(type, ArrayType):
34            return '[{}; {}]'.format(
35                self.typename(type.element_type), type.count)
36        else:
37            raise Exception('Unable to generate Rust declaration '
38                            'for type: {}'.format(type))
39
40    def valname(self, type, value):
41        if isinstance(type, FlagsType) or isinstance(type, EnumType):
42            if value.name == '2big':
43                return 'TOOBIG'
44            return value.name.upper()
45        else:
46            return '{}{}'.format(type.cprefix, value.name).upper()
47
48    def syscallname(self, syscall):
49        return syscall.name
50
51    def vardecl(self, type, name, array_need_parens=False):
52        return '{}: {}'.format(name, self.typename(type))
53
54    def fieldname(self, name):
55        if name == 'type':
56            return 'type_'
57        return name
58
59
60class MarkdownRustNaming(MarkdownNaming, RustNaming):
61    def typename(self, type, link=True, **kwargs):
62        if link:
63            return self.link(type, code=False)
64        else:
65            return super().typename(type, **kwargs)
66
67    def memname(self, *path):
68        name = self.typename(path[0], link=False) + '.'
69        name += '.'.join(
70            self.variantmem(m) if isinstance(m, VariantMember) else
71            self.fieldname(m.name) for m in path[1:])
72        return name
73
74    def variantmem(self, member):
75        return 'union.' + self.fieldname(member.name)
76
77    def syscallname(self, syscall):
78        return RustNaming.syscallname(self, syscall) + '()'
79
80    def kinddesc(self, type):
81        if isinstance(type, EnumType):
82            return '{} `enum`'.format(self.link(type.int_type))
83        elif isinstance(type, AliasType):
84            return '= {}'.format(self.link(type.int_type))
85        elif isinstance(type, OpaqueType):
86            return '`struct({})`'.format(self.typename(type.int_type))
87        elif isinstance(type, FlagsType):
88            return '{} bitfield'.format(self.link(type.int_type))
89        elif isinstance(type, StructType):
90            return '`struct`'
91        elif isinstance(type, FunctionType):
92            return 'function pointer'
93        else:
94            assert (False)
95