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
extern crate anyhow;
extern crate bitflags;

use self::anyhow::Result;
use self::bitflags::bitflags;

macro_rules! impl_flags {
    ( $flag_type:ident, $impl_type:ident ) => {
        #[derive(Clone, Copy, Debug)]
        pub struct $impl_type {
            pub flags: $flag_type,
        }

        impl $impl_type {
            pub fn from_bits(raw: u16) -> Result<Self> {
                let mut flags = <$flag_type>::from_bits(raw);

                if flags.is_none() {
                    flags = Some(<$flag_type>::from_bits_truncate(raw));
                }

                Ok(Self {
                    flags: flags.unwrap(),
                })
            }

            pub fn has(&self, other: $flag_type) -> bool {
                self.flags.contains(other)
            }
        }
    };
}

bitflags! {
    pub struct ClassFileAccessFlag: u16 {
         const PUBLIC = 0x0001;
         const FINAL = 0x0010;
         const SUPER = 0x0020;
         const INTERFACE = 0x0200;
         const ABSTRACT = 0x0400;
         const SYNTHETIC = 0x1000;
         const ANNOTATION = 0x2000;
         const ENUM = 0x4000;
         const MODULE = 0x8000;
    }
}

bitflags! {
    pub struct MethodAccessFlag: u16 {
         const PUBLIC = 0x0001;
         const PRIVATE = 0x0002;
         const PROTECTED = 0x0004;
         const STATIC = 0x0008;
         const FINAL = 0x0010;
         const SYNCHRONIZED = 0x0020;
         const BRIDGE = 0x0040;
         const VARARGS = 0x0080;
         const NATIVE = 0x0100;
         const ABSTRACT = 0x0400;
         const STRICT_FP = 0x0800;
         const SYNTHETIC = 0x1000;
    }
}

bitflags! {
    pub struct FieldAccessFlag: u16 {
         const PUBLIC = 0x0001;
         const PRIVATE = 0x0002;
         const PROTECTED = 0x0004;
         const STATIC = 0x0008;
         const FINAL = 0x0010;
         const VOLATILE = 0x0040;
         const SYNTHETIC = 0x1000;
         const ENUM = 0x4000;
    }
}

impl_flags!(MethodAccessFlag, MethodAccessFlags);
impl_flags!(ClassFileAccessFlag, ClassFileAccessFlags);
impl_flags!(FieldAccessFlag, FieldAccessFlags);