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 => 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.index() + 1) << $size | $code,)*
27 }
28 }
29 }
30 $(
31 impl From<$table> for $name {
32 fn from(from: $table) -> Self {
33 Self::$table(from)
34 }
35 }
36 )*
37 };
38}
39
40code! { AttributeType(3)
41 (MemberRef, 3)
42}
43
44code! { HasAttribute(5)
45 (MethodDef, 0)
46 (Field, 1)
47 (TypeRef, 2)
48 (TypeDef, 3)
49 (Param, 4)
50 (InterfaceImpl, 5)
51 (MemberRef, 6)
52 (TypeSpec, 13)
53 (GenericParam, 19)
54}
55
56code! { HasConstant(2)
57 (Field, 0)
58}
59
60code! { MemberForwarded(1)
61 (MethodDef, 1)
62}
63
64code! { MemberRefParent(3)
65 (TypeRef, 1)
66}
67
68code! { TypeDefOrRef(2)
69 (TypeDef, 0)
70 (TypeRef, 1)
71 (TypeSpec, 2)
72}
73
74code! { TypeOrMethodDef(1)
75 (TypeDef, 0)
76}
77
78impl TypeDefOrRef {
79 pub fn type_name(&self) -> TypeName {
80 match self {
81 Self::TypeDef(row: &TypeDef) => row.type_name(),
82 Self::TypeRef(row: &TypeRef) => row.type_name(),
83 rest: &TypeDefOrRef => panic!("{rest:?}"),
84 }
85 }
86
87 pub fn reader(&self) -> &'static Reader {
88 match self {
89 Self::TypeDef(row: &TypeDef) => row.reader(),
90 Self::TypeRef(row: &TypeRef) => row.reader(),
91 Self::TypeSpec(row: &TypeSpec) => row.reader(),
92 }
93 }
94}
95