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
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
/// A type.
#[derive(Debug)]
#[allow(non_camel_case_types)]
pub enum Type {
    Ignored,
    usize(Primitive),
    isize(Primitive),
    u8(Primitive),
    i8(Primitive),
    u16(Primitive),
    i16(Primitive),
    u32(Primitive),
    i32(Primitive),
    u64(Primitive),
    i64(Primitive),
    f32(Primitive),
    f64(Primitive),
    char(Primitive),
    bool(Primitive),
    Struct(Struct),
    Tuple(Tuple),
    Opaque(Opaque),
}

impl Type {
    pub fn size(self: &Self) -> Option<usize> {
        match *self {
            Type::usize(ref p) => Some(p.size),
            Type::isize(ref p) => Some(p.size),
            Type::u8(ref p) => Some(p.size),
            Type::i8(ref p) => Some(p.size),
            Type::u16(ref p) => Some(p.size),
            Type::i16(ref p) => Some(p.size),
            Type::u32(ref p) => Some(p.size),
            Type::i32(ref p) => Some(p.size),
            Type::u64(ref p) => Some(p.size),
            Type::i64(ref p) => Some(p.size),
            Type::f32(ref p) => Some(p.size),
            Type::f64(ref p) => Some(p.size),
            Type::char(ref p) => Some(p.size),
            Type::bool(ref p) => Some(p.size),
            Type::Struct(ref s) => Some(s.size),
            Type::Tuple(ref t) => Some(t.size),
            Type::Opaque(ref o) => Some(o.size),
            _ => None
        }
    }
    pub fn name(self: &Self) -> Option<&'static str> {
        match *self {
            Type::usize(ref p) => Some(p.name),
            Type::isize(ref p) => Some(p.name),
            Type::u8(ref p) => Some(p.name),
            Type::i8(ref p) => Some(p.name),
            Type::u16(ref p) => Some(p.name),
            Type::i16(ref p) => Some(p.name),
            Type::u32(ref p) => Some(p.name),
            Type::i32(ref p) => Some(p.name),
            Type::u64(ref p) => Some(p.name),
            Type::i64(ref p) => Some(p.name),
            Type::f32(ref p) => Some(p.name),
            Type::f64(ref p) => Some(p.name),
            Type::char(ref p) => Some(p.name),
            Type::bool(ref p) => Some(p.name),
            Type::Struct(ref s) => Some(s.name),
            Type::Tuple(ref t) => Some(t.name),
            Type::Opaque(ref o) => Some(o.name),
            _ => None
        }
    }
}

/// Visibility of a type or struct member.
#[derive(Debug)]
pub enum Visibility {
    Public,
    Crate,
    Restricted,
    Inherited,
    Unknown
}

/// Field of a struct or tuple struct.
#[derive(Debug)]
pub struct Field {
    pub vis: Visibility,
    pub offset: usize,
    pub ty: Type,
    pub hints: Vec<&'static str>,
}

/// A struct (with named members).
#[derive(Debug)]
pub struct Struct {
    pub name: &'static str,
    pub size: usize,
    pub vis: Visibility,
    pub fields: Vec<(&'static str, Field)>,
}

/// A tuple struct (unnamed members).
#[derive(Debug)]
pub struct Tuple {
    pub name: &'static str,
    pub size: usize,
    pub vis: Visibility,
    pub fields: Vec<Field>,
}

/// An opaque type.
#[derive(Debug)]
pub struct Opaque {
    pub name: &'static str,
    pub size: usize,
    pub tys: Vec<Type>,
}

/// An primitive type.
#[derive(Debug)]
pub struct Primitive {
    pub name: &'static str,
    pub size: usize,
}