windows_metadata/reader/
codes.rs

1use super::*;
2
3pub trait Decode<'a> {
4    fn decode(index: &'a Index, file: usize, code: usize) -> Self;
5}
6
7macro_rules! code {
8    ($name:ident($size:literal) $(($table:ident, $code:literal))+) => {
9        #[derive(Clone, Debug, Hash, PartialEq, Eq, Ord, PartialOrd)]
10        pub enum $name<'a> {
11            $($table($table<'a>),)*
12        }
13        impl<'a> Decode<'a> for $name<'a> {
14            fn decode(index: &'a Index, file: usize, code: usize) -> Self {
15                let (kind, row) = (code & ((1 << $size) - 1), (code >> $size) - 1);
16                match kind {
17                    $($code => Self::$table($table(Row::new(index, file, row))),)*
18                    rest => panic!("{rest:?}"),
19                }
20            }
21        }
22        impl $name<'_> {
23            #[allow(dead_code)]
24            pub fn encode(&self) -> usize {
25                match self {
26                    $(Self::$table(row) => (row.pos() + 1) << $size | $code,)*
27                }
28            }
29        }
30        $(
31            impl<'a> From<$table<'a>> for $name<'a> {
32                fn from(from: $table<'a>) -> Self {
33                    Self::$table(from)
34                }
35            }
36        )*
37    };
38}
39
40code! { AttributeType(3)
41    (MethodDef, 2)
42    (MemberRef, 3)
43}
44
45impl AttributeType<'_> {
46    pub fn parent(&self) -> MemberRefParent {
47        match self {
48            Self::MethodDef(row) => row.parent(),
49            Self::MemberRef(row) => row.parent(),
50        }
51    }
52
53    pub fn signature(&self, generics: &[Type]) -> Signature {
54        match self {
55            Self::MethodDef(row) => row.signature(generics),
56            Self::MemberRef(row) => row.signature(generics),
57        }
58    }
59}
60
61code! { HasAttribute(5)
62    (MethodDef, 0)
63    (Field, 1)
64    (TypeRef, 2)
65    (TypeDef, 3)
66    (MethodParam, 4)
67    (InterfaceImpl, 5)
68    (MemberRef, 6)
69    (TypeSpec, 13)
70    (GenericParam, 19)
71}
72
73code! { HasConstant(2)
74    (Field, 0)
75}
76
77code! { MemberForwarded(1)
78    (MethodDef, 1)
79}
80
81code! { MemberRefParent(3)
82    (TypeDef, 0)
83    (TypeRef, 1)
84}
85
86impl MemberRefParent<'_> {
87    pub fn namespace(&self) -> &str {
88        match self {
89            Self::TypeDef(row) => row.namespace(),
90            Self::TypeRef(row) => row.namespace(),
91        }
92    }
93
94    pub fn name(&self) -> &str {
95        match self {
96            Self::TypeDef(row) => row.name(),
97            Self::TypeRef(row) => row.name(),
98        }
99    }
100}
101
102code! { TypeDefOrRef(2)
103    (TypeDef, 0)
104    (TypeRef, 1)
105    (TypeSpec, 2)
106}
107
108code! { TypeOrMethodDef(1)
109    (TypeDef, 0)
110}
111
112impl TypeDefOrRef<'_> {
113    pub fn namespace(&self) -> &str {
114        match self {
115            Self::TypeDef(row) => row.namespace(),
116            Self::TypeRef(row) => row.namespace(),
117            rest => panic!("{rest:?}"),
118        }
119    }
120
121    pub fn name(&self) -> &str {
122        match self {
123            Self::TypeDef(row) => row.name(),
124            Self::TypeRef(row) => row.name(),
125            rest => panic!("{rest:?}"),
126        }
127    }
128
129    pub fn ty(&self, generics: &[Type]) -> Type {
130        if let Self::TypeSpec(def) = self {
131            return def.ty(generics);
132        }
133
134        Type::named(self.namespace(), self.name())
135    }
136}
137
138code! { ResolutionScope(2)
139    (Module, 0)
140    (ModuleRef, 1)
141    (AssemblyRef, 2)
142    (TypeRef, 3)
143}