blob: 6822c0eaf29546cb4ef49942495085ce88c55eb2 [file] [log] [blame]
/* 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();
}
_ => (),
}
}
}