use maud::Markup;
use maud::html;
use wdl_ast::AstNode;
use wdl_ast::AstToken;
use wdl_ast::v1::Decl;
use wdl_ast::v1::MetadataValue;
use crate::callable::Group;
use crate::meta::render_value;
#[derive(Debug, Clone, Copy)]
pub enum InputOutput {
Input,
Output,
}
#[derive(Debug)]
pub struct Parameter {
decl: Decl,
meta: Option<MetadataValue>,
io: InputOutput,
}
impl Parameter {
pub fn new(decl: Decl, meta: Option<MetadataValue>, io: InputOutput) -> Self {
Self { decl, meta, io }
}
pub fn name(&self) -> String {
self.decl.name().text().to_owned()
}
pub fn ty(&self) -> String {
self.decl.ty().to_string()
}
pub fn io(&self) -> InputOutput {
self.io
}
pub fn expr(&self) -> String {
self.decl
.expr()
.map(|expr| expr.text().to_string())
.unwrap_or("None".to_string())
}
pub fn required(&self) -> Option<bool> {
match self.io {
InputOutput::Input => match self.decl.as_unbound_decl() {
Some(d) => Some(!d.ty().is_optional()),
_ => Some(false),
},
InputOutput::Output => None,
}
}
pub fn group(&self) -> Option<Group> {
if let Some(MetadataValue::Object(o)) = &self.meta {
for item in o.items() {
if item.name().text() == "group" {
if let MetadataValue::String(s) = item.value() {
return s.text().map(|t| t.text().to_string()).map(Group);
}
}
}
}
None
}
pub fn description(&self) -> Markup {
if let Some(meta) = &self.meta {
if let MetadataValue::String(_) = meta {
return render_value(meta);
} else if let MetadataValue::Object(o) = meta {
for item in o.items() {
if item.name().text() == "description" {
if let MetadataValue::String(_) = item.value() {
return render_value(&item.value());
}
}
}
}
}
html! {}
}
pub fn render_remaining_meta(&self) -> Markup {
if let Some(MetadataValue::Object(o)) = &self.meta {
let filtered_items = o.items().filter(|item| {
item.name().text() != "description" && item.name().text() != "group"
});
return html! {
ul {
@for item in filtered_items {
li {
b { (item.name().text()) ":" } " " (render_value(&item.value()))
}
}
}
};
}
html! {}
}
pub fn render(&self) -> Markup {
if self.required() == Some(true) {
html! {
tr class="border" {
td class="border" { (self.name()) }
td class="border" { code { (self.ty()) } }
td class="border" { (self.description()) }
td class="border" { (self.render_remaining_meta()) }
}
}
} else {
html! {
tr class="border" {
td class="border" { (self.name()) }
td class="border" { code { (self.ty()) } }
td class="border" { code { (self.expr()) } }
td class="border" { (self.description()) }
td class="border" { (self.render_remaining_meta()) }
}
}
}
}
}