summaryrefslogtreecommitdiffstats
path: root/src/bindgen/ir/documentation.rs
diff options
context:
space:
mode:
Diffstat (limited to 'src/bindgen/ir/documentation.rs')
-rw-r--r--src/bindgen/ir/documentation.rs111
1 files changed, 111 insertions, 0 deletions
diff --git a/src/bindgen/ir/documentation.rs b/src/bindgen/ir/documentation.rs
new file mode 100644
index 0000000..6822c0e
--- /dev/null
+++ b/src/bindgen/ir/documentation.rs
@@ -0,0 +1,111 @@
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+use std::io::Write;
+
+use crate::bindgen::config::{Config, DocumentationLength, DocumentationStyle, Language};
+use crate::bindgen::utilities::SynAttributeHelpers;
+use crate::bindgen::writer::{Source, SourceWriter};
+
+#[derive(Debug, Clone)]
+pub struct Documentation {
+ pub doc_comment: Vec<String>,
+}
+
+impl Documentation {
+ pub fn load(attrs: &[syn::Attribute]) -> Self {
+ let doc = attrs
+ .get_comment_lines()
+ .into_iter()
+ .filter(|x| !x.trim_start().starts_with("cbindgen:"))
+ .collect();
+
+ Documentation { doc_comment: doc }
+ }
+
+ pub fn simple(line: &str) -> Self {
+ Documentation {
+ doc_comment: vec![line.to_owned()],
+ }
+ }
+
+ pub fn none() -> Self {
+ Documentation {
+ doc_comment: Vec::new(),
+ }
+ }
+}
+
+impl Source for Documentation {
+ fn write<F: Write>(&self, config: &Config, out: &mut SourceWriter<F>) {
+ if self.doc_comment.is_empty() || !config.documentation {
+ return;
+ }
+
+ let end = match config.documentation_length {
+ DocumentationLength::Short => 1,
+ DocumentationLength::Full => self.doc_comment.len(),
+ };
+
+ // Cython uses Python-style comments, so `documentation_style` is not relevant.
+ if config.language == Language::Cython {
+ for line in &self.doc_comment[..end] {
+ write!(out, "#{}", line);
+ out.new_line();
+ }
+ return;
+ }
+
+ let style = match config.documentation_style {
+ DocumentationStyle::Auto if config.language == Language::C => DocumentationStyle::Doxy,
+ DocumentationStyle::Auto if config.language == Language::Cxx => DocumentationStyle::Cxx,
+ DocumentationStyle::Auto => DocumentationStyle::C, // Fallback if `Language` gets extended.
+ other => other,
+ };
+
+ // Following these documents for style conventions:
+ // https://en.wikibooks.org/wiki/C++_Programming/Code/Style_Conventions/Comments
+ // https://www.cs.cmu.edu/~410/doc/doxygen.html
+ match style {
+ DocumentationStyle::C => {
+ out.write("/*");
+ out.new_line();
+ }
+
+ DocumentationStyle::Doxy => {
+ out.write("/**");
+ out.new_line();
+ }
+
+ _ => (),
+ }
+
+ for line in &self.doc_comment[..end] {
+ match style {
+ DocumentationStyle::C => out.write(""),
+ DocumentationStyle::Doxy => out.write(" *"),
+ DocumentationStyle::C99 => out.write("//"),
+ DocumentationStyle::Cxx => out.write("///"),
+ DocumentationStyle::Auto => unreachable!(), // Auto case should always be covered
+ }
+
+ write!(out, "{}", line);
+ out.new_line();
+ }
+
+ match style {
+ DocumentationStyle::C => {
+ out.write(" */");
+ out.new_line();
+ }
+
+ DocumentationStyle::Doxy => {
+ out.write(" */");
+ out.new_line();
+ }
+
+ _ => (),
+ }
+ }
+}