use std::path;
use std::path::Path;
use crate::directives::directive_options::{DirectiveOption, DirectiveVisibility};
use crate::directives::{order_items, CrateDirective, Directive, MdDirective, RstDirective};
use crate::formats::{Format, MdContent, RstContent};
use crate::nodes::Node;
use crate::utils::{FileTopLevelDirective, SourceCodeFile};
use crate::RuntimeConfiguration;
#[derive(Clone, Debug)]
pub struct ExecutableDirective(pub(crate) CrateDirective);
impl ExecutableDirective {
const DIRECTIVE_NAME: &'static str = "executable";
pub(crate) fn new(
rc: &RuntimeConfiguration,
source_code_file: &SourceCodeFile,
) -> ExecutableDirective {
let mut inner = CrateDirective::new(rc, source_code_file);
inner.options.extend([
DirectiveOption::Layout(vec![Node::Name(source_code_file.item.to_string())]),
DirectiveOption::Toc(source_code_file.item.to_string()),
]);
ExecutableDirective(inner)
}
pub(crate) fn filter_items(&mut self, max_visibility: &DirectiveVisibility) -> Vec<Directive> {
self.0.filter_items(max_visibility)
}
}
impl RstDirective for ExecutableDirective {
fn get_rst_text(self, level: usize, max_visibility: &DirectiveVisibility) -> Vec<String> {
let content_indent = Self::make_content_indent(level);
let mut text =
Self::make_rst_header(Self::DIRECTIVE_NAME, &self.0.name, &self.0.options, level);
text.extend(self.0.content.get_rst_text(&content_indent));
for use_ in self.0.file_directives.uses {
text.extend(use_.get_rst_text(level + 1, max_visibility));
}
let doc_file_parent = self.0.doc_file.parent().unwrap().to_str().unwrap();
text.extend(Self::make_rst_toctree(
&content_indent,
"Modules",
Some(1),
self.0.file_directives.modules.iter().map(|m| {
m.doc_file
.to_str()
.unwrap()
.trim_start_matches(doc_file_parent)
.trim_start_matches(path::MAIN_SEPARATOR)
}),
));
for (name, items) in order_items(self.0.file_directives.items) {
text.extend(Self::make_rst_section(name, level, items, max_visibility));
}
text
}
}
impl MdDirective for ExecutableDirective {
fn get_md_text(self, fence_size: usize, max_visibility: &DirectiveVisibility) -> Vec<String> {
let fence = Self::make_fence(fence_size);
let mut text =
Self::make_md_header(Self::DIRECTIVE_NAME, &self.0.name, &self.0.options, &fence);
text.extend(self.0.content.get_md_text());
for use_ in self.0.file_directives.uses {
text.extend(use_.get_md_text(3, max_visibility));
}
let doc_file_parent = self.0.doc_file.parent().unwrap().to_str().unwrap();
text.extend(Self::make_md_toctree(
3,
"Modules",
Some(1),
self.0.file_directives.modules.iter().map(|m| {
m.doc_file
.to_str()
.unwrap()
.trim_start_matches(doc_file_parent)
.trim_start_matches(path::MAIN_SEPARATOR)
}),
));
for (name, items) in order_items(self.0.file_directives.items) {
text.extend(Self::make_md_section(
name,
fence_size,
items,
max_visibility,
));
}
text
}
fn fence_size(&self) -> usize {
Self::calc_fence_size(&self.0.file_directives.items)
}
}
impl FileTopLevelDirective for ExecutableDirective {
fn get_doc_file(&self) -> &Path {
&self.0.doc_file
}
fn get_text(self, format: &Format, max_visibility: &DirectiveVisibility) -> Vec<String> {
let mut text = format.make_title(&self.0.name);
text.extend(format.format_directive(self, max_visibility));
text
}
}