#![allow(dead_code)]
#[cfg(not(all(feature = "metadata", feature = "doc-gen")))]
compile_error!(
"\n\n\
❌ This example requires both 'metadata' and 'doc-gen' features!\n\
\n\
Run with:\n\
cargo run --example in_component_doc_generation --features metadata,doc-gen\n\
"
);
#[cfg(all(feature = "metadata", feature = "doc-gen"))]
use std::fs;
#[cfg(all(feature = "metadata", feature = "doc-gen"))]
use waddling_errors_macros::{diag, in_component, setup};
#[cfg(all(feature = "metadata", feature = "doc-gen"))]
pub mod components {
use waddling_errors_macros::component;
component! {
pub enum Component {
Auth {
docs: "Authentication and authorization",
},
Api {
docs: "External API integrations",
},
}
}
pub use Component::*;
}
#[cfg(all(feature = "metadata", feature = "doc-gen"))]
pub mod primaries {
use waddling_errors_macros::primary;
primary! {
pub enum Primary {
Token {
docs: "Token-related errors",
},
Connection {
docs: "Connection errors",
},
Session {
docs: "Session errors",
},
}
}
}
#[cfg(all(feature = "metadata", feature = "doc-gen"))]
pub mod sequences {
use waddling_errors_macros::sequence;
sequence! {
EXPIRED(1) {
description: "Resource has expired",
},
INVALID(2) {
description: "Resource is invalid",
},
FAILED(3) {
description: "Operation failed",
},
}
}
#[cfg(all(feature = "metadata", feature = "doc-gen"))]
setup! {
components = crate::components,
primaries = crate::primaries,
sequences = crate::sequences,
}
#[cfg(all(feature = "metadata", feature = "doc-gen"))]
#[in_component(Auth, role = public)]
mod auth_public_example {
use super::*;
pub fn example_usage() {
println!("Example: Using JWT authentication");
}
diag! {
strict(component, primary, sequence, naming, duplicates, sequence_values, string_values),
E.Auth.Token.EXPIRED: {
message: "JWT token has expired",
hints: ["Request a new token"],
},
}
}
#[cfg(all(feature = "metadata", feature = "doc-gen"))]
#[in_component(Auth, role = internal)]
mod auth_internal {
use super::*;
pub fn verify_token() {
println!("Internal: Verifying token signature");
}
diag! {
strict(component, primary, sequence, naming, duplicates, sequence_values, string_values),
E.Auth.Token.INVALID: {
message: "JWT token signature invalid",
hints: ["Check signing key"],
},
}
}
#[cfg(all(feature = "metadata", feature = "doc-gen"))]
#[in_component(Auth, role = developer)]
mod auth_debug {
use super::*;
pub fn inspect_claims() {
println!("Debug: Inspecting JWT claims");
}
diag! {
strict(component, primary, sequence, naming, duplicates, sequence_values, string_values),
W.Auth.Session.INVALID: {
message: "Session validation warning",
hints: ["Check session store"],
},
}
}
#[cfg(all(feature = "metadata", feature = "doc-gen"))]
#[in_component(Api, role = public)]
mod api_example {
use super::*;
pub fn call_api() {
println!("Example: Calling external API");
}
diag! {
strict(component, primary, sequence, naming, duplicates, sequence_values, string_values),
E.Api.Connection.FAILED: {
message: "API connection failed",
hints: ["Check network connectivity"],
},
}
}
#[cfg(all(feature = "metadata", feature = "doc-gen"))]
#[in_component(Api)] mod api_internal {
use super::*;
pub fn retry_with_backoff() {
println!("Internal: Retry with exponential backoff");
}
diag! {
strict(component, primary, sequence, naming, duplicates, sequence_values, string_values),
E.Api.Connection.INVALID: {
message: "API endpoint URL invalid",
hints: ["Verify API configuration"],
},
}
}
#[cfg(all(feature = "metadata", feature = "doc-gen"))]
fn main() {
use waddling_errors::doc_generator::{DocRegistry, JsonRenderer};
println!("🦆 In-Component Documentation Generation Test");
println!("==============================================\n");
let mut registry = DocRegistry::new("in_component_test", "1.0.0");
println!("📝 Registering diagnostics...");
registry.register_diagnostic_runtime(&auth_public_example::E_AUTH_TOKEN_EXPIRED);
registry.register_diagnostic_runtime(&auth_internal::E_AUTH_TOKEN_INVALID);
registry.register_diagnostic_runtime(&auth_debug::W_AUTH_SESSION_INVALID);
registry.register_diagnostic_runtime(&api_example::E_API_CONNECTION_FAILED);
registry.register_diagnostic_runtime(&api_internal::E_API_CONNECTION_INVALID);
println!(" ✓ Registered 5 diagnostics");
println!("\n📍 Registering component locations...");
auth_public_example::__register_component_location(&mut registry);
auth_internal::__register_component_location(&mut registry);
auth_debug::__register_component_location(&mut registry);
api_example::__register_component_location(&mut registry);
api_internal::__register_component_location(&mut registry);
println!(" ✓ Registered 5 component locations");
println!(" - Auth: 3 locations (public, developer, internal)");
println!(" - Api: 2 locations (public, internal)");
println!("\n🔍 Verifying component name case preservation...");
assert_eq!(
auth_public_example::__COMPONENT,
"Auth",
"Expected PascalCase Auth"
);
assert_eq!(
auth_internal::__COMPONENT,
"Auth",
"Expected PascalCase Auth"
);
assert_eq!(auth_debug::__COMPONENT, "Auth", "Expected PascalCase Auth");
assert_eq!(api_example::__COMPONENT, "Api", "Expected PascalCase Api");
assert_eq!(api_internal::__COMPONENT, "Api", "Expected PascalCase Api");
println!(" ✓ All component names preserve PascalCase");
let output_dir = "target/doc/in_component_test";
println!("\n📚 Generating documentation to {}/...", output_dir);
match registry.render_all_roles(vec![Box::new(JsonRenderer)], output_dir) {
Ok(_) => println!(" ✓ Documentation generated successfully"),
Err(e) => {
eprintln!(" ❌ Failed to generate documentation: {}", e);
std::process::exit(1);
}
}
println!("\n🔬 Verifying generated JSON output...\n");
let int_json_path = format!("{}/in_component_test-int.json", output_dir);
verify_json_locations(
&int_json_path,
"Internal",
&[
("Auth", 3, vec!["Public", "Developer", "Internal"]),
("Api", 2, vec!["Public", "Internal"]),
],
);
let dev_json_path = format!("{}/in_component_test-dev.json", output_dir);
verify_json_locations(
&dev_json_path,
"Developer",
&[
("Auth", 2, vec!["Public", "Developer"]),
("Api", 1, vec!["Public"]),
],
);
let pub_json_path = format!("{}/in_component_test-pub.json", output_dir);
verify_json_locations(
&pub_json_path,
"Public",
&[("Auth", 1, vec!["Public"]), ("Api", 1, vec!["Public"])],
);
println!("\n✅ All verifications passed!");
println!("\n📋 Summary:");
println!(" - #[in_component] correctly preserves PascalCase component names");
println!(" - Component locations are registered in DocRegistry");
println!(" - Role-based filtering works for locations");
println!(" - JSON output includes component locations");
println!();
println!("🎉 The in_component macro is working correctly!");
}
#[cfg(all(feature = "metadata", feature = "doc-gen"))]
fn verify_json_locations(json_path: &str, role_name: &str, expected: &[(&str, usize, Vec<&str>)]) {
println!(" Checking {} JSON ({})...", role_name, json_path);
let content = fs::read_to_string(json_path).unwrap_or_else(|e| {
panic!("Failed to read {}: {}", json_path, e);
});
for (component_name, expected_count, expected_roles) in expected {
let component_marker = format!("\"{}\":", component_name);
if !content.contains(&component_marker) {
panic!(
"Component '{}' not found in {} JSON",
component_name, role_name
);
}
for role in expected_roles {
let role_pattern = format!("\"role\": \"{}\"", role);
if !content.contains(&role_pattern) {
panic!(
"Role '{}' not found in {} JSON for component {}",
role, role_name, component_name
);
}
}
let component_section_start = content.find(&component_marker).unwrap();
let component_section = &content[component_section_start..];
if let Some(locations_start) = component_section.find("\"locations\": [") {
let locations_section = &component_section[locations_start..];
if let Some(locations_end) = locations_section.find(']') {
let locations_content = &locations_section[..locations_end];
let path_count = locations_content.matches("\"path\":").count();
if path_count != *expected_count {
println!(
" Locations content for {}: {}",
component_name, locations_content
);
panic!(
"Component '{}' in {} JSON: expected {} locations, got {}",
component_name, role_name, expected_count, path_count
);
}
println!(" ✓ {} has {} locations", component_name, path_count);
}
} else {
panic!(
"No locations array found for component '{}'",
component_name
);
}
}
}
#[cfg(not(all(feature = "metadata", feature = "doc-gen")))]
fn main() {}