1#![allow(unused_unsafe)]
18
19use std::fmt;
20use std::mem;
21use std::marker::{PhantomData};
22
23use clang_sys::*;
24
25use utility;
26use super::{TranslationUnit};
27
28#[derive(Clone, Debug, PartialEq, Eq)]
36pub enum CommentChild {
37 BlockCommand(BlockCommand),
39 HtmlStartTag(HtmlStartTag),
41 HtmlEndTag(String),
43 InlineCommand(InlineCommand),
45 Paragraph(Vec<CommentChild>),
47 ParamCommand(ParamCommand),
49 TParamCommand(TParamCommand),
51 Text(String),
53 VerbatimCommand(Vec<String>),
55 VerbatimLineCommand(String),
57}
58
59impl CommentChild {
60 fn from_raw(raw: CXComment) -> CommentChild {
63 unsafe {
64 match clang_Comment_getKind(raw) {
65 CXComment_Text =>
66 CommentChild::Text(utility::to_string(clang_TextComment_getText(raw))),
67 CXComment_InlineCommand =>
68 CommentChild::InlineCommand(InlineCommand::from_raw(raw)),
69 CXComment_HTMLStartTag => CommentChild::HtmlStartTag(HtmlStartTag::from_raw(raw)),
70 CXComment_HTMLEndTag => {
71 let name = utility::to_string(clang_HTMLTagComment_getTagName(raw));
72 CommentChild::HtmlEndTag(name)
73 },
74 CXComment_Paragraph =>
75 CommentChild::Paragraph(Comment::from_raw(raw).get_children()),
76 CXComment_BlockCommand => CommentChild::BlockCommand(BlockCommand::from_raw(raw)),
77 CXComment_ParamCommand => CommentChild::ParamCommand(ParamCommand::from_raw(raw)),
78 CXComment_TParamCommand =>
79 CommentChild::TParamCommand(TParamCommand::from_raw(raw)),
80 CXComment_VerbatimBlockCommand => {
81 let lines = iter!(
82 clang_Comment_getNumChildren(raw),
83 clang_Comment_getChild(raw),
84 ).map(|c| {
85 utility::to_string(clang_VerbatimBlockLineComment_getText(c))
86 }).collect();
87 CommentChild::VerbatimCommand(lines)
88 },
89 CXComment_VerbatimLine => {
90 let line = utility::to_string(clang_VerbatimLineComment_getText(raw));
91 CommentChild::VerbatimLineCommand(line)
92 },
93 _ => unreachable!(),
94 }
95 }
96 }
97}
98
99#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash)]
103#[repr(C)]
104pub enum ParameterDirection {
105 In = 0,
107 Out = 1,
109 InOut = 2,
111}
112
113#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash)]
117#[repr(C)]
118pub enum InlineCommandStyle {
119 Bold = 1,
121 Monospace = 2,
123 Emphasized = 3,
125}
126
127#[derive(Clone, Debug, PartialEq, Eq)]
135pub struct BlockCommand {
136 pub command: String,
138 pub arguments: Vec<String>,
140 pub children: Vec<CommentChild>,
142}
143
144impl BlockCommand {
145 unsafe fn from_raw(raw: CXComment) -> BlockCommand {
148 let command = utility::to_string(clang_BlockCommandComment_getCommandName(raw));
149 let arguments = iter!(
150 clang_BlockCommandComment_getNumArgs(raw),
151 clang_BlockCommandComment_getArgText(raw),
152 ).map(utility::to_string).collect();
153 let paragraph = clang_BlockCommandComment_getParagraph(raw);
154 let children = Comment::from_raw(paragraph).get_children();
155 BlockCommand { command, arguments, children }
156 }
157}
158
159#[derive(Copy, Clone)]
163pub struct Comment<'tu> {
164 raw: CXComment,
165 _marker: PhantomData<&'tu TranslationUnit<'tu>>,
166}
167
168impl<'tu> Comment<'tu> {
169 #[doc(hidden)]
172 pub fn from_raw(raw: CXComment) -> Comment<'tu> {
173 Comment { raw, _marker: PhantomData }
174 }
175
176 pub fn get_children(&self) -> Vec<CommentChild> {
180 iter!(
181 clang_Comment_getNumChildren(self.raw),
182 clang_Comment_getChild(self.raw),
183 ).map(CommentChild::from_raw).collect()
184 }
185
186 pub fn as_html(&self) -> String {
188 unsafe { utility::to_string(clang_FullComment_getAsHTML(self.raw)) }
189 }
190
191 pub fn as_xml(&self) -> String {
193 unsafe { utility::to_string(clang_FullComment_getAsXML(self.raw)) }
194 }
195}
196
197impl<'tu> fmt::Debug for Comment<'tu> {
198 fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
199 write!(formatter, "{:?}", self.get_children())
200 }
201}
202
203#[derive(Clone, Debug, PartialEq, Eq)]
207pub struct HtmlStartTag {
208 pub name: String,
210 pub attributes: Vec<(String, String)>,
212 pub closing: bool,
214}
215
216impl HtmlStartTag {
217 unsafe fn from_raw(raw: CXComment) -> HtmlStartTag {
220 let name = utility::to_string(clang_HTMLTagComment_getTagName(raw));
221 let attributes = iter!(
222 clang_HTMLStartTag_getNumAttrs(raw),
223 clang_HTMLStartTag_getAttrName(raw),
224 clang_HTMLStartTag_getAttrValue(raw),
225 ).map(|(n, v)| (utility::to_string(n), utility::to_string(v))).collect();
226 let closing = clang_HTMLStartTagComment_isSelfClosing(raw) != 0;
227 HtmlStartTag { name, attributes, closing }
228 }
229}
230
231#[derive(Clone, Debug, PartialEq, Eq)]
235pub struct InlineCommand {
236 pub command: String,
238 pub arguments: Vec<String>,
240 pub style: Option<InlineCommandStyle>,
242}
243
244impl InlineCommand {
245 unsafe fn from_raw(raw: CXComment) -> InlineCommand {
248 let command = utility::to_string(clang_InlineCommandComment_getCommandName(raw));
249 let arguments = iter!(
250 clang_InlineCommandComment_getNumArgs(raw),
251 clang_InlineCommandComment_getArgText(raw),
252 ).map(utility::to_string).collect();
253 let style = match clang_InlineCommandComment_getRenderKind(raw) {
254 CXCommentInlineCommandRenderKind_Normal => None,
255 other => Some(mem::transmute(other)),
256 };
257 InlineCommand { command, arguments, style }
258 }
259}
260
261#[derive(Clone, Debug, PartialEq, Eq)]
265pub struct ParamCommand {
266 pub index: Option<usize>,
268 pub parameter: String,
270 pub direction: Option<ParameterDirection>,
272 pub children: Vec<CommentChild>
274}
275
276impl ParamCommand {
277 unsafe fn from_raw(raw: CXComment) -> ParamCommand {
280 let index = if clang_ParamCommandComment_isParamIndexValid(raw) != 0 {
281 Some(clang_ParamCommandComment_getParamIndex(raw) as usize)
282 } else {
283 None
284 };
285 let parameter = utility::to_string(clang_ParamCommandComment_getParamName(raw));
286 let direction = if clang_ParamCommandComment_isDirectionExplicit(raw) != 0 {
287 Some(mem::transmute(clang_ParamCommandComment_getDirection(raw)))
288 } else {
289 None
290 };
291 let paragraph = clang_BlockCommandComment_getParagraph(raw);
292 let children = Comment::from_raw(paragraph).get_children();
293 ParamCommand { index, parameter, direction, children }
294 }
295}
296
297#[derive(Clone, Debug, PartialEq, Eq)]
301pub struct TParamCommand {
302 pub position: Option<(usize, usize)>,
305 pub parameter: String,
307 pub children: Vec<CommentChild>
309}
310
311impl TParamCommand {
312 unsafe fn from_raw(raw: CXComment) -> TParamCommand {
315 let position = if clang_TParamCommandComment_isParamPositionValid(raw) != 0 {
316 let depth = clang_TParamCommandComment_getDepth(raw);
317 let index = clang_TParamCommandComment_getIndex(raw, depth) as usize;
318 Some((depth as usize, index))
319 } else {
320 None
321 };
322 let parameter = utility::to_string(clang_TParamCommandComment_getParamName(raw));
323 let paragraph = clang_BlockCommandComment_getParagraph(raw);
324 let children = Comment::from_raw(paragraph).get_children();
325 TParamCommand { position, parameter, children }
326 }
327}