1 //! Different variants of an `Item` in our intermediate representation.
2 
3 use super::context::BindgenContext;
4 use super::dot::DotAttributes;
5 use super::function::Function;
6 use super::module::Module;
7 use super::ty::Type;
8 use super::var::Var;
9 use std::io;
10 
11 /// A item we parse and translate.
12 #[derive(Debug)]
13 pub enum ItemKind {
14     /// A module, created implicitly once (the root module), or via C++
15     /// namespaces.
16     Module(Module),
17 
18     /// A type declared in any of the multiple ways it can be declared.
19     Type(Type),
20 
21     /// A function or method declaration.
22     Function(Function),
23 
24     /// A variable declaration, most likely a static.
25     Var(Var),
26 }
27 
28 impl ItemKind {
29     /// Get a reference to this `ItemKind`'s underying `Module`, or `None` if it
30     /// is some other kind.
as_module(&self) -> Option<&Module>31     pub fn as_module(&self) -> Option<&Module> {
32         match *self {
33             ItemKind::Module(ref module) => Some(module),
34             _ => None,
35         }
36     }
37 
38     /// Transform our `ItemKind` into a string.
kind_name(&self) -> &'static str39     pub fn kind_name(&self) -> &'static str {
40         match *self {
41             ItemKind::Module(..) => "Module",
42             ItemKind::Type(..) => "Type",
43             ItemKind::Function(..) => "Function",
44             ItemKind::Var(..) => "Var",
45         }
46     }
47 
48     /// Is this a module?
is_module(&self) -> bool49     pub fn is_module(&self) -> bool {
50         self.as_module().is_some()
51     }
52 
53     /// Get a reference to this `ItemKind`'s underying `Module`, or panic if it
54     /// is some other kind.
expect_module(&self) -> &Module55     pub fn expect_module(&self) -> &Module {
56         self.as_module().expect("Not a module")
57     }
58 
59     /// Get a reference to this `ItemKind`'s underying `Function`, or `None` if
60     /// it is some other kind.
as_function(&self) -> Option<&Function>61     pub fn as_function(&self) -> Option<&Function> {
62         match *self {
63             ItemKind::Function(ref func) => Some(func),
64             _ => None,
65         }
66     }
67 
68     /// Is this a function?
is_function(&self) -> bool69     pub fn is_function(&self) -> bool {
70         self.as_function().is_some()
71     }
72 
73     /// Get a reference to this `ItemKind`'s underying `Function`, or panic if
74     /// it is some other kind.
expect_function(&self) -> &Function75     pub fn expect_function(&self) -> &Function {
76         self.as_function().expect("Not a function")
77     }
78 
79     /// Get a reference to this `ItemKind`'s underying `Type`, or `None` if
80     /// it is some other kind.
as_type(&self) -> Option<&Type>81     pub fn as_type(&self) -> Option<&Type> {
82         match *self {
83             ItemKind::Type(ref ty) => Some(ty),
84             _ => None,
85         }
86     }
87 
88     /// Get a mutable reference to this `ItemKind`'s underying `Type`, or `None`
89     /// if it is some other kind.
as_type_mut(&mut self) -> Option<&mut Type>90     pub fn as_type_mut(&mut self) -> Option<&mut Type> {
91         match *self {
92             ItemKind::Type(ref mut ty) => Some(ty),
93             _ => None,
94         }
95     }
96 
97     /// Is this a type?
is_type(&self) -> bool98     pub fn is_type(&self) -> bool {
99         self.as_type().is_some()
100     }
101 
102     /// Get a reference to this `ItemKind`'s underying `Type`, or panic if it is
103     /// some other kind.
expect_type(&self) -> &Type104     pub fn expect_type(&self) -> &Type {
105         self.as_type().expect("Not a type")
106     }
107 
108     /// Get a reference to this `ItemKind`'s underying `Var`, or `None` if it is
109     /// some other kind.
as_var(&self) -> Option<&Var>110     pub fn as_var(&self) -> Option<&Var> {
111         match *self {
112             ItemKind::Var(ref v) => Some(v),
113             _ => None,
114         }
115     }
116 
117     /// Is this a variable?
is_var(&self) -> bool118     pub fn is_var(&self) -> bool {
119         self.as_var().is_some()
120     }
121 
122     /// Get a reference to this `ItemKind`'s underying `Var`, or panic if it is
123     /// some other kind.
expect_var(&self) -> &Var124     pub fn expect_var(&self) -> &Var {
125         self.as_var().expect("Not a var")
126     }
127 }
128 
129 impl DotAttributes for ItemKind {
dot_attributes<W>( &self, ctx: &BindgenContext, out: &mut W, ) -> io::Result<()> where W: io::Write,130     fn dot_attributes<W>(
131         &self,
132         ctx: &BindgenContext,
133         out: &mut W,
134     ) -> io::Result<()>
135     where
136         W: io::Write,
137     {
138         writeln!(out, "<tr><td>kind</td><td>{}</td></tr>", self.kind_name())?;
139 
140         match *self {
141             ItemKind::Module(ref module) => module.dot_attributes(ctx, out),
142             ItemKind::Type(ref ty) => ty.dot_attributes(ctx, out),
143             ItemKind::Function(ref func) => func.dot_attributes(ctx, out),
144             ItemKind::Var(ref var) => var.dot_attributes(ctx, out),
145         }
146     }
147 }
148