1//! Different variants of an `Item` in our intermediate representation.
2
3use super::context::BindgenContext;
4use super::dot::DotAttributes;
5use super::function::Function;
6use super::module::Module;
7use super::ty::Type;
8use super::var::Var;
9use std::io;
10
11/// A item we parse and translate.
12#[derive(Debug)]
13pub(crate) 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
28impl ItemKind {
29 /// Get a reference to this `ItemKind`'s underying `Module`, or `None` if it
30 /// is some other kind.
31 pub(crate) 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.
39 pub(crate) 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?
49 pub(crate) fn is_module(&self) -> bool {
50 self.as_module().is_some()
51 }
52
53 /// Get a reference to this `ItemKind`'s underying `Function`, or `None` if
54 /// it is some other kind.
55 pub(crate) fn as_function(&self) -> Option<&Function> {
56 match *self {
57 ItemKind::Function(ref func) => Some(func),
58 _ => None,
59 }
60 }
61
62 /// Is this a function?
63 pub(crate) fn is_function(&self) -> bool {
64 self.as_function().is_some()
65 }
66
67 /// Get a reference to this `ItemKind`'s underying `Function`, or panic if
68 /// it is some other kind.
69 pub(crate) fn expect_function(&self) -> &Function {
70 self.as_function().expect("Not a function")
71 }
72
73 /// Get a reference to this `ItemKind`'s underying `Type`, or `None` if
74 /// it is some other kind.
75 pub(crate) fn as_type(&self) -> Option<&Type> {
76 match *self {
77 ItemKind::Type(ref ty) => Some(ty),
78 _ => None,
79 }
80 }
81
82 /// Get a mutable reference to this `ItemKind`'s underying `Type`, or `None`
83 /// if it is some other kind.
84 pub(crate) fn as_type_mut(&mut self) -> Option<&mut Type> {
85 match *self {
86 ItemKind::Type(ref mut ty) => Some(ty),
87 _ => None,
88 }
89 }
90
91 /// Is this a type?
92 pub(crate) fn is_type(&self) -> bool {
93 self.as_type().is_some()
94 }
95
96 /// Get a reference to this `ItemKind`'s underying `Type`, or panic if it is
97 /// some other kind.
98 pub(crate) fn expect_type(&self) -> &Type {
99 self.as_type().expect("Not a type")
100 }
101
102 /// Get a reference to this `ItemKind`'s underying `Var`, or `None` if it is
103 /// some other kind.
104 pub(crate) fn as_var(&self) -> Option<&Var> {
105 match *self {
106 ItemKind::Var(ref v) => Some(v),
107 _ => None,
108 }
109 }
110
111 /// Is this a variable?
112 pub(crate) fn is_var(&self) -> bool {
113 self.as_var().is_some()
114 }
115}
116
117impl DotAttributes for ItemKind {
118 fn dot_attributes<W>(
119 &self,
120 ctx: &BindgenContext,
121 out: &mut W,
122 ) -> io::Result<()>
123 where
124 W: io::Write,
125 {
126 writeln!(out, "<tr><td>kind</td><td>{}</td></tr>", self.kind_name())?;
127
128 match *self {
129 ItemKind::Module(ref module: &Module) => module.dot_attributes(ctx, out),
130 ItemKind::Type(ref ty: &Type) => ty.dot_attributes(ctx, out),
131 ItemKind::Function(ref func: &Function) => func.dot_attributes(ctx, out),
132 ItemKind::Var(ref var: &Var) => var.dot_attributes(ctx, out),
133 }
134 }
135}
136