summaryrefslogtreecommitdiffstats
path: root/vendor/windows-metadata/src/codes.rs
blob: 3171cb5281a7fa400adfcf57457711dcc5d27e4a (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
use super::*;

pub trait Decode {
    fn decode(file: &'static File, code: usize) -> Self;
}

macro_rules! code {
    ($name:ident($size:literal) $(($table:ident, $code:literal))+) => {
        #[derive(Clone, Debug, Hash, PartialEq, Eq, Ord, PartialOrd)]
        pub enum $name {
            $($table($table),)*
        }
        impl Decode for $name {
            fn decode(file: &'static File, code: usize) -> Self {
                let (kind, row) = (code & ((1 << $size) - 1), (code >> $size) - 1);
                match kind {
                    $($code => Self::$table($table(Row::new(file, row))),)*
                    rest => unimplemented!("{rest:?}"),
                }
            }
        }
        impl $name {
            pub fn encode(&self) -> usize {
                match self {
                    $(Self::$table(row) => (row.index() + 1) << $size | $code,)*
                }
            }
        }
        $(
            impl From<$table> for $name {
                fn from(from: $table) -> Self {
                    Self::$table(from)
                }
            }
        )*
    };
}

code! { AttributeType(3)
    (MemberRef, 3)
}

code! { HasAttribute(5)
    (MethodDef, 0)
    (Field, 1)
    (TypeRef, 2)
    (TypeDef, 3)
    (Param, 4)
    (InterfaceImpl, 5)
    (MemberRef, 6)
    (TypeSpec, 13)
    (GenericParam, 19)
}

code! { HasConstant(2)
    (Field, 0)
}

code! { MemberForwarded(1)
    (MethodDef, 1)
}

code! { MemberRefParent(3)
    (TypeRef, 1)
}

code! { TypeDefOrRef(2)
    (TypeDef, 0)
    (TypeRef, 1)
    (TypeSpec, 2)
}

code! { TypeOrMethodDef(1)
    (TypeDef, 0)
}

code! { ResolutionScope(2)
    (Module, 0)
    (ModuleRef, 1)
    (AssemblyRef, 2)
    (TypeRef, 3)
}

impl TypeDefOrRef {
    pub fn type_name(&self) -> TypeName {
        match self {
            Self::TypeDef(row) => row.type_name(),
            Self::TypeRef(row) => row.type_name(),
            rest => unimplemented!("{rest:?}"),
        }
    }
}