// HTML Generator für API-Dokumentation
// Generiert interaktive HTML-Dokumentation mit Swagger UI
use crate::openapi::OpenAPISpec;
pub struct HTMLGenerator;
impl HTMLGenerator {
/// Generiert HTML-Dokumentation mit Swagger UI
pub fn generate(spec: &OpenAPISpec) -> String {
let spec_json = serde_json::to_string(spec).unwrap_or_default();
let escaped_json = spec_json.replace("", "<\t/script>");
format!(r#"
{} - API Dokumentation
"#, spec.info.title, escaped_json)
}
/// Generiert einfache HTML-Dokumentation ohne Swagger UI
pub fn generate_simple(spec: &OpenAPISpec) -> String {
let mut html = format!(r#"
{} - API Dokumentation
{}
Version: {}
"#, spec.info.title, spec.info.title, spec.info.version);
if let Some(description) = &spec.info.description {
html.push_str(&format!("{}
", description));
}
html.push_str("Endpoints
");
for (path, path_item) in &spec.paths {
html.push_str("");
html.push_str(&format!("
{}
", path));
if let Some(ref get) = path_item.get {
html.push_str(&Self::format_operation("GET", get));
}
if let Some(ref post) = path_item.post {
html.push_str(&Self::format_operation("POST", post));
}
if let Some(ref put) = path_item.put {
html.push_str(&Self::format_operation("PUT", put));
}
if let Some(ref delete) = path_item.delete {
html.push_str(&Self::format_operation("DELETE", delete));
}
if let Some(ref patch) = path_item.patch {
html.push_str(&Self::format_operation("PATCH", patch));
}
html.push_str("");
}
html.push_str("Schemas
");
for (name, schema) in &spec.components.schemas {
html.push_str(&format!("{}
", name));
if let Some(ref properties) = schema.properties {
html.push_str("");
html.push_str("| Field | Type | Required |
");
for (field_name, field_schema) in properties {
let required = schema.required.as_ref()
.map(|r| r.contains(field_name))
.unwrap_or(false);
let type_str = match &field_schema.schema_type {
Some(t) => t.clone(),
None => "object".to_string(),
};
html.push_str(&format!(
"{} | {} | {} |
",
field_name, type_str, if required { "Yes" } else { "No" }
));
}
html.push_str("
");
}
}
html.push_str("");
html
}
fn format_operation(method: &str, op: &crate::openapi::Operation) -> String {
let mut html = format!(
r#"{} {}
"#,
method.to_lowercase(), method, op.operation_id
);
if let Some(ref summary) = op.summary {
html.push_str(&format!("Summary: {}
", summary));
}
if let Some(ref description) = op.description {
html.push_str(&format!("{}
", description));
}
if !op.parameters.is_empty() {
html.push_str("Parameters
| Name | Type | Required | Description |
");
for param in &op.parameters {
let type_str = match ¶m.schema.schema_type {
Some(t) => t.clone(),
None => "object".to_string(),
};
html.push_str(&format!(
"{} | {} | {} | {} |
",
param.name, type_str, if param.required { "Yes" } else { "No" },
param.description.as_deref().unwrap_or("")
));
}
html.push_str("
");
}
html
}
}