1use super::*;
2
3pub trait Decode {
4 fn decode(file: &'static File, 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 {
11 $($table($table),)*
12 }
13 impl Decode for $name {
14 fn decode(file: &'static File, code: usize) -> Self {
15 let (kind, row) = (code & ((1 << $size) - 1), (code >> $size) - 1);
16 match kind {
17 $($code => Self::$table($table(Row::new(file, row))),)*
18 rest => unimplemented!("{rest:?}"),
19 }
20 }
21 }
22 impl $name {
23 pub fn encode(&self) -> usize {
24 match self {
25 $(Self::$table(row) => (row.index() + 1) << $size | $code,)*
26 }
27 }
28 }
29 $(
30 impl From<$table> for $name {
31 fn from(from: $table) -> Self {
32 Self::$table(from)
33 }
34 }
35 )*
36 };
37}
38
39code! { AttributeType(3)
40 (MemberRef, 3)
41}
42
43code! { HasAttribute(5)
44 (MethodDef, 0)
45 (Field, 1)
46 (TypeRef, 2)
47 (TypeDef, 3)
48 (Param, 4)
49 (InterfaceImpl, 5)
50 (MemberRef, 6)
51 (TypeSpec, 13)
52 (GenericParam, 19)
53}
54
55code! { HasConstant(2)
56 (Field, 0)
57}
58
59code! { MemberForwarded(1)
60 (MethodDef, 1)
61}
62
63code! { MemberRefParent(3)
64 (TypeRef, 1)
65}
66
67code! { TypeDefOrRef(2)
68 (TypeDef, 0)
69 (TypeRef, 1)
70 (TypeSpec, 2)
71}
72
73code! { TypeOrMethodDef(1)
74 (TypeDef, 0)
75}
76
77code! { ResolutionScope(2)
78 (Module, 0)
79 (ModuleRef, 1)
80 (AssemblyRef, 2)
81 (TypeRef, 3)
82}
83
84impl TypeDefOrRef {
85 pub fn type_name(&self) -> TypeName {
86 match self {
87 Self::TypeDef(row: &TypeDef) => row.type_name(),
88 Self::TypeRef(row: &TypeRef) => row.type_name(),
89 rest: &TypeDefOrRef => unimplemented!("{rest:?}"),
90 }
91 }
92}
93