use std::path::Path;
use maud::Markup;
use maud::html;
use wdl_ast::AstToken;
use wdl_ast::SupportedVersion;
use wdl_ast::v1::EnumDefinition;
use wdl_ast::v1::EnumVariant;
use crate::VersionBadge;
use crate::docs_tree::PageSections;
use crate::meta::DEFAULT_DESCRIPTION;
use crate::meta::DESCRIPTION_KEY;
use crate::meta::DefinitionMeta;
use crate::meta::MetaMap;
use crate::meta::MetaMapExt;
use crate::meta::doc_comments;
#[derive(Debug)]
pub(crate) struct DocumentedEnumChoice {
meta: MetaMap,
choice: EnumVariant,
}
impl DocumentedEnumChoice {
pub fn full_description(&self) -> String {
self.meta
.full_description()
.unwrap_or_else(|| String::from(DEFAULT_DESCRIPTION))
}
}
#[derive(Debug)]
pub(crate) struct Enum {
meta: MetaMap,
choices: Vec<DocumentedEnumChoice>,
definition: EnumDefinition,
version: VersionBadge,
}
impl DefinitionMeta for Enum {
fn meta(&self) -> &MetaMap {
&self.meta
}
}
impl Enum {
pub fn new(
definition: EnumDefinition,
version: SupportedVersion,
enable_doc_comments: bool,
) -> Self {
let (meta, choices) = parse_meta(&definition, enable_doc_comments);
Self {
meta,
choices,
definition,
version: VersionBadge::new(version),
}
}
pub fn render(&self, assets: &Path) -> (Markup, PageSections) {
let name = self.definition.name();
let name = name.text();
let choices = html! {
div class="main__section" {
h2 id="choices" class="main__section-header" { "Choices" }
@for choice in self.choices.iter() {
@let choice_name = choice.choice.name();
@let choice_id = format!("choice.{}", choice_name.text());
@let choice_anchor = format!("#{choice_id}");
section id=(choice_id) {
div class="main__meta-item-member" {
a href=(choice_anchor) {}
h3 class="main__section-subheader" { (choice_name.text()) }
}
div class="main__meta-item-member-description" {
@for paragraph in choice.full_description().split('\n') {
p class="main__meta-item-member-description-para" { (paragraph) }
}
}
}
}
}
};
let meta_markup = self
.meta
.render_remaining(&[DESCRIPTION_KEY], assets)
.map_or_else(|| html! {}, |markup| html! { (markup) });
let definition = self.definition.display(None);
let markup = html! {
div class="main__container" {
p class="text-brand-lime-300" { "Enum" }
h1 id="title" class="main__title" { code { (name) } }
div class="markdown-body mb-4" {
(self.meta.render_description(false))
}
div class="main__badge-container" {
(self.version.render())
}
div class="main__section" {
sprocket-code language="wdl" {
(definition)
}
}
div class="main__section" {
(meta_markup)
}
(choices)
}
};
(markup, PageSections::default())
}
}
fn parse_meta(
definition: &EnumDefinition,
enable_doc_comments: bool,
) -> (MetaMap, Vec<DocumentedEnumChoice>) {
let enum_docs = if enable_doc_comments {
doc_comments(definition.keyword().inner())
} else {
MetaMap::new()
};
let mut choice_docs = Vec::new();
for choice in definition.variants() {
let meta = if enable_doc_comments {
doc_comments(choice.name().inner())
} else {
MetaMap::new()
};
choice_docs.push(DocumentedEnumChoice {
meta,
choice: choice.clone(),
});
}
(enum_docs, choice_docs)
}