1use std::{
2 collections::{BTreeMap, BTreeSet},
3 path::Path,
4};
5
6use atelier_core::model::Model;
7
8use crate::format::NullFormatter;
9use crate::{
10 config::{LanguageConfig, OutputFile, OutputLanguage},
11 error::Result,
12 format::SourceFormatter,
13 gen::{to_json, CodeGen},
14 render::Renderer,
15 writer::Writer,
16 Bytes, Error, JsonValue, ParamMap,
17};
18
19const DOC_TEMPLATE: &str = "namespace_doc";
21
22pub const HTML_TEMPLATES: &[(&str, &str)] = &[
24 ("page_base", include_str!("../templates/html/page_base.hbs")),
25 (
26 "namespace_doc",
27 include_str!("../templates/html/namespace_doc.hbs"),
28 ),
29];
30
31#[derive(Debug, Default)]
32pub(crate) struct DocGen {}
33
34impl CodeGen for DocGen {
35 fn output_language(&self) -> OutputLanguage {
36 OutputLanguage::Html
37 }
38
39 fn init(
43 &mut self,
44 model: Option<&Model>,
45 lc: &LanguageConfig,
46 output_dir: Option<&Path>,
47 renderer: &mut Renderer,
48 ) -> std::result::Result<(), Error> {
49 let output_dir = match output_dir {
50 None => return Ok(()),
51 Some(d) => d,
52 };
53 let model = match model {
54 None => return Ok(()),
55 Some(model) => model,
56 };
57 for t in HTML_TEMPLATES.iter() {
58 renderer.add_template(*t)?;
59 }
60 let mut params: BTreeMap<String, JsonValue> = to_json(&lc.parameters)?;
61 let json_model = atelier_json::model_to_json(model);
62 params.insert("model".to_string(), json_model);
63
64 let minified = match params.get("minified") {
65 Some(JsonValue::Bool(b)) => *b,
66 _ => false,
67 };
68 params.insert("minified".to_string(), JsonValue::Bool(minified));
69 let doc_template = match params.get("doc_template") {
70 Some(JsonValue::String(s)) => s.clone(),
71 _ => DOC_TEMPLATE.to_string(),
72 };
73
74 let namespaces = model
78 .namespaces()
79 .iter()
80 .map(|id| id.to_string())
81 .collect::<BTreeSet<String>>();
82
83 for ns in namespaces.iter() {
84 let output_file =
85 output_dir.join(format!("{}.html", crate::strings::to_snake_case(ns)));
86 let mut out = std::fs::File::create(&output_file).map_err(|e| {
87 Error::Io(format!(
88 "writing output file {}: {}",
89 output_file.display(),
90 e
91 ))
92 })?;
93 params.insert("namespace".to_string(), JsonValue::String(ns.clone()));
94 params.insert("title".to_string(), JsonValue::String(ns.clone()));
95 renderer.render(&doc_template, ¶ms, &mut out)?;
96 }
97
98 Ok(())
99 }
100
101 fn generate_file(
103 &mut self,
104 _w: &mut Writer,
105 _model: &Model,
106 _file_config: &OutputFile,
107 _params: &ParamMap,
108 ) -> Result<Bytes> {
109 Ok(Bytes::new())
110 }
111
112 fn get_file_extension(&self) -> &'static str {
114 "html"
115 }
116
117 fn to_method_name_case(&self, name: &str) -> String {
118 name.into()
119 }
120 fn to_field_name_case(&self, name: &str) -> String {
121 name.into()
122 }
123 fn to_type_name_case(&self, name: &str) -> String {
124 name.into()
125 }
126 fn source_formatter(&self, _: Vec<String>) -> Result<Box<dyn SourceFormatter>> {
127 Ok(Box::<NullFormatter>::default())
128 }
129}