blob: ffd04137e38af6ad89411d142dd4da9a5b127ffb [file] [log] [blame]
// Copyright 2021 The Fuchsia Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
pub use reference_doc_macro::ReferenceDoc;
/// Trait added by using `derive(ReferenceDoc)]`.
pub trait MarkdownReferenceDocGenerator {
/// Returns a Markdown representation of the reference docs for the
/// struct that is derived from `ReferenceDoc`. The returned Markdown
/// indents any `#` Markdown headers in individual field doc comments
/// to ensure a well structured final Markdown document.
fn get_reference_doc_markdown() -> String;
/// This method is called internally by the reference doc generator when
/// recursing to generate documentation for field types.
fn get_reference_doc_markdown_with_options(
indent_headers_by: usize,
indent_with_spaces: usize,
) -> String {
let doc = Self::get_reference_doc_markdown();
indent_lines_with_spaces(
&indent_all_markdown_headers_by(&doc, indent_headers_by),
indent_with_spaces,
)
}
}
/// Helper function to indent markdown headers in `str` by `n` additional hash
/// marks.
fn indent_all_markdown_headers_by(s: &str, n: usize) -> String {
if n == 0 {
s.to_string()
} else {
s.split('\n').map(|part| indent_markdown_header_by(part, n)).collect::<Vec<_>>().join("\n")
}
}
fn indent_markdown_header_by(s: &str, n: usize) -> String {
if s.starts_with("#") {
"#".to_string().repeat(n) + &s
} else {
s.to_string()
}
}
fn indent_lines_with_spaces(s: &str, n: usize) -> String {
if n == 0 {
s.to_string()
} else {
let prefix = " ".to_string().repeat(n);
s.split('\n')
.map(|part| if part.is_empty() { "".to_string() } else { prefix.clone() + part })
.collect::<Vec<_>>()
.join("\n")
}
}