diff --git a/crates/dmdoc/src/main.rs b/crates/dmdoc/src/main.rs index 248ed948..65775eea 100644 --- a/crates/dmdoc/src/main.rs +++ b/crates/dmdoc/src/main.rs @@ -8,6 +8,7 @@ extern crate walkdir; mod markdown; mod template; +use dm::ast::InputType; use dm::objtree::ObjectTree; use maud::{Markup, PreEscaped}; use pulldown_cmark::{BrokenLink, CowStr}; @@ -404,6 +405,7 @@ fn main2() -> Result<(), Box> { params: proc_value.parameters.iter().map(|p| Param { name: p.name.clone(), type_path: format_type_path(&p.var_type.type_path), + input_type: p.input_type, }).collect(), decl: match proc.declaration { Some(ref decl) => decl.kind.name(), @@ -1298,6 +1300,7 @@ struct Proc { struct Param { name: String, type_path: String, + input_type: Option, } /// Module struct exposed to templates. diff --git a/crates/dmdoc/src/template.rs b/crates/dmdoc/src/template.rs index d6d3827f..734fd94f 100644 --- a/crates/dmdoc/src/template.rs +++ b/crates/dmdoc/src/template.rs @@ -2,6 +2,7 @@ use std::path::Path; +use dm::ast::InputType; use maud::{display, html, Markup, PreEscaped, Render, DOCTYPE}; use crate::{markdown::DocBlock, Environment, Index, IndexTree, ModuleArgs, ModuleItem, Type}; @@ -443,6 +444,12 @@ pub(crate) fn dm_type(ty: &Type) -> Markup { "/" } (param.name) + @if let Some(input_type) = param.input_type { + @if !input_type.is_empty() { + i { " as " } + (render_input_type(env, input_type)) + } + } } ") " (git_link(env, &proc.file.to_string_lossy(), proc.line)) @@ -455,6 +462,48 @@ pub(crate) fn dm_type(ty: &Type) -> Markup { ) } +pub fn render_input_type(env: &Environment, input_type: InputType) -> Markup { + html! { + @for (i, &name) in matching_names(input_type).iter().enumerate() { + @if i > 0 { " | " } + @match name { + "mob" => (linkify_input_type(env, "mob", "/mob")), + "obj" => (linkify_input_type(env, "obj", "/obj")), + "turf" => (linkify_input_type(env, "turf", "/turf")), + "area" => (linkify_input_type(env, "area", "/area")), + //"icon" => (linkify_input_type(env, "icon", "/icon")), + //"sound" => (linkify_input_type(env, "sound", "/sound")), + "movable" => (linkify_input_type(env, "movable", "/atom/movable")), + "atom" => (linkify_input_type(env, "atom", "/atom")), + "list" => (linkify_input_type(env, "list", "/list")), + _ => (name), + } + } + } +} + +fn linkify_input_type(env: &Environment, show: &str, typepath: &str) -> Markup { + if env.all_type_names.contains(typepath) { + html! { + a href=(format!("{}.html", &typepath[1..])) { (show) } + } + } else { + html! { (show) } + } +} + +fn matching_names(mut input_type: InputType) -> Vec<&'static str> { + let mut result = Vec::with_capacity(input_type.bits().count_ones() as usize); + for &(name, value) in InputType::ENTRIES.iter().rev() { + if input_type.contains(value) { + input_type.remove(value); + result.push(name); + } + } + result.reverse(); + result +} + pub fn save_resources(output_path: &Path) -> std::io::Result<()> { #[cfg(debug_assertions)] macro_rules! resources { diff --git a/crates/dreammaker/src/ast.rs b/crates/dreammaker/src/ast.rs index c338b561..bbdeca0c 100644 --- a/crates/dreammaker/src/ast.rs +++ b/crates/dreammaker/src/ast.rs @@ -456,6 +456,12 @@ macro_rules! type_table { } } + impl $name { + pub const ENTRIES: &'static [(&'static str, $name)] = &[ + $(($txt, $name::$i),)* + ]; + } + impl std::str::FromStr for $name { type Err = ();