1 | use super::*; |
2 | |
3 | pub trait Decode { |
4 | fn decode(file: &'static File, code: usize) -> Self; |
5 | } |
6 | |
7 | macro_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 | |
39 | code! { AttributeType(3) |
40 | (MemberRef, 3) |
41 | } |
42 | |
43 | code! { 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 | |
55 | code! { HasConstant(2) |
56 | (Field, 0) |
57 | } |
58 | |
59 | code! { MemberForwarded(1) |
60 | (MethodDef, 1) |
61 | } |
62 | |
63 | code! { MemberRefParent(3) |
64 | (TypeRef, 1) |
65 | } |
66 | |
67 | code! { TypeDefOrRef(2) |
68 | (TypeDef, 0) |
69 | (TypeRef, 1) |
70 | (TypeSpec, 2) |
71 | } |
72 | |
73 | code! { TypeOrMethodDef(1) |
74 | (TypeDef, 0) |
75 | } |
76 | |
77 | code! { ResolutionScope(2) |
78 | (Module, 0) |
79 | (ModuleRef, 1) |
80 | (AssemblyRef, 2) |
81 | (TypeRef, 3) |
82 | } |
83 | |
84 | impl 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 | |