1/* This Source Code Form is subject to the terms of the Mozilla Public
2 * License, v. 2.0. If a copy of the MPL was not distributed with this
3 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
4
5use std::io::Write;
6
7use crate::bindgen::config::{Config, DocumentationLength, DocumentationStyle, Language};
8use crate::bindgen::utilities::SynAttributeHelpers;
9use crate::bindgen::writer::{Source, SourceWriter};
10
11#[derive(Debug, Clone)]
12pub struct Documentation {
13 pub doc_comment: Vec<String>,
14}
15
16impl Documentation {
17 pub fn load(attrs: &[syn::Attribute]) -> Self {
18 let doc: Vec = attrsimpl Iterator
19 .get_comment_lines()
20 .into_iter()
21 .filter(|x: &String| !x.trim_start().starts_with("cbindgen:"))
22 .collect();
23
24 Documentation { doc_comment: doc }
25 }
26
27 pub fn simple(line: &str) -> Self {
28 Documentation {
29 doc_comment: vec![line.to_owned()],
30 }
31 }
32
33 pub fn none() -> Self {
34 Documentation {
35 doc_comment: Vec::new(),
36 }
37 }
38}
39
40impl Source for Documentation {
41 fn write<F: Write>(&self, config: &Config, out: &mut SourceWriter<F>) {
42 if self.doc_comment.is_empty() || !config.documentation {
43 return;
44 }
45
46 let end = match config.documentation_length {
47 DocumentationLength::Short => 1,
48 DocumentationLength::Full => self.doc_comment.len(),
49 };
50
51 // Cython uses Python-style comments, so `documentation_style` is not relevant.
52 if config.language == Language::Cython {
53 for line in &self.doc_comment[..end] {
54 write!(out, "#{}", line);
55 out.new_line();
56 }
57 return;
58 }
59
60 let style = match config.documentation_style {
61 DocumentationStyle::Auto if config.language == Language::C => DocumentationStyle::Doxy,
62 DocumentationStyle::Auto if config.language == Language::Cxx => DocumentationStyle::Cxx,
63 DocumentationStyle::Auto => DocumentationStyle::C, // Fallback if `Language` gets extended.
64 other => other,
65 };
66
67 // Following these documents for style conventions:
68 // https://en.wikibooks.org/wiki/C++_Programming/Code/Style_Conventions/Comments
69 // https://www.cs.cmu.edu/~410/doc/doxygen.html
70 match style {
71 DocumentationStyle::C => {
72 out.write("/*");
73 out.new_line();
74 }
75
76 DocumentationStyle::Doxy => {
77 out.write("/**");
78 out.new_line();
79 }
80
81 _ => (),
82 }
83
84 for line in &self.doc_comment[..end] {
85 match style {
86 DocumentationStyle::C => out.write(""),
87 DocumentationStyle::Doxy => out.write(" *"),
88 DocumentationStyle::C99 => out.write("//"),
89 DocumentationStyle::Cxx => out.write("///"),
90 DocumentationStyle::Auto => unreachable!(), // Auto case should always be covered
91 }
92
93 write!(out, "{}", line);
94 out.new_line();
95 }
96
97 match style {
98 DocumentationStyle::C => {
99 out.write(" */");
100 out.new_line();
101 }
102
103 DocumentationStyle::Doxy => {
104 out.write(" */");
105 out.new_line();
106 }
107
108 _ => (),
109 }
110 }
111}
112