windows_metadata/reader/
codes.rs1use 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}